r204300 - scanf format checking: include the buffer length in the fix-it for %s.
Jordan Rose
jordan_rose at apple.com
Wed Mar 19 20:32:40 PDT 2014
Author: jrose
Date: Wed Mar 19 22:32:39 2014
New Revision: 204300
URL: http://llvm.org/viewvc/llvm-project?rev=204300&view=rev
Log:
scanf format checking: include the buffer length in the fix-it for %s.
Patch by Zach Davis!
Modified:
cfe/trunk/include/clang/Analysis/Analyses/FormatString.h
cfe/trunk/lib/Analysis/ScanfFormatString.cpp
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/test/Sema/format-strings-fixit.c
Modified: cfe/trunk/include/clang/Analysis/Analyses/FormatString.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/FormatString.h?rev=204300&r1=204299&r2=204300&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/Analyses/FormatString.h (original)
+++ cfe/trunk/include/clang/Analysis/Analyses/FormatString.h Wed Mar 19 22:32:39 2014
@@ -572,7 +572,8 @@ public:
ArgType getArgType(ASTContext &Ctx) const;
- bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx);
+ bool fixType(QualType QT, QualType RawQT, const LangOptions &LangOpt,
+ ASTContext &Ctx);
void toString(raw_ostream &os) const;
Modified: cfe/trunk/lib/Analysis/ScanfFormatString.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ScanfFormatString.cpp?rev=204300&r1=204299&r2=204300&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/ScanfFormatString.cpp (original)
+++ cfe/trunk/lib/Analysis/ScanfFormatString.cpp Wed Mar 19 22:32:39 2014
@@ -379,21 +379,23 @@ ArgType ScanfSpecifier::getArgType(ASTCo
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 +407,15 @@ bool ScanfSpecifier::fixType(QualType QT
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;
}
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=204300&r1=204299&r2=204300&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Wed Mar 19 22:32:39 2014
@@ -3518,8 +3518,9 @@ bool CheckScanfHandler::HandleScanfSpeci
const analyze_format_string::ArgType &AT = FS.getArgType(S.Context);
if (AT.isValid() && !AT.matchesType(S.Context, Ex->getType())) {
ScanfSpecifier fixedFS = FS;
- bool success = fixedFS.fixType(Ex->getType(), S.getLangOpts(),
- S.Context);
+ bool success = fixedFS.fixType(Ex->getType(),
+ Ex->IgnoreImpCasts()->getType(),
+ S.getLangOpts(), S.Context);
if (success) {
// Get the fix string from the fixed format specifier.
Modified: cfe/trunk/test/Sema/format-strings-fixit.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-strings-fixit.c?rev=204300&r1=204299&r2=204300&view=diff
==============================================================================
--- cfe/trunk/test/Sema/format-strings-fixit.c (original)
+++ cfe/trunk/test/Sema/format-strings-fixit.c Wed Mar 19 22:32:39 2014
@@ -14,6 +14,7 @@ typedef __SIZE_TYPE__ size_t;
typedef __INTMAX_TYPE__ intmax_t;
typedef __UINTMAX_TYPE__ uintmax_t;
typedef __PTRDIFF_TYPE__ ptrdiff_t;
+typedef __WCHAR_TYPE__ wchar_t;
void test() {
// Basic types
@@ -97,11 +98,14 @@ void test() {
int scanf(char const *, ...);
-void test2() {
+void test2(int intSAParm[static 2]) {
char str[100];
+ char *vstr = "abc";
+ wchar_t wstr[100];
short shortVar;
unsigned short uShortVar;
int intVar;
+ int intAVar[2];
unsigned uIntVar;
float floatVar;
double doubleVar;
@@ -114,11 +118,22 @@ void test2() {
intmax_t intmaxVar;
uintmax_t uIntmaxVar;
ptrdiff_t ptrdiffVar;
+ enum {A, B, C} enumVar;
+ // Some string types.
scanf("%lf", str);
+ scanf("%lf", vstr);
+ scanf("%ls", str);
+ scanf("%f", wstr); // FIXME: wchar_t should resolve to %ls, not %d.
+ scanf("%s", wstr); // FIXME: wchar_t should resolve to %ls, not %d.
+ scanf("%ls", str);
+
+ // Some integer types.
scanf("%f", &shortVar);
scanf("%f", &uShortVar);
scanf("%p", &intVar);
+ scanf("%f", intAVar);
+ scanf("%f", intSAParm);
scanf("%Lf", &uIntVar);
scanf("%ld", &floatVar);
scanf("%f", &doubleVar);
@@ -127,6 +142,7 @@ void test2() {
scanf("%f", &uLongVar);
scanf("%f", &longLongVar);
scanf("%f", &uLongLongVar);
+ scanf("%d", &enumVar); // FIXME: We ought to fix specifiers for enums.
// Some named ints.
scanf("%f", &sizeVar);
@@ -206,10 +222,17 @@ void test2() {
// CHECK: printf("%La", (long double) 42);
// CHECK: printf("%LA", (long double) 42);
-// CHECK: scanf("%s", str);
+// CHECK: scanf("%99s", str);
+// CHECK: scanf("%s", vstr);
+// CHECK: scanf("%99s", str);
+// CHECK: scanf("%d", wstr);
+// CHECK: scanf("%d", wstr);
+// CHECK: scanf("%99s", str);
// CHECK: scanf("%hd", &shortVar);
// CHECK: scanf("%hu", &uShortVar);
// CHECK: scanf("%d", &intVar);
+// CHECK: scanf("%d", intAVar);
+// CHECK: scanf("%d", intSAParm);
// CHECK: scanf("%u", &uIntVar);
// CHECK: scanf("%f", &floatVar);
// CHECK: scanf("%lf", &doubleVar);
@@ -218,6 +241,7 @@ void test2() {
// CHECK: scanf("%lu", &uLongVar);
// CHECK: scanf("%lld", &longLongVar);
// CHECK: scanf("%llu", &uLongLongVar);
+// CHECK: scanf("%d", &enumVar);
// CHECK: scanf("%zu", &sizeVar);
// CHECK: scanf("%jd", &intmaxVar);
// CHECK: scanf("%ju", &uIntmaxVar);
More information about the cfe-commits
mailing list