From 121ba0c4d34b59512db1309fc2e511e0b36a5fe0 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Sat, 9 Aug 2008 23:32:40 +0000 Subject: [PATCH] Fix for PR2631; make va_arg work correctly on x86-64. llvm-svn: 54600 --- clang/lib/Sema/SemaExpr.cpp | 13 ++++++++++--- clang/test/Sema/va_arg_x86_64.c | 6 ++++++ 2 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 clang/test/Sema/va_arg_x86_64.c diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 2982c45865e8..003f3dea59fe 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2604,9 +2604,16 @@ Sema::ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc, QualType T = QualType::getFromOpaquePtr(type); InitBuiltinVaListType(); - - if (CheckAssignmentConstraints(Context.getBuiltinVaListType(), E->getType()) - != Compatible) + + // 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()) + VaListType = Context.getArrayDecayedType(VaListType); + + if (CheckAssignmentConstraints(VaListType, E->getType()) != Compatible) return Diag(E->getLocStart(), diag::err_first_argument_to_va_arg_not_of_type_va_list, E->getType().getAsString(), diff --git a/clang/test/Sema/va_arg_x86_64.c b/clang/test/Sema/va_arg_x86_64.c new file mode 100644 index 000000000000..86511349c398 --- /dev/null +++ b/clang/test/Sema/va_arg_x86_64.c @@ -0,0 +1,6 @@ +// RUN: clang -fsyntax-only -verify -triple=x86_64-unknown-freebsd7.0 %s + +char* foo(char *fmt, __builtin_va_list ap) +{ + return __builtin_va_arg((ap), char *); +}