[cfe-commits] r123055 - in /cfe/trunk: include/clang/Analysis/Analyses/FormatString.h lib/Analysis/PrintfFormatString.cpp lib/Sema/SemaChecking.cpp test/Sema/format-strings.c

Ted Kremenek kremenek at apple.com
Fri Jan 7 21:28:46 PST 2011


Author: kremenek
Date: Fri Jan  7 23:28:46 2011
New Revision: 123055

URL: http://llvm.org/viewvc/llvm-project?rev=123055&view=rev
Log:
Add semantic checking that the "thousands grouping"
prefix in a printf format string is matched
with the appropriate conversion specifier.

Modified:
    cfe/trunk/include/clang/Analysis/Analyses/FormatString.h
    cfe/trunk/lib/Analysis/PrintfFormatString.cpp
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/test/Sema/format-strings.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=123055&r1=123054&r2=123055&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/Analyses/FormatString.h (original)
+++ cfe/trunk/include/clang/Analysis/Analyses/FormatString.h Fri Jan  7 23:28:46 2011
@@ -450,6 +450,9 @@
   /// more than one type.
   ArgTypeResult getArgType(ASTContext &Ctx) const;
 
+  const OptionalFlag &hasThousandsGrouping() const { 
+      return HasThousandsGrouping;
+  }
   const OptionalFlag &isLeftJustified() const { return IsLeftJustified; }
   const OptionalFlag &hasPlusPrefix() const { return HasPlusPrefix; }
   const OptionalFlag &hasAlternativeForm() const { return HasAlternativeForm; }
@@ -470,6 +473,7 @@
   bool hasValidLeadingZeros() const;
   bool hasValidSpacePrefix() const;
   bool hasValidLeftJustified() const;
+  bool hasValidThousandsGroupingPrefix() const;
 
   bool hasValidPrecision() const;
   bool hasValidFieldWidth() const;

Modified: cfe/trunk/lib/Analysis/PrintfFormatString.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/PrintfFormatString.cpp?rev=123055&r1=123054&r2=123055&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/PrintfFormatString.cpp (original)
+++ cfe/trunk/lib/Analysis/PrintfFormatString.cpp Fri Jan  7 23:28:46 2011
@@ -590,6 +590,24 @@
   }
 }
 
+bool PrintfSpecifier::hasValidThousandsGroupingPrefix() const {
+  if (!HasThousandsGrouping)
+    return true;
+  
+  switch (CS.getKind()) {
+    case ConversionSpecifier::dArg:
+    case ConversionSpecifier::iArg:
+    case ConversionSpecifier::uArg:
+    case ConversionSpecifier::fArg:
+    case ConversionSpecifier::FArg:
+    case ConversionSpecifier::gArg:
+    case ConversionSpecifier::GArg:
+      return true;
+    default:
+      return false;
+  }
+}
+
 bool PrintfSpecifier::hasValidPrecision() const {
   if (Precision.getHowSpecified() == OptionalAmount::NotSpecified)
     return true;

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=123055&r1=123054&r2=123055&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Jan  7 23:28:46 2011
@@ -1491,6 +1491,8 @@
   }
 
   // Check each flag does not conflict with any other component.
+  if (!FS.hasValidThousandsGroupingPrefix())
+    HandleFlag(FS, FS.hasThousandsGrouping(), startSpecifier, specifierLen);
   if (!FS.hasValidLeadingZeros())
     HandleFlag(FS, FS.hasLeadingZeros(), startSpecifier, specifierLen);
   if (!FS.hasValidPlusPrefix())

Modified: cfe/trunk/test/Sema/format-strings.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-strings.c?rev=123055&r1=123054&r2=123055&view=diff
==============================================================================
--- cfe/trunk/test/Sema/format-strings.c (original)
+++ cfe/trunk/test/Sema/format-strings.c Fri Jan  7 23:28:46 2011
@@ -336,4 +336,7 @@
   // Test %'d, "thousands grouping".
   // <rdar://problem/8816343>
   printf("%'d\n", 123456789); // no-warning
+  printf("%'i\n", 123456789); // no-warning
+  printf("%'f\n", (float) 1.0); // no-warning
+  printf("%'p\n", (void*) 0); // expected-warning{{results in undefined behavior with 'p' conversion specifier}}
 }





More information about the cfe-commits mailing list