[cfe-commits] r89113 - in /cfe/trunk: lib/Sema/SemaChecking.cpp lib/Sema/SemaDeclAttr.cpp test/SemaCXX/format-attribute.cpp

Sebastian Redl sebastian.redl at getdesigned.at
Tue Nov 17 10:02:24 PST 2009


Author: cornedbee
Date: Tue Nov 17 12:02:24 2009
New Revision: 89113

URL: http://llvm.org/viewvc/llvm-project?rev=89113&view=rev
Log:
Adjust format attribute index for implicit object arguments. Fixes PR5521.

Added:
    cfe/trunk/test/SemaCXX/format-attribute.cpp
Modified:
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Tue Nov 17 12:02:24 2009
@@ -91,6 +91,12 @@
   if (Format->getType() == "printf0") {
     // printf0 allows null "format" string; if so don't check format/args
     unsigned format_idx = Format->getFormatIdx() - 1;
+    // Does the index refer to the implicit object argument?
+    if (isa<CXXMemberCallExpr>(TheCall)) {
+      if (format_idx == 0)
+        return false;
+      --format_idx;
+    }
     if (format_idx < TheCall->getNumArgs()) {
       Expr *Format = TheCall->getArg(format_idx)->IgnoreParenCasts();
       if (!Format->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull))
@@ -204,7 +210,7 @@
       if (!HasVAListArg) {
         if (const FunctionProtoType *Proto
             = FDecl->getType()->getAs<FunctionProtoType>())
-        HasVAListArg = !Proto->isVariadic();
+          HasVAListArg = !Proto->isVariadic();
       }
       CheckPrintfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1,
                            HasVAListArg ? 0 : Format->getFirstArg() - 1);
@@ -970,6 +976,18 @@
                            unsigned format_idx, unsigned firstDataArg) {
   const Expr *Fn = TheCall->getCallee();
 
+  // The way the format attribute works in GCC, the implicit this argument
+  // of member functions is counted. However, it doesn't appear in our own
+  // lists, so decrement format_idx in that case.
+  if (isa<CXXMemberCallExpr>(TheCall)) {
+    // Catch a format attribute mistakenly referring to the object argument.
+    if (format_idx == 0)
+      return;
+    --format_idx;
+    if(firstDataArg != 0)
+      --firstDataArg;
+  }
+
   // CHECK: printf-like function is called with no format string.
   if (format_idx >= TheCall->getNumArgs()) {
     Diag(TheCall->getRParenLoc(), diag::warn_printf_missing_format_string)

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Nov 17 12:02:24 2009
@@ -1351,7 +1351,14 @@
   // FIXME: Do we need to bounds check?
   unsigned ArgIdx = Idx.getZExtValue() - 1;
 
-  if (HasImplicitThisParam) ArgIdx--;
+  if (HasImplicitThisParam) {
+    if (ArgIdx == 0) {
+      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
+        << "a string type" << IdxExpr->getSourceRange();
+      return;
+    }
+    ArgIdx--;
+  }
 
   // make sure the format string is really a string
   QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);

Added: cfe/trunk/test/SemaCXX/format-attribute.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/format-attribute.cpp?rev=89113&view=auto

==============================================================================
--- cfe/trunk/test/SemaCXX/format-attribute.cpp (added)
+++ cfe/trunk/test/SemaCXX/format-attribute.cpp Tue Nov 17 12:02:24 2009
@@ -0,0 +1,8 @@
+// RUN: clang-cc -fsyntax-only -verify %s 
+
+// PR5521
+struct A { void a(const char*,...) __attribute((format(printf,2,3))); };
+void b(A x) {
+  x.a("%d", 3);
+}
+struct X { void a(const char*,...) __attribute((format(printf,1,3))); }; // expected-error {{format argument not a string type}}





More information about the cfe-commits mailing list