diff options
author | dim <dim@FreeBSD.org> | 2014-11-24 09:15:30 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-11-24 09:15:30 +0000 |
commit | 173a4f43a911175643bda81ee675e8d9269056ea (patch) | |
tree | 47df2c12b57214af6c31e47404b005675b8b7ffc /lib/Analysis/ScanfFormatString.cpp | |
parent | 88f7a7d5251a2d813460274c92decc143a11569b (diff) | |
download | FreeBSD-src-173a4f43a911175643bda81ee675e8d9269056ea.zip FreeBSD-src-173a4f43a911175643bda81ee675e8d9269056ea.tar.gz |
Vendor import of clang RELEASE_350/final tag r216957 (effectively, 3.5.0 release):
https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_350/final@216957
Diffstat (limited to 'lib/Analysis/ScanfFormatString.cpp')
-rw-r--r-- | lib/Analysis/ScanfFormatString.cpp | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/lib/Analysis/ScanfFormatString.cpp b/lib/Analysis/ScanfFormatString.cpp index f5ce84f..ed28627 100644 --- a/lib/Analysis/ScanfFormatString.cpp +++ b/lib/Analysis/ScanfFormatString.cpp @@ -50,6 +50,15 @@ static bool ParseScanList(FormatStringHandler &H, } } + // Special case: "^]" are the first characters. + if (I + 1 != E && I[0] == '^' && I[1] == ']') { + I += 2; + if (I == E) { + H.HandleIncompleteScanList(start, I - 1); + return true; + } + } + // Look for a ']' character which denotes the end of the scan list. while (*I != ']') { if (++I == E) { @@ -73,7 +82,7 @@ static ScanfSpecifierResult ParseScanfSpecifier(FormatStringHandler &H, using namespace clang::analyze_scanf; const char *I = Beg; - const char *Start = 0; + const char *Start = nullptr; UpdateOnReturn <const char*> UpdateBeg(Beg, I); // Look for a '%' character that indicates the start of a format specifier. @@ -379,21 +388,23 @@ ArgType ScanfSpecifier::getArgType(ASTContext &Ctx) const { return ArgType(); } -bool ScanfSpecifier::fixType(QualType QT, const LangOptions &LangOpt, +bool ScanfSpecifier::fixType(QualType QT, QualType RawQT, + const LangOptions &LangOpt, ASTContext &Ctx) { - if (!QT->isPointerType()) - return false; // %n is different from other conversion specifiers; don't try to fix it. if (CS.getKind() == ConversionSpecifier::nArg) return false; + if (!QT->isPointerType()) + return false; + QualType PT = QT->getPointeeType(); // If it's an enum, get its underlying type. - if (const EnumType *ETy = QT->getAs<EnumType>()) - QT = ETy->getDecl()->getIntegerType(); - + if (const EnumType *ETy = PT->getAs<EnumType>()) + PT = ETy->getDecl()->getIntegerType(); + const BuiltinType *BT = PT->getAs<BuiltinType>(); if (!BT) return false; @@ -405,6 +416,15 @@ bool ScanfSpecifier::fixType(QualType QT, const LangOptions &LangOpt, LM.setKind(LengthModifier::AsWideChar); else LM.setKind(LengthModifier::None); + + // If we know the target array length, we can use it as a field width. + if (const ConstantArrayType *CAT = Ctx.getAsConstantArrayType(RawQT)) { + if (CAT->getSizeModifier() == ArrayType::Normal) + FieldWidth = OptionalAmount(OptionalAmount::Constant, + CAT->getSize().getZExtValue() - 1, + "", 0, false); + + } return true; } |