[cfe-commits] r166369 - in /cfe/trunk: lib/Sema/SemaExpr.cpp test/SemaCXX/builtins-arm.cpp test/SemaCXX/builtins-va_arg.cpp

Logan Chien tzuhsiang.chien at gmail.com
Fri Oct 19 23:11:33 PDT 2012


Author: logan
Date: Sat Oct 20 01:11:33 2012
New Revision: 166369

URL: http://llvm.org/viewvc/llvm-project?rev=166369&view=rev
Log:
Fix __builtin_va_arg assertion failure in ARM AAPCS.


Added:
    cfe/trunk/test/SemaCXX/builtins-arm.cpp
    cfe/trunk/test/SemaCXX/builtins-va_arg.cpp
Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=166369&r1=166368&r2=166369&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Oct 20 01:11:33 2012
@@ -9643,6 +9643,16 @@
     if (Result.isInvalid())
       return ExprError();
     E = Result.take();
+  } else if (VaListType->isRecordType() && getLangOpts().CPlusPlus) {
+    // If va_list is a record type and we are compiling in C++ mode,
+    // check the argument using reference binding.
+    InitializedEntity Entity
+      = InitializedEntity::InitializeParameter(Context,
+          Context.getLValueReferenceType(VaListType), false);
+    ExprResult Init = PerformCopyInitialization(Entity, SourceLocation(), E);
+    if (Init.isInvalid())
+      return ExprError();
+    E = Init.takeAs<Expr>();
   } else {
     // Otherwise, the va_list argument must be an l-value because
     // it is modified by va_arg.

Added: cfe/trunk/test/SemaCXX/builtins-arm.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/builtins-arm.cpp?rev=166369&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/builtins-arm.cpp (added)
+++ cfe/trunk/test/SemaCXX/builtins-arm.cpp Sat Oct 20 01:11:33 2012
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -triple armv7 -fsyntax-only -verify %s
+
+// va_list on ARM AAPCS is struct { void* __ap }.
+int test1(const __builtin_va_list &ap) {
+  return __builtin_va_arg(ap, int); // expected-error {{binding of reference to type '__builtin_va_list' to a value of type 'const __builtin_va_list' drops qualifiers}}
+}

Added: cfe/trunk/test/SemaCXX/builtins-va_arg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/builtins-va_arg.cpp?rev=166369&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/builtins-va_arg.cpp (added)
+++ cfe/trunk/test/SemaCXX/builtins-va_arg.cpp Sat Oct 20 01:11:33 2012
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 %s -ffreestanding
+// RUN: %clang_cc1 %s -ffreestanding -triple i686-unknown-linux
+// RUN: %clang_cc1 %s -ffreestanding -triple x86_64-unknown-linux
+// RUN: %clang_cc1 %s -ffreestanding -triple mips-unknown-linux
+// RUN: %clang_cc1 %s -ffreestanding -triple mipsel-unknown-linux
+// RUN: %clang_cc1 %s -ffreestanding -triple armv7-unknown-linux-gnueabi
+// RUN: %clang_cc1 %s -ffreestanding -triple thumbv7-unknown-linux-gnueabi
+
+#include "stdarg.h"
+
+int int_accumulator = 0;
+double double_accumulator = 0;
+
+int test_vprintf(const char *fmt, va_list ap) {
+  char ch;
+  int result = 0;
+  while (*fmt != '\0') {
+    ch = *fmt++;
+    if (ch != '%') {
+      continue;
+    }
+
+    ch = *fmt++;
+    switch (ch) {
+    case 'd':
+      int_accumulator += va_arg(ap, int);
+      result++;
+      break;
+
+    case 'f':
+      double_accumulator += va_arg(ap, double);
+      result++;
+      break;
+
+    default:
+      break;
+    }
+
+    if (ch == '0') {
+      break;
+    }
+  }
+  return result;
+}
+
+int test_printf(const char *fmt, ...) {
+  va_list ap;
+  va_start(ap, fmt);
+  int result = test_vprintf(fmt, ap);
+  va_end(ap);
+  return result;
+}





More information about the cfe-commits mailing list