[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