diff options
| author | Anders Carlsson <andersca@mac.com> | 2007-10-12 17:48:41 +0000 |
|---|---|---|
| committer | Anders Carlsson <andersca@mac.com> | 2007-10-12 17:48:41 +0000 |
| commit | 431ef632cbac174076d4c07fef6162eac5eacc14 (patch) | |
| tree | 52151b9023492a28a27c13a5b55ba6b0424f4a6e /clang/Sema/SemaChecking.cpp | |
| parent | 1410b8512c83b62076fdb8c8e4fdedc8568cc164 (diff) | |
| download | bcm5719-llvm-431ef632cbac174076d4c07fef6162eac5eacc14.tar.gz bcm5719-llvm-431ef632cbac174076d4c07fef6162eac5eacc14.zip | |
Add some more diagnostics for va_start, fix tests so they pass with these new diags.
llvm-svn: 42917
Diffstat (limited to 'clang/Sema/SemaChecking.cpp')
| -rw-r--r-- | clang/Sema/SemaChecking.cpp | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/clang/Sema/SemaChecking.cpp b/clang/Sema/SemaChecking.cpp index ea63b7dc1ca..f764d80df25 100644 --- a/clang/Sema/SemaChecking.cpp +++ b/clang/Sema/SemaChecking.cpp @@ -43,6 +43,37 @@ Sema::CheckFunctionCall(Expr *Fn, assert(NumArgsInCall == 1 && "Wrong number of arguments to builtin CFStringMakeConstantString"); return CheckBuiltinCFStringArgument(Args[0]); + } else if (FnInfo->getBuiltinID() == Builtin::BI__builtin_va_start) { + if (NumArgsInCall > 2) { + Diag(Args[2]->getLocStart(), + diag::err_typecheck_call_too_many_args, Fn->getSourceRange(), + SourceRange(Args[2]->getLocStart(), + Args[NumArgsInCall - 1]->getLocEnd())); + return true; + } + + FunctionTypeProto* proto = + cast<FunctionTypeProto>(CurFunctionDecl->getType()); + if (!proto->isVariadic()) { + Diag(Fn->getLocStart(), + diag::err_va_start_used_in_non_variadic_function); + return true; + } + + bool SecondArgIsLastNamedArgument = false; + if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Args[1])) { + if (ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) { + ParmVarDecl *LastNamedArg = + CurFunctionDecl->getParamDecl(CurFunctionDecl->getNumParams() - 1); + + if (PV == LastNamedArg) + SecondArgIsLastNamedArgument = true; + } + } + + if (!SecondArgIsLastNamedArgument) + Diag(Args[1]->getLocStart(), + diag::warn_second_parameter_of_va_start_not_last_named_argument); } // Search the KnownFunctionIDs for the identifier. |

