summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2013-05-24 23:31:57 +0000
committerNico Weber <nicolasweber@gmx.de>2013-05-24 23:31:57 +0000
commit9eea764a1fafb5883286b088422e2ec77db25dec (patch)
treefd0183607e3c98d63bf26460d9a2d72f1786506d /clang/lib/Sema/SemaChecking.cpp
parentba63e07f3a8b698b300b154abd2dcc49ba197f69 (diff)
downloadbcm5719-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.cpp14
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;
}
OpenPOWER on IntegriCloud