]> granicus.if.org Git - clang/commitdiff
Format string analysis: give 'q' its own enumerator.
authorHans Wennborg <hans@hanshq.net>
Thu, 16 Feb 2012 16:34:54 +0000 (16:34 +0000)
committerHans Wennborg <hans@hanshq.net>
Thu, 16 Feb 2012 16:34:54 +0000 (16:34 +0000)
This is in preparation for being able to warn about 'q' and other
non-standard format string features.

It also allows us to print its name correctly.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150697 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/Analyses/FormatString.h
lib/Analysis/FormatString.cpp
lib/Analysis/PrintfFormatString.cpp
lib/Analysis/ScanfFormatString.cpp
test/Sema/format-strings-scanf.c
test/Sema/format-strings.c

index f3fe32474c760f1f027bc555c51f52cdedc4064d..ce66fcf2123fb32213440326b0d918374076c146 100644 (file)
@@ -66,7 +66,8 @@ public:
     AsChar,       // 'hh'
     AsShort,      // 'h'
     AsLong,       // 'l'
-    AsLongLong,   // 'll', 'q' (BSD, deprecated)
+    AsLongLong,   // 'll'
+    AsQuad,       // 'q' (BSD, deprecated, same as 'll')
     AsIntMax,     // 'j'
     AsSizeT,      // 'z'
     AsPtrDiff,    // 't'
index 1c911c45c3b5af4d5e97276cad65d84d1ef3d23f..fcc293bf30d26d59749fdfdc952f70ddb1dfb21e 100644 (file)
@@ -198,7 +198,7 @@ clang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS,
     case 'z': lmKind = LengthModifier::AsSizeT;      ++I; break;
     case 't': lmKind = LengthModifier::AsPtrDiff;    ++I; break;
     case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break;
