Add stricter checking for va_arg.

llvm-svn: 71942
This commit is contained in:
Eli Friedman 2009-05-16 12:46:54 +00:00
parent 54135838e2
commit e2cad65015
2 changed files with 19 additions and 7 deletions

View File

@ -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());

View File

@ -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 *'}}
}