summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenCXX')
-rw-r--r--test/CodeGenCXX/anonymous-union-member-initializer.cpp18
-rw-r--r--test/CodeGenCXX/attr-used.cpp4
-rw-r--r--test/CodeGenCXX/block-byref-cxx-objc.cpp4
-rw-r--r--test/CodeGenCXX/blocks.cpp4
-rw-r--r--test/CodeGenCXX/class-layout.cpp2
-rw-r--r--test/CodeGenCXX/compound-literals.cpp27
-rw-r--r--test/CodeGenCXX/const-init.cpp4
-rw-r--r--test/CodeGenCXX/constructor-init.cpp16
-rw-r--r--test/CodeGenCXX/constructors.cpp15
-rw-r--r--test/CodeGenCXX/copy-constructor-elim-2.cpp14
-rw-r--r--test/CodeGenCXX/copy-constructor-synthesis-2.cpp2
-rw-r--r--test/CodeGenCXX/copy-initialization.cpp2
-rw-r--r--test/CodeGenCXX/cxx0x-defaulted-templates.cpp12
-rw-r--r--test/CodeGenCXX/cxx0x-delegating-ctors.cpp20
-rw-r--r--test/CodeGenCXX/default-constructor-default-argument.cpp2
-rw-r--r--test/CodeGenCXX/default-constructor-template-member.cpp6
-rw-r--r--test/CodeGenCXX/delete.cpp58
-rw-r--r--test/CodeGenCXX/destructors.cpp46
-rw-r--r--test/CodeGenCXX/eh.cpp14
-rw-r--r--test/CodeGenCXX/elide-call-reference.cpp4
-rw-r--r--test/CodeGenCXX/for-range.cpp8
-rw-r--r--test/CodeGenCXX/global-init.cpp31
-rw-r--r--test/CodeGenCXX/implicit-copy-constructor.cpp10
-rw-r--r--test/CodeGenCXX/init-incomplete-type.cpp19
-rw-r--r--test/CodeGenCXX/mangle-subst-std.cpp4
-rw-r--r--test/CodeGenCXX/mangle-template.cpp4
-rw-r--r--test/CodeGenCXX/mangle.cpp157
-rw-r--r--test/CodeGenCXX/member-function-pointers.cpp44
-rw-r--r--test/CodeGenCXX/member-init-assignment.cpp4
-rw-r--r--test/CodeGenCXX/member-init-ctor.cpp2
-rw-r--r--test/CodeGenCXX/new-overflow.cpp209
-rw-r--r--test/CodeGenCXX/new.cpp36
-rw-r--r--test/CodeGenCXX/noinline-template.cpp16
-rw-r--r--test/CodeGenCXX/nrvo.cpp42
-rw-r--r--test/CodeGenCXX/partial-destruction.cpp169
-rw-r--r--test/CodeGenCXX/pointers-to-data-members.cpp6
-rw-r--r--test/CodeGenCXX/pr9965.cpp6
-rw-r--r--test/CodeGenCXX/references.cpp32
-rw-r--r--test/CodeGenCXX/static-init-3.cpp4
-rw-r--r--test/CodeGenCXX/static-init.cpp3
-rw-r--r--test/CodeGenCXX/stmtexpr.cpp10
-rw-r--r--test/CodeGenCXX/template-anonymous-types.cpp4
-rw-r--r--test/CodeGenCXX/temporaries.cpp22
-rw-r--r--test/CodeGenCXX/value-init.cpp69
-rw-r--r--test/CodeGenCXX/variadic-templates.cpp11
-rw-r--r--test/CodeGenCXX/virt-call-offsets.cpp2
-rw-r--r--test/CodeGenCXX/virtual-base-destructor-call.cpp30
-rw-r--r--test/CodeGenCXX/virtual-bases.cpp4
-rw-r--r--test/CodeGenCXX/virtual-functions-incomplete-types.cpp2
-rw-r--r--test/CodeGenCXX/virtual-pseudo-destructor-call.cpp6
-rw-r--r--test/CodeGenCXX/visibility-inlines-hidden.cpp2
-rw-r--r--test/CodeGenCXX/visibility.cpp32
-rw-r--r--test/CodeGenCXX/vla.cpp43
-rw-r--r--test/CodeGenCXX/volatile-1.cpp2
-rw-r--r--test/CodeGenCXX/vtable-pointer-initialization.cpp6
-rw-r--r--test/CodeGenCXX/x86_32-arguments.cpp2
-rw-r--r--test/CodeGenCXX/x86_64-arguments.cpp34
57 files changed, 1112 insertions, 249 deletions
diff --git a/test/CodeGenCXX/anonymous-union-member-initializer.cpp b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
index 2ddafec..324ff4a 100644
--- a/test/CodeGenCXX/anonymous-union-member-initializer.cpp
+++ b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
@@ -86,7 +86,7 @@ namespace test3 {
// CHECK-NEXT: [[UNION:%.*]] = getelementptr inbounds {{.*}} [[THIS]], i32 0, i32 0
// CHECK-NEXT: [[STRUCT:%.*]] = bitcast {{.*}}* [[UNION]] to
// CHECK-NEXT: [[CALLBACK:%.*]] = getelementptr inbounds {{.*}} [[STRUCT]], i32 0, i32 0
- // CHECK-NEXT: store void (i8*)* null, void (i8*)** [[CALLBACK]]
+ // CHECK: store
// CHECK-NEXT: [[UNION:%.*]] = getelementptr inbounds {{.*}} [[THIS]], i32 0, i32 0
// CHECK-NEXT: [[STRUCT:%.*]] = bitcast {{.*}}* [[UNION]] to
// CHECK-NEXT: [[CVALUE:%.*]] = getelementptr inbounds {{.*}} [[STRUCT]], i32 0, i32 1
@@ -114,3 +114,19 @@ template <typename T> struct Foo {
};
};
Foo<int> f;
+
+namespace PR9683 {
+ struct QueueEntry {
+ union {
+ struct {
+ void* mPtr;
+ union {
+ unsigned mSubmissionTag;
+ };
+ };
+ unsigned mValue;
+ };
+ QueueEntry() {}
+ };
+ QueueEntry QE;
+}
diff --git a/test/CodeGenCXX/attr-used.cpp b/test/CodeGenCXX/attr-used.cpp
index 26109e7..2c82184 100644
--- a/test/CodeGenCXX/attr-used.cpp
+++ b/test/CodeGenCXX/attr-used.cpp
@@ -2,8 +2,8 @@
// <rdar://problem/8684363>: clang++ not respecting __attribute__((used)) on destructors
struct X0 {
- // CHECK: define linkonce_odr void @_ZN2X0C1Ev
+ // CHECK: define linkonce_odr {{.*}} @_ZN2X0C1Ev
__attribute__((used)) X0() {}
- // CHECK: define linkonce_odr void @_ZN2X0D1Ev
+ // CHECK: define linkonce_odr {{.*}} @_ZN2X0D1Ev
__attribute__((used)) ~X0() {}
};
diff --git a/test/CodeGenCXX/block-byref-cxx-objc.cpp b/test/CodeGenCXX/block-byref-cxx-objc.cpp
index a4fbd6c..135e0c7 100644
--- a/test/CodeGenCXX/block-byref-cxx-objc.cpp
+++ b/test/CodeGenCXX/block-byref-cxx-objc.cpp
@@ -16,9 +16,9 @@ int main()
}
// CHECK: define internal void @__Block_byref_object_copy_
-// CHECK: call void @_ZN1AC1ERKS_
+// CHECK: call {{.*}} @_ZN1AC1ERKS_
// CHECK: define internal void @__Block_byref_object_dispose_
-// CHECK: call void @_ZN1AD1Ev
+// CHECK: call {{.*}} @_ZN1AD1Ev
// CHECK: define internal void @__copy_helper_block_
// CHECK: call void @_Block_object_assign
// CHECK: define internal void @__destroy_helper_block_
diff --git a/test/CodeGenCXX/blocks.cpp b/test/CodeGenCXX/blocks.cpp
index a4d5b86..0e310bd 100644
--- a/test/CodeGenCXX/blocks.cpp
+++ b/test/CodeGenCXX/blocks.cpp
@@ -31,7 +31,7 @@ namespace test1 {
// ...unless they have mutable fields...
// CHECK: define void @_ZN5test15test3Ev()
- // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:%.*]],
+ // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
// CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
// CHECK: store void ()* [[T0]], void ()** @out
struct mut { mutable int x; };
@@ -43,7 +43,7 @@ namespace test1 {
// ...or non-trivial destructors...
// CHECK: define void @_ZN5test15test4Ev()
// CHECK: [[OBJ:%.*]] = alloca
- // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:%.*]],
+ // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
// CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
// CHECK: store void ()* [[T0]], void ()** @out
struct scope { int x; ~scope(); };
diff --git a/test/CodeGenCXX/class-layout.cpp b/test/CodeGenCXX/class-layout.cpp
index 96fbae8..9569f47 100644
--- a/test/CodeGenCXX/class-layout.cpp
+++ b/test/CodeGenCXX/class-layout.cpp
@@ -20,8 +20,8 @@ namespace Test3 {
namespace Test4 {
// Test from PR5589.
- // CHECK: %"struct.Test4::A" = type { i32, i8, float }
// CHECK: %"struct.Test4::B" = type { %"struct.Test4::A", i16, double }
+ // CHECK: %"struct.Test4::A" = type { i32, i8, float }
struct A {
int a;
char c;
diff --git a/test/CodeGenCXX/compound-literals.cpp b/test/CodeGenCXX/compound-literals.cpp
new file mode 100644
index 0000000..cd44e97
--- /dev/null
+++ b/test/CodeGenCXX/compound-literals.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+struct X {
+ X();
+ X(const X&);
+ X(const char*);
+ ~X();
+};
+
+struct Y {
+ int i;
+ X x;
+};
+
+// CHECK: define i32 @_Z1fv()
+int f() {
+ // CHECK: [[LVALUE:%[a-z0-9.]+]] = alloca
+ // CHECK-NEXT: [[I:%[a-z0-9]+]] = getelementptr inbounds {{.*}}* [[LVALUE]], i32 0, i32 0
+ // CHECK-NEXT: store i32 17, i32* [[I]]
+ // CHECK-NEXT: [[X:%[a-z0-9]+]] = getelementptr inbounds {{.*}} [[LVALUE]], i32 0, i32 1
+ // CHECK-NEXT: call void @_ZN1XC1EPKc({{.*}}[[X]]
+ // CHECK-NEXT: [[I:%[a-z0-9]+]] = getelementptr inbounds {{.*}} [[LVALUE]], i32 0, i32 0
+ // CHECK-NEXT: [[RESULT:%[a-z0-9]+]] = load i32*
+ // CHECK-NEXT: call void @_ZN1YD1Ev
+ // CHECK-NEXT: ret i32 [[RESULT]]
+ return ((Y){17, "seventeen"}).i;
+}
diff --git a/test/CodeGenCXX/const-init.cpp b/test/CodeGenCXX/const-init.cpp
index a8c6f30..797d137 100644
--- a/test/CodeGenCXX/const-init.cpp
+++ b/test/CodeGenCXX/const-init.cpp
@@ -10,7 +10,7 @@ void f();
void (&fr)() = f;
struct S { int& a; };
-// CHECK: @s = global %0 { i32* @a }
+// CHECK: @s = global %struct.S { i32* @a }
S s = { a };
// PR5581
@@ -21,7 +21,7 @@ public:
unsigned f;
};
-// CHECK: @_ZN6PR55812g0E = global %1 { i32 1 }
+// CHECK: @_ZN6PR55812g0E = global %"class.PR5581::C" { i32 1 }
C g0 = { C::e1 };
}
diff --git a/test/CodeGenCXX/constructor-init.cpp b/test/CodeGenCXX/constructor-init.cpp
index 47e3b7b..a195afe 100644
--- a/test/CodeGenCXX/constructor-init.cpp
+++ b/test/CodeGenCXX/constructor-init.cpp
@@ -113,6 +113,22 @@ namespace InitVTable {
B::B(int x) : A(x + 5) {}
}
+namespace rdar9694300 {
+ struct X {
+ int x;
+ };
+
+ // CHECK: define void @_ZN11rdar96943001fEv
+ void f() {
+ // CHECK: alloca
+ X x;
+ // CHECK-NEXT: [[I:%.*]] = alloca i32
+ // CHECK-NEXT: store i32 17, i32* [[I]]
+ int i = 17;
+ // CHECK-NEXT: ret void
+ }
+}
+
template<typename T>
struct X {
X(const X &);
diff --git a/test/CodeGenCXX/constructors.cpp b/test/CodeGenCXX/constructors.cpp
index 75588ce..ec7f06c 100644
--- a/test/CodeGenCXX/constructors.cpp
+++ b/test/CodeGenCXX/constructors.cpp
@@ -83,12 +83,12 @@ struct D : A {
D::D(int x, ...) : A(ValueClass(x, x+1)), mem(x*x) {}
-// CHECK: define void @_ZN1DC1Eiz(%struct.B* %this, i32 %x, ...) unnamed_addr
+// CHECK: define void @_ZN1DC1Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr
// CHECK: call void @_ZN10ValueClassC1Eii(
// CHECK: call void @_ZN1AC2E10ValueClass(
// CHECK: call void @_ZN6MemberC1Ei(
-// CHECK: define void @_ZN1DC2Eiz(%struct.B* %this, i32 %x, ...) unnamed_addr
+// CHECK: define void @_ZN1DC2Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr
// CHECK: call void @_ZN10ValueClassC1Eii(
// CHECK: call void @_ZN1AC2E10ValueClass(
// CHECK: call void @_ZN6MemberC1Ei(
@@ -104,3 +104,14 @@ namespace test0 {
C tmp = in;
}
}
+
+namespace test1 {
+ struct A { A(); void *ptr; };
+ struct B { B(); int x; A a[0]; };
+ B::B() {}
+ // CHECK: define void @_ZN5test11BC2Ev(
+ // CHECK: [[THIS:%.*]] = load [[B:%.*]]**
+ // CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [[B:%.*]]* [[THIS]], i32 0, i32 1
+ // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [0 x {{%.*}}]* [[A]], i32 0, i32 0
+ // CHECK-NEXT: ret void
+}
diff --git a/test/CodeGenCXX/copy-constructor-elim-2.cpp b/test/CodeGenCXX/copy-constructor-elim-2.cpp
index 4f4a8e9..a4a688f 100644
--- a/test/CodeGenCXX/copy-constructor-elim-2.cpp
+++ b/test/CodeGenCXX/copy-constructor-elim-2.cpp
@@ -3,7 +3,7 @@
struct A { int x; A(int); ~A(); };
A f() { return A(0); }
// CHECK: define void @_Z1fv
-// CHECK: call void @_ZN1AC1Ei
+// CHECK: call {{.*}} @_ZN1AC1Ei
// CHECK-NEXT: ret void
// Verify that we do not elide copies when constructing a base class.
@@ -21,14 +21,14 @@ namespace no_elide_base {
Derived(const Other &O);
};
- // CHECK: define void @_ZN13no_elide_base7DerivedC1ERKNS_5OtherE(%"struct.no_elide_base::Derived"* %this, %"struct.PR8683::A"* %O) unnamed_addr
+ // CHECK: define {{.*}} @_ZN13no_elide_base7DerivedC1ERKNS_5OtherE(%"struct.no_elide_base::Derived"* %this, %"struct.no_elide_base::Other"* %O) unnamed_addr
Derived::Derived(const Other &O)
- // CHECK: call void @_ZNK13no_elide_base5OthercvNS_4BaseEEv
- // CHECK: call void @_ZN13no_elide_base4BaseC2ERKS0_
- // CHECK: call void @_ZN13no_elide_base4BaseD1Ev
+ // CHECK: call {{.*}} @_ZNK13no_elide_base5OthercvNS_4BaseEEv
+ // CHECK: call {{.*}} @_ZN13no_elide_base4BaseC2ERKS0_
+ // CHECK: call {{.*}} @_ZN13no_elide_base4BaseD1Ev
: Base(O)
{
- // CHECK: ret void
+ // CHECK: ret
}
}
@@ -48,7 +48,7 @@ struct B {
void f() {
// Verify that we don't mark the copy constructor in this expression as elidable.
- // CHECK: call void @_ZN6PR86831AC1ERKS0_
+ // CHECK: call {{.*}} @_ZN6PR86831AC1ERKS0_
A a = (B().a);
}
diff --git a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
index a556679..d028a28 100644
--- a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
+++ b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
@@ -3,5 +3,5 @@
struct A { virtual void a(); };
A x(A& y) { return y; }
-// CHECK: define linkonce_odr void @_ZN1AC1ERKS_(%struct.A* %this, %struct.A*) unnamed_addr
+// CHECK: define linkonce_odr {{.*}} @_ZN1AC1ERKS_(%struct.A* %this, %struct.A*) unnamed_addr
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
diff --git a/test/CodeGenCXX/copy-initialization.cpp b/test/CodeGenCXX/copy-initialization.cpp
index 62b9f26..aecd64e 100644
--- a/test/CodeGenCXX/copy-initialization.cpp
+++ b/test/CodeGenCXX/copy-initialization.cpp
@@ -12,7 +12,7 @@ struct Bar {
void f(Foo);
-// CHECK: define void @_Z1g3Foo(%struct.Bar* %foo)
+// CHECK: define void @_Z1g3Foo(%struct.Foo* %foo)
void g(Foo foo) {
// CHECK: call void @_ZN3BarC1Ev
// CHECK: @_ZNK3BarcvRK3FooEv
diff --git a/test/CodeGenCXX/cxx0x-defaulted-templates.cpp b/test/CodeGenCXX/cxx0x-defaulted-templates.cpp
index 3d4000e..09eb4fe 100644
--- a/test/CodeGenCXX/cxx0x-defaulted-templates.cpp
+++ b/test/CodeGenCXX/cxx0x-defaulted-templates.cpp
@@ -5,15 +5,15 @@ struct X {
X();
};
-// CHECK: define void @_ZN1XIbEC1Ev
-// CHECK: define void @_ZN1XIbEC2Ev
+// CHECK: define {{.*}} @_ZN1XIbEC1Ev
+// CHECK: define {{.*}} @_ZN1XIbEC2Ev
template <> X<bool>::X() = default;
-// CHECK: define weak_odr void @_ZN1XIiEC1Ev
-// CHECK: define weak_odr void @_ZN1XIiEC2Ev
+// CHECK: define weak_odr {{.*}} @_ZN1XIiEC1Ev
+// CHECK: define weak_odr {{.*}} @_ZN1XIiEC2Ev
template <typename T> X<T>::X() = default;
template X<int>::X();
-// CHECK: define linkonce_odr void @_ZN1XIcEC1Ev
-// CHECK: define linkonce_odr void @_ZN1XIcEC2Ev
+// CHECK: define linkonce_odr {{.*}} @_ZN1XIcEC1Ev
+// CHECK: define linkonce_odr {{.*}} @_ZN1XIcEC2Ev
X<char> x;
diff --git a/test/CodeGenCXX/cxx0x-delegating-ctors.cpp b/test/CodeGenCXX/cxx0x-delegating-ctors.cpp
index 15c8e7f..0bac492 100644
--- a/test/CodeGenCXX/cxx0x-delegating-ctors.cpp
+++ b/test/CodeGenCXX/cxx0x-delegating-ctors.cpp
@@ -26,28 +26,28 @@ delegator::delegator() {
delegator::delegator(bool)
{}
-// CHECK: define void @_ZN9delegatorC1Ec
-// CHECK: void @_ZN9delegatorC1Eb
+// CHECK: define {{.*}} @_ZN9delegatorC1Ec
+// CHECK: {{.*}} @_ZN9delegatorC1Eb
// CHECK: void @__cxa_throw
// CHECK: void @_ZSt9terminatev
-// CHECK: void @_ZN9delegatorD1Ev
-// CHECK: define void @_ZN9delegatorC2Ec
-// CHECK: void @_ZN9delegatorC2Eb
+// CHECK: {{.*}} @_ZN9delegatorD1Ev
+// CHECK: define {{.*}} @_ZN9delegatorC2Ec
+// CHECK: {{.*}} @_ZN9delegatorC2Eb
// CHECK: void @__cxa_throw
// CHECK: void @_ZSt9terminatev
-// CHECK: void @_ZN9delegatorD2Ev
+// CHECK: {{.*}} @_ZN9delegatorD2Ev
delegator::delegator(char)
: delegator(true) {
throw 0;
}
-// CHECK: define void @_ZN9delegatorC1Ei
-// CHECK: void @_ZN9delegatorC1Ev
+// CHECK: define {{.*}} @_ZN9delegatorC1Ei
+// CHECK: {{.*}} @_ZN9delegatorC1Ev
// CHECK-NOT: void @_ZSt9terminatev
// CHECK: ret
// CHECK-NOT: void @_ZSt9terminatev
-// CHECK: define void @_ZN9delegatorC2Ei
-// CHECK: void @_ZN9delegatorC2Ev
+// CHECK: define {{.*}} @_ZN9delegatorC2Ei
+// CHECK: {{.*}} @_ZN9delegatorC2Ev
// CHECK-NOT: void @_ZSt9terminatev
// CHECK: ret
// CHECK-NOT: void @_ZSt9terminatev
diff --git a/test/CodeGenCXX/default-constructor-default-argument.cpp b/test/CodeGenCXX/default-constructor-default-argument.cpp
index f2c7f6d..374a967 100644
--- a/test/CodeGenCXX/default-constructor-default-argument.cpp
+++ b/test/CodeGenCXX/default-constructor-default-argument.cpp
@@ -5,4 +5,4 @@ struct A { A(int x = 2); };
struct B : public A {};
B x;
-// CHECK: call void @_ZN1AC2Ei
+// CHECK: call {{.*}} @_ZN1AC2Ei
diff --git a/test/CodeGenCXX/default-constructor-template-member.cpp b/test/CodeGenCXX/default-constructor-template-member.cpp
index 422cc09..0dd64df 100644
--- a/test/CodeGenCXX/default-constructor-template-member.cpp
+++ b/test/CodeGenCXX/default-constructor-template-member.cpp
@@ -5,6 +5,6 @@ struct B { A<int> x; };
void a() {
B b;
}
-// CHECK: call void @_ZN1BC1Ev
-// CHECK: define linkonce_odr void @_ZN1BC1Ev(%struct.B* %this) unnamed_addr
-// CHECK: call void @_ZN1AIiEC1Ev
+// CHECK: call {{.*}} @_ZN1BC1Ev
+// CHECK: define linkonce_odr {{.*}} @_ZN1BC1Ev(%struct.B* %this) unnamed_addr
+// CHECK: call {{.*}} @_ZN1AIiEC1Ev
diff --git a/test/CodeGenCXX/delete.cpp b/test/CodeGenCXX/delete.cpp
index ddc7bb8..08ce0de 100644
--- a/test/CodeGenCXX/delete.cpp
+++ b/test/CodeGenCXX/delete.cpp
@@ -54,7 +54,7 @@ namespace test0 {
delete a;
}
- // CHECK: define linkonce_odr void @_ZN5test01AD1Ev(%class.A* %this) unnamed_addr
+ // CHECK: define linkonce_odr void @_ZN5test01AD1Ev(%"struct.test0::A"* %this) unnamed_addr
// CHECK: define linkonce_odr void @_ZN5test01AdlEPv
}
@@ -67,31 +67,22 @@ namespace test1 {
// CHECK: define void @_ZN5test14testEPA10_A20_NS_1AE(
void test(A (*arr)[10][20]) {
delete [] arr;
- // CHECK: icmp eq [10 x [20 x [[S:%.*]]]]* [[PTR:%.*]], null
+ // CHECK: icmp eq [10 x [20 x [[A:%.*]]]]* [[PTR:%.*]], null
// CHECK-NEXT: br i1
- // CHECK: [[ARR:%.*]] = getelementptr inbounds [10 x [20 x [[S]]]]* [[PTR]], i32 0, i32 0, i32 0
- // CHECK-NEXT: bitcast {{.*}} to i8*
- // CHECK-NEXT: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i64 -8
- // CHECK-NEXT: bitcast i8* [[ALLOC]] to i64*
- // CHECK-NEXT: load
- // CHECK-NEXT: store i64 {{.*}}, i64* [[IDX:%.*]]
-
- // CHECK: load i64* [[IDX]]
- // CHECK-NEXT: icmp ne {{.*}}, 0
- // CHECK-NEXT: br i1
-
- // CHECK: load i64* [[IDX]]
- // CHECK-NEXT: [[I:%.*]] = sub i64 {{.*}}, 1
- // CHECK-NEXT: getelementptr inbounds [[S]]* [[ARR]], i64 [[I]]
- // CHECK-NEXT: call void @_ZN5test11AD1Ev(
- // CHECK-NEXT: br label
-
- // CHECK: load i64* [[IDX]]
- // CHECK-NEXT: sub
- // CHECK-NEXT: store {{.*}}, i64* [[IDX]]
- // CHECK-NEXT: br label
-
+ // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [10 x [20 x [[A]]]]* [[PTR]], i32 0, i32 0, i32 0
+ // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[BEGIN]] to i8*
+ // CHECK-NEXT: [[ALLOC:%.*]] = getelementptr inbounds i8* [[T0]], i64 -8
+ // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[ALLOC]] to i64*
+ // CHECK-NEXT: [[COUNT:%.*]] = load i64* [[T1]]
+ // CHECK: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 [[COUNT]]
+ // CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[END]]
+ // CHECK-NEXT: br i1 [[ISEMPTY]],
+ // CHECK: [[PAST:%.*]] = phi [[A]]* [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]]* [[PAST]], i64 -1
+ // CHECK-NEXT: call void @_ZN5test11AD1Ev([[A]]* [[CUR]])
+ // CHECK-NEXT: [[ISDONE:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]]
+ // CHECK-NEXT: br i1 [[ISDONE]]
// CHECK: call void @_ZdaPv(i8* [[ALLOC]])
}
}
@@ -112,3 +103,22 @@ namespace test3 {
delete a;
}
}
+
+namespace test4 {
+ // PR10341: ::delete with a virtual destructor
+ struct X {
+ virtual ~X();
+ void operator delete (void *);
+ };
+
+ // CHECK: define void @_ZN5test421global_delete_virtualEPNS_1XE
+ void global_delete_virtual(X *xp) {
+ // CHECK: [[VTABLE:%.*]] = load void ([[X:%.*]])***
+ // CHECK-NEXT: [[VFN:%.*]] = getelementptr inbounds void ([[X]])** [[VTABLE]], i64 0
+ // CHECK-NEXT: [[VFNPTR:%.*]] = load void ([[X]])** [[VFN]]
+ // CHECK-NEXT: call void [[VFNPTR]]([[X]] [[OBJ:%.*]])
+ // CHECK-NEXT: [[OBJVOID:%.*]] = bitcast [[X]] [[OBJ]] to i8*
+ // CHECK-NEXT: call void @_ZdlPv(i8* [[OBJVOID]]) nounwind
+ ::delete xp;
+ }
+}
diff --git a/test/CodeGenCXX/destructors.cpp b/test/CodeGenCXX/destructors.cpp
index 94d8833..3381985 100644
--- a/test/CodeGenCXX/destructors.cpp
+++ b/test/CodeGenCXX/destructors.cpp
@@ -40,11 +40,11 @@ namespace PR7526 {
struct allocator_derived : allocator { };
- // CHECK: define void @_ZN6PR75269allocatorD2Ev(%"struct.PR5529::A"* %this) unnamed_addr
+ // CHECK: define void @_ZN6PR75269allocatorD2Ev(%"struct.PR7526::allocator"* %this) unnamed_addr
// CHECK: call void @__cxa_call_unexpected
allocator::~allocator() throw() { foo(); }
- // CHECK: define linkonce_odr void @_ZN6PR752617allocator_derivedD1Ev(%"struct.PR5529::A"* %this) unnamed_addr
+ // CHECK: define linkonce_odr void @_ZN6PR752617allocator_derivedD1Ev(%"struct.PR7526::allocator_derived"* %this) unnamed_addr
// CHECK-NOT: call void @__cxa_call_unexpected
// CHECK: }
void foo() {
@@ -145,10 +145,10 @@ namespace test1 {
P::~P() {} // CHECK: define void @_ZN5test11PD2Ev(%"struct.test1::P"* %this) unnamed_addr
struct Q : A, B { ~Q(); };
- Q::~Q() {} // CHECK: define void @_ZN5test11QD2Ev(%"struct.test1::M"* %this) unnamed_addr
+ Q::~Q() {} // CHECK: define void @_ZN5test11QD2Ev(%"struct.test1::Q"* %this) unnamed_addr
struct R : A { ~R(); };
- R::~R() { A a; } // CHECK: define void @_ZN5test11RD2Ev(%"struct.test1::M"* %this) unnamed_addr
+ R::~R() { A a; } // CHECK: define void @_ZN5test11RD2Ev(%"struct.test1::R"* %this) unnamed_addr
struct S : A { ~S(); int x; };
S::~S() {} // alias tested above
@@ -168,7 +168,7 @@ namespace test2 {
struct B : A { ~B(); };
B::~B() {}
- // CHECK: define void @_ZN5test21BD2Ev(%"struct.test1::M"* %this) unnamed_addr
+ // CHECK: define void @_ZN5test21BD2Ev(%"struct.test2::B"* %this) unnamed_addr
// CHECK: call void @_ZN5test21AD2Ev
}
@@ -233,28 +233,28 @@ namespace test4 {
namespace test5 {
struct A { ~A(); };
- // This is really unnecessarily verbose; we should be using phis,
- // even at -O0.
-
// CHECK: define void @_ZN5test53fooEv()
// CHECK: [[ELEMS:%.*]] = alloca [5 x [[A:%.*]]], align
- // CHECK-NEXT: [[IVAR:%.*]] = alloca i64
- // CHECK: [[ELEMSARRAY:%.*]] = bitcast [5 x [[A]]]* [[ELEMS]] to [[A]]
- // CHECK-NEXT: store i64 5, i64* [[IVAR]]
- // CHECK-NEXT: br label
- // CHECK: [[I:%.*]] = load i64* [[IVAR]]
- // CHECK-NEXT: icmp ne i64 [[I]], 0
- // CHECK-NEXT: br i1
- // CHECK: [[I:%.*]] = load i64* [[IVAR]]
- // CHECK-NEXT: [[I2:%.*]] = sub i64 [[I]], 1
- // CHECK-NEXT: getelementptr inbounds [[A]]* [[ELEMSARRAY]], i64 [[I2]]
- // CHECK-NEXT: call void @_ZN5test51AD1Ev(
- // CHECK-NEXT: br label
- // CHECK: [[I:%.*]] = load i64* [[IVAR]]
- // CHECK-NEXT: [[I1:%.*]] = sub i64 [[I]], 1
- // CHECK-NEXT: store i64 [[I1]], i64* [[IVAR]]
+ // CHECK-NEXT: [[EXN:%.*]] = alloca i8*
+ // CHECK-NEXT: [[SEL:%.*]] = alloca i32
+ // CHECK-NEXT: [[EHCLEANUP:%.*]] = alloca i32
+ // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [5 x [[A]]]* [[ELEMS]], i32 0, i32 0
+ // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 5
// CHECK-NEXT: br label
+ // CHECK: [[POST:%.*]] = phi [[A]]* [ [[END]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]]* [[POST]], i64 -1
+ // CHECK-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[ELT]])
+ // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[ELT]], [[BEGIN]]
+ // CHECK-NEXT: br i1 [[T0]],
// CHECK: ret void
+ // lpad
+ // CHECK: [[EMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[ELT]]
+ // CHECK-NEXT: br i1 [[EMPTY]]
+ // CHECK: [[AFTER:%.*]] = phi [[A]]* [ [[ELT]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]]* [[AFTER]], i64 -1
+ // CHECK-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[CUR]])
+ // CHECK: [[DONE:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]]
+ // CHECK-NEXT: br i1 [[DONE]],
void foo() {
A elems[5];
}
diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp
index 44219b4..58cb445 100644
--- a/test/CodeGenCXX/eh.cpp
+++ b/test/CodeGenCXX/eh.cpp
@@ -14,7 +14,7 @@ void test1() {
// CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSTAR:%[^*]*\*]]
// CHECK-NEXT: [[EXN2:%.*]] = bitcast [[DSTAR]] [[EXN]] to i8*
// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[EXN2]], i8* bitcast ([[DSTAR]] @d1 to i8*), i64 8, i32 8, i1 false)
-// CHECK-NEXT: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast (%0* @_ZTI7test1_D to i8*), i8* null) noreturn
+// CHECK-NEXT: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({ i8*, i8* }* @_ZTI7test1_D to i8*), i8* null) noreturn
// CHECK-NEXT: unreachable
@@ -38,7 +38,7 @@ void test2() {
// CHECK-NEXT: invoke void @_ZN7test2_DC1ERKS_([[DSTAR]] [[EXN]], [[DSTAR]] @d2)
// CHECK-NEXT: to label %[[CONT:.*]] unwind label %{{.*}}
// : [[CONT]]: (can't check this in Release-Asserts builds)
-// CHECK: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast (%{{.*}}* @_ZTI7test2_D to i8*), i8* null) noreturn
+// CHECK: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({{.*}}* @_ZTI7test2_D to i8*), i8* null) noreturn
// CHECK-NEXT: unreachable
@@ -56,7 +56,7 @@ void test3() {
// CHECK: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 8)
// CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[D:%[^*]+]]**
// CHECK-NEXT: store [[D]]* null, [[D]]** [[EXN]]
-// CHECK-NEXT: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast (%1* @_ZTIPV7test3_D to i8*), i8* null) noreturn
+// CHECK-NEXT: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({ i8*, i8*, i32, i8* }* @_ZTIPV7test3_D to i8*), i8* null) noreturn
// CHECK-NEXT: unreachable
@@ -84,10 +84,10 @@ namespace test5 {
// CHECK: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 1)
// CHECK: [[EXNCAST:%.*]] = bitcast i8* [[EXNOBJ]] to [[A:%[^*]*]]*
// CHECK-NEXT: invoke void @_ZN5test51AC1Ev([[A]]* [[EXNCAST]])
-// CHECK: invoke void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({{%.*}}* @_ZTIN5test51AE to i8*), i8* bitcast (void ([[A]]*)* @_ZN5test51AD1Ev to i8*)) noreturn
+// CHECK: invoke void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({{.*}}* @_ZTIN5test51AE to i8*), i8* bitcast (void ([[A]]*)* @_ZN5test51AD1Ev to i8*)) noreturn
// CHECK-NEXT: to label {{%.*}} unwind label %[[HANDLER:[^ ]*]]
// : [[HANDLER]]: (can't check this in Release-Asserts builds)
-// CHECK: {{%.*}} = call i32 @llvm.eh.typeid.for(i8* bitcast ({{%.*}}* @_ZTIN5test51AE to i8*))
+// CHECK: {{%.*}} = call i32 @llvm.eh.typeid.for(i8* bitcast ({{.*}}* @_ZTIN5test51AE to i8*))
}
namespace test6 {
@@ -177,11 +177,11 @@ namespace test9 {
struct A { A(); };
- // CHECK: define void @_ZN5test91AC1Ev(%"struct.test10::A"* %this) unnamed_addr
+ // CHECK: define void @_ZN5test91AC1Ev(%"struct.test9::A"* %this) unnamed_addr
// CHECK: call void @_ZN5test91AC2Ev
// CHECK-NEXT: ret void
- // CHECK: define void @_ZN5test91AC2Ev(%"struct.test10::A"* %this) unnamed_addr
+ // CHECK: define void @_ZN5test91AC2Ev(%"struct.test9::A"* %this) unnamed_addr
A::A() try {
// CHECK: invoke void @_ZN5test96opaqueEv()
opaque();
diff --git a/test/CodeGenCXX/elide-call-reference.cpp b/test/CodeGenCXX/elide-call-reference.cpp
index c82eee7..55d30e2 100644
--- a/test/CodeGenCXX/elide-call-reference.cpp
+++ b/test/CodeGenCXX/elide-call-reference.cpp
@@ -7,5 +7,5 @@ void b() {
A x = a();
}
-// CHECK: call void @_ZN1AC1ERKS_
-// CHECK: call void @_ZN1AD1Ev
+// CHECK: call {{.*}} @_ZN1AC1ERKS_
+// CHECK: call {{.*}} @_ZN1AD1Ev
diff --git a/test/CodeGenCXX/for-range.cpp b/test/CodeGenCXX/for-range.cpp
index af46644..ab1a231 100644
--- a/test/CodeGenCXX/for-range.cpp
+++ b/test/CodeGenCXX/for-range.cpp
@@ -69,8 +69,8 @@ void for_range() {
A a;
for (B b : C()) {
// CHECK: call void @_ZN1CC1Ev(
- // CHECK: = call %struct.A* @_ZSt5beginR1C(
- // CHECK: = call %struct.A* @_ZSt3endR1C(
+ // CHECK: = call %struct.B* @_ZSt5beginR1C(
+ // CHECK: = call %struct.B* @_ZSt3endR1C(
// CHECK: br label %[[COND:.*]]
// CHECK: [[COND]]:
@@ -101,8 +101,8 @@ void for_member_range() {
A a;
for (B b : D()) {
// CHECK: call void @_ZN1DC1Ev(
- // CHECK: = call %struct.A* @_ZN1D5beginEv(
- // CHECK: = call %struct.A* @_ZN1D3endEv(
+ // CHECK: = call %struct.B* @_ZN1D5beginEv(
+ // CHECK: = call %struct.B* @_ZN1D3endEv(
// CHECK: br label %[[COND:.*]]
// CHECK: [[COND]]:
diff --git a/test/CodeGenCXX/global-init.cpp b/test/CodeGenCXX/global-init.cpp
index 9bd7390..053210b 100644
--- a/test/CodeGenCXX/global-init.cpp
+++ b/test/CodeGenCXX/global-init.cpp
@@ -21,21 +21,21 @@ struct D { ~D(); };
// PR6205: The casts should not require global initializers
// CHECK: @_ZN6PR59741cE = external global %"struct.PR5974::C"
// CHECK: @_ZN6PR59741aE = global %"struct.PR5974::A"* getelementptr inbounds (%"struct.PR5974::C"* @_ZN6PR59741cE, i32 0, i32 0)
-// CHECK: @_ZN6PR59741bE = global %"struct.PR5974::A"* bitcast (i8* getelementptr (i8* bitcast (%"struct.PR5974::C"* @_ZN6PR59741cE to i8*), i64 4) to %"struct.PR5974::A"*), align 8
+// CHECK: @_ZN6PR59741bE = global %"struct.PR5974::B"* bitcast (i8* getelementptr (i8* bitcast (%"struct.PR5974::C"* @_ZN6PR59741cE to i8*), i64 4) to %"struct.PR5974::B"*), align 8
// CHECK: call void @_ZN1AC1Ev(%struct.A* @a)
// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
A a;
-// CHECK: call void @_ZN1BC1Ev(%struct.A* @b)
-// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1BD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @b, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
+// CHECK: call void @_ZN1BC1Ev(%struct.B* @b)
+// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.B*)* @_ZN1BD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.B* @b, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
B b;
// PR6205: this should not require a global initializer
// CHECK-NOT: call void @_ZN1CC1Ev(%struct.C* @c)
C c;
-// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1DD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @d, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
+// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.D*)* @_ZN1DD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.D* @d, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
D d;
// <rdar://problem/7458115>
@@ -70,6 +70,20 @@ namespace test3 {
const char *test() { return var; }
}
+namespace test6 {
+ struct A {
+ A();
+ };
+ extern int foo();
+
+ // This needs an initialization function and guard variables.
+ // CHECK: load i8* bitcast (i64* @_ZGVN5test61xE
+ // CHECK: [[CALL:%.*]] = call i32 @_ZN5test63fooEv
+ // CHECK-NEXT: store i32 [[CALL]], i32* @_ZN5test61xE
+ // CHECK-NEXT: store i64 1, i64* @_ZGVN5test61xE
+ __attribute__((weak)) int x = foo();
+}
+
namespace PR5974 {
struct A { int a; };
struct B { int b; };
@@ -97,15 +111,6 @@ namespace test5 {
};
}
-namespace test6 {
- struct A {
- A();
- };
- extern int foo();
-
- // This needs an initialization function but not guard variables.
- __attribute__((weak)) int x = foo();
-}
// At the end of the file, we check that y is initialized before z.
diff --git a/test/CodeGenCXX/implicit-copy-constructor.cpp b/test/CodeGenCXX/implicit-copy-constructor.cpp
index 5008601..8bc84a5 100644
--- a/test/CodeGenCXX/implicit-copy-constructor.cpp
+++ b/test/CodeGenCXX/implicit-copy-constructor.cpp
@@ -70,3 +70,13 @@ void test_X2()
pimpl pdata;
pdata.f0( new impl(*i));
}
+
+// rdar://problem/9598341
+namespace test3 {
+ struct A { A(const A&); A&operator=(const A&); };
+ struct B { A a; unsigned : 0; };
+ void test(const B &x) {
+ B y = x;
+ y = x;
+ }
+}
diff --git a/test/CodeGenCXX/init-incomplete-type.cpp b/test/CodeGenCXX/init-incomplete-type.cpp
index 3312d3e..1755dfb 100644
--- a/test/CodeGenCXX/init-incomplete-type.cpp
+++ b/test/CodeGenCXX/init-incomplete-type.cpp
@@ -10,3 +10,22 @@ static struct Bar<int> bar[1] = {
{ 0 }
};
+
+
+namespace incomplete_type_refs {
+ struct A;
+ extern A g[];
+ void foo(A*);
+ void f(void) {
+ foo(g); // Reference to array with unknown element type.
+ }
+
+ struct A { // define the element type.
+ int a,b,c;
+ };
+
+ A *f2() {
+ return &g[1];
+ }
+
+} \ No newline at end of file
diff --git a/test/CodeGenCXX/mangle-subst-std.cpp b/test/CodeGenCXX/mangle-subst-std.cpp
index 837d4fa..30b579c 100644
--- a/test/CodeGenCXX/mangle-subst-std.cpp
+++ b/test/CodeGenCXX/mangle-subst-std.cpp
@@ -15,8 +15,8 @@
namespace std {
struct A { A(); };
- // CHECK: define void @_ZNSt1AC1Ev(%"struct.N::std::A"* %this) unnamed_addr
- // CHECK: define void @_ZNSt1AC2Ev(%"struct.N::std::A"* %this) unnamed_addr
+ // CHECK: define void @_ZNSt1AC1Ev(%"struct.std::A"* %this) unnamed_addr
+ // CHECK: define void @_ZNSt1AC2Ev(%"struct.std::A"* %this) unnamed_addr
A::A() { }
};
diff --git a/test/CodeGenCXX/mangle-template.cpp b/test/CodeGenCXX/mangle-template.cpp
index 463f15d..f95e152 100644
--- a/test/CodeGenCXX/mangle-template.cpp
+++ b/test/CodeGenCXX/mangle-template.cpp
@@ -82,7 +82,7 @@ namespace test7 {
X(U*, typename int_c<(meta<T>::value + meta<U>::value)>::type *) { }
};
- // CHECK: define weak_odr void @_ZN5test71XIiEC1IdEEPT_PNS_5int_cIXplL_ZNS_4metaIiE5valueEEsrNS6_IS3_EE5valueEE4typeE(%"class.test1::T"* %this, double*, float*) unnamed_addr
+ // CHECK: define weak_odr {{.*}} @_ZN5test71XIiEC1IdEEPT_PNS_5int_cIXplL_ZNS_4metaIiE5valueEEsr4metaIS3_EE5valueEE4typeE(%"struct.test7::X"* %this, double*, float*) unnamed_addr
template X<int>::X(double*, float*);
}
@@ -101,7 +101,7 @@ namespace test8 {
template<typename T>
void f(int_c<meta<T>::type::value>) { }
- // CHECK: define weak_odr void @_ZN5test81fIiEEvNS_5int_cIXsrNS_4metaIT_E4typeE5valueEEE
+ // CHECK: define weak_odr void @_ZN5test81fIiEEvNS_5int_cIXsr4metaIT_E4typeE5valueEEE
template void f<int>(int_c<sizeof(int)>);
}
diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp
index 01dcf8b..453b7b7 100644
--- a/test/CodeGenCXX/mangle.cpp
+++ b/test/CodeGenCXX/mangle.cpp
@@ -196,9 +196,9 @@ template<typename T> struct __enable_if<true, T> {
// PR5063
template<typename T> typename __enable_if<__is_scalar_type<T>::__value, void>::__type ft7() { }
-// CHECK: @_Z3ft7IiEN11__enable_ifIXsr16__is_scalar_typeIT_E7__valueEvE6__typeEv
+// CHECK: @_Z3ft7IiEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
template void ft7<int>();
-// CHECK: @_Z3ft7IPvEN11__enable_ifIXsr16__is_scalar_typeIT_E7__valueEvE6__typeEv
+// CHECK: @_Z3ft7IPvEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
template void ft7<void*>();
// PR5144
@@ -226,9 +226,9 @@ S7::S7() {}
// PR5063
template<typename T> typename __enable_if<(__is_scalar_type<T>::__value), void>::__type ft8() { }
-// CHECK: @_Z3ft8IiEN11__enable_ifIXsr16__is_scalar_typeIT_E7__valueEvE6__typeEv
+// CHECK: @_Z3ft8IiEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
template void ft8<int>();
-// CHECK: @_Z3ft8IPvEN11__enable_ifIXsr16__is_scalar_typeIT_E7__valueEvE6__typeEv
+// CHECK: @_Z3ft8IPvEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
template void ft8<void*>();
// PR5796
@@ -241,7 +241,7 @@ template<bool, typename> struct __enable_if {};
template<typename T> struct __enable_if<true, T> { typedef T __type; };
template<typename T>
-// CHECK: define linkonce_odr void @_ZN6PR57968__fill_aIiEENS_11__enable_ifIXntsrNS_16__is_scalar_typeIT_EE7__valueEvE6__typeEv
+// CHECK: define linkonce_odr void @_ZN6PR57968__fill_aIiEENS_11__enable_ifIXntsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
typename __enable_if<!__is_scalar_type<T>::__value, void>::__type __fill_a() { };
void f() { __fill_a<int>(); }
@@ -711,3 +711,150 @@ namespace test27 {
b<A>(f);
}
}
+
+// An injected class name type in a unresolved-name.
+namespace test28 {
+ template <class T> struct A {
+ enum { bit };
+ };
+
+ template <class T> void foo(decltype(A<T>::A::bit) x);
+
+ void test() {
+ foo<char>(A<char>::bit);
+ // CHECK: call void @_ZN6test283fooIcEEvDtsr1AIT_E1AE3bitE(
+ }
+}
+
+// An enclosing template type parameter in an unresolved-name.
+namespace test29 {
+ template <class T> struct A {
+ template <class U> static void foo(decltype(T::fn(U())) x);
+ };
+ struct B { static int fn(int); static long fn(long); };
+
+ void test() {
+ A<B>::foo<int>(0);
+ // CHECK: call void @_ZN6test291AINS_1BEE3fooIiEEvDTclsrS1_2fncvT__EEE(
+ }
+}
+
+// An enclosing template template parameter in an unresolved-name.
+namespace test30 {
+ template <template <class> class T> struct A {
+ template <class U> static void foo(decltype(T<U>::fn()) x);
+ };
+ template <class T> struct B { static T fn(); };
+
+ void test() {
+ A<B>::foo<int>(0);
+ // CHECK: call void @_ZN6test301AINS_1BEE3fooIiEEvDTclsrS1_IT_EE2fnEE(
+ }
+}
+
+namespace test31 { // instantiation-dependent mangling of decltype
+ int x;
+ template<class T> auto f1(T p)->decltype(x) { return 0; }
+ // The return type in the mangling of the template signature
+ // is encoded as "i".
+ template<class T> auto f2(T p)->decltype(p) { return 0; }
+ // The return type in the mangling of the template signature
+ // is encoded as "Dtfp_E".
+ void g(int);
+ template<class T> auto f3(T p)->decltype(g(p)) {}
+
+ // CHECK: define weak_odr i32 @_ZN6test312f1IiEEiT_(
+ template int f1(int);
+ // CHECK: define weak_odr i32 @_ZN6test312f2IiEEDtfp_ET_
+ template int f2(int);
+ // CHECK: define weak_odr void @_ZN6test312f3IiEEDTcl1gfp_EET_
+ template void f3(int);
+}
+
+// PR10205
+namespace test32 {
+ template<typename T, int=T::value> struct A {
+ typedef int type;
+ };
+ struct B { enum { value = 4 }; };
+
+ template <class T> typename A<T>::type foo() { return 0; }
+ void test() {
+ foo<B>();
+ // CHECK: call i32 @_ZN6test323fooINS_1BEEENS_1AIT_XsrS3_5valueEE4typeEv()
+ }
+}
+
+namespace test33 {
+ template <class T> struct X {
+ enum { value = T::value };
+ };
+
+ template<typename T, int=X<T>::value> struct A {
+ typedef int type;
+ };
+ struct B { enum { value = 4 }; };
+
+ template <class T> typename A<T>::type foo() { return 0; }
+
+ void test() {
+ foo<B>();
+ // CHECK: call i32 @_ZN6test333fooINS_1BEEENS_1AIT_Xsr1XIS3_EE5valueEE4typeEv()
+ }
+}
+
+namespace test34 {
+ // Mangling for instantiation-dependent decltype expressions.
+ template<typename T>
+ void f(decltype(sizeof(decltype(T() + T())))) {}
+
+ // CHECK: define weak_odr void @_ZN6test341fIiEEvDTstDTplcvT__EcvS1__EEE
+ template void f<int>(decltype(sizeof(1)));
+
+ // Mangling for non-instantiation-dependent sizeof expressions.
+ template<unsigned N>
+ void f2(int (&)[N + sizeof(int*)]) {}
+
+ // CHECK: define weak_odr void @_ZN6test342f2ILj4EEEvRAplT_Lm8E_i
+ template void f2<4>(int (&)[4 + sizeof(int*)]);
+
+ // Mangling for non-instantiation-dependent sizeof expressions
+ // involving an implicit conversion of the result of the sizeof.
+ template<unsigned long long N>
+ void f3(int (&)[N + sizeof(int*)]) {}
+
+ // CHECK: define weak_odr void @_ZN6test342f3ILy4EEEvRAplT_Ly8E_i
+ template void f3<4>(int (&)[4 + sizeof(int*)]);
+
+ // Mangling for instantiation-dependent sizeof() expressions as
+ // template arguments.
+ template<unsigned> struct A { };
+
+ template<typename T> void f4(::test34::A<sizeof(sizeof(decltype(T() + T())))>) { }
+
+ // CHECK: define weak_odr void @_ZN6test342f4IiEEvNS_1AIXszstDTplcvT__EcvS2__EEEEE
+ template void f4<int>(A<sizeof(sizeof(int))>);
+}
+
+namespace test35 {
+ // Dependent operator names of unknown arity.
+ struct A {
+ template<typename U> A operator+(U) const;
+ };
+
+ template<typename T>
+ void f1(decltype(sizeof(&T::template operator+<int>))) {}
+
+ // CHECK: define weak_odr void @_ZN6test352f1INS_1AEEEvDTszadsrT_plIiEE
+ template void f1<A>(__SIZE_TYPE__);
+}
+
+namespace test36 {
+ template<unsigned> struct A { };
+
+ template<typename ...Types>
+ auto f1(Types... values) -> A<sizeof...(values)> { }
+
+ // CHECK: define weak_odr {{.*}} @_ZN6test362f1IJifEEENS_1AIXsZfp_EEEDpT_
+ template A<2> f1(int, float);
+}
diff --git a/test/CodeGenCXX/member-function-pointers.cpp b/test/CodeGenCXX/member-function-pointers.cpp
index 011e9cd..4c42bd8 100644
--- a/test/CodeGenCXX/member-function-pointers.cpp
+++ b/test/CodeGenCXX/member-function-pointers.cpp
@@ -11,56 +11,56 @@ void (A::*volatile vpa)();
void (B::*pb)();
void (C::*pc)();
-// CHECK: @pa2 = global %0 { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 0 }, align 8
+// CHECK: @pa2 = global { i64, i64 } { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 0 }, align 8
void (A::*pa2)() = &A::f;
-// CHECK: @pa3 = global %0 { i64 1, i64 0 }, align 8
-// CHECK-LP32: @pa3 = global %0 { i32 1, i32 0 }, align 4
+// CHECK: @pa3 = global { i64, i64 } { i64 1, i64 0 }, align 8
+// CHECK-LP32: @pa3 = global { i32, i32 } { i32 1, i32 0 }, align 4
void (A::*pa3)() = &A::vf1;
-// CHECK: @pa4 = global %0 { i64 9, i64 0 }, align 8
-// CHECK-LP32: @pa4 = global %0 { i32 5, i32 0 }, align 4
+// CHECK: @pa4 = global { i64, i64 } { i64 9, i64 0 }, align 8
+// CHECK-LP32: @pa4 = global { i32, i32 } { i32 5, i32 0 }, align 4
void (A::*pa4)() = &A::vf2;
-// CHECK: @pc2 = global %0 { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 16 }, align 8
+// CHECK: @pc2 = global { i64, i64 } { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 16 }, align 8
void (C::*pc2)() = &C::f;
-// CHECK: @pc3 = global %0 { i64 1, i64 0 }, align 8
+// CHECK: @pc3 = global { i64, i64 } { i64 1, i64 0 }, align 8
void (A::*pc3)() = &A::vf1;
void f() {
- // CHECK: store %0 zeroinitializer, %0* @pa
+ // CHECK: store { i64, i64 } zeroinitializer, { i64, i64 }* @pa
pa = 0;
// Is this okay? What are LLVM's volatile semantics for structs?
- // CHECK: volatile store %0 zeroinitializer, %0* @vpa
+ // CHECK: volatile store { i64, i64 } zeroinitializer, { i64, i64 }* @vpa
vpa = 0;
- // CHECK: [[TMP:%.*]] = load %0* @pa, align 8
- // CHECK: [[TMPADJ:%.*]] = extractvalue %0 [[TMP]], 1
+ // CHECK: [[TMP:%.*]] = load { i64, i64 }* @pa, align 8
+ // CHECK: [[TMPADJ:%.*]] = extractvalue { i64, i64 } [[TMP]], 1
// CHECK: [[ADJ:%.*]] = add nsw i64 [[TMPADJ]], 16
- // CHECK: [[RES:%.*]] = insertvalue %0 [[TMP]], i64 [[ADJ]], 1
- // CHECK: store %0 [[RES]], %0* @pc, align 8
+ // CHECK: [[RES:%.*]] = insertvalue { i64, i64 } [[TMP]], i64 [[ADJ]], 1
+ // CHECK: store { i64, i64 } [[RES]], { i64, i64 }* @pc, align 8
pc = pa;
- // CHECK: [[TMP:%.*]] = load %0* @pc, align 8
- // CHECK: [[TMPADJ:%.*]] = extractvalue %0 [[TMP]], 1
+ // CHECK: [[TMP:%.*]] = load { i64, i64 }* @pc, align 8
+ // CHECK: [[TMPADJ:%.*]] = extractvalue { i64, i64 } [[TMP]], 1
// CHECK: [[ADJ:%.*]] = sub nsw i64 [[TMPADJ]], 16
- // CHECK: [[RES:%.*]] = insertvalue %0 [[TMP]], i64 [[ADJ]], 1
- // CHECK: store %0 [[RES]], %0* @pa, align 8
+ // CHECK: [[RES:%.*]] = insertvalue { i64, i64 } [[TMP]], i64 [[ADJ]], 1
+ // CHECK: store { i64, i64 } [[RES]], { i64, i64 }* @pa, align 8
pa = static_cast<void (A::*)()>(pc);
}
void f2() {
- // CHECK: store %0 { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 0 }
+ // CHECK: store { i64, i64 } { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 0 }
void (A::*pa2)() = &A::f;
- // CHECK: store %0 { i64 1, i64 0 }
- // CHECK-LP32: store %0 { i32 1, i32 0 }
+ // CHECK: store { i64, i64 } { i64 1, i64 0 }
+ // CHECK-LP32: store { i32, i32 } { i32 1, i32 0 }
void (A::*pa3)() = &A::vf1;
- // CHECK: store %0 { i64 9, i64 0 }
- // CHECK-LP32: store %0 { i32 5, i32 0 }
+ // CHECK: store { i64, i64 } { i64 9, i64 0 }
+ // CHECK-LP32: store { i32, i32 } { i32 5, i32 0 }
void (A::*pa4)() = &A::vf2;
}
diff --git a/test/CodeGenCXX/member-init-assignment.cpp b/test/CodeGenCXX/member-init-assignment.cpp
index 128cb88..84c4a36 100644
--- a/test/CodeGenCXX/member-init-assignment.cpp
+++ b/test/CodeGenCXX/member-init-assignment.cpp
@@ -10,8 +10,8 @@ struct Foo {
Foo::Foo(unsigned arg) : file_id(arg = 42)
{ }
-// CHECK: define void @_ZN3FooC2Ej(%struct.Foo* %this, i32 %arg) unnamed_addr
+// CHECK: define {{.*}} @_ZN3FooC2Ej(%struct.Foo* %this, i32 %arg) unnamed_addr
// CHECK: [[ARG:%.*]] = alloca i32
// CHECK: store i32 42, i32* [[ARG]]
// CHECK: store i32 42, i32* %{{.*}}
-// CHECK: ret void
+// CHECK: ret {{void|%struct.Foo}}
diff --git a/test/CodeGenCXX/member-init-ctor.cpp b/test/CodeGenCXX/member-init-ctor.cpp
index d9a6734..d70947b 100644
--- a/test/CodeGenCXX/member-init-ctor.cpp
+++ b/test/CodeGenCXX/member-init-ctor.cpp
@@ -7,7 +7,7 @@ struct S {
S s;
-// CHECK: define{{.*}} void @_ZN1SC2Ev(
+// CHECK: define {{.*}} @_ZN1SC2Ev(
// CHECK-NOT }
// CHECK: call {{.*}} @_Z1bv()
// CHECK-NOT }
diff --git a/test/CodeGenCXX/new-overflow.cpp b/test/CodeGenCXX/new-overflow.cpp
new file mode 100644
index 0000000..68f89c3
--- /dev/null
+++ b/test/CodeGenCXX/new-overflow.cpp
@@ -0,0 +1,209 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
+
+// rdar://problem/9246208
+
+// Basic test.
+namespace test0 {
+ struct A {
+ A();
+ int x;
+ };
+
+ typedef A elt;
+
+ // CHECK: define [[A:%.*]]* @_ZN5test04testEs(i16 signext
+ // CHECK: [[N:%.*]] = sext i16 {{%.*}} to i32
+ // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
+ // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
+ // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
+ // CHECK-NEXT: [[T3:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
+ // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T3]])
+ // CHECK: getelementptr inbounds {{.*}}, i32 [[N]]
+ elt *test(short s) {
+ return new elt[s];
+ }
+}
+
+// test0 with a nested array.
+namespace test1 {
+ struct A {
+ A();
+ int x;
+ };
+
+ typedef A elt[100];
+
+ // CHECK: define [100 x [[A:%.*]]]* @_ZN5test14testEs(i16 signext
+ // CHECK: [[N:%.*]] = sext i16 {{%.*}} to i32
+ // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 400)
+ // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
+ // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
+ // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
+ // CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
+ // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T4]])
+ // CHECK: getelementptr inbounds {{.*}}, i32 [[T3]]
+ elt *test(short s) {
+ return new elt[s];
+ }
+}
+
+// test1 with an array cookie.
+namespace test2 {
+ struct A {
+ A();
+ ~A();
+ int x;
+ };
+
+ typedef A elt[100];
+
+ // CHECK: define [100 x [[A:%.*]]]* @_ZN5test24testEs(i16 signext
+ // CHECK: [[N:%.*]] = sext i16 {{%.*}} to i32
+ // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 400)
+ // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
+ // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
+ // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
+ // CHECK-NEXT: [[T4:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T2]], i32 4)
+ // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T4]], 1
+ // CHECK-NEXT: [[T6:%.*]] = or i1 [[T1]], [[T5]]
+ // CHECK-NEXT: [[T7:%.*]] = extractvalue { i32, i1 } [[T4]], 0
+ // CHECK-NEXT: [[T8:%.*]] = select i1 [[T6]], i32 -1, i32 [[T7]]
+ // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T8]])
+ // CHECK: getelementptr inbounds {{.*}}, i32 [[T3]]
+ elt *test(short s) {
+ return new elt[s];
+ }
+}
+
+// test0 with a 1-byte element.
+namespace test4 {
+ struct A {
+ A();
+ };
+
+ typedef A elt;
+
+ // CHECK: define [[A:%.*]]* @_ZN5test44testEs(i16 signext
+ // CHECK: [[N:%.*]] = sext i16 {{%.*}} to i32
+ // CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[N]], 0
+ // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 -1, i32 [[N]]
+ // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T1]])
+ // CHECK: getelementptr inbounds {{.*}}, i32 [[N]]
+ elt *test(short s) {
+ return new elt[s];
+ }
+}
+
+// test4 with no sext required.
+namespace test5 {
+ struct A {
+ A();
+ };
+
+ typedef A elt;
+
+ // CHECK: define [[A:%.*]]* @_ZN5test54testEi(i32
+ // CHECK: [[N:%.*]] = load i32*
+ // CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[N]], 0
+ // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 -1, i32 [[N]]
+ // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T1]])
+ // CHECK: getelementptr inbounds {{.*}}, i32 [[N]]
+ elt *test(int s) {
+ return new elt[s];
+ }
+}
+
+// test0 with an unsigned size.
+namespace test6 {
+ struct A {
+ A();
+ int x;
+ };
+
+ typedef A elt;
+
+ // CHECK: define [[A:%.*]]* @_ZN5test64testEt(i16 zeroext
+ // CHECK: [[N:%.*]] = zext i16 {{%.*}} to i32
+ // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
+ // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
+ // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
+ // CHECK-NEXT: [[T3:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
+ // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T3]])
+ // CHECK: getelementptr inbounds {{.*}}, i32 [[N]]
+ elt *test(unsigned short s) {
+ return new elt[s];
+ }
+}
+
+// test1 with an unsigned size.
+namespace test7 {
+ struct A {
+ A();
+ int x;
+ };
+
+ typedef A elt[100];
+
+ // CHECK: define [100 x [[A:%.*]]]* @_ZN5test74testEt(i16 zeroext
+ // CHECK: [[N:%.*]] = zext i16 {{%.*}} to i32
+ // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 400)
+ // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
+ // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
+ // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
+ // CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
+ // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T4]])
+ // CHECK: getelementptr inbounds {{.*}}, i32 [[T3]]
+ elt *test(unsigned short s) {
+ return new elt[s];
+ }
+}
+
+// test0 with a signed type larger than size_t.
+namespace test8 {
+ struct A {
+ A();
+ int x;
+ };
+
+ typedef A elt;
+
+ // CHECK: define [[A:%.*]]* @_ZN5test84testEx(i64
+ // CHECK: [[N:%.*]] = load i64*
+ // CHECK-NEXT: [[T0:%.*]] = icmp uge i64 [[N]], 4294967296
+ // CHECK-NEXT: [[T1:%.*]] = trunc i64 [[N]] to i32
+ // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 4)
+ // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 1
+ // CHECK-NEXT: [[T4:%.*]] = or i1 [[T0]], [[T3]]
+ // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0
+ // CHECK-NEXT: [[T6:%.*]] = select i1 [[T4]], i32 -1, i32 [[T5]]
+ // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T6]])
+ // CHECK: getelementptr inbounds {{.*}}, i32 [[T1]]
+ elt *test(long long s) {
+ return new elt[s];
+ }
+}
+
+// test8 with an unsigned type.
+namespace test9 {
+ struct A {
+ A();
+ int x;
+ };
+
+ typedef A elt;
+
+ // CHECK: define [[A:%.*]]* @_ZN5test94testEy(i64
+ // CHECK: [[N:%.*]] = load i64*
+ // CHECK-NEXT: [[T0:%.*]] = icmp uge i64 [[N]], 4294967296
+ // CHECK-NEXT: [[T1:%.*]] = trunc i64 [[N]] to i32
+ // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 4)
+ // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 1
+ // CHECK-NEXT: [[T4:%.*]] = or i1 [[T0]], [[T3]]
+ // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0
+ // CHECK-NEXT: [[T6:%.*]] = select i1 [[T4]], i32 -1, i32 [[T5]]
+ // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T6]])
+ // CHECK: getelementptr inbounds {{.*}}, i32 [[T1]]
+ elt *test(unsigned long long s) {
+ return new elt[s];
+ }
+}
diff --git a/test/CodeGenCXX/new.cpp b/test/CodeGenCXX/new.cpp
index d14a5e2..3a72bb84 100644
--- a/test/CodeGenCXX/new.cpp
+++ b/test/CodeGenCXX/new.cpp
@@ -182,12 +182,17 @@ namespace test15 {
}
// CHECK: define void @_ZN6test155test1EPv(
- // CHECK: [[P:%.*]] = load i8*
+ // CHECK: [[P:%.*]] = load i8**
// CHECK-NEXT: icmp eq i8* [[P]], null
// CHECK-NEXT: br i1
- // CHECK: [[T0:%.*]] = bitcast i8* [[P]] to [[A:%.*]]*
- // CHECK: [[T1:%.*]] = getelementptr inbounds [[A]]* [[T0]],
- // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[T1]])
+ // CHECK: [[BEGIN:%.*]] = bitcast i8* [[P]] to [[A:%.*]]*
+ // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 5
+ // CHECK-NEXT: br label
+ // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
+ // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[CUR]])
+ // CHECK-NEXT: [[NEXT]] = getelementptr inbounds [[A]]* [[CUR]], i64 1
+ // CHECK-NEXT: [[DONE:%.*]] = icmp eq [[A]]* [[NEXT]], [[END]]
+ // CHECK-NEXT: br i1 [[DONE]]
void test1(void *p) {
new (p) A[5];
}
@@ -202,10 +207,27 @@ namespace test15 {
// CHECK-NEXT: [[P:%.*]] = load i8*
// CHECK-NEXT: icmp eq i8* [[P]], null
// CHECK-NEXT: br i1
- // CHECK: [[T0:%.*]] = bitcast i8* [[P]] to [[A:%.*]]*
- // CHECK: [[T1:%.*]] = getelementptr inbounds [[A]]* [[T0]],
- // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[T1]])
+ // CHECK: [[BEGIN:%.*]] = bitcast i8* [[P]] to [[A:%.*]]*
+ // CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq i64 [[T0]], 0
+ // CHECK-NEXT: br i1 [[ISEMPTY]],
+ // CHECK: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 [[T0]]
+ // CHECK-NEXT: br label
+ // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]],
+ // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[CUR]])
void test2(void *p, int n) {
new (p) A[n];
}
}
+
+namespace PR10197 {
+ // CHECK: define weak_odr void @_ZN7PR101971fIiEEvv()
+ template<typename T>
+ void f() {
+ // CHECK: [[CALL:%.*]] = call noalias i8* @_Znwm
+ // CHECK-NEXT: [[CASTED:%.*]] = bitcast i8* [[CALL]] to
+ new T;
+ // CHECK-NEXT: ret void
+ }
+
+ template void f<int>();
+}
diff --git a/test/CodeGenCXX/noinline-template.cpp b/test/CodeGenCXX/noinline-template.cpp
new file mode 100644
index 0000000..6ee3935
--- /dev/null
+++ b/test/CodeGenCXX/noinline-template.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+// This was a problem in Sema, but only shows up as noinline missing
+// in CodeGen.
+
+// CHECK: define linkonce_odr void @_ZN6VectorIiE13growStorageByEv(%struct.Vector* %this) nounwind noinline
+
+template <class Ty> struct Vector {
+ void growStorageBy();
+};
+template <class T> __attribute__((noinline)) void Vector<T>::growStorageBy() {
+}
+void foo() {
+ Vector<int> strs;
+ strs.growStorageBy();
+}
diff --git a/test/CodeGenCXX/nrvo.cpp b/test/CodeGenCXX/nrvo.cpp
index 82caff8..0efb355 100644
--- a/test/CodeGenCXX/nrvo.cpp
+++ b/test/CodeGenCXX/nrvo.cpp
@@ -13,10 +13,10 @@ public:
// CHECK-EH: define void @_Z5test0v
X test0() {
X x;
- // CHECK: call void @_ZN1XC1Ev
+ // CHECK: call {{.*}} @_ZN1XC1Ev
// CHECK-NEXT: ret void
- // CHECK-EH: call void @_ZN1XC1Ev
+ // CHECK-EH: call {{.*}} @_ZN1XC1Ev
// CHECK-EH-NEXT: ret void
return x;
}
@@ -24,13 +24,13 @@ X test0() {
// CHECK: define void @_Z5test1b(
// CHECK-EH: define void @_Z5test1b(
X test1(bool B) {
- // CHECK: tail call void @_ZN1XC1Ev
+ // CHECK: tail call {{.*}} @_ZN1XC1Ev
// CHECK-NEXT: ret void
X x;
if (B)
return (x);
return x;
- // CHECK-EH: tail call void @_ZN1XC1Ev
+ // CHECK-EH: tail call {{.*}} @_ZN1XC1Ev
// CHECK-EH-NEXT: ret void
}
@@ -45,18 +45,18 @@ X test2(bool B) {
return y;
return x;
- // CHECK: call void @_ZN1XC1Ev
- // CHECK-NEXT: call void @_ZN1XC1Ev
- // CHECK: call void @_ZN1XC1ERKS_
- // CHECK: call void @_ZN1XC1ERKS_
- // CHECK: call void @_ZN1XD1Ev
- // CHECK: call void @_ZN1XD1Ev
+ // CHECK: call {{.*}} @_ZN1XC1Ev
+ // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev
+ // CHECK: call {{.*}} @_ZN1XC1ERKS_
+ // CHECK: call {{.*}} @_ZN1XC1ERKS_
+ // CHECK: call {{.*}} @_ZN1XD1Ev
+ // CHECK: call {{.*}} @_ZN1XD1Ev
// CHECK: ret void
// The block ordering in the -fexceptions IR is unfortunate.
- // CHECK-EH: call void @_ZN1XC1Ev
- // CHECK-EH-NEXT: invoke void @_ZN1XC1Ev
+ // CHECK-EH: call {{.*}} @_ZN1XC1Ev
+ // CHECK-EH-NEXT: invoke {{.*}} @_ZN1XC1Ev
// -> %invoke.cont, %lpad
// %invoke.cont:
@@ -64,7 +64,7 @@ X test2(bool B) {
// -> %if.then, %if.end
// %if.then: returning 'x'
- // CHECK-EH: invoke void @_ZN1XC1ERKS_
+ // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
// -> %cleanup, %lpad1
// %lpad: landing pad for ctor of 'y', dtor of 'y'
@@ -74,23 +74,23 @@ X test2(bool B) {
// -> %eh.cleanup
// %lpad1: landing pad for return copy ctors, EH cleanup for 'y'
- // CHECK-EH: invoke void @_ZN1XD1Ev
+ // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev
// -> %eh.cleanup, %terminate.lpad
// %if.end: returning 'y'
- // CHECK-EH: invoke void @_ZN1XC1ERKS_
+ // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
// -> %cleanup, %lpad1
// %cleanup: normal cleanup for 'y'
- // CHECK-EH: invoke void @_ZN1XD1Ev
+ // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev
// -> %invoke.cont11, %lpad
// %invoke.cont11: normal cleanup for 'x'
- // CHECK-EH: call void @_ZN1XD1Ev
+ // CHECK-EH: call {{.*}} @_ZN1XD1Ev
// CHECK-EH-NEXT: ret void
// %eh.cleanup: EH cleanup for 'x'
- // CHECK-EH: invoke void @_ZN1XD1Ev
+ // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev
// -> %invoke.cont17, %terminate.lpad
// %invoke.cont17: rethrow block for %eh.cleanup.
@@ -121,13 +121,13 @@ extern "C" void exit(int) throw();
// CHECK: define void @_Z5test4b
X test4(bool B) {
{
- // CHECK: tail call void @_ZN1XC1Ev
+ // CHECK: tail call {{.*}} @_ZN1XC1Ev
X x;
// CHECK: br i1
if (B)
return x;
}
- // CHECK: tail call void @_ZN1XD1Ev
+ // CHECK: tail call {{.*}} @_ZN1XD1Ev
// CHECK: tail call void @exit(i32 1)
exit(1);
}
@@ -139,7 +139,7 @@ X test5() {
try {
may_throw();
} catch (X x) {
- // CHECK-EH: invoke void @_ZN1XC1ERKS_
+ // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
// CHECK-EH: call void @__cxa_end_catch()
// CHECK-EH: ret void
return x;
diff --git a/test/CodeGenCXX/partial-destruction.cpp b/test/CodeGenCXX/partial-destruction.cpp
new file mode 100644
index 0000000..82deca0
--- /dev/null
+++ b/test/CodeGenCXX/partial-destruction.cpp
@@ -0,0 +1,169 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s
+
+// Test IR generation for partial destruction of aggregates.
+
+void opaque();
+
+// Initializer lists.
+namespace test0 {
+ struct A { A(int); A(); ~A(); void *v; };
+ void test() {
+ A as[10] = { 5, 7 };
+ opaque();
+ }
+ // CHECK: define void @_ZN5test04testEv()
+ // CHECK: [[AS:%.*]] = alloca [10 x [[A:%.*]]], align
+ // CHECK-NEXT: [[ENDVAR:%.*]] = alloca [[A]]*
+ // CHECK-NEXT: [[EXN:%.*]] = alloca i8*
+ // CHECK-NEXT: [[SEL:%.*]] = alloca i32
+ // CHECK-NEXT: [[CLEANUP:%.*]] = alloca i32
+
+ // Initialize.
+ // CHECK-NEXT: [[E_BEGIN:%.*]] = getelementptr inbounds [10 x [[A]]]* [[AS]], i64 0, i64 0
+ // CHECK-NEXT: store [[A]]* [[E_BEGIN]], [[A]]** [[ENDVAR]]
+ // CHECK-NEXT: invoke void @_ZN5test01AC1Ei([[A]]* [[E_BEGIN]], i32 5)
+ // CHECK: [[E1:%.*]] = getelementptr inbounds [[A]]* [[E_BEGIN]], i64 1
+ // CHECK-NEXT: store [[A]]* [[E1]], [[A]]** [[ENDVAR]]
+ // CHECK-NEXT: invoke void @_ZN5test01AC1Ei([[A]]* [[E1]], i32 7)
+ // CHECK: [[E2:%.*]] = getelementptr inbounds [[A]]* [[E1]], i64 1
+ // CHECK-NEXT: store [[A]]* [[E2]], [[A]]** [[ENDVAR]]
+ // CHECK-NEXT: [[E_END:%.*]] = getelementptr inbounds [[A]]* [[E_BEGIN]], i64 10
+ // CHECK-NEXT: br label
+ // CHECK: [[E_CUR:%.*]] = phi [[A]]* [ [[E2]], {{%.*}} ], [ [[E_NEXT:%.*]], {{%.*}} ]
+ // CHECK-NEXT: invoke void @_ZN5test01AC1Ev([[A]]* [[E_CUR]])
+ // CHECK: [[E_NEXT]] = getelementptr inbounds [[A]]* [[E_CUR]], i64 1
+ // CHECK-NEXT: store [[A]]* [[E_NEXT]], [[A]]** [[ENDVAR]]
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[E_NEXT]], [[E_END]]
+ // CHECK-NEXT: br i1 [[T0]],
+
+ // Run.
+ // CHECK: invoke void @_Z6opaquev()
+
+ // Normal destroy.
+ // CHECK: [[ED_BEGIN:%.*]] = getelementptr inbounds [10 x [[A]]]* [[AS]], i32 0, i32 0
+ // CHECK-NEXT: [[ED_END:%.*]] = getelementptr inbounds [[A]]* [[ED_BEGIN]], i64 10
+ // CHECK-NEXT: br label
+ // CHECK: [[ED_AFTER:%.*]] = phi [[A]]* [ [[ED_END]], {{%.*}} ], [ [[ED_CUR:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[ED_CUR]] = getelementptr inbounds [[A]]* [[ED_AFTER]], i64 -1
+ // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[ED_CUR]])
+ // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[ED_CUR]], [[ED_BEGIN]]
+ // CHECK-NEXT: br i1 [[T0]],
+ // CHECK: ret void
+
+ // Partial destroy for initialization.
+ // CHECK: llvm.eh.selector({{.*}}, i32 0)
+ // CHECK: [[PARTIAL_END:%.*]] = load [[A]]** [[ENDVAR]]
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[E_BEGIN]], [[PARTIAL_END]]
+ // CHECK-NEXT: br i1 [[T0]],
+ // CHECK: [[E_AFTER:%.*]] = phi [[A]]* [ [[PARTIAL_END]], {{%.*}} ], [ [[E_CUR:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[E_CUR]] = getelementptr inbounds [[A]]* [[E_AFTER]], i64 -1
+ // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[E_CUR]])
+ // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[E_CUR]], [[E_BEGIN]]
+ // CHECK-NEXT: br i1 [[T0]],
+
+ // Primary EH destructor.
+ // CHECK: llvm.eh.selector({{.*}}, i32 0)
+ // CHECK: [[E0:%.*]] = getelementptr inbounds [10 x [[A]]]* [[AS]], i32 0, i32 0
+ // CHECK-NEXT: [[E_END:%.*]] = getelementptr inbounds [[A]]* [[E0]], i64 10
+ // CHECK-NEXT: br label
+
+ // Partial destructor for primary normal destructor.
+ // FIXME: There's some really bad block ordering here which causes
+ // the partial destroy for the primary normal destructor to fall
+ // within the primary EH destructor.
+ // CHECK: llvm.eh.selector({{.*}}, i32 0)
+ // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[ED_BEGIN]], [[ED_CUR]]
+ // CHECK-NEXT: br i1 [[T0]]
+ // CHECK: [[EDD_AFTER:%.*]] = phi [[A]]* [ [[ED_CUR]], {{%.*}} ], [ [[EDD_CUR:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[EDD_CUR]] = getelementptr inbounds [[A]]* [[EDD_AFTER]], i64 -1
+ // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[EDD_CUR]])
+ // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[EDD_CUR]], [[ED_BEGIN]]
+ // CHECK-NEXT: br i1 [[T0]]
+
+ // Back to the primary EH destructor.
+ // CHECK: [[E_AFTER:%.*]] = phi [[A]]* [ [[E_END]], {{%.*}} ], [ [[E_CUR:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[E_CUR]] = getelementptr inbounds [[A]]* [[E_AFTER]], i64 -1
+ // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[E_CUR]])
+ // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[E_CUR]], [[E0]]
+ // CHECK-NEXT: br i1 [[T0]],
+
+}
+
+namespace test1 {
+ struct A { A(); A(int); ~A(); };
+ struct B { A x, y, z; int w; };
+
+ void test() {
+ B v = { 5, 6, 7, 8 };
+ }
+ // CHECK: define void @_ZN5test14testEv()
+ // CHECK: [[V:%.*]] = alloca [[B:%.*]], align 4
+ // CHECK-NEXT: alloca i8*
+ // CHECK-NEXT: alloca i32
+ // CHECK-NEXT: alloca i32
+ // CHECK-NEXT: [[X:%.*]] = getelementptr inbounds [[B]]* [[V]], i32 0, i32 0
+ // CHECK-NEXT: call void @_ZN5test11AC1Ei([[A:%.*]]* [[X]], i32 5)
+ // CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds [[B]]* [[V]], i32 0, i32 1
+ // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[Y]], i32 6)
+ // CHECK: [[Z:%.*]] = getelementptr inbounds [[B]]* [[V]], i32 0, i32 2
+ // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[Z]], i32 7)
+ // CHECK: [[W:%.*]] = getelementptr inbounds [[B]]* [[V]], i32 0, i32 3
+ // CHECK-NEXT: store i32 8, i32* [[W]], align 4
+ // CHECK-NEXT: call void @_ZN5test11BD1Ev([[B]]* [[V]])
+ // CHECK-NEXT: ret void
+
+ // FIXME: again, the block ordering is pretty bad here
+ // CHECK: eh.selector({{.*}}, i32 0)
+ // CHECK: eh.selector({{.*}}, i32 0)
+ // CHECK: invoke void @_ZN5test11AD1Ev([[A]]* [[Y]])
+ // CHECK: invoke void @_ZN5test11AD1Ev([[A]]* [[X]])
+}
+
+namespace test2 {
+ struct A { A(); ~A(); };
+
+ void test() {
+ A v[4][7];
+
+ // CHECK: define void @_ZN5test24testEv()
+ // CHECK: [[V:%.*]] = alloca [4 x [7 x [[A:%.*]]]], align 1
+ // CHECK-NEXT: alloca i8*
+ // CHECK-NEXT: alloca i32
+ // CHECK-NEXT: alloca i32
+
+ // Main initialization loop.
+ // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [4 x [7 x [[A]]]]* [[V]], i32 0, i32 0, i32 0
+ // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 28
+ // CHECK-NEXT: br label
+ // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
+ // CHECK-NEXT: invoke void @_ZN5test21AC1Ev([[A]]* [[CUR]])
+ // CHECK: [[NEXT:%.*]] = getelementptr inbounds [[A]]* [[CUR]], i64 1
+ // CHECK-NEXT: [[DONE:%.*]] = icmp eq [[A]]* [[NEXT]], [[END]]
+ // CHECK-NEXT: br i1 [[DONE]],
+
+ // Partial destruction landing pad.
+ // CHECK: llvm.eh.exception()
+ // CHECK: [[EMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[CUR]]
+ // CHECK-NEXT: br i1 [[EMPTY]],
+ // CHECK: [[PAST:%.*]] = phi [[A]]* [ [[CUR]], {{%.*}} ], [ [[DEL:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[DEL]] = getelementptr inbounds [[A]]* [[PAST]], i64 -1
+ // CHECK-NEXT: invoke void @_ZN5test21AD1Ev([[A]]* [[DEL]])
+ // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[DEL]], [[BEGIN]]
+ // CHECK-NEXT: br i1 [[T0]],
+ }
+
+}
+
+// PR10351
+namespace test3 {
+ struct A { A(); ~A(); void *p; };
+ struct B {
+ B() {}
+ A a;
+ };
+
+ B *test() {
+ return new B[10];
+ // invoke void @_ZN5test31BD1Ev(
+ }
+}
diff --git a/test/CodeGenCXX/pointers-to-data-members.cpp b/test/CodeGenCXX/pointers-to-data-members.cpp
index 2a22d23..f0246c8 100644
--- a/test/CodeGenCXX/pointers-to-data-members.cpp
+++ b/test/CodeGenCXX/pointers-to-data-members.cpp
@@ -35,7 +35,7 @@ namespace ZeroInit {
} ssa[2];
void test_ssa() { (void) ssa; }
- // CHECK-GLOBAL: @_ZN8ZeroInit2ssE = internal global %1 { %struct.anon { i64 -1 } }
+ // CHECK-GLOBAL: @_ZN8ZeroInit2ssE = internal global %struct.anon.1 { %struct.anon.2 { i64 -1 } }
struct {
struct {
int A::*pa;
@@ -55,7 +55,7 @@ namespace ZeroInit {
};
struct C : A, B { int j; };
- // CHECK-GLOBAL: @_ZN8ZeroInit1cE = global {{%.*}} { %"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }, %"struct.ZeroInit::B" { [10 x %"struct.PR7139::ptr_to_member_struct"] [%"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }, %"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }, %"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }, %"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }, %"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }, %"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }, %"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }, %"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }, %"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }, %"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }], i8 0, i64 -1 }, i32 0 }, align 8
+ // CHECK-GLOBAL: @_ZN8ZeroInit1cE = global {{%.*}} { %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::B" { [10 x %"struct.ZeroInit::A"] [%"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }], i8 0, i64 -1 }, i32 0 }, align 8
C c;
}
@@ -227,6 +227,6 @@ namespace test4 {
struct C : virtual B { int *C_p; };
struct D : C { int *D_p; };
- // CHECK-GLOBAL: @_ZN5test41dE = global %"struct.test4::D" { %"struct.test4::C.base" zeroinitializer, i32* null, %"struct.VirtualBases::C.base" { i32 (...)** null, i64 -1 }, %"struct.test4::A" zeroinitializer }, align 8
+ // CHECK-GLOBAL: @_ZN5test41dE = global %"struct.test4::D" { %"struct.test4::C.base" zeroinitializer, i32* null, %"struct.test4::B.base" { i32 (...)** null, i64 -1 }, %"struct.test4::A" zeroinitializer }, align 8
D d;
}
diff --git a/test/CodeGenCXX/pr9965.cpp b/test/CodeGenCXX/pr9965.cpp
index b87fcf4..596dee9 100644
--- a/test/CodeGenCXX/pr9965.cpp
+++ b/test/CodeGenCXX/pr9965.cpp
@@ -7,6 +7,6 @@ struct X
X<int> x;
// CHECK: define internal void @__cxx_global_var_init()
-// CHECK: call void @_ZN1XIiEC1Ev
-// CHECK: define linkonce_odr void @_ZN1XIiEC1Ev
-// CHECK: define linkonce_odr void @_ZN1XIiEC2Ev
+// CHECK: call {{.*}} @_ZN1XIiEC1Ev
+// CHECK: define linkonce_odr {{.*}} @_ZN1XIiEC1Ev
+// CHECK: define linkonce_odr {{.*}} @_ZN1XIiEC2Ev
diff --git a/test/CodeGenCXX/references.cpp b/test/CodeGenCXX/references.cpp
index 25bc8d8..4bbc251 100644
--- a/test/CodeGenCXX/references.cpp
+++ b/test/CodeGenCXX/references.cpp
@@ -235,7 +235,7 @@ struct A {
};
// CHECK: define internal void @__cxx_global_var_init
-// CHECK: call void @_ZN2N31AC1Ei(%"class.N2::X"* @_ZGRN2N35sA123E, i32 123)
+// CHECK: call void @_ZN2N31AC1Ei(%"struct.N3::A"* @_ZGRN2N35sA123E, i32 123)
// CHECK: call i32 @__cxa_atexit
// CHECK: ret void
const A &sA123 = A(123);
@@ -250,7 +250,7 @@ struct A {
void f() {
// CHECK: define void @_ZN2N41fEv
- // CHECK: call void @_ZN2N41AC1Ev(%"class.N2::X"* @_ZGRZN2N41fEvE2ar)
+ // CHECK: call void @_ZN2N41AC1Ev(%"struct.N4::A"* @_ZGRZN2N41fEvE2ar)
// CHECK: call i32 @__cxa_atexit
// CHECK: ret void
static const A& ar = A();
@@ -269,3 +269,31 @@ void h() {
f(g().b);
}
}
+
+// PR9565
+namespace PR9565 {
+ struct a { int a : 10, b : 10; };
+ // CHECK: define void @_ZN6PR95651fEv()
+ void f() {
+ // CHECK: call void @llvm.memcpy
+ a x = { 0, 0 };
+ // CHECK: [[WITH_SEVENTEEN:%[a-zA-Z0-9]+]] = or i32 [[WITHOUT_SEVENTEEN:%[a-zA-Z0-9]+]], 17
+ // CHECK: store i32 [[WITH_SEVENTEEN]], i32* [[XA:%[a-zA-Z0-9]+]]
+ x.a = 17;
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: load
+ // CHECK-NEXT: and
+ // CHECK-NEXT: shl
+ // CHECK-NEXT: ashr
+ // CHECK-NEXT: store i32
+ // CHECK-NEXT: store i32*
+ const int &y = x.a;
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: load
+ // CHECK-NEXT: and
+ // CHECK-NEXT: or
+ // CHECK-NEXT: store i32
+ x.b = 19;
+ // CHECK-NEXT: ret void
+ }
+}
diff --git a/test/CodeGenCXX/static-init-3.cpp b/test/CodeGenCXX/static-init-3.cpp
index bd717ca..dc28d5a 100644
--- a/test/CodeGenCXX/static-init-3.cpp
+++ b/test/CodeGenCXX/static-init-3.cpp
@@ -16,8 +16,8 @@ struct X1
}
};
-// CHECK: @_ZN2X1I2X2I1BEE8instanceE = weak_odr global %struct.X0* null, align 8
-// CHECJ: @_ZN2X1I2X2I1AEE8instanceE = weak_odr global %struct.X0* null, align 8
+// CHECK: @_ZN2X1I2X2I1BEE8instanceE = weak_odr global %struct.X2* null, align 8
+// CHECJ: @_ZN2X1I2X2I1AEE8instanceE = weak_odr global %struct.X2* null, align 8
template<class T> T & X1<T>::instance = X1<T>::get();
class A { };
diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp
index 78749a7..d488e63 100644
--- a/test/CodeGenCXX/static-init.cpp
+++ b/test/CodeGenCXX/static-init.cpp
@@ -16,6 +16,9 @@ void f() {
// CHECK: call void @_ZN1AC1Ev
// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @_ZZ1fvE1a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
// CHECK: call void @__cxa_guard_release
+
+ // rdar://problem/9496726
+ // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 false, i1 false, i1 false)
static A a;
}
diff --git a/test/CodeGenCXX/stmtexpr.cpp b/test/CodeGenCXX/stmtexpr.cpp
index 0828d59..1f0e4ac 100644
--- a/test/CodeGenCXX/stmtexpr.cpp
+++ b/test/CodeGenCXX/stmtexpr.cpp
@@ -46,11 +46,11 @@ void foo3()
void foo4()
{
-// CHECK: call void @_ZN1AC1Ei
-// CHECK: call void @_ZN1AC1ERKS_
-// CHECK: call void @_ZN1AD1Ev
-// CHECK: call void @_ZN1BC1ERK1A
-// CHECK: call void @_ZN1AD1Ev
+// CHECK: call {{.*}} @_ZN1AC1Ei
+// CHECK: call {{.*}} @_ZN1AC1ERKS_
+// CHECK: call {{.*}} @_ZN1AD1Ev
+// CHECK: call {{.*}} @_ZN1BC1ERK1A
+// CHECK: call {{.*}} @_ZN1AD1Ev
const B &b = ({ A a(1); a; });
if (b.i != 1)
abort();
diff --git a/test/CodeGenCXX/template-anonymous-types.cpp b/test/CodeGenCXX/template-anonymous-types.cpp
index 68bdc0c..72fe090 100644
--- a/test/CodeGenCXX/template-anonymous-types.cpp
+++ b/test/CodeGenCXX/template-anonymous-types.cpp
@@ -32,6 +32,6 @@ void test() {
// CHECK: define internal void @"_ZN1XIN1S3$_1EEC2ES1_"(%struct.X* %this, i32 %t) unnamed_addr
//
// FOO's instantiation of X:
- // CHECK: define internal i32 @"_ZN1XIN1S3$_0EE1fEv"(%struct.X* %this)
- // CHECK: define internal void @"_ZN1XIN1S3$_0EEC2ES1_"(%struct.X* %this, i32 %t) unnamed_addr
+ // CHECK: define internal i32 @"_ZN1XIN1S3$_0EE1fEv"(%struct.X.0* %this)
+ // CHECK: define internal void @"_ZN1XIN1S3$_0EEC2ES1_"(%struct.X.0* %this, i32 %t) unnamed_addr
}
diff --git a/test/CodeGenCXX/temporaries.cpp b/test/CodeGenCXX/temporaries.cpp
index 348d51e..8aeca65 100644
--- a/test/CodeGenCXX/temporaries.cpp
+++ b/test/CodeGenCXX/temporaries.cpp
@@ -421,28 +421,24 @@ namespace Elision {
void test4() {
// CHECK: [[X:%.*]] = alloca [[A]], align 8
// CHECK-NEXT: [[XS:%.*]] = alloca [2 x [[A]]], align 16
- // CHECK-NEXT: [[I:%.*]] = alloca i64
// CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[X]])
A x;
- // CHECK-NEXT: [[XS0:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i32 0, i32 0
+ // CHECK-NEXT: [[XS0:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i64 0, i64 0
// CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[XS0]])
- // CHECK-NEXT: [[XS1:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i32 0, i32 1
+ // CHECK-NEXT: [[XS1:%.*]] = getelementptr inbounds [[A]]* [[XS0]], i64 1
// CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[XS1]], [[A]]* [[X]])
- // CHECK-NEXT: [[XSB:%.*]] = bitcast [2 x [[A]]]* [[XS]] to [[A]]*
A xs[] = { A(), x };
- // CHECK-NEXT: store i64 2, i64* [[I]]
- // CHECK-NEXT: br label
- // CHECK: [[I0:%.*]] = load i64* [[I]]
- // CHECK-NEXT: icmp ne i64 [[I0]], 0
- // CHECK-NEXT: br i1
- // CHECK: [[I1:%.*]] = load i64* [[I]]
- // CHECK-NEXT: [[I2:%.*]] = sub i64 [[I1]], 1
- // CHECK-NEXT: [[XSI:%.*]] = getelementptr inbounds [[A]]* [[XSB]], i64 [[I2]]
- // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[XSI]])
+ // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i32 0, i32 0
+ // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 2
// CHECK-NEXT: br label
+ // CHECK: [[AFTER:%.*]] = phi [[A]]*
+ // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]]* [[AFTER]], i64 -1
+ // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[CUR]])
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]]
+ // CHECK-NEXT: br i1 [[T0]],
// CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[X]])
}
diff --git a/test/CodeGenCXX/value-init.cpp b/test/CodeGenCXX/value-init.cpp
index a5a0b67..04a18b3 100644
--- a/test/CodeGenCXX/value-init.cpp
+++ b/test/CodeGenCXX/value-init.cpp
@@ -105,34 +105,24 @@ void f() {
// CHECK: call void @_ZN6PR98014TestC1Ei
// CHECK-NOT: call void @llvm.memset.p0i8.i64
// CHECK: call void @_ZN6PR98014TestC1Ev
- // CHECK-NOT: call void @llvm.memset.p0i8.i64
- // CHECK: call void @_ZN6PR98014TestC1Ev
Test partial[3] = { 1 };
// CHECK-NOT: call void @llvm.memset.p0i8.i64
// CHECK: call void @_ZN6PR98014TestC1Ev
- // CHECK-NOT: call void @llvm.memset.p0i8.i64
- // CHECK: call void @_ZN6PR98014TestC1Ev
- // CHECK-NOT: call void @llvm.memset.p0i8.i64
- // CHECK: call void @_ZN6PR98014TestC1Ev
+ // CHECK-NOT: call void @_ZN6PR98014TestC1Ev
Test empty[3] = {};
// CHECK: call void @llvm.memset.p0i8.i64
// CHECK-NOT: call void @llvm.memset.p0i8.i64
// CHECK: call void @_ZN6PR98015Test2C1Ev
- // CHECK-NOT: call void @llvm.memset.p0i8.i64
- // CHECK: call void @_ZN6PR98015Test2C1Ev
- // CHECK-NOT: call void @llvm.memset.p0i8.i64
- // CHECK: call void @_ZN6PR98015Test2C1Ev
+ // CHECK-NOT: call void @_ZN6PR98015Test2C1Ev
Test2 empty2[3] = {};
// CHECK: call void @llvm.memset.p0i8.i64
// CHECK-NOT: call void @llvm.memset.p0i8.i64
// CHECK: call void @_ZN6PR98015Test3C1Ev
// CHECK-NOT: call void @llvm.memset.p0i8.i64
- // CHECK: call void @_ZN6PR98015Test3C1Ev
- // CHECK-NOT: call void @llvm.memset.p0i8.i64
- // CHECK: call void @_ZN6PR98015Test3C1Ev
+ // CHECK-NOT: call void @_ZN6PR98015Test3C1Ev
Test3 empty3[3] = {};
}
@@ -189,10 +179,7 @@ namespace zeroinit {
X3<int>().f();
}
- // CHECK: define linkonce_odr void @_ZN8zeroinit2X3IiEC2Ev(%"struct.zeroinit::X3"* %this) unnamed_addr
- // CHECK: call void @llvm.memset.p0i8.i64
- // CHECK-NEXT: call void @_ZN8zeroinit2X2IiEC2Ev
- // CHECK-NEXT: ret void
+ // More checks at EOF
}
namespace PR8726 {
@@ -207,3 +194,51 @@ void f(const C& c) {
}
}
+
+// rdar://problem/9355931
+namespace test6 {
+ struct A { A(); A(int); };
+
+ void test() {
+ A arr[10][20] = { 5 };
+ };
+ // CHECK: define void @_ZN5test64testEv()
+ // CHECK: [[ARR:%.*]] = alloca [10 x [20 x [[A:%.*]]]],
+
+ // CHECK-NEXT: [[INNER:%.*]] = getelementptr inbounds [10 x [20 x [[A]]]]* [[ARR]], i64 0, i64 0
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [20 x [[A]]]* [[INNER]], i64 0, i64 0
+ // CHECK-NEXT: call void @_ZN5test61AC1Ei([[A]]* [[T0]], i32 5)
+ // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [[A]]* [[T0]], i64 1
+ // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[T0]], i64 20
+ // CHECK-NEXT: br label
+ // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
+ // CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* [[CUR]])
+ // CHECK-NEXT: [[NEXT]] = getelementptr inbounds [[A]]* [[CUR]], i64 1
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[NEXT]], [[END]]
+ // CHECK-NEXT: br i1
+
+ // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [20 x [[A]]]* [[INNER]], i64 1
+ // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [20 x [[A]]]* [[INNER]], i64 10
+ // CHECK-NEXT: br label
+ // CHECK: [[CUR:%.*]] = phi [20 x [[A]]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
+
+ // Inner loop.
+ // CHECK-NEXT: [[IBEGIN:%.*]] = getelementptr inbounds [20 x [[A]]]* [[CUR]], i32 0, i32 0
+ // CHECK-NEXT: [[IEND:%.*]] = getelementptr inbounds [[A]]* [[IBEGIN]], i64 20
+ // CHECK-NEXT: br label
+ // CHECK: [[ICUR:%.*]] = phi [[A]]* [ [[IBEGIN]], {{%.*}} ], [ [[INEXT:%.*]], {{%.*}} ]
+ // CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* [[ICUR]])
+ // CHECK-NEXT: [[INEXT:%.*]] = getelementptr inbounds [[A]]* [[ICUR]], i64 1
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[INEXT]], [[IEND]]
+ // CHECK-NEXT: br i1 [[T0]],
+
+ // CHECK: [[NEXT]] = getelementptr inbounds [20 x [[A]]]* [[CUR]], i64 1
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq [20 x [[A]]]* [[NEXT]], [[END]]
+ // CHECK-NEXT: br i1 [[T0]]
+ // CHECK: ret void
+}
+
+// CHECK: define linkonce_odr void @_ZN8zeroinit2X3IiEC2Ev(%"struct.zeroinit::X3"* %this) unnamed_addr
+// CHECK: call void @llvm.memset.p0i8.i64
+// CHECK-NEXT: call void @_ZN8zeroinit2X2IiEC2Ev
+// CHECK-NEXT: ret void
diff --git a/test/CodeGenCXX/variadic-templates.cpp b/test/CodeGenCXX/variadic-templates.cpp
index 4f3cf1f..90c8370 100644
--- a/test/CodeGenCXX/variadic-templates.cpp
+++ b/test/CodeGenCXX/variadic-templates.cpp
@@ -9,4 +9,15 @@ int get_num_types(Types...) {
// CHECK: ret i32 3
template int get_num_types(int, float, double);
+// PR10260 - argument packs that expand to nothing
+namespace test1 {
+ template <class... T> void foo() {
+ int values[sizeof...(T)+1] = { T::value... };
+ // CHECK: define linkonce_odr void @_ZN5test13fooIJEEEvv()
+ // CHECK: alloca [1 x i32], align 4
+ }
+ void test() {
+ foo<>();
+ }
+}
diff --git a/test/CodeGenCXX/virt-call-offsets.cpp b/test/CodeGenCXX/virt-call-offsets.cpp
index 3eb6b5d..5eef6fe 100644
--- a/test/CodeGenCXX/virt-call-offsets.cpp
+++ b/test/CodeGenCXX/virt-call-offsets.cpp
@@ -5,4 +5,4 @@ struct B : A {};
struct C : B { virtual void a(); };
void (C::*x)() = &C::a;
-// CHECK: @x = global %0 { i{{[0-9]+}} 1, i{{[0-9]+}} 0 }
+// CHECK: @x = global { i{{[0-9]+}}, i{{[0-9]+}} } { i{{[0-9]+}} 1, i{{[0-9]+}} 0 }
diff --git a/test/CodeGenCXX/virtual-base-destructor-call.cpp b/test/CodeGenCXX/virtual-base-destructor-call.cpp
index f028e4c..2424d21 100644
--- a/test/CodeGenCXX/virtual-base-destructor-call.cpp
+++ b/test/CodeGenCXX/virtual-base-destructor-call.cpp
@@ -18,34 +18,34 @@ int main() {
// basic_iostream's complete dtor calls its base dtor, then its
// virtual base's dtor.
-// CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED1Ev(%struct.basic_iostream* %this) unnamed_addr
-// CHECK: call void @_ZN14basic_iostreamIcED2Ev
-// CHECK: call void @_ZN9basic_iosD2Ev
+// CHECK: define linkonce_odr {{.*}} @_ZN14basic_iostreamIcED1Ev(%struct.basic_iostream* %this) unnamed_addr
+// CHECK: call {{.*}} @_ZN14basic_iostreamIcED2Ev
+// CHECK: call {{.*}} @_ZN9basic_iosD2Ev
// basic_iostream's base dtor calls its non-virtual base dtor.
-// CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED2Ev(%struct.basic_iostream* %this, i8** %vtt) unnamed_addr
-// CHECK: call void @_ZN13basic_istreamIcED2Ev
+// CHECK: define linkonce_odr {{.*}} @_ZN14basic_iostreamIcED2Ev(%struct.basic_iostream* %this, i8** %vtt) unnamed_addr
+// CHECK: call {{.*}} @_ZN13basic_istreamIcED2Ev
// CHECK: }
// basic_iostream's deleting dtor calls its complete dtor, then
// operator delete().
-// CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED0Ev(%struct.basic_iostream* %this) unnamed_addr
-// CHECK: call void @_ZN14basic_iostreamIcED1Ev
-// CHECK: call void @_ZdlPv
+// CHECK: define linkonce_odr {{.*}} @_ZN14basic_iostreamIcED0Ev(%struct.basic_iostream* %this) unnamed_addr
+// CHECK: call {{.*}} @_ZN14basic_iostreamIcED1Ev
+// CHECK: call {{.*}} @_ZdlPv
// basic_istream's complete dtor calls the base dtor,
// then its virtual base's base dtor.
-// CHECK: define linkonce_odr void @_ZN13basic_istreamIcED1Ev(%struct.basic_istream* %this) unnamed_addr
-// CHECK: call void @_ZN13basic_istreamIcED2Ev
-// CHECK: call void @_ZN9basic_iosD2Ev
+// CHECK: define linkonce_odr {{.*}} @_ZN13basic_istreamIcED1Ev(%struct.basic_istream* %this) unnamed_addr
+// CHECK: call {{.*}} @_ZN13basic_istreamIcED2Ev
+// CHECK: call {{.*}} @_ZN9basic_iosD2Ev
// basic_istream's deleting dtor calls the complete dtor, then
// operator delete().
-// CHECK: define linkonce_odr void @_ZN13basic_istreamIcED0Ev(%struct.basic_istream* %this) unnamed_addr
-// CHECK: call void @_ZN13basic_istreamIcED1Ev
-// CHECK: call void @_ZdlPv
+// CHECK: define linkonce_odr {{.*}} @_ZN13basic_istreamIcED0Ev(%struct.basic_istream* %this) unnamed_addr
+// CHECK: call {{.*}} @_ZN13basic_istreamIcED1Ev
+// CHECK: call {{.*}} @_ZdlPv
// basic_istream's base dtor is a no-op.
-// CHECK: define linkonce_odr void @_ZN13basic_istreamIcED2Ev(%struct.basic_istream* %this, i8** %vtt) unnamed_addr
+// CHECK: define linkonce_odr {{.*}} @_ZN13basic_istreamIcED2Ev(%struct.basic_istream* %this, i8** %vtt) unnamed_addr
// CHECK-NOT: call
// CHECK: }
diff --git a/test/CodeGenCXX/virtual-bases.cpp b/test/CodeGenCXX/virtual-bases.cpp
index cfb4c83..c9f13f8 100644
--- a/test/CodeGenCXX/virtual-bases.cpp
+++ b/test/CodeGenCXX/virtual-bases.cpp
@@ -20,8 +20,8 @@ struct C : virtual A {
C(bool);
};
-// CHECK: define void @_ZN1CC1Eb(%struct.B* %this, i1 zeroext) unnamed_addr
-// CHECK: define void @_ZN1CC2Eb(%struct.B* %this, i8** %vtt, i1 zeroext) unnamed_addr
+// CHECK: define void @_ZN1CC1Eb(%struct.C* %this, i1 zeroext) unnamed_addr
+// CHECK: define void @_ZN1CC2Eb(%struct.C* %this, i8** %vtt, i1 zeroext) unnamed_addr
C::C(bool) { }
// PR6251
diff --git a/test/CodeGenCXX/virtual-functions-incomplete-types.cpp b/test/CodeGenCXX/virtual-functions-incomplete-types.cpp
index 052a019..afa658f 100644
--- a/test/CodeGenCXX/virtual-functions-incomplete-types.cpp
+++ b/test/CodeGenCXX/virtual-functions-incomplete-types.cpp
@@ -9,7 +9,7 @@ struct B {
void B::f() { }
-// CHECK: define i32 @_ZN1D1gEv(%struct.B* %this)
+// CHECK: define i32 @_ZN1D1gEv(%struct.D* %this)
// CHECK: declare void @_ZN1B1gEv()
struct C;
diff --git a/test/CodeGenCXX/virtual-pseudo-destructor-call.cpp b/test/CodeGenCXX/virtual-pseudo-destructor-call.cpp
index 285e3da..0d3574e 100644
--- a/test/CodeGenCXX/virtual-pseudo-destructor-call.cpp
+++ b/test/CodeGenCXX/virtual-pseudo-destructor-call.cpp
@@ -5,6 +5,10 @@ struct A {
};
void f(A *a) {
- // CHECK: call void %
+ // CHECK: define {{.*}} @_Z1fP1A
+ // CHECK: load
+ // CHECK: load
+ // CHECK: [[CALLEE:%[a-zA-Z0-9.]*]] = load
+ // CHECK: call {{.*}} [[CALLEE]](
a->~A();
}
diff --git a/test/CodeGenCXX/visibility-inlines-hidden.cpp b/test/CodeGenCXX/visibility-inlines-hidden.cpp
index 760879a..f7fabed 100644
--- a/test/CodeGenCXX/visibility-inlines-hidden.cpp
+++ b/test/CodeGenCXX/visibility-inlines-hidden.cpp
@@ -77,7 +77,7 @@ namespace test1 {
a.foo();
}
// CHECK: declare void @_ZN5test11A3fooEv
-// CHECK: declare void @_ZN5test11AD1Ev
+// CHECK: declare {{.*}} @_ZN5test11AD1Ev
}
// PR8713
diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp
index 7644e47..fdccd46 100644
--- a/test/CodeGenCXX/visibility.cpp
+++ b/test/CodeGenCXX/visibility.cpp
@@ -422,3 +422,35 @@ namespace test21 {
// CHECK: define weak_odr void @_ZN6test211AILNS_2EnE0EE3fooEv(
template void A<en>::foo();
}
+
+// rdar://problem/9616154
+// Visibility on explicit specializations should take precedence.
+namespace test22 {
+ class A1 {};
+ class A2 {};
+
+ template <class T> struct B {};
+ template <> struct DEFAULT B<A1> {
+ static void foo();
+ static void bar() {}
+ };
+ template <> struct B<A2> {
+ static void foo();
+ static void bar() {}
+ };
+
+ void test() {
+ B<A1>::foo();
+ B<A1>::bar();
+ B<A2>::foo();
+ B<A2>::bar();
+ }
+ // CHECK: declare void @_ZN6test221BINS_2A1EE3fooEv()
+ // CHECK: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv()
+ // CHECK: declare void @_ZN6test221BINS_2A2EE3fooEv()
+ // CHECK: define linkonce_odr void @_ZN6test221BINS_2A2EE3barEv()
+ // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A1EE3fooEv()
+ // CHECK-HIDDEN: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv()
+ // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A2EE3fooEv()
+ // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test221BINS_2A2EE3barEv()
+}
diff --git a/test/CodeGenCXX/vla.cpp b/test/CodeGenCXX/vla.cpp
new file mode 100644
index 0000000..58cdf79
--- /dev/null
+++ b/test/CodeGenCXX/vla.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck %s
+
+// rdar://problem/9506377
+void test0(void *array, int n) {
+ // CHECK: define void @_Z5test0Pvi(
+ // CHECK: [[ARRAY:%.*]] = alloca i8*, align 8
+ // CHECK-NEXT: [[N:%.*]] = alloca i32, align 4
+ // CHECK-NEXT: [[REF:%.*]] = alloca i16*, align 8
+ // CHECK-NEXT: [[S:%.*]] = alloca i16, align 2
+ // CHECK-NEXT: store i8*
+ // CHECK-NEXT: store i32
+
+ // Capture the bounds.
+ // CHECK-NEXT: [[T0:%.*]] = load i32* [[N]], align 4
+ // CHECK-NEXT: [[DIM0:%.*]] = zext i32 [[T0]] to i64
+ // CHECK-NEXT: [[T0:%.*]] = load i32* [[N]], align 4
+ // CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], 1
+ // CHECK-NEXT: [[DIM1:%.*]] = zext i32 [[T1]] to i64
+ typedef short array_t[n][n+1];
+
+ // CHECK-NEXT: [[T0:%.*]] = load i8** [[ARRAY]], align 8
+ // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to i16*
+ // CHECK-NEXT: store i16* [[T1]], i16** [[REF]], align 8
+ array_t &ref = *(array_t*) array;
+
+ // CHECK-NEXT: [[T0:%.*]] = load i16** [[REF]]
+ // CHECK-NEXT: [[T1:%.*]] = mul nsw i64 1, [[DIM1]]
+ // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i16* [[T0]], i64 [[T1]]
+ // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i16* [[T2]], i64 2
+ // CHECK-NEXT: store i16 3, i16* [[T3]]
+ ref[1][2] = 3;
+
+ // CHECK-NEXT: [[T0:%.*]] = load i16** [[REF]]
+ // CHECK-NEXT: [[T1:%.*]] = mul nsw i64 4, [[DIM1]]
+ // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i16* [[T0]], i64 [[T1]]
+ // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i16* [[T2]], i64 5
+ // CHECK-NEXT: [[T4:%.*]] = load i16* [[T3]]
+ // CHECK-NEXT: store i16 [[T4]], i16* [[S]], align 2
+ short s = ref[4][5];
+
+ // CHECK-NEXT: ret void
+}
+
diff --git a/test/CodeGenCXX/volatile-1.cpp b/test/CodeGenCXX/volatile-1.cpp
index 3ae17bd..1a69648 100644
--- a/test/CodeGenCXX/volatile-1.cpp
+++ b/test/CodeGenCXX/volatile-1.cpp
@@ -4,7 +4,7 @@
volatile int i, j, k;
volatile int ar[5];
volatile char c;
-// CHECK: @ci = global [[CINT:%.*]] zeroinitializer
+// CHECK: @ci = global [[CINT:.*]] zeroinitializer
volatile _Complex int ci;
volatile struct S {
#ifdef __cplusplus
diff --git a/test/CodeGenCXX/vtable-pointer-initialization.cpp b/test/CodeGenCXX/vtable-pointer-initialization.cpp
index f629c2d..9b1eaa5 100644
--- a/test/CodeGenCXX/vtable-pointer-initialization.cpp
+++ b/test/CodeGenCXX/vtable-pointer-initialization.cpp
@@ -41,16 +41,16 @@ struct B : Base {
void f() { B b; }
-// CHECK: define linkonce_odr void @_ZN1BC1Ev(%struct.A* %this) unnamed_addr
+// CHECK: define linkonce_odr void @_ZN1BC1Ev(%struct.B* %this) unnamed_addr
// CHECK: call void @_ZN1BC2Ev(
-// CHECK: define linkonce_odr void @_ZN1BD1Ev(%struct.A* %this) unnamed_addr
+// CHECK: define linkonce_odr void @_ZN1BD1Ev(%struct.B* %this) unnamed_addr
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2)
// CHECK: call void @_ZN5FieldD1Ev(
// CHECK: call void @_ZN4BaseD2Ev(
// CHECK: ret void
-// CHECK: define linkonce_odr void @_ZN1BC2Ev(%struct.A* %this) unnamed_addr
+// CHECK: define linkonce_odr void @_ZN1BC2Ev(%struct.B* %this) unnamed_addr
// CHECK: call void @_ZN4BaseC2Ev(
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2)
// CHECK: call void @_ZN5FieldC1Ev
diff --git a/test/CodeGenCXX/x86_32-arguments.cpp b/test/CodeGenCXX/x86_32-arguments.cpp
index 4c06033..4d43393 100644
--- a/test/CodeGenCXX/x86_32-arguments.cpp
+++ b/test/CodeGenCXX/x86_32-arguments.cpp
@@ -89,7 +89,7 @@ struct s5 { s5(); int &x; };
s5 f5() { return s5(); }
// CHECK: define i32 @_Z4f6_0M2s6i(i32 %a)
-// CHECK: define i64 @_Z4f6_1M2s6FivE(%{{.*}} byval align 4)
+// CHECK: define i64 @_Z4f6_1M2s6FivE({ i32, i32 }* byval align 4)
// FIXME: It would be nice to avoid byval on the previous case.
struct s6 {};
typedef int s6::* s6_mdp;
diff --git a/test/CodeGenCXX/x86_64-arguments.cpp b/test/CodeGenCXX/x86_64-arguments.cpp
index 01f1a44..e1d9dfc 100644
--- a/test/CodeGenCXX/x86_64-arguments.cpp
+++ b/test/CodeGenCXX/x86_64-arguments.cpp
@@ -115,3 +115,37 @@ namespace test6 {
}
// CHECK: define i32 @_ZN5test64testENS_5outerE(i64 %x.coerce0, i32 %x.coerce1)
}
+
+namespace test7 {
+ struct StringRef {char* ptr; long len; };
+ class A { public: ~A(); };
+ A x(A, A, long, long, StringRef) { return A(); }
+ // Check that the StringRef is passed byval instead of expanded
+ // (which would split it between registers and memory).
+ // rdar://problem/9686430
+ // CHECK: define void @_ZN5test71xENS_1AES0_llNS_9StringRefE({{.*}} byval align 8)
+
+ // And a couple extra related tests:
+ A y(A, long double, long, long, StringRef) { return A(); }
+ // CHECK: define void @_ZN5test71yENS_1AEellNS_9StringRefE({{.*}} i8*
+ struct StringDouble {char * ptr; double d;};
+ A z(A, A, A, A, A, StringDouble) { return A(); }
+ A zz(A, A, A, A, StringDouble) { return A(); }
+ // CHECK: define void @_ZN5test71zENS_1AES0_S0_S0_S0_NS_12StringDoubleE({{.*}} byval align 8)
+ // CHECK: define void @_ZN5test72zzENS_1AES0_S0_S0_NS_12StringDoubleE({{.*}} i8*
+}
+
+namespace test8 {
+ // CHECK: declare void @_ZN5test83fooENS_1BE(%"class.test8::B"* byval align 8)
+ class A {
+ char big[17];
+ };
+
+ class B : public A {};
+
+ void foo(B b);
+ void bar() {
+ B b;
+ foo(b);
+ }
+}
OpenPOWER on IntegriCloud