aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenCXX/runtimecc.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2013-02-28 19:01:20 +0000
committerJohn McCall <rjmccall@apple.com>2013-02-28 19:01:20 +0000
commitbd7370a78604e9a20d698bfe328c1e43f12a0613 (patch)
tree4284f2da0de9b36088c1a2c2ebac23c81a221792 /test/CodeGenCXX/runtimecc.cpp
parent280b956c8ead04adaa08b271cd93f7e49ca7eb3b (diff)
Use the actual ABI-determined C calling convention for runtime
calls and declarations. LLVM has a default CC determined by the target triple. This is not always the actual default CC for the ABI we've been asked to target, and so we sometimes find ourselves annotating all user functions with an explicit calling convention. Since these calling conventions usually agree for the simple set of argument types passed to most runtime functions, using the LLVM-default CC in principle has no effect. However, the LLVM optimizer goes into histrionics if it sees this kind of formal CC mismatch, since it has no concept of CC compatibility. Therefore, if this module happens to define the "runtime" function, or got LTO'ed with such a definition, we can miscompile; so it's quite important to get this right. Defining runtime functions locally is quite common in embedded applications. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176286 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/runtimecc.cpp')
-rw-r--r--test/CodeGenCXX/runtimecc.cpp53
1 files changed, 53 insertions, 0 deletions
diff --git a/test/CodeGenCXX/runtimecc.cpp b/test/CodeGenCXX/runtimecc.cpp
new file mode 100644
index 0000000000..66d3f41589
--- /dev/null
+++ b/test/CodeGenCXX/runtimecc.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 %s -triple=armv7-apple-darwin10 -emit-llvm -o - -fexceptions -fcxx-exceptions | FileCheck %s
+
+// Check that we annotate all compiler-synthesized runtime calls and
+// functions with the actual ABI-determined CC. This usually doesn't
+// matter as long as we're internally consistent (and the LLVM-default
+// CC is consistent with the real one), but it's possible for user
+// translation units to define these runtime functions (or, equivalently,
+// for us to get LTO'ed with such a translation unit), and then the
+// mismatch will kill us.
+//
+// rdar://12818655
+
+// CHECK: [[A:%.*]] = type { double }
+
+namespace test0 {
+ struct A {
+ double d;
+ A();
+ ~A();
+ };
+
+ A global;
+// CHECK: define internal arm_aapcscc void @__cxx_global_var_init()
+// CHECK: call arm_aapcscc [[A]]* @_ZN5test01AC1Ev([[A]]* @_ZN5test06globalE)
+// CHECK-NEXT: call arm_aapcscc i32 @__cxa_atexit(void (i8*)* bitcast ([[A]]* ([[A]]*)* @_ZN5test01AD1Ev to void (i8*)*), i8* bitcast ([[A]]* @_ZN5test06globalE to i8*), i8* @__dso_handle) [[NOUNWIND:#[0-9]+]]
+// CHECK-NEXT: ret void
+}
+
+// CHECK: declare arm_aapcscc i32 @__cxa_atexit(void (i8*)*, i8*, i8*) [[NOUNWIND]]
+
+namespace test1 {
+ void test() {
+ throw 0;
+ }
+
+// CHECK: define arm_aapcscc void @_ZN5test14testEv()
+// CHECK: [[T0:%.*]] = call arm_aapcscc i8* @__cxa_allocate_exception(i32 4) [[NOUNWIND]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to i32*
+// CHECK-NEXT: store i32 0, i32* [[T1]]
+// CHECK-NEXT: call arm_aapcscc void @__cxa_throw(i8* [[T0]], i8* bitcast (i8** @_ZTIi to i8*), i8* null) [[NORETURN:#[0-9]+]]
+// CHECK-NEXT: unreachable
+}
+
+// CHECK: declare arm_aapcscc i8* @__cxa_allocate_exception(i32)
+
+// CHECK: declare arm_aapcscc void @__cxa_throw(i8*, i8*, i8*)
+
+// CHECK: define internal arm_aapcscc void @_GLOBAL__I_a()
+// CHECK: call arm_aapcscc void @__cxx_global_var_init()
+
+
+// CHECK: attributes [[NOUNWIND]] = { nounwind }
+// CHECK: attributes [[NORETURN]] = { noreturn }