forked from OSchip/llvm-project
Move the check for vprintf* functions inside of SemaCheckStringLiteral. Fixes PR4470.
llvm-svn: 74413
This commit is contained in:
parent
877a48e67a
commit
b012ca92ac
|
@ -717,8 +717,6 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
|
||||||
if (E->isTypeDependent() || E->isValueDependent())
|
if (E->isTypeDependent() || E->isValueDependent())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
E = E->IgnoreParenCasts();
|
|
||||||
|
|
||||||
switch (E->getStmtClass()) {
|
switch (E->getStmtClass()) {
|
||||||
case Stmt::ConditionalOperatorClass: {
|
case Stmt::ConditionalOperatorClass: {
|
||||||
const ConditionalOperator *C = cast<ConditionalOperator>(E);
|
const ConditionalOperator *C = cast<ConditionalOperator>(E);
|
||||||
|
@ -763,6 +761,28 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
|
||||||
return SemaCheckStringLiteral(Init, TheCall,
|
return SemaCheckStringLiteral(Init, TheCall,
|
||||||
HasVAListArg, format_idx, firstDataArg);
|
HasVAListArg, format_idx, firstDataArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 (isa<ParmVarDecl>(VD))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -901,29 +921,6 @@ Sema::CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg,
|
||||||
firstDataArg))
|
firstDataArg))
|
||||||
return; // Literal format string found, check done!
|
return; // Literal format string found, check done!
|
||||||
|
|
||||||
// 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 (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(OrigFormatExpr))
|
|
||||||
if (isa<ParmVarDecl>(DR->getDecl()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// If there are no arguments specified, warn with -Wformat-security, otherwise
|
// If there are no arguments specified, warn with -Wformat-security, otherwise
|
||||||
// warn only with -Wformat-nonliteral.
|
// warn only with -Wformat-nonliteral.
|
||||||
if (TheCall->getNumArgs() == format_idx+1)
|
if (TheCall->getNumArgs() == format_idx+1)
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
// RUN: clang-cc -fsyntax-only -verify -Wformat=2 %s
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
const char *foo(const char *format) __attribute__((format_arg(1)));
|
||||||
|
|
||||||
|
void __attribute__((format(printf, 1, 0)))
|
||||||
|
foo2(const char *fmt, va_list va)
|
||||||
|
{
|
||||||
|
vprintf(foo(fmt), va);
|
||||||
|
}
|
Loading…
Reference in New Issue