From 431ef632cbac174076d4c07fef6162eac5eacc14 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Fri, 12 Oct 2007 17:48:41 +0000 Subject: Add some more diagnostics for va_start, fix tests so they pass with these new diags. llvm-svn: 42917 --- clang/Sema/SemaChecking.cpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'clang/Sema/SemaChecking.cpp') 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(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(Args[1])) { + if (ParmVarDecl *PV = dyn_cast(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. -- cgit v1.2.3