[cfe-commits] r45114 - in /cfe/trunk: Sema/SemaChecking.cpp test/Sema/format-strings.c
Ted Kremenek
kremenek at apple.com
Mon Dec 17 11:03:14 PST 2007
Author: kremenek
Date: Mon Dec 17 13:03:13 2007
New Revision: 45114
URL: http://llvm.org/viewvc/llvm-project?rev=45114&view=rev
Log:
Modified format-string checking to not emit a warning when all of the
following hold:
(1) A vprintf-like function is called that takes the argument list via a
via_list argument.
(2) The format string is a non-literal that is the parameter value of
the enclosing function, e.g:
void logmessage(const char *fmt,...) {
va_list ap;
va_start(ap,fmt);
fprintf(fmt,ap); // Do not emit a warning.
}
In the future this special case will be enhanced to consult the "format"
attribute attached to a function declaration instead of just allowing a blank
check for all function parameters to be used as format strings to vprintf-like
functions. This will happen when more support for attributes becomes
available.
Modified:
cfe/trunk/Sema/SemaChecking.cpp
cfe/trunk/test/Sema/format-strings.c
Modified: cfe/trunk/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaChecking.cpp?rev=45114&r1=45113&r2=45114&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/Sema/SemaChecking.cpp Mon Dec 17 13:03:13 2007
@@ -237,8 +237,32 @@
StringLiteral *FExpr = dyn_cast<StringLiteral>(OrigFormatExpr);
if (FExpr == NULL) {
- Diag(Args[format_idx]->getLocStart(),
- diag::warn_printf_not_string_constant, Fn->getSourceRange());
+ // For vprintf* functions (i.e., HasVAListArg==true), we add a
+ // special check to see if the format string is a function parameter
+ // of the function calling the printf function. If the function
+ // has an attribute indicating it is a printf-like function, then we
+ // should suppress warnings concerning non-literals being used in a call
+ // to a vprintf function. For example:
+ //
+ // void
+ // logmessage(char const *fmt __attribute__ (format (printf, 1, 2)), ...) {
+ // va_list ap;
+ // va_start(ap, fmt);
+ // vprintf(fmt, ap); // Do NOT emit a warning about "fmt".
+ // ...
+ //
+ //
+ // FIXME: We don't have full attribute support yet, so just check to see
+ // if the argument is a DeclRefExpr that references a parameter. We'll
+ // add proper support for checking the attribute later.
+ if (HasVAListArg)
+ if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(IgnoreParen(OrigFormatExpr)))
+ if (isa<ParmVarDecl>(DR->getDecl()))
+ return;
+
+ Diag(Args[format_idx]->getLocStart(), diag::warn_printf_not_string_constant,
+ Fn->getSourceRange());
+
return;
}
Modified: cfe/trunk/test/Sema/format-strings.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-strings.c?rev=45114&r1=45113&r2=45114&view=diff
==============================================================================
--- cfe/trunk/test/Sema/format-strings.c (original)
+++ cfe/trunk/test/Sema/format-strings.c Mon Dec 17 13:03:13 2007
@@ -3,6 +3,8 @@
#include <stdio.h>
#include <stdarg.h>
+char * global_fmt;
+
void check_string_literal( FILE* fp, const char* s, char *buf, ... ) {
char * b;
@@ -10,15 +12,16 @@
va_start(ap,buf);
printf(s); // expected-warning {{format string is not a string literal}}
- vprintf(s,ap); // expected-warning {{format string is not a string liter}}
+ vprintf(s,ap); // // no-warning
fprintf(fp,s); // expected-warning {{format string is not a string literal}}
- vfprintf(fp,s,ap); // expected-warning {{format string is not a string lit}}
+ vfprintf(fp,s,ap); // no-warning
asprintf(&b,s); // expected-warning {{format string is not a string lit}}
- vasprintf(&b,s,ap); // expected-warning {{format string is not a string lit}}
+ vasprintf(&b,s,ap); // no-warning
sprintf(buf,s); // expected-warning {{format string is not a string literal}}
snprintf(buf,2,s); // expected-warning {{format string is not a string lit}}
- vsprintf(buf,s,ap); // expected-warning {{format string is not a string lit}}
- vsnprintf(buf,2,s,ap); // expected-warning {{mat string is not a string lit}}
+ vsprintf(buf,s,ap); // no-warning
+ vsnprintf(buf,2,s,ap); // no-warning
+ vsnprintf(buf,2,global_fmt,ap); // expected-warning {{format string is not a string literal}}
}
void check_writeback_specifier()
More information about the cfe-commits
mailing list