diff options
author | Nico Weber <nicolasweber@gmx.de> | 2013-05-24 23:31:57 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2013-05-24 23:31:57 +0000 |
commit | 9eea764a1fafb5883286b088422e2ec77db25dec (patch) | |
tree | fd0183607e3c98d63bf26460d9a2d72f1786506d /clang/lib/Sema/SemaChecking.cpp | |
parent | ba63e07f3a8b698b300b154abd2dcc49ba197f69 (diff) | |
download | bcm5719-llvm-9eea764a1fafb5883286b088422e2ec77db25dec.tar.gz bcm5719-llvm-9eea764a1fafb5883286b088422e2ec77db25dec.zip |
Warn on va_start() when called with a reference parameter.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf 18.7p3
explicitly calls this (and some other things) out as undefined.
Also move 2 other existing warnings behind the new -Wvarargs flag.
llvm-svn: 182694
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 3471c004406..cdc546c4761 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1355,6 +1355,11 @@ bool Sema::SemaBuiltinVAStart(CallExpr *TheCall) { bool SecondArgIsLastNamedArgument = false; const Expr *Arg = TheCall->getArg(1)->IgnoreParenCasts(); + // These are valid if SecondArgIsLastNamedArgument is false after the next + // block. + QualType Type; + SourceLocation ParamLoc; + if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) { if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) { // FIXME: This isn't correct for methods (results in bogus warning). @@ -1367,12 +1372,21 @@ bool Sema::SemaBuiltinVAStart(CallExpr *TheCall) { else LastArg = *(getCurMethodDecl()->param_end()-1); SecondArgIsLastNamedArgument = PV == LastArg; + + Type = PV->getType(); + ParamLoc = PV->getLocation(); } } if (!SecondArgIsLastNamedArgument) Diag(TheCall->getArg(1)->getLocStart(), diag::warn_second_parameter_of_va_start_not_last_named_argument); + else if (Type->isReferenceType()) { + Diag(Arg->getLocStart(), + diag::warn_va_start_of_reference_type_is_undefined); + Diag(ParamLoc, diag::note_parameter_type) << Type; + } + return false; } |