summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenCXX')
-rw-r--r--test/CodeGenCXX/condition.cpp1
-rw-r--r--test/CodeGenCXX/eh.cpp43
-rw-r--r--test/CodeGenCXX/instantiate-blocks.cpp26
-rw-r--r--test/CodeGenCXX/lvalue-bitcasts.cpp163
-rw-r--r--test/CodeGenCXX/mangle.cpp13
-rw-r--r--test/CodeGenCXX/member-qual-debug-info.cpp20
-rw-r--r--test/CodeGenCXX/nrvo.cpp32
-rw-r--r--test/CodeGenCXX/static-init-2.cpp2
8 files changed, 275 insertions, 25 deletions
diff --git a/test/CodeGenCXX/condition.cpp b/test/CodeGenCXX/condition.cpp
index bbc6d2f..652e7c8 100644
--- a/test/CodeGenCXX/condition.cpp
+++ b/test/CodeGenCXX/condition.cpp
@@ -26,6 +26,7 @@ struct Y {
X getX();
+// CHECK: define void @_Z11if_destructi(
void if_destruct(int z) {
// Verify that the condition variable is destroyed at the end of the
// "if" statement.
diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp
index d03dc91..6d79c3e 100644
--- a/test/CodeGenCXX/eh.cpp
+++ b/test/CodeGenCXX/eh.cpp
@@ -136,9 +136,6 @@ namespace test7 {
// CHECK-NEXT: invoke void @__cxa_throw(i8* [[EXNALLOC]], i8* bitcast (i8** @_ZTIi to i8*), i8* null
throw 1;
}
-// This cleanup ends up here for no good reason. It's actually unused.
-// CHECK: load i8** [[EXNALLOCVAR]]
-// CHECK-NEXT: call void @__cxa_free_exception(
// CHECK: [[CAUGHTEXN:%.*]] = call i8* @llvm.eh.exception()
// CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]]
@@ -184,11 +181,7 @@ namespace test8 {
// CHECK-NEXT: invoke void @_ZN5test81AC1ERKS0_(
// CHECK: call i8* @__cxa_begin_catch
// CHECK-NEXT: invoke void @_ZN5test81AD1Ev(
-
// CHECK: call void @__cxa_end_catch()
- // CHECK-NEXT: load
- // CHECK-NEXT: switch
-
// CHECK: ret void
}
}
@@ -220,3 +213,39 @@ namespace test9 {
// CHECK: call i8* @llvm.eh.exception
// CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* {{.*}}, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*), i8* null)
}
+
+// __cxa_end_catch can throw for some kinds of caught exceptions.
+namespace test10 {
+ void opaque();
+
+ struct A { ~A(); };
+ struct B { int x; };
+
+ // CHECK: define void @_ZN6test103fooEv()
+ void foo() {
+ A a; // force a cleanup context
+
+ try {
+ // CHECK: invoke void @_ZN6test106opaqueEv()
+ opaque();
+ } catch (int i) {
+ // CHECK: call i8* @__cxa_begin_catch
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: load i32*
+ // CHECK-NEXT: store i32
+ // CHECK-NEXT: call void @__cxa_end_catch() nounwind
+ } catch (B a) {
+ // CHECK: call i8* @__cxa_begin_catch
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: call void @llvm.memcpy
+ // CHECK-NEXT: invoke void @__cxa_end_catch()
+ } catch (...) {
+ // CHECK: call i8* @__cxa_begin_catch
+ // CHECK-NEXT: invoke void @__cxa_end_catch()
+ }
+
+ // CHECK: call void @_ZN6test101AD1Ev(
+ }
+}
diff --git a/test/CodeGenCXX/instantiate-blocks.cpp b/test/CodeGenCXX/instantiate-blocks.cpp
index c8f897d..e206582 100644
--- a/test/CodeGenCXX/instantiate-blocks.cpp
+++ b/test/CodeGenCXX/instantiate-blocks.cpp
@@ -31,3 +31,29 @@ void test2(void)
{
foo(100, 'a');
}
+
+namespace rdar6182276 {
+extern "C" {
+int printf(const char *, ...);
+}
+
+template <typename T> T foo(T t)
+{
+ void (^testing)(int) = ^(int bar) { printf("bar is %d\n", bar); };
+ printf("bar is\n");
+ return 1;
+}
+
+template <typename T> void gorf(T t)
+{
+ foo(t);
+}
+
+
+void test(void)
+{
+ gorf(2);
+}
+}
+
+
diff --git a/test/CodeGenCXX/lvalue-bitcasts.cpp b/test/CodeGenCXX/lvalue-bitcasts.cpp
new file mode 100644
index 0000000..8c5fa4a
--- /dev/null
+++ b/test/CodeGenCXX/lvalue-bitcasts.cpp
@@ -0,0 +1,163 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s | FileCheck %s
+
+struct X { int i; float f; };
+struct Y { X x; };
+
+// CHECK: define void @_Z21reinterpret_cast_testRiRfR1X
+void reinterpret_cast_test(int &ir, float &fr, X &xr) {
+ // CHECK: load float**
+ // CHECK: bitcast float*
+ // CHECK: load i32*
+ ir = reinterpret_cast<int&>(fr);
+ // CHECK: load
+ // CHECK: {{bitcast.*to i32\*}}
+ // CHECK: load i32*
+ ir = reinterpret_cast<int&>(xr);
+ // CHECK: load i32
+ // CHECK: {{bitcast.*to float\*}}
+ // CHECK: load float*
+ fr = reinterpret_cast<float&>(ir);
+ // CHECK: load
+ // CHECK: {{bitcast.*to float\*}}
+ // CHECK: load float*
+ fr = reinterpret_cast<float&>(xr);
+ // CHECK: load i32**
+ // CHECK: bitcast i32*
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+ xr = reinterpret_cast<X&>(ir);
+ // CHECK: load float**
+ // CHECK: bitcast float*
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+ xr = reinterpret_cast<X&>(fr);
+ _Complex float cf;
+ _Complex float &cfr = cf;
+ // CHECK: load i32**
+ // CHECK: bitcast i32*
+ // CHECK: load float*
+ // CHECK: load float*
+ cfr = reinterpret_cast<_Complex float&>(ir);
+ // CHECK: load float**
+ // CHECK: bitcast float*
+ // CHECK: load float*
+ // CHECK: load float*
+ cfr = reinterpret_cast<_Complex float&>(fr);
+ // CHECK: bitcast
+ // CHECK: load float*
+ // CHECK: load float*
+ cfr = reinterpret_cast<_Complex float&>(xr);
+ // CHECK: ret void
+}
+
+// CHECK: define void @_Z6c_castRiRfR1X
+void c_cast(int &ir, float &fr, X &xr) {
+ // CHECK: load float**
+ // CHECK: bitcast float*
+ // CHECK: load i32*
+ ir = (int&)fr;
+ // CHECK: load
+ // CHECK: {{bitcast.*to i32\*}}
+ // CHECK: load i32*
+ ir = (int&)xr;
+ // CHECK: load i32
+ // CHECK: {{bitcast.*to float\*}}
+ // CHECK: load float*
+ fr = (float&)ir;
+ // CHECK: load
+ // CHECK: {{bitcast.*to float\*}}
+ // CHECK: load float*
+ fr = (float&)xr;
+ // CHECK: load i32**
+ // CHECK: bitcast i32*
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+ xr = (X&)ir;
+ // CHECK: load float**
+ // CHECK: bitcast float*
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+ xr = (X&)fr;
+ _Complex float cf;
+ _Complex float &cfr = cf;
+ // CHECK: load i32**
+ // CHECK: bitcast i32*
+ // CHECK: load float*
+ // CHECK: load float*
+ cfr = (_Complex float&)ir;
+ // CHECK: load float**
+ // CHECK: bitcast float*
+ // CHECK: load float*
+ // CHECK: load float*
+ cfr = (_Complex float&)fr;
+ // CHECK: bitcast
+ // CHECK: load float*
+ // CHECK: load float*
+ cfr = (_Complex float&)xr;
+ // CHECK: ret void
+}
+
+// CHECK: define void @_Z15functional_castRiRfR1X
+void functional_cast(int &ir, float &fr, X &xr) {
+ typedef int &intref;
+ typedef float &floatref;
+ typedef X &Xref;
+ // CHECK: load float**
+ // CHECK: bitcast float*
+ // CHECK: load i32*
+ ir = intref(fr);
+ // CHECK: load
+ // CHECK: {{bitcast.*to i32\*}}
+ // CHECK: load i32*
+ ir = intref(xr);
+ // CHECK: load i32
+ // CHECK: {{bitcast.*to float\*}}
+ // CHECK: load float*
+ fr = floatref(ir);
+ // CHECK: load
+ // CHECK: {{bitcast.*to float\*}}
+ // CHECK: load float*
+ fr = floatref(xr);
+ // CHECK: load i32**
+ // CHECK: bitcast i32*
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+ xr = Xref(ir);
+ // CHECK: load float**
+ // CHECK: bitcast float*
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+ xr = Xref(fr);
+ typedef _Complex float &complex_float_ref;
+ _Complex float cf;
+ _Complex float &cfr = cf;
+ // CHECK: load i32**
+ // CHECK: bitcast i32*
+ // CHECK: load float*
+ // CHECK: load float*
+ cfr = complex_float_ref(ir);
+ // CHECK: load float**
+ // CHECK: bitcast float*
+ // CHECK: load float*
+ // CHECK: load float*
+ cfr = complex_float_ref(fr);
+ // CHECK: bitcast
+ // CHECK: load float*
+ // CHECK: load float*
+ cfr = complex_float_ref(xr);
+ // CHECK: ret void
+}
+
+namespace PR6437 {
+ struct in_addr {};
+ void copy( const struct in_addr &new_addr ) {
+ int addr = (int&)new_addr;
+ }
+}
+
+namespace PR7593 {
+ void foo(double &X, char *A) {
+ X = reinterpret_cast<double&>(A[4]);
+ }
+}
+
+namespace PR7344 {
+ void serialize_annotatable_id( void*& id )
+ {
+ unsigned long l_id = (unsigned long&)id;
+ }
+}
diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp
index 54a4060..814a759 100644
--- a/test/CodeGenCXX/mangle.cpp
+++ b/test/CodeGenCXX/mangle.cpp
@@ -495,4 +495,15 @@ namespace test12 {
// CHECK: _ZN6test121fENS_1AILt33000EEE
template <unsigned short> struct A { };
void f(A<33000>) { }
-} \ No newline at end of file
+}
+
+// PR7446
+namespace test13 {
+ template <template <class> class T> class A {};
+ template <class U> class B {};
+
+ template <template<class> class T> void foo(const A<T> &a) {}
+
+ // CHECK: define weak_odr void @_ZN6test133fooINS_1BEEEvRKNS_1AIT_EE(
+ template void foo(const A<B> &a);
+}
diff --git a/test/CodeGenCXX/member-qual-debug-info.cpp b/test/CodeGenCXX/member-qual-debug-info.cpp
new file mode 100644
index 0000000..c6e0991
--- /dev/null
+++ b/test/CodeGenCXX/member-qual-debug-info.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -g -S -masm-verbose -x c++ -o %t %s
+// RUN: grep DW_TAG_volatile_type %t | count 3
+// RUN: grep DW_TAG_const_type %t | count 3
+// one for decl, one for def, one for abbrev
+
+namespace A {
+ class B {
+ public:
+ void dump() const volatile;
+ };
+}
+
+int main () {
+ using namespace A;
+ B b;
+ return 0;
+}
+
+void A::B::dump() const volatile{
+}
diff --git a/test/CodeGenCXX/nrvo.cpp b/test/CodeGenCXX/nrvo.cpp
index 6181f0e..8d19b1e 100644
--- a/test/CodeGenCXX/nrvo.cpp
+++ b/test/CodeGenCXX/nrvo.cpp
@@ -57,20 +57,15 @@ X test2(bool B) {
// CHECK-EH: call void @_ZN1XC1Ev
// CHECK-EH-NEXT: invoke void @_ZN1XC1Ev
- // -> %invoke.cont1, %lpad
+ // -> %invoke.cont, %lpad
- // %invoke.cont1:
+ // %invoke.cont:
// CHECK-EH: br i1
// -> %if.then, %if.end
// %if.then: returning 'x'
// CHECK-EH: invoke void @_ZN1XC1ERKS_
- // -> %cleanup, %lpad5
-
- // %invoke.cont: rethrow block for %eh.cleanup.
- // This really should be elsewhere in the function.
- // CHECK-EH: call void @_Unwind_Resume_or_Rethrow
- // CHECK-EH-NEXT: unreachable
+ // -> %cleanup, %lpad1
// %lpad: landing pad for ctor of 'y', dtor of 'y'
// CHECK-EH: call i8* @llvm.eh.exception()
@@ -78,25 +73,30 @@ X test2(bool B) {
// CHECK-EH-NEXT: br label
// -> %eh.cleanup
- // %invoke.cont2: normal cleanup for 'x'
- // CHECK-EH: call void @_ZN1XD1Ev
- // CHECK-EH-NEXT: ret void
-
- // %lpad5: landing pad for return copy ctors, EH cleanup for 'y'
+ // %lpad1: landing pad for return copy ctors, EH cleanup for 'y'
// CHECK-EH: invoke void @_ZN1XD1Ev
// -> %eh.cleanup, %terminate.lpad
// %if.end: returning 'y'
// CHECK-EH: invoke void @_ZN1XC1ERKS_
- // -> %cleanup, %lpad5
+ // -> %cleanup, %lpad1
// %cleanup: normal cleanup for 'y'
// CHECK-EH: invoke void @_ZN1XD1Ev
- // -> %invoke.cont2, %lpad
+ // -> %invoke.cont11, %lpad
+
+ // %invoke.cont11: normal cleanup for 'x'
+ // CHECK-EH: call void @_ZN1XD1Ev
+ // CHECK-EH-NEXT: ret void
// %eh.cleanup: EH cleanup for 'x'
// CHECK-EH: invoke void @_ZN1XD1Ev
- // -> %invoke.cont, %terminate.lpad
+ // -> %invoke.cont17, %terminate.lpad
+
+ // %invoke.cont17: rethrow block for %eh.cleanup.
+ // This really should be elsewhere in the function.
+ // CHECK-EH: call void @_Unwind_Resume_or_Rethrow
+ // CHECK-EH-NEXT: unreachable
// %terminate.lpad: terminate landing pad.
// CHECK-EH: call i8* @llvm.eh.exception()
diff --git a/test/CodeGenCXX/static-init-2.cpp b/test/CodeGenCXX/static-init-2.cpp
index 65ab3bb..7eb4a7d 100644
--- a/test/CodeGenCXX/static-init-2.cpp
+++ b/test/CodeGenCXX/static-init-2.cpp
@@ -3,4 +3,4 @@
// Make sure we don't crash generating y; its value is constant, but the
// initializer has side effects, so EmitConstantExpr should fail.
int x();
-int y = x() && 0;
+int y = x() && 0; // expected-warning {{use of logical && with constant operand}}
OpenPOWER on IntegriCloud