]> granicus.if.org Git - clang/commitdiff
Fix for PR3350: add special-casing for "references" to va_lists in
authorEli Friedman <eli.friedman@gmail.com>
Tue, 20 Jan 2009 07:46:22 +0000 (07:46 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Tue, 20 Jan 2009 07:46:22 +0000 (07:46 +0000)
builtins.

Also, a minor tweak to va_copy for consistency.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62574 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Builtins.def
include/clang/AST/Builtins.h
lib/AST/Builtins.cpp
lib/CodeGen/CGBuiltin.cpp
test/Sema/varargs.c

index ba20bbc463b57a4ea30466a0aff2b02d98461a53..07c751db3ee4e848064e154e36645cb76505af11 100644 (file)
@@ -33,6 +33,7 @@
 //  z -> size_t
 //  F -> constant CFString
 //  a -> __builtin_va_list
+//  A -> "reference" to __builtin_va_list
 //  V -> Vector, following num elements and a base type.
 //  . -> "...".  This may only occur at the end of the function list.
 //
@@ -115,10 +116,10 @@ BUILTIN(__builtin_bswap64, "ULLiULLi", "nc")
 BUILTIN(__builtin_constant_p, "Us.", "nc")
 BUILTIN(__builtin_classify_type, "i.", "nc")
 BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "nc")
-BUILTIN(__builtin_va_start, "va&.", "n")
-BUILTIN(__builtin_va_end, "va&", "n")
-BUILTIN(__builtin_va_copy, "va&a", "n")
-BUILTIN(__builtin_stdarg_start, "va&.", "n")
+BUILTIN(__builtin_va_start, "vA.", "n")
+BUILTIN(__builtin_va_end, "vA", "n")
+BUILTIN(__builtin_va_copy, "vAA", "n")
+BUILTIN(__builtin_stdarg_start, "vA.", "n")
 BUILTIN(__builtin_bzero, "vv*z", "n")
 BUILTIN(__builtin_memcpy, "v*v*vC*z", "n")
 BUILTIN(__builtin_memmove, "v*v*vC*z", "n")
index 7da9a5f26af06eac6c9c6b532a7731be7a79f8f4..c1771924ba35a5019fe323814810ddff9bd465f0 100644 (file)
@@ -81,7 +81,7 @@ public:
   /// hasVAListUse - Return true of the specified builtin uses __builtin_va_list
   /// as an operand or return type.
   bool hasVAListUse(unsigned ID) const {
-    return strchr(GetRecord(ID).Type, 'a') != 0;
+    return strpbrk(GetRecord(ID).Type, "Aa") != 0;
   }
   
   /// GetBuiltinType - Return the type for the specified builtin.
index a721c6ea8c187d69851e37b2d3832857508ccd44..b675c729738e8b2e5d3a2e289646e3d2cdf73daa 100644 (file)
@@ -142,6 +142,23 @@ static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context,
     Type = Context.getBuiltinVaListType();
     assert(!Type.isNull() && "builtin va list type not initialized!");
     break;
+  case 'A':
+    // This is a "reference" to a va_list; however, what exactly
+    // this means depends on how va_list is defined. There are two
+    // different kinds of va_list: ones passed by value, and ones
+    // passed by reference.  An example of a by-value va_list is
+    // x86, where va_list is a char*. An example of by-ref va_list
+    // is x86-64, where va_list is a __va_list_tag[1]. For x86,
+    // we want this argument to be a char*&; for x86-64, we want
+    // it to be a __va_list_tag*.
+    Type = Context.getBuiltinVaListType();
+    assert(!Type.isNull() && "builtin va list type not initialized!");
+    if (Type->isArrayType()) {
+      Type = Context.getArrayDecayedType(Type);
+    } else {
+      Type = Context.getReferenceType(Type);
+    }
+    break;
   case 'V': {
     char *End;
     
index 6e140da7323df0efda00e69e06534d392be138c3..2d840ffd8d64a33d1da70788bcbdfe3c9e46adaf 100644 (file)
@@ -67,11 +67,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) {
   case Builtin::BI__builtin_va_copy: {
     // FIXME: This does not yet handle architectures where va_list is a struct.
     Value *DstPtr = EmitLValue(E->getArg(0)).getAddress();
-    Value *SrcValue = EmitScalarExpr(E->getArg(1));
-    
-    Value *SrcPtr = CreateTempAlloca(SrcValue->getType(), "dst_ptr");
-    
-    Builder.CreateStore(SrcValue, SrcPtr, false);
+    Value *SrcPtr = EmitLValue(E->getArg(1)).getAddress();
 
     const llvm::Type *Type = 
       llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
index 5e0f28b7c25c16aab92363a802c0c636f44589ca..ae21c208eb8ada9088f1c7a4ea15a6fce13df127 100644 (file)
@@ -43,3 +43,12 @@ void f6(int a, ...) {
   __builtin_va_list ap;
   __builtin_va_start(ap); // expected-error {{too few arguments to function}}
 }
+
+// PR3350
+void
+foo(__builtin_va_list authors, ...) {
+  __builtin_va_start (authors, authors);
+  (void)__builtin_va_arg(authors, int);
+  __builtin_va_end (authors);
+}
+