diff options
| author | Reid Kleckner <reid@kleckner.net> | 2013-12-04 19:23:12 +0000 | 
|---|---|---|
| committer | Reid Kleckner <reid@kleckner.net> | 2013-12-04 19:23:12 +0000 | 
| commit | 739756c0f925fbb967109f4ba289d26be69c9c0a (patch) | |
| tree | 6f6102249a4aee2dd120cafc29141fbb42feb290 /clang/test | |
| parent | 91a9b247d473cebc23cee55309aecc56a0c29f64 (diff) | |
| download | bcm5719-llvm-739756c0f925fbb967109f4ba289d26be69c9c0a.tar.gz bcm5719-llvm-739756c0f925fbb967109f4ba289d26be69c9c0a.zip  | |
[ms-cxxabi] Construct and destroy call arguments in the correct order
Summary:
MSVC destroys arguments in the callee from left to right.  Because C++
objects have to be destroyed in the reverse order of construction, Clang
has to construct arguments from right to left and destroy arguments from
left to right.
This patch fixes the ordering by reversing the order of evaluation of
all call arguments under the MS C++ ABI.
Fixes PR18035.
Reviewers: rsmith
Differential Revision: http://llvm-reviews.chandlerc.com/D2275
llvm-svn: 196402
Diffstat (limited to 'clang/test')
| -rw-r--r-- | clang/test/CodeGen/tbaa-ms-abi.cpp | 4 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/microsoft-abi-arg-order.cpp | 41 | ||||
| -rw-r--r-- | clang/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm | 20 | 
3 files changed, 63 insertions, 2 deletions
diff --git a/clang/test/CodeGen/tbaa-ms-abi.cpp b/clang/test/CodeGen/tbaa-ms-abi.cpp index 67390b1a8a5..9908ac06d98 100644 --- a/clang/test/CodeGen/tbaa-ms-abi.cpp +++ b/clang/test/CodeGen/tbaa-ms-abi.cpp @@ -16,7 +16,7 @@ StructB::StructB() {  // CHECK: store i32 42, i32* {{.*}}, !tbaa [[TAG_A_i32:!.*]]  } -// CHECK: [[TYPE_CHAR:!.*]] = metadata !{metadata !"omnipotent char", metadata -// CHECK: [[TYPE_INT:!.*]] = metadata !{metadata !"int", metadata [[TYPE_CHAR]], i64 0} +// CHECK: [[TYPE_INT:!.*]] = metadata !{metadata !"int", metadata [[TYPE_CHAR:!.*]], i64 0} +// CHECK: [[TYPE_CHAR]] = metadata !{metadata !"omnipotent char", metadata  // CHECK: [[TAG_A_i32]] = metadata !{metadata [[TYPE_A:!.*]], metadata [[TYPE_INT]], i64 0}  // CHECK: [[TYPE_A]] = metadata !{metadata !"?AUStructA@@", metadata [[TYPE_INT]], i64 0} diff --git a/clang/test/CodeGenCXX/microsoft-abi-arg-order.cpp b/clang/test/CodeGenCXX/microsoft-abi-arg-order.cpp new file mode 100644 index 00000000000..4f96f2a1bf1 --- /dev/null +++ b/clang/test/CodeGenCXX/microsoft-abi-arg-order.cpp @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -mconstructor-aliases -std=c++11 -fexceptions -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s + +struct A { +  A(int a); +  ~A(); +  int a; +}; + +void foo(A a, A b, A c) { +} + +// Order of destruction should be left to right. +// +// CHECK-LABEL: define void @"\01?foo@@YAXUA@@00@Z" +// CHECK:              ({{.*}} %[[a:.*]], {{.*}} %[[b:.*]], {{.*}} %[[c:.*]]) +// CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[a]]) +// CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[b]]) +// CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[c]]) +// CHECK: ret void + + +void call_foo() { +  foo(A(1), A(2), A(3)); +} + +// Order of evaluation should be right to left, and we should clean up the right +// things as we unwind. +// +// CHECK-LABEL: define void @"\01?call_foo@@YAXXZ"() +// CHECK: call   x86_thiscallcc %struct.A* @"\01??0A@@QAE@H@Z"(%struct.A* %[[arg3:.*]], i32 3) +// CHECK: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@H@Z"(%struct.A* %[[arg2:.*]], i32 2) +// CHECK: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@H@Z"(%struct.A* %[[arg1:.*]], i32 1) +// CHECK: call void @"\01?foo@@YAXUA@@00@Z"({{.*}} %[[arg1]], {{.*}} %[[arg2]], {{.*}} %[[arg3]]) +// CHECK: ret void +// +//   lpad2: +// CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[arg2]]) +// CHECK: br label +// +//   ehcleanup: +// CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[arg3]]) diff --git a/clang/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm b/clang/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm new file mode 100644 index 00000000000..91fd47ac6a7 --- /dev/null +++ b/clang/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -cxx-abi microsoft -mconstructor-aliases -fobjc-arc -triple i686-pc-win32 -emit-llvm -o - %s | FileCheck %s + +struct A { +  A(); +  A(const A &); +  ~A(); +  int a; +}; + +// Verify that we destruct things from left to right in the MS C++ ABI: a, b, c, d. +// +// CHECK-LABEL: define void @"\01?test_arc_order@@YAXUA@@PAAAPAUobjc_object@@01@Z" +// CHECK:                       ({{.*}} %[[a:.*]], {{.*}}, {{.*}} %[[c:.*]], {{.*}}) +void test_arc_order(A a, id __attribute__((ns_consumed)) b , A c, id __attribute__((ns_consumed)) d) { +  // CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[a]]) +  // CHECK: call void @objc_storeStrong(i8** %{{.*}}, i8* null) +  // CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[c]]) +  // CHECK: call void @objc_storeStrong(i8** %{{.*}}, i8* null) +  // CHECK: ret void +}  | 

