[cfe-commits] r52336 - in /cfe/trunk/lib/Sema: ParseAST.cpp Sema.cpp Sema.h SemaChecking.cpp

Ted Kremenek kremenek at apple.com
Mon Jun 16 11:00:43 PDT 2008


Author: kremenek
Date: Mon Jun 16 13:00:42 2008
New Revision: 52336

URL: http://llvm.org/viewvc/llvm-project?rev=52336&view=rev
Log:
Introduce preliminary support for NSString format-string checking.
Patch by Nikita Zhuk!

Modified:
    cfe/trunk/lib/Sema/ParseAST.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaChecking.cpp

Modified: cfe/trunk/lib/Sema/ParseAST.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/ParseAST.cpp?rev=52336&r1=52335&r2=52336&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/ParseAST.cpp (original)
+++ cfe/trunk/lib/Sema/ParseAST.cpp Mon Jun 16 13:00:42 2008
@@ -39,6 +39,8 @@
                      PP.getIdentifierTable(), PP.getSelectorTable());
   
   TranslationUnit TU(Context);
+  TU.SetOwnsDecls(false);
+  
 
   Sema S(PP, Context, *Consumer);
   Parser P(PP, S);

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=52336&r1=52335&r2=52336&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Mon Jun 16 13:00:42 2008
@@ -85,6 +85,7 @@
   KnownFunctionIDs[id_sprintf]   = &IT.get("sprintf");
   KnownFunctionIDs[id_snprintf]  = &IT.get("snprintf");
   KnownFunctionIDs[id_asprintf]  = &IT.get("asprintf");
+  KnownFunctionIDs[id_NSLog]     = &IT.get("NSLog");
   KnownFunctionIDs[id_vsnprintf] = &IT.get("vsnprintf");
   KnownFunctionIDs[id_vasprintf] = &IT.get("vasprintf");
   KnownFunctionIDs[id_vfprintf]  = &IT.get("vfprintf");

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=52336&r1=52335&r2=52336&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Jun 16 13:00:42 2008
@@ -124,6 +124,7 @@
     id_sprintf,
     id_snprintf,
     id_asprintf,
+    id_NSLog,
     id_vsnprintf,
     id_vasprintf,
     id_vfprintf,

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=52336&r1=52335&r2=52336&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Mon Jun 16 13:00:42 2008
@@ -17,6 +17,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/LiteralSupport.h"
 #include "clang/Basic/SourceManager.h"
@@ -86,6 +87,7 @@
     case id_sprintf:   format_idx = 1; break;
     case id_snprintf:  format_idx = 2; break;
     case id_asprintf:  format_idx = 1; break;
+    case id_NSLog:     format_idx = 0; break;
     case id_vsnprintf: format_idx = 2; HasVAListArg = true; break;
     case id_vasprintf: format_idx = 1; HasVAListArg = true; break;
     case id_vfprintf:  format_idx = 1; HasVAListArg = true; break;
@@ -361,7 +363,19 @@
   // are string literals: (1) permits the checking of format strings by
   // the compiler and thereby (2) can practically remove the source of
   // many format string exploits.
-  StringLiteral *FExpr = dyn_cast<StringLiteral>(OrigFormatExpr);
+
+  // Format string can be either ObjC string (e.g. @"%d") or 
+  // C string (e.g. "%d")
+  // ObjC string uses the same format specifiers as C string, so we can use 
+  // the same format string checking logic for both ObjC and C strings.
+  ObjCStringLiteral *ObjCFExpr = dyn_cast<ObjCStringLiteral>(OrigFormatExpr);
+  StringLiteral *FExpr = NULL;
+
+  if(ObjCFExpr != NULL) 
+    FExpr = ObjCFExpr->getString();
+  else
+    FExpr = dyn_cast<StringLiteral>(OrigFormatExpr);
+
   if (FExpr == NULL) {
     // For vprintf* functions (i.e., HasVAListArg==true), we add a
     // special check to see if the format string is a function parameter
@@ -540,7 +554,25 @@
       Diag(Loc, diag::warn_printf_write_back, Fn->getSourceRange());
       break;
     }
-                  
+             
+    // Handle "%@"
+    case '@':
+      // %@ is allowed in ObjC format strings only.
+      if(ObjCFExpr != NULL)
+        CurrentState = state_OrdChr; 
+      else {
+        // Issue a warning: invalid format conversion.
+        SourceLocation Loc = PP.AdvanceToTokenCharacter(FExpr->getLocStart(),
+                                                    LastConversionIdx+1);
+    
+        Diag(Loc, diag::warn_printf_invalid_conversion, 
+          std::string(Str+LastConversionIdx, 
+          Str+std::min(LastConversionIdx+2, StrLen)),
+          Fn->getSourceRange());
+      }
+      ++numConversions;
+      break;
+    
     // Handle "%%"
     case '%':
       // Sanity check: Was the first "%" character the previous one?





More information about the cfe-commits mailing list