From: Eli Friedman Date: Sat, 16 May 2009 12:46:54 +0000 (+0000) Subject: Add stricter checking for va_arg. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5c091bab12d2e3fc69d7580a89dd3b9520bd471c;p=clang Add stricter checking for va_arg. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71942 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index ea0d22ce25..4145be6ab7 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -5208,15 +5208,21 @@ Sema::OwningExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc, // Get the va_list type QualType VaListType = Context.getBuiltinVaListType(); - // Deal with implicit array decay; for example, on x86-64, - // va_list is an array, but it's supposed to decay to - // a pointer for va_arg. - if (VaListType->isArrayType()) + if (VaListType->isArrayType()) { + // Deal with implicit array decay; for example, on x86-64, + // va_list is an array, but it's supposed to decay to + // a pointer for va_arg. VaListType = Context.getArrayDecayedType(VaListType); - // Make sure the input expression also decays appropriately. - UsualUnaryConversions(E); + // Make sure the input expression also decays appropriately. + UsualUnaryConversions(E); + } else { + // Otherwise, the va_list argument must be an l-value because + // it is modified by va_arg. + if (CheckForModifiableLvalue(E, BuiltinLoc, *this)) + return ExprError(); + } - if (CheckAssignmentConstraints(VaListType, E->getType()) != Compatible) { + if (!Context.hasSameType(VaListType, E->getType())) { return ExprError(Diag(E->getLocStart(), diag::err_first_argument_to_va_arg_not_of_type_va_list) << OrigExpr->getType() << E->getSourceRange()); diff --git a/test/Sema/va_arg_x86_32.c b/test/Sema/va_arg_x86_32.c new file mode 100644 index 0000000000..850d324dbf --- /dev/null +++ b/test/Sema/va_arg_x86_32.c @@ -0,0 +1,6 @@ +// RUN: clang-cc -fsyntax-only -verify -triple=i686-pc-linux-gnu %s + +int a() { + __builtin_va_arg((char*)0, int); // expected-error {{expression is not assignable}} + __builtin_va_arg((void*){0}, int); // expected-error {{first argument to 'va_arg' is of type 'void *'}} +}