From de1f674fbda42709c5cefee3fd4b5792ac36fac1 Mon Sep 17 00:00:00 2001 From: Eric Rannaud Date: Fri, 24 Oct 2014 09:40:09 -0700 Subject: [PATCH 1/2] Handle va_arg on struct types for the le32 target (PNaCl and Emscripten) Cherry picked from https://codereview.chromium.org/183973037, itself a cherry pick from clang upstream r199830, originally authored by mseaborn@chromium.org PNaCl and Emscripten can both handle va_arg IR instructions with struct type. Also add a test to cover generating a va_arg IR instruction from va_arg in C on le32 (as already handled by VisitVAArgExpr() in CGExprScalar.cpp), which was not covered by a test before. (This fixes https://code.google.com/p/nativeclient/issues/detail?id=2381) Differential Revision: http://llvm-reviews.chandlerc.com/D2539 R=mseaborn@chromium.org, dschuff@chromium.org, jvoung@chromium.org TEST= ninja clang-check BUG= https://code.google.com/p/nativeclient/issues/detail?id=2381 --- lib/CodeGen/CGExprAgg.cpp | 6 +++++- test/CodeGen/le32-vaarg.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 test/CodeGen/le32-vaarg.c diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index b974e1dcc68..7a38b36baf6 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -996,7 +996,11 @@ void AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) { llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, VE->getType()); if (!ArgPtr) { - CGF.ErrorUnsupported(VE, "aggregate va_arg expression"); + // If EmitVAArg fails, we fall back to the LLVM instruction. + llvm::Value *Val = + Builder.CreateVAArg(ArgValue, CGF.ConvertType(VE->getType())); + if (!Dest.isIgnored()) + Builder.CreateStore(Val, Dest.getAddr()); return; } diff --git a/test/CodeGen/le32-vaarg.c b/test/CodeGen/le32-vaarg.c new file mode 100644 index 00000000000..51bbb029684 --- /dev/null +++ b/test/CodeGen/le32-vaarg.c @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple le32-unknown-nacl -emit-llvm -o - %s | FileCheck %s +#include + +int get_int(va_list *args) { + return va_arg(*args, int); +} +// CHECK: define i32 @get_int +// CHECK: [[RESULT:%[a-z_0-9]+]] = va_arg {{.*}}, i32{{$}} +// CHECK: ret i32 [[RESULT]] + +struct Foo { + int x; +}; + +struct Foo dest; + +void get_struct(va_list *args) { + dest = va_arg(*args, struct Foo); +} +// CHECK: define void @get_struct +// CHECK: [[RESULT:%[a-z_0-9]+]] = va_arg {{.*}}, %struct.Foo{{$}} +// CHECK: store %struct.Foo [[RESULT]], %struct.Foo* @dest + +void skip_struct(va_list *args) { + va_arg(*args, struct Foo); +} +// CHECK: define void @skip_struct +// CHECK: va_arg {{.*}}, %struct.Foo{{$}} From 85ab97a461958651a93779e9644e9b294665a54c Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 7 Nov 2014 10:48:39 -0800 Subject: [PATCH 2/2] 1.26.1 --- emscripten-version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emscripten-version.txt b/emscripten-version.txt index 958bb4d7634..9f67c6b08c1 100644 --- a/emscripten-version.txt +++ b/emscripten-version.txt @@ -1,2 +1,2 @@ -1.26.0 +1.26.1