-    case 'q': lmKind = LengthModifier::AsLongLong;   ++I; break;
+    case 'q': lmKind = LengthModifier::AsQuad;       ++I; break;
     case 'a':
       if (IsScanf && !LO.C99 && !LO.CPlusPlus0x) {
         // For scanf in C90, look at the next character to see if this should
@@ -417,6 +417,8 @@ analyze_format_string::LengthModifier::toString() const {
     return "l";
   case AsLongLong:
     return "ll";
+  case AsQuad:
+    return "q";
   case AsIntMax:
     return "j";
   case AsSizeT:
@@ -506,10 +508,11 @@ bool FormatSpecifier::hasValidLengthModifier() const {
     case LengthModifier::None:
       return true;
       
-        // Handle most integer flags
+    // Handle most integer flags
     case LengthModifier::AsChar:
     case LengthModifier::AsShort:
     case LengthModifier::AsLongLong:
+    case LengthModifier::AsQuad:
     case LengthModifier::AsIntMax:
     case LengthModifier::AsSizeT:
     case LengthModifier::AsPtrDiff:
@@ -526,7 +529,7 @@ bool FormatSpecifier::hasValidLengthModifier() const {
           return false;
       }
       
-        // Handle 'l' flag
+    // Handle 'l' flag
     case LengthModifier::AsLong:
       switch (CS.getKind()) {
         case ConversionSpecifier::dArg:
index ff0174e3c3e57d091c36ae5e7b9981aa61b91a51..e1049b3c685bf725eac9f3ce9aad15a6ae003122 100644 (file)
@@ -266,7 +266,9 @@ ArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx,
       case LengthModifier::AsChar: return ArgTypeResult::AnyCharTy;
       case LengthModifier::AsShort: return Ctx.ShortTy;
       case LengthModifier::AsLong: return Ctx.LongTy;
-      case LengthModifier::AsLongLong: return Ctx.LongLongTy;
+      case LengthModifier::AsLongLong:
+      case LengthModifier::AsQuad:
+        return Ctx.LongLongTy;
       case LengthModifier::AsIntMax:
         return ArgTypeResult(Ctx.getIntMaxType(), "intmax_t");
       case LengthModifier::AsSizeT:
@@ -288,7 +290,9 @@ ArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx,
       case LengthModifier::AsChar: return Ctx.UnsignedCharTy;
       case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
       case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
-      case LengthModifier::AsLongLong: return Ctx.UnsignedLongLongTy;
+      case LengthModifier::AsLongLong:
+      case LengthModifier::AsQuad:
+        return Ctx.UnsignedLongLongTy;
       case LengthModifier::AsIntMax:
         return ArgTypeResult(Ctx.getUIntMaxType(), "uintmax_t");
       case LengthModifier::AsSizeT:
index 5990a56c35c6c000e17a65268f0c9752b043b2f2..6bc4adb4f3c62613e509d62145eb3f16aa50e0c4 100644 (file)
@@ -210,7 +210,9 @@ ScanfArgTypeResult ScanfSpecifier::getArgType(ASTContext &Ctx) const {
           return ArgTypeResult(ArgTypeResult::AnyCharTy);
         case LengthModifier::AsShort: return ArgTypeResult(Ctx.ShortTy);
         case LengthModifier::AsLong: return ArgTypeResult(Ctx.LongTy);
-        case LengthModifier::AsLongLong: return ArgTypeResult(Ctx.LongLongTy);
+        case LengthModifier::AsLongLong:
+        case LengthModifier::AsQuad:
+          return ArgTypeResult(Ctx.LongLongTy);
         case LengthModifier::AsIntMax:
           return ScanfArgTypeResult(Ctx.getIntMaxType(), "intmax_t *");
         case LengthModifier::AsSizeT:
@@ -236,6 +238,7 @@ ScanfArgTypeResult ScanfSpecifier::getArgType(ASTContext &Ctx) const {
         case LengthModifier::AsShort: return ArgTypeResult(Ctx.UnsignedShortTy);
         case LengthModifier::AsLong: return ArgTypeResult(Ctx.UnsignedLongTy);
         case LengthModifier::AsLongLong:
+        case LengthModifier::AsQuad:
           return ArgTypeResult(Ctx.UnsignedLongLongTy);
         case LengthModifier::AsIntMax:
           return ScanfArgTypeResult(Ctx.getUIntMaxType(), "uintmax_t *");
index c97da3fd9219750fe2209881789974cc60f0628f..e94af5acb11c978e02522580098a783f880d73ea 100644 (file)
@@ -117,3 +117,7 @@ void test_longlong(long long *x, unsigned long long *y) {
   scanf("%Ls", "hello"); // expected-warning {{length modifier 'L' results in undefined behavior or no effect with 's' conversion specifier}}
 }
 
+void test_quad(int *x, long long *llx) {
+  scanf("%qd", x); // expected-warning{{format specifies type 'long long *' but the argument has type 'int *'}}
+  scanf("%qd", llx); // no-warning
+}
index a7b40f8a55fa2f3d61ec7e3732dd63a83b23fcb8..e6ce6e3c4ab8e103ea7803b2037dc3b1a6c6394e 100644 (file)
@@ -167,7 +167,9 @@ void test10(int x, float f, int i, long long lli) {
   printf("%.d", x); // no-warning
   printf("%.", x);  // expected-warning{{incomplete format specifier}}
   printf("%f", 4); // expected-warning{{format specifies type 'double' but the argument has type 'int'}}
-  printf("%qd", lli);
+  printf("%qd", lli); // no-warning
+  printf("%qd", x); // expected-warning{{format specifies type 'long long' but the argument has type 'int'}}
+  printf("%qp", (void *)0); // expected-warning{{length modifier 'q' results in undefined behavior or no effect with 'p' conversion specifier}}
   printf("hhX %hhX", (unsigned char)10); // no-warning
   printf("llX %llX", (long long) 10); // no-warning
   // This is fine, because there is an implicit conversion to an int.