diff options
Diffstat (limited to 'test/CodeGenCXX')
96 files changed, 1218 insertions, 132 deletions
diff --git a/test/CodeGenCXX/2005-01-03-StaticInitializers.cpp b/test/CodeGenCXX/2005-01-03-StaticInitializers.cpp index 875c412c6b488..1c9d1202afb22 100644 --- a/test/CodeGenCXX/2005-01-03-StaticInitializers.cpp +++ b/test/CodeGenCXX/2005-01-03-StaticInitializers.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s +// REQUIRES: LP64 struct S { int A[2]; diff --git a/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp b/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp index 8361680546f3d..7acc07d0c5b85 100644 --- a/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp +++ b/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fexceptions -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-unknown -fexceptions -emit-llvm %s -o - | FileCheck %s int c(void) __attribute__((const)); int p(void) __attribute__((pure)); int t(void); diff --git a/test/CodeGenCXX/assign-construct-memcpy.cpp b/test/CodeGenCXX/assign-construct-memcpy.cpp new file mode 100644 index 0000000000000..3d42051324093 --- /dev/null +++ b/test/CodeGenCXX/assign-construct-memcpy.cpp @@ -0,0 +1,89 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin12 -emit-llvm -o - -std=c++11 %s -DPOD | FileCheck %s -check-prefix=CHECK-POD +// RUN: %clang_cc1 -triple x86_64-apple-darwin12 -emit-llvm -o - -std=c++11 %s | FileCheck %s -check-prefix=CHECK-NONPOD + +// Declare the reserved placement operators. +typedef __typeof__(sizeof(0)) size_t; +void *operator new(size_t, void*) throw(); +void operator delete(void*, void*) throw(); +void *operator new[](size_t, void*) throw(); +void operator delete[](void*, void*) throw(); +template<typename T> T &&move(T&); + +struct foo { +#ifndef POD + foo() {} // non-POD +#endif + void *a, *b; + bool c; +}; + +// It is not legal to copy the tail padding in all cases, but if it is it can +// yield better codegen. + +foo *test1(void *f, const foo &x) { + return new (f) foo(x); +// CHECK-POD: test1 +// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8 + +// CHECK-NONPOD: test1 +// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8 +} + +foo *test2(const foo &x) { + return new foo(x); +// CHECK-POD: test2 +// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8 + +// CHECK-NONPOD: test2 +// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8 +} + +foo test3(const foo &x) { + foo f = x; + return f; +// CHECK-POD: test3 +// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8 + +// CHECK-NONPOD: test3 +// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8 +} + +foo *test4(foo &&x) { + return new foo(x); +// CHECK-POD: test4 +// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8 + +// CHECK-NONPOD: test4 +// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8 +} + +void test5(foo &f, const foo &x) { + f = x; +// CHECK-POD: test5 +// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8 + +// CHECK-NONPOD: test5 +// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 17, i32 8 +} + +extern foo globtest; + +void test6(foo &&x) { + globtest = move(x); +// CHECK-POD: test6 +// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8 + +// CHECK-NONPOD: test6 +// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 17, i32 8 +} + +void byval(foo f); + +void test7(const foo &x) { + byval(x); +// CHECK-POD: test7 +// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8 + +// CHECK-NONPOD: test7 +// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8 +} diff --git a/test/CodeGenCXX/attr.cpp b/test/CodeGenCXX/attr.cpp index 9e8740e54700b..a0dd748601340 100644 --- a/test/CodeGenCXX/attr.cpp +++ b/test/CodeGenCXX/attr.cpp @@ -10,17 +10,21 @@ class C { virtual void bar1() __attribute__((aligned(1))); virtual void bar2() __attribute__((aligned(2))); virtual void bar3() __attribute__((aligned(1024))); + void bar4() __attribute__((aligned(1024))); } c; -// CHECK: define void @_ZN1C4bar1Ev(%class.C* %this) nounwind align 2 +// CHECK: define void @_ZN1C4bar1Ev(%class.C* %this) unnamed_addr nounwind align 2 void C::bar1() { } -// CHECK: define void @_ZN1C4bar2Ev(%class.C* %this) nounwind align 2 +// CHECK: define void @_ZN1C4bar2Ev(%class.C* %this) unnamed_addr nounwind align 2 void C::bar2() { } -// CHECK: define void @_ZN1C4bar3Ev(%class.C* %this) nounwind align 1024 +// CHECK: define void @_ZN1C4bar3Ev(%class.C* %this) unnamed_addr nounwind align 1024 void C::bar3() { } +// CHECK: define void @_ZN1C4bar4Ev(%class.C* %this) nounwind align 1024 +void C::bar4() { } + // PR6635 // CHECK: define i32 @_Z5test1v() int test1() { return 10; } diff --git a/test/CodeGenCXX/builtins.cpp b/test/CodeGenCXX/builtins.cpp index 4542563717a11..0629c31015c76 100644 --- a/test/CodeGenCXX/builtins.cpp +++ b/test/CodeGenCXX/builtins.cpp @@ -7,15 +7,3 @@ int main() { // CHECK: call signext i8 @memmove() return memmove(); } - -// <rdar://problem/10063539> - -template<int (*Compare)(const char *s1, const char *s2)> -int equal(const char *s1, const char *s2) { - return Compare(s1, s2) == 0; -} - -// CHECK: define weak_odr i32 @_Z5equalIXadL_Z16__builtin_strcmpPKcS1_EEEiS1_S1_ -// CHECK: call i32 @strcmp -template int equal<&__builtin_strcmp>(const char*, const char*); - diff --git a/test/CodeGenCXX/catch-undef-behavior.cpp b/test/CodeGenCXX/catch-undef-behavior.cpp new file mode 100644 index 0000000000000..fd9e3d7278a7c --- /dev/null +++ b/test/CodeGenCXX/catch-undef-behavior.cpp @@ -0,0 +1,134 @@ +// RUN: %clang_cc1 -fsanitize=signed-integer-overflow,divide-by-zero,shift,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s + +// CHECK: @_Z17reference_binding +void reference_binding(int *p) { + // C++ core issue 453: If an lvalue to which a reference is directly bound + // designates neither an existing object or function of an appropriate type, + // nor a region of storage of suitable size and alignment to contain an object + // of the reference's type, the behavior is undefined. + + // CHECK: icmp ne {{.*}}, null + + // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64 + // CHECK-NEXT: icmp uge i64 %[[SIZE]], 4 + + // CHECK: %[[PTRINT:.*]] = ptrtoint + // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 3 + // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0 + int &r = *p; +} + +struct S { + double d; + int a, b; + virtual int f(); +}; + +// CHECK: @_Z13member_access +void member_access(S *p) { + // (1a) Check 'p' is appropriately sized and aligned for member access. + + // CHECK: icmp ne {{.*}}, null + + // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64 + // CHECK-NEXT: icmp uge i64 %[[SIZE]], 24 + + // CHECK: %[[PTRINT:.*]] = ptrtoint + // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 7 + // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0 + + // (1b) Check that 'p' actually points to an 'S'. + + // CHECK: %[[VPTRADDR:.*]] = bitcast {{.*}} to i64* + // CHECK-NEXT: %[[VPTR:.*]] = load i64* %[[VPTRADDR]] + // + // hash_16_bytes: + // + // If this number changes, it indicates that either the mangled name of ::S + // has changed, or that LLVM's hashing function has changed. The latter case + // is OK if the hashing function is still stable. + // + // The two hash values are for 64- and 32-bit Clang binaries, respectively. + // FIXME: We should produce a 64-bit value either way. + // + // CHECK-NEXT: xor i64 {{-4030275160588942838|2562089159}}, %[[VPTR]] + // CHECK-NEXT: mul i64 {{.*}}, -7070675565921424023 + // CHECK-NEXT: lshr i64 {{.*}}, 47 + // CHECK-NEXT: xor i64 + // CHECK-NEXT: xor i64 %[[VPTR]] + // CHECK-NEXT: mul i64 {{.*}}, -7070675565921424023 + // CHECK-NEXT: lshr i64 {{.*}}, 47 + // CHECK-NEXT: xor i64 + // CHECK-NEXT: %[[HASH:.*]] = mul i64 {{.*}}, -7070675565921424023 + // + // Check the hash against the table: + // + // CHECK-NEXT: %[[IDX:.*]] = and i64 %{{.*}}, 127 + // CHECK-NEXT: getelementptr inbounds [128 x i64]* @__ubsan_vptr_type_cache, i32 0, i64 %[[IDX]] + // CHECK-NEXT: %[[CACHEVAL:.*]] = load i64* + // CHECK-NEXT: icmp eq i64 %[[CACHEVAL]], %[[HASH]] + // CHECK-NEXT: br i1 + + // CHECK: call void @__ubsan_handle_dynamic_type_cache_miss({{.*}}, i64 %{{.*}}, i64 %[[HASH]]) + + // (2) Check 'p->b' is appropriately sized and aligned for a load. + + // FIXME: Suppress this in the trivial case of a member access, because we + // know we've just checked the member access expression itself. + + // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64 + // CHECK-NEXT: icmp uge i64 %[[SIZE]], 4 + + // CHECK: %[[PTRINT:.*]] = ptrtoint + // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 3 + // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0 + int k = p->b; + + // (3a) Check 'p' is appropriately sized and aligned for member function call. + + // CHECK: icmp ne {{.*}}, null + + // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64 + // CHECK-NEXT: icmp uge i64 %[[SIZE]], 24 + + // CHECK: %[[PTRINT:.*]] = ptrtoint + // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 7 + // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0 + + // (3b) Check that 'p' actually points to an 'S' + + // CHECK: load i64* + // CHECK-NEXT: xor i64 {{-4030275160588942838|2562089159}}, + // [...] + // CHECK: getelementptr inbounds [128 x i64]* @__ubsan_vptr_type_cache, i32 0, i64 % + // CHECK: br i1 + // CHECK: call void @__ubsan_handle_dynamic_type_cache_miss({{.*}}, i64 %{{.*}}, i64 %{{.*}}) + + k = p->f(); +} + +// CHECK: @_Z12lsh_overflow +int lsh_overflow(int a, int b) { + // CHECK: %[[INBOUNDS:.*]] = icmp ule i32 %[[RHS:.*]], 31 + // CHECK-NEXT: br i1 %[[INBOUNDS]] + + // CHECK: %[[SHIFTED_OUT_WIDTH:.*]] = sub nuw nsw i32 31, %[[RHS]] + // CHECK-NEXT: %[[SHIFTED_OUT:.*]] = lshr i32 %[[LHS:.*]], %[[SHIFTED_OUT_WIDTH]] + + // This is present for C++11 but not for C: C++ core issue 1457 allows a '1' + // to be shifted into the sign bit, but not out of it. + // CHECK-NEXT: %[[SHIFTED_OUT_NOT_SIGN:.*]] = lshr i32 %[[SHIFTED_OUT]], 1 + + // CHECK-NEXT: %[[NO_OVERFLOW:.*]] = icmp eq i32 %[[SHIFTED_OUT_NOT_SIGN]], 0 + // CHECK-NEXT: br i1 %[[NO_OVERFLOW]] + + // CHECK: %[[RET:.*]] = shl i32 %[[LHS]], %[[RHS]] + // CHECK-NEXT: ret i32 %[[RET]] + return a << b; +} + +// CHECK: @_Z9no_return +int no_return() { + // CHECK: call void @__ubsan_handle_missing_return(i8* bitcast ({{.*}}* @{{.*}} to i8*)) noreturn nounwind + // CHECK-NEXT: unreachable +} diff --git a/test/CodeGenCXX/compound-literals.cpp b/test/CodeGenCXX/compound-literals.cpp index 17a31149e13e7..5df0ea5876679 100644 --- a/test/CodeGenCXX/compound-literals.cpp +++ b/test/CodeGenCXX/compound-literals.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple armv7-none-eabi -emit-llvm -o - %s | FileCheck %s struct X { X(); @@ -18,10 +18,10 @@ int f() { // 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: call %struct.X* @_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: call %struct.Y* @_ZN1YD1Ev // CHECK-NEXT: ret i32 [[RESULT]] return ((Y){17, "seventeen"}).i; } diff --git a/test/CodeGenCXX/const-global-linkage.cpp b/test/CodeGenCXX/const-global-linkage.cpp index d0a055b494959..df78fdd0287cc 100644 --- a/test/CodeGenCXX/const-global-linkage.cpp +++ b/test/CodeGenCXX/const-global-linkage.cpp @@ -2,12 +2,16 @@ const int x = 10; const int y = 20; +const volatile int z = 30; // CHECK-NOT: @x +// CHECK: @z = constant i32 30 // CHECK: @_ZL1y = internal constant i32 20 const int& b() { return y; } const char z1[] = "asdf"; const char z2[] = "zxcv"; +const volatile char z3[] = "zxcv"; // CHECK-NOT: @z1 +// CHECK: @z3 = constant // CHECK: @_ZL2z2 = internal constant const char* b2() { return z2; } diff --git a/test/CodeGenCXX/const-init-cxx11.cpp b/test/CodeGenCXX/const-init-cxx11.cpp index db1bb412606b1..833adba8bae7f 100644 --- a/test/CodeGenCXX/const-init-cxx11.cpp +++ b/test/CodeGenCXX/const-init-cxx11.cpp @@ -432,11 +432,7 @@ namespace InitFromConst { // CHECK: call void @_ZN13InitFromConst7consumeIRKNS_1SEEEvT_(%"struct.InitFromConst::S"* @_ZN13InitFromConstL1sE) consume<const S&>(s); - // FIXME CHECK-NOT: call void @_ZN13InitFromConst7consumeIRKNS_1SEEEvT_(%"struct.InitFromConst::S"* @_ZN13InitFromConstL1sE) - // There's no lvalue-to-rvalue conversion here, so 'r' is odr-used, and - // we're permitted to emit a load of it. This seems likely to be a defect - // in the standard. If we start emitting a direct reference to 's', update - // this test. + // CHECK: call void @_ZN13InitFromConst7consumeIRKNS_1SEEEvT_(%"struct.InitFromConst::S"* @_ZN13InitFromConstL1sE) consume<const S&>(r); // CHECK: call void @_ZN13InitFromConst7consumeIPKNS_1SEEEvT_(%"struct.InitFromConst::S"* @_ZN13InitFromConstL1sE) diff --git a/test/CodeGenCXX/conversion-operator-base.cpp b/test/CodeGenCXX/conversion-operator-base.cpp index 8fbeadf14916a..e62e225a201fc 100644 --- a/test/CodeGenCXX/conversion-operator-base.cpp +++ b/test/CodeGenCXX/conversion-operator-base.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -emit-llvm-only %s -verify +// expected-no-diagnostics // PR5730 struct A { operator int(); float y; }; diff --git a/test/CodeGenCXX/copy-assign-synthesis-3.cpp b/test/CodeGenCXX/copy-assign-synthesis-3.cpp index ce4640a7eddb5..5469d113357e0 100644 --- a/test/CodeGenCXX/copy-assign-synthesis-3.cpp +++ b/test/CodeGenCXX/copy-assign-synthesis-3.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -emit-llvm-only -verify %s +// expected-no-diagnostics struct A { A& operator=(A&); diff --git a/test/CodeGenCXX/copy-constructor-elim-2.cpp b/test/CodeGenCXX/copy-constructor-elim-2.cpp index 9480cbfdbb3a3..4ff877516b097 100644 --- a/test/CodeGenCXX/copy-constructor-elim-2.cpp +++ b/test/CodeGenCXX/copy-constructor-elim-2.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple armv7-none-eabi -emit-llvm -o - %s | FileCheck %s struct A { int x; A(int); ~A(); }; A f() { return A(0); } @@ -66,7 +66,7 @@ namespace PR12139 { // CHECK: define i32 @_ZN7PR121394testEv int test() { // CHECK: call void @_ZN7PR121391A5makeAEv - // CHECK-NEXT: call void @_ZN7PR121391AC1ERKS0_i + // CHECK-NEXT: call %"struct.PR12139::A"* @_ZN7PR121391AC1ERKS0_i A a(A::makeA(), 3); // CHECK-NEXT: getelementptr inbounds // CHECK-NEXT: load diff --git a/test/CodeGenCXX/cxx0x-delegating-ctors.cpp b/test/CodeGenCXX/cxx0x-delegating-ctors.cpp index ad6492f5bfdcc..338159cd8258a 100644 --- a/test/CodeGenCXX/cxx0x-delegating-ctors.cpp +++ b/test/CodeGenCXX/cxx0x-delegating-ctors.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -fexceptions -fcxx-exceptions -std=c++11 -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -fexceptions -fcxx-exceptions -std=c++11 -o - %s | FileCheck %s struct non_trivial { non_trivial(); diff --git a/test/CodeGenCXX/cxx0x-initializer-array.cpp b/test/CodeGenCXX/cxx0x-initializer-array.cpp index b773178e6b812..df689978a8899 100644 --- a/test/CodeGenCXX/cxx0x-initializer-array.cpp +++ b/test/CodeGenCXX/cxx0x-initializer-array.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -S -emit-llvm -o - %s | FileCheck %s struct A { int a[1]; }; typedef A x[]; diff --git a/test/CodeGenCXX/cxx0x-initializer-constructors.cpp b/test/CodeGenCXX/cxx0x-initializer-constructors.cpp index 48fbe85d0d7a8..be5b44df1fec5 100644 --- a/test/CodeGenCXX/cxx0x-initializer-constructors.cpp +++ b/test/CodeGenCXX/cxx0x-initializer-constructors.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -S -triple x86_64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s struct S { S(int x) { } diff --git a/test/CodeGenCXX/cxx0x-initializer-references.cpp b/test/CodeGenCXX/cxx0x-initializer-references.cpp index 660b018460dbb..10586c11a7a72 100644 --- a/test/CodeGenCXX/cxx0x-initializer-references.cpp +++ b/test/CodeGenCXX/cxx0x-initializer-references.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -S -triple armv7-none-eabi -emit-llvm -o - %s | FileCheck %s namespace reference { struct A { @@ -64,10 +64,10 @@ namespace reference { { // Ensure lifetime extension. - // CHECK: call void @_ZN9reference1BC1Ev + // CHECK: call %"struct.reference::B"* @_ZN9reference1BC1Ev // CHECK-NEXT: store %{{.*}}* %{{.*}}, %{{.*}}** % const B &rb{ B() }; - // CHECK: call void @_ZN9reference1BD1Ev + // CHECK: call %"struct.reference::B"* @_ZN9reference1BD1Ev } } diff --git a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp index c533e453a5e4b..209ee65138552 100644 --- a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp +++ b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -S -triple x86_64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s namespace std { typedef decltype(sizeof(int)) size_t; diff --git a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp index 81ce559844665..8d9fce040fd7f 100644 --- a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp +++ b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -S -triple x86_64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s namespace std { typedef decltype(sizeof(int)) size_t; diff --git a/test/CodeGenCXX/cxx11-special-members.cpp b/test/CodeGenCXX/cxx11-special-members.cpp new file mode 100644 index 0000000000000..59461f9e2f4bd --- /dev/null +++ b/test/CodeGenCXX/cxx11-special-members.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=i686-linux-gnu | FileCheck %s + +struct A { + A(const A&); + A &operator=(const A&); +}; + +struct B { + A a; + B(B&&) = default; + B &operator=(B&&) = default; +}; + +// CHECK: define {{.*}} @_Z2f1 +void f1(B &x) { + // CHECK-NOT: memcpy + // CHECK: call {{.*}} @_ZN1BC1EOS_( + B b(static_cast<B&&>(x)); +} + +// CHECK: define {{.*}} @_Z2f2 +void f2(B &x, B &y) { + // CHECK-NOT: memcpy + // CHECK: call {{.*}} @_ZN1BaSEOS_( + x = static_cast<B&&>(y); +} + +// CHECK: define {{.*}} @_ZN1BaSEOS_( +// CHECK: call {{.*}} @_ZN1AaSERKS_( + +// CHECK: define {{.*}} @_ZN1BC2EOS_( +// CHECK: call {{.*}} @_ZN1AC1ERKS_( diff --git a/test/CodeGenCXX/debug-info-artificial-arg.cpp b/test/CodeGenCXX/debug-info-artificial-arg.cpp index 35e5f2775fd7a..ee9384979d301 100644 --- a/test/CodeGenCXX/debug-info-artificial-arg.cpp +++ b/test/CodeGenCXX/debug-info-artificial-arg.cpp @@ -23,7 +23,7 @@ int main(int argc, char **argv) { } // FIXME: The numbers are truly awful. -// CHECK: !16 = metadata !{i32 {{.*}}, i32 0, metadata !"", i32 0, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !17} ; [ DW_TAG_pointer_type ] +// CHECK: !16 = metadata !{i32 786447, i32 0, metadata !"", i32 0, i32 0, i64 64, i64 64, i64 0, i32 1088, metadata !17} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from A] // CHECK: !17 = metadata !{i32 {{.*}}, null, metadata !"A", metadata !6, i32 8, i64 128, i64 64, i32 0, i32 0, null, metadata !18, i32 0, metadata !17, null} ; [ DW_TAG_class_type ] // CHECK: metadata !17, metadata !"A", metadata !"A", metadata !"", metadata !6, i32 12, metadata !43, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !45, i32 12} ; [ DW_TAG_subprogram ] // CHECK: metadata !"", i32 0, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !44, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] diff --git a/test/CodeGenCXX/debug-info-blocks.cpp b/test/CodeGenCXX/debug-info-blocks.cpp new file mode 100644 index 0000000000000..5b20db5828032 --- /dev/null +++ b/test/CodeGenCXX/debug-info-blocks.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 %s -gline-tables-only -fblocks -S -emit-llvm -o - | FileCheck %s + +struct A { + A(); + A(const A &); + ~A(); +}; + +void test() { + __block A a; +} + +// CHECK: [ DW_TAG_subprogram ] [line 10] [local] [def] [__Block_byref_object_copy_] +// CHECK: [ DW_TAG_subprogram ] [line 10] [local] [def] [__Block_byref_object_dispose_] diff --git a/test/CodeGenCXX/debug-info-class.cpp b/test/CodeGenCXX/debug-info-class.cpp index 151c5f90534c5..062227a02382f 100644 --- a/test/CodeGenCXX/debug-info-class.cpp +++ b/test/CodeGenCXX/debug-info-class.cpp @@ -1,12 +1,24 @@ -// RUN: %clang -emit-llvm -g -S %s -o - | grep HdrSize -struct A { +// RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s +struct foo; +void func(foo *f) { // CHECK: DW_TAG_structure_type +} +class bar; +void func(bar *f) { // CHECK: DW_TAG_class_type +} +union baz; +void func(baz *f) { // CHECK: DW_TAG_union_type +} +struct A { // CHECK: DW_TAG_structure_type int one; - static const int HdrSize = 52; + static const int HdrSize = 52; // CHECK: HdrSize int two; A() { int x = 1; } }; +class B { // CHECK: DW_TAG_class_type +}; int main() { A a; + B b; } diff --git a/test/CodeGenCXX/debug-info-enum-class.cpp b/test/CodeGenCXX/debug-info-enum-class.cpp index 6f88439b1eed7..fd243abb2e84b 100644 --- a/test/CodeGenCXX/debug-info-enum-class.cpp +++ b/test/CodeGenCXX/debug-info-enum-class.cpp @@ -12,4 +12,18 @@ D d; // CHECK: metadata !{i32 {{.*}}, null, metadata !"A", metadata !4, i32 3, i64 32, i64 32, i32 0, i32 0, metadata !5, metadata !6, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] // CHECK: metadata !{i32 {{.*}}, null, metadata !"B", metadata !4, i32 4, i64 64, i64 64, i32 0, i32 0, metadata !9, metadata !10, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] // CHECK: metadata !{i32 {{.*}}, null, metadata !"C", metadata !4, i32 5, i64 32, i64 32, i32 0, i32 0, null, metadata !13, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] -// CHECK: metadata !{i32 {{.*}}, null, metadata !"D", metadata !4, i32 6, i64 16, i64 16, i32 0, i32 4, null, metadata !16, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] +// CHECK: metadata !{i32 {{.*}}, null, metadata !"D", metadata !4, i32 6, i64 16, i64 16, i32 0, i32 4, null, null, i32 0} ; [ DW_TAG_enumeration_type ] + +namespace PR14029 { + // Make sure this doesn't crash/assert. + template <typename T> struct Test { + enum class Tag { + test = 0 + }; + Test() { + auto t = Tag::test; + } + Tag tag() const { return static_cast<Tag>(1); } + }; + Test<int> t; +} diff --git a/test/CodeGenCXX/debug-info-fwd-ref.cpp b/test/CodeGenCXX/debug-info-fwd-ref.cpp index e7f2ed19d79f8..9135032320510 100644 --- a/test/CodeGenCXX/debug-info-fwd-ref.cpp +++ b/test/CodeGenCXX/debug-info-fwd-ref.cpp @@ -16,11 +16,10 @@ int main(int argc, char** argv) { return 0; } -// Make sure we have two DW_TAG_class_types for baz and bar and no forward +// Make sure we have two DW_TAG_structure_types for baz and bar and no forward // references. -// FIXME: These should be struct types to match the declaration. -// CHECK: metadata !{i32 {{.*}}, null, metadata !"bar", metadata !6, i32 8, i64 128, i64 64, i32 0, i32 0, null, metadata !18, i32 0, null, null} ; [ DW_TAG_class_type ] -// CHECK: metadata !{i32 {{.*}}, null, metadata !"baz", metadata !6, i32 3, i64 32, i64 32, i32 0, i32 0, null, metadata !21, i32 0, null, null} ; [ DW_TAG_class_type ] -// CHECK-NOT: metadata !{i32 {{.*}}, null, metadata !"bar", metadata !6, i32 8, i64 0, i64 0, i32 0, i32 4, i32 0, null, i32 0, i32 0} ; [ DW_TAG_class_type ] -// CHECK-NOT: metadata !{i32 {{.*}}, null, metadata !"baz", metadata !6, i32 3, i64 0, i64 0, i32 0, i32 4, null, null, i32 0, null, null} ; [ DW_TAG_class_type ] +// CHECK: metadata !{i32 {{.*}}, null, metadata !"bar", metadata !6, i32 8, i64 128, i64 64, i32 0, i32 0, null, metadata !18, i32 0, null, null} ; [ DW_TAG_structure_type ] +// CHECK: metadata !{i32 {{.*}}, null, metadata !"baz", metadata !6, i32 3, i64 32, i64 32, i32 0, i32 0, null, metadata !21, i32 0, null, null} ; [ DW_TAG_structure_type ] +// CHECK-NOT: metadata !{i32 {{.*}}, null, metadata !"bar", metadata !6, i32 8, i64 0, i64 0, i32 0, i32 4, i32 0, null, i32 0, i32 0} ; [ DW_TAG_structure_type ] +// CHECK-NOT: metadata !{i32 {{.*}}, null, metadata !"baz", metadata !6, i32 3, i64 0, i64 0, i32 0, i32 4, null, null, i32 0, null, null} ; [ DW_TAG_structure_type ] diff --git a/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp b/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp new file mode 100644 index 0000000000000..bdaf58c827036 --- /dev/null +++ b/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 %s -g -fno-use-cxa-atexit -S -emit-llvm -o - \ +// RUN: | FileCheck %s --check-prefix=CHECK-NOKEXT +// RUN: %clang_cc1 %s -g -fno-use-cxa-atexit -fapple-kext -S -emit-llvm -o - \ +// RUN: | FileCheck %s --check-prefix=CHECK-KEXT + +class A { + public: + A() {} + virtual ~A() {} +}; + +A glob; +A array[2]; + +void foo() { + static A stat; +} + +// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line 12] [local] [def] [__cxx_global_var_init] +// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line 12] [local] [def] [__dtor_glob] +// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line 13] [local] [def] [__cxx_global_var_init1] +// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line 13] [local] [def] [__cxx_global_array_dtor] +// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line 13] [local] [def] [__dtor_] +// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line 16] [local] [def] [__dtor__ZZ3foovE4stat] +// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line {{.*}}] [local] [def] [_GLOBAL__I_a] + +// CHECK-KEXT: [ DW_TAG_subprogram ] [line {{.*}}] [local] [def] [_GLOBAL__D_a] diff --git a/test/CodeGenCXX/debug-info-globalinit.cpp b/test/CodeGenCXX/debug-info-globalinit.cpp index ff50fac4cfa36..b3891c148e3e4 100644 --- a/test/CodeGenCXX/debug-info-globalinit.cpp +++ b/test/CodeGenCXX/debug-info-globalinit.cpp @@ -27,4 +27,4 @@ int main(void) {} // CHECK-NOT: dbg // CHECK: store i32 %[[C1]], i32* @_ZL1j, align 4 // -// CHECK: ![[LINE]] = metadata !{i32 13, i32 16 +// CHECK: ![[LINE]] = metadata !{i32 13, i32 diff --git a/test/CodeGenCXX/debug-info-pubtypes.cpp b/test/CodeGenCXX/debug-info-pubtypes.cpp index a7abade3929fc..612b6b500abca 100644 --- a/test/CodeGenCXX/debug-info-pubtypes.cpp +++ b/test/CodeGenCXX/debug-info-pubtypes.cpp @@ -1,5 +1,5 @@ // REQUIRES: x86-64-registered-target -// RUN: %clang -cc1 -triple x86_64-apple-darwin10 -g -fno-limit-debug-info -S %s -o %t +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -g -fno-limit-debug-info -S %s -o %t // RUN: FileCheck %s < %t // FIXME: This testcase shouldn't rely on assembly emission. diff --git a/test/CodeGenCXX/debug-info-template-member.cpp b/test/CodeGenCXX/debug-info-template-member.cpp index f21718da5e67c..6208c80aeb610 100644 --- a/test/CodeGenCXX/debug-info-template-member.cpp +++ b/test/CodeGenCXX/debug-info-template-member.cpp @@ -17,5 +17,5 @@ private: MyClass m; // CHECK: metadata !{i32 {{.*}}, null, metadata !"MyClass", metadata {{.*}}, i32 {{.*}}, i64 8, i64 8, i32 0, i32 0, null, metadata [[C_MEM:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] -// CHECK: [[C_MEM]] = metadata !{metadata {{.*}}, metadata [[C_TEMP:.*]]} +// CHECK: [[C_MEM]] = metadata !{metadata {{.*}}, metadata [[C_TEMP:.*]], metadata {{.*}}} // CHECK: [[C_TEMP]] = metadata !{i32 {{.*}}, i32 0, metadata {{.*}}, metadata !"add<2>", metadata !"add<2>", metadata !"_ZN7MyClass3addILi2EEEii", metadata {{.*}} diff --git a/test/CodeGenCXX/debug-info-template-quals.cpp b/test/CodeGenCXX/debug-info-template-quals.cpp index e5a9082c9c298..ffb1ca3849f13 100644 --- a/test/CodeGenCXX/debug-info-template-quals.cpp +++ b/test/CodeGenCXX/debug-info-template-quals.cpp @@ -20,4 +20,4 @@ void foo (const char *c) { // CHECK: [[CH]] = metadata !{i32 {{.*}}, metadata !"char", {{.*}}} ; [ DW_TAG_base_type ] [char] [line 0, size 8, align 8, offset 0, enc DW_ATE_signed_char] // CHECK: metadata !{i32 {{.*}}, metadata !"_ZN12basic_stringIcE6assignEPKc", metadata !6, i32 7, metadata [[TYPE:.*]], i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, %struct.basic_string* (%struct.basic_string*, i8*)* @_ZN12basic_stringIcE6assignEPKc, null, metadata !18, metadata !1, i32 8} ; [ DW_TAG_subprogram ] [line 7] [def] [scope 8] [assign] // CHECK: [[TYPE]] = metadata !{i32 {{.*}}, null, metadata [[ARGS:.*]], i32 0, i32 0} -// CHECK: [[ARGS]] = metadata !{metadata !15, metadata !23, metadata [[P]]} +// CHECK: [[ARGS]] = metadata !{metadata !15, metadata !24, metadata [[P]]} diff --git a/test/CodeGenCXX/debug-info-thunk.cpp b/test/CodeGenCXX/debug-info-thunk.cpp new file mode 100644 index 0000000000000..394ebd829188d --- /dev/null +++ b/test/CodeGenCXX/debug-info-thunk.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 %s -g -S -emit-llvm -o - | FileCheck %s + +struct A { + virtual void f(); +}; + +struct B { + virtual void f(); +}; + +struct C : A, B { + virtual void f(); +}; + +void C::f() { } + +// CHECK: [ DW_TAG_subprogram ] [line 15] [def] [_ZThn{{4|8}}_N1C1fEv] diff --git a/test/CodeGenCXX/debug-info-user-def.cpp b/test/CodeGenCXX/debug-info-user-def.cpp deleted file mode 100644 index ecd387870549c..0000000000000 --- a/test/CodeGenCXX/debug-info-user-def.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin -std=c++11 %s -o - | FileCheck %s - -class A { -}; - -template <typename T> class B { - T t; -}; - -A a; -B<int> b; - -// Check that no subprograms are emitted into debug info. -// CHECK-NOT: [ DW_TAG_subprogram ] diff --git a/test/CodeGenCXX/debug-lambda-expressions.cpp b/test/CodeGenCXX/debug-lambda-expressions.cpp index 1c823990c1d90..430371f382c80 100644 --- a/test/CodeGenCXX/debug-lambda-expressions.cpp +++ b/test/CodeGenCXX/debug-lambda-expressions.cpp @@ -31,39 +31,41 @@ int d(int x) { D y[10]; [x,y] { return y[x].x; }(); } // Back to D. -- 24 // CHECK: [[LAM_D:.*]] = metadata !{i32 {{.*}}, metadata [[D_FUNC]], metadata !"", metadata [[FILE]], i32 [[D_LINE]], i64 352, i64 32, i32 0, i32 0, null, metadata [[LAM_D_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] -// CHECK: [[LAM_D_ARGS]] = metadata !{metadata [[CAP_D_X:.*]], metadata [[CAP_D_Y:.*]], metadata [[CON_LAM_D:.*]]} +// CHECK: [[LAM_D_ARGS]] = metadata !{metadata [[CAP_D_X:.*]], metadata [[CAP_D_Y:.*]], metadata [[CON_LAM_D:.*]], metadata [[DES_LAM_D:.*]]} // CHECK: [[CAP_D_X]] = metadata !{i32 {{.*}}, metadata [[LAM_D]], metadata !"x", metadata [[FILE]], i32 [[D_LINE]], i64 32, i64 32, i64 0, i32 1, metadata {{.*}} ; [ DW_TAG_member ] // CHECK: [[CAP_D_Y]] = metadata !{i32 {{.*}}, metadata [[LAM_D]], metadata !"y", metadata [[FILE]], i32 [[D_LINE]], i64 320, i64 32, i64 32, i32 1, metadata {{.*}} ; [ DW_TAG_member ] // CHECK: [[CON_LAM_D]] = metadata {{.*}}[[LAM_D]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ] +// CHECK: [[DES_LAM_D]] = metadata {{.*}}[[LAM_D]], metadata !"~", metadata !"~"{{.*}}[ DW_TAG_subprogram ] // Back to C. -- 55 // CHECK: [[LAM_C:.*]] = metadata !{i32 {{.*}}, metadata [[C_FUNC]], metadata !"", metadata [[FILE]], i32 [[C_LINE]], i64 64, i64 64, i32 0, i32 0, null, metadata [[LAM_C_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] -// CHECK: [[LAM_C_ARGS]] = metadata !{metadata [[CAP_C:.*]], metadata [[CON_LAM_C:.*]]} +// CHECK: [[LAM_C_ARGS]] = metadata !{metadata [[CAP_C:.*]], metadata [[CON_LAM_C:.*]], metadata [[DES_LAM_C:.*]]} // Ignoring the member type for now. // CHECK: [[CAP_C]] = metadata !{i32 {{.*}}, metadata [[LAM_C]], metadata !"x", metadata [[FILE]], i32 [[C_LINE]], i64 64, i64 64, i64 0, i32 1, metadata {{.*}}} ; [ DW_TAG_member ] // CHECK: [[CON_LAM_C]] = metadata {{.*}}[[LAM_C]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ] +// CHECK: [[DES_LAM_C]] = metadata {{.*}}[[LAM_C]], metadata !"~", metadata !"~"{{.*}}[ DW_TAG_subprogram ] // Back to B. -- 67 // CHECK: [[LAM_B:.*]] = metadata !{i32 {{.*}}, metadata [[B_FUNC]], metadata !"", metadata [[FILE]], i32 [[B_LINE]], i64 32, i64 32, i32 0, i32 0, null, metadata [[LAM_B_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] -// CHECK: [[LAM_B_ARGS]] = metadata !{metadata [[CAP_B:.*]], metadata [[CON_LAM_B:.*]]} +// CHECK: [[LAM_B_ARGS]] = metadata !{metadata [[CAP_B:.*]], metadata [[CON_LAM_B:.*]], metadata [[DES_LAM_B:.*]]} // CHECK: [[CAP_B]] = metadata !{i32 {{.*}}, metadata [[LAM_B]], metadata !"x", metadata [[FILE]], i32 [[B_LINE]], i64 32, i64 32, i64 0, i32 1, metadata {{.*}}} ; [ DW_TAG_member ] // CHECK: [[CON_LAM_B]] = metadata {{.*}}[[LAM_B]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ] - +// CHECK: [[DES_LAM_B]] = metadata {{.*}}[[LAM_B]], metadata !"~", metadata !"~"{{.*}}[ DW_TAG_subprogram ] // Back to A. -- 78 // CHECK: [[LAM_A:.*]] = metadata !{i32 {{.*}}, metadata [[A_FUNC]], metadata !"", metadata [[FILE]], i32 [[A_LINE]], i64 8, i64 8, i32 0, i32 0, null, metadata [[LAM_A_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] -// CHECK: [[LAM_A_ARGS]] = metadata !{metadata [[CON_LAM_A:.*]]} +// CHECK: [[LAM_A_ARGS]] = metadata !{metadata [[CON_LAM_A:.*]], metadata [[DES_LAM_A:.*]]} // CHECK: [[CON_LAM_A]] = metadata {{.*}}[[LAM_A]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ] - +// CHECK: [[DES_LAM_A]] = metadata {{.*}}[[LAM_A]], metadata !"~", metadata !"~"{{.*}}[ DW_TAG_subprogram ] // CVAR: // CHECK: metadata !{i32 {{.*}}, i32 0, null, metadata !"cvar", metadata !"cvar", metadata !"", metadata [[FILE]], i32 [[CVAR_LINE:.*]], metadata ![[CVAR_T:.*]], i32 0, i32 1, %class.anon.0* @cvar} ; [ DW_TAG_variable ] // CHECK: [[CVAR_T]] = metadata !{i32 {{.*}}, null, metadata !"", metadata [[FILE]], i32 [[CVAR_LINE]], i64 8, i64 8, i32 0, i32 0, null, metadata ![[CVAR_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] -// CHECK: [[CVAR_ARGS]] = metadata !{metadata !{{.*}}} +// CHECK: [[CVAR_ARGS]] = metadata !{metadata !{{.*}}, metadata !{{.*}}, metadata !{{.*}}} // VAR: // CHECK: metadata !{i32 {{.*}}, i32 0, null, metadata !"var", metadata !"var", metadata !"", metadata [[FILE]], i32 [[VAR_LINE:.*]], metadata ![[VAR_T:.*]], i32 1, i32 1, %class.anon* @var} ; [ DW_TAG_variable ] // CHECK: [[VAR_T]] = metadata !{i32 {{.*}}, null, metadata !"", metadata [[FILE]], i32 [[VAR_LINE]], i64 8, i64 8, i32 0, i32 0, null, metadata ![[VAR_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ] -// CHECK: [[VAR_ARGS]] = metadata !{metadata !{{.*}}} +// CHECK: [[VAR_ARGS]] = metadata !{metadata !{{.*}}, metadata !{{.*}}, metadata !{{.*}}} diff --git a/test/CodeGenCXX/debug-lambda-this.cpp b/test/CodeGenCXX/debug-lambda-this.cpp new file mode 100644 index 0000000000000..7c37fbe35c6bc --- /dev/null +++ b/test/CodeGenCXX/debug-lambda-this.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -fexceptions -std=c++11 -g | FileCheck %s + +struct D { + D(); + D(const D&); + int x; + int d(int x); +}; +int D::d(int x) { + [=] { + return this->x; + }(); +} + +// CHECK: metadata !{i32 {{.*}}, metadata !"this", metadata !6, i32 11, i64 64, i64 64, i64 0, i32 1, metadata !37} ; [ DW_TAG_member ] [this] [line 11, size 64, align 64, offset 0] [private] [from ] diff --git a/test/CodeGenCXX/delete.cpp b/test/CodeGenCXX/delete.cpp index 5a88f9f924373..7a91ca814637f 100644 --- a/test/CodeGenCXX/delete.cpp +++ b/test/CodeGenCXX/delete.cpp @@ -113,12 +113,23 @@ namespace test4 { // 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 + // Load the offset-to-top from the vtable and apply it. + // This has to be done first because the dtor can mess it up. + // CHECK: [[T0:%.*]] = bitcast [[X:%.*]]* [[XP:%.*]] to i64** + // CHECK-NEXT: [[VTABLE:%.*]] = load i64** [[T0]] + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i64* [[VTABLE]], i64 -2 + // CHECK-NEXT: [[OFFSET:%.*]] = load i64* [[T0]], align 8 + // CHECK-NEXT: [[T0:%.*]] = bitcast [[X]]* [[XP]] to i8* + // CHECK-NEXT: [[ALLOCATED:%.*]] = getelementptr inbounds i8* [[T0]], i64 [[OFFSET]] + // Load the complete-object destructor (not the deleting destructor) + // and call it. + // CHECK-NEXT: [[T0:%.*]] = bitcast [[X:%.*]]* [[XP:%.*]] to void ([[X]]*)*** + // CHECK-NEXT: [[VTABLE:%.*]] = load void ([[X]]*)*** [[T0]] + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds void ([[X]]*)** [[VTABLE]], i64 0 + // CHECK-NEXT: [[DTOR:%.*]] = load void ([[X]]*)** [[T0]] + // CHECK-NEXT: call void [[DTOR]]([[X]]* [[OBJ:%.*]]) + // Call the global operator delete. + // CHECK-NEXT: call void @_ZdlPv(i8* [[ALLOCATED]]) nounwind ::delete xp; } } diff --git a/test/CodeGenCXX/dependent-type-member-pointer.cpp b/test/CodeGenCXX/dependent-type-member-pointer.cpp index 41bb5e29d58c3..99b8ecd555c79 100644 --- a/test/CodeGenCXX/dependent-type-member-pointer.cpp +++ b/test/CodeGenCXX/dependent-type-member-pointer.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -emit-llvm-only -verify %s +// expected-no-diagnostics // PR7736 template <class scriptmemberptr> int InitMember(scriptmemberptr); diff --git a/test/CodeGenCXX/destructor-debug-info.cpp b/test/CodeGenCXX/destructor-debug-info.cpp index 385c86d9be19f..f2e2a39bd6b6b 100644 --- a/test/CodeGenCXX/destructor-debug-info.cpp +++ b/test/CodeGenCXX/destructor-debug-info.cpp @@ -19,4 +19,4 @@ void foo() { } } // Check there is a line number entry for line 19 where b1 is destructed. -// CHECK: i32 19, i32 3, metadata +// CHECK: i32 19, i32 0, metadata diff --git a/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp b/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp index 634bf84b416d0..40f3cada7d46b 100644 --- a/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp +++ b/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 %s -emit-llvm -o - | FileCheck %s namespace Test1 { struct A { @@ -131,8 +131,7 @@ namespace Test7 { // CHECK: alloca // CHECK-NEXT: store // CHECK-NEXT: load - // CHECK-NEXT: bitcast - // CHECK-NEXT: call {{.*}} @_ZN5Test73zed1fEv + // CHECK-NEXT: call i32 @_ZN5Test73zed1fEv // CHECK-NEXT: ret return static_cast<bar*>(z)->f(); } diff --git a/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp b/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp index 7ef4864c8367e..52f1cd3fa236d 100644 --- a/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp +++ b/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple armv7-none-eabi -emit-llvm -o - | FileCheck %s struct A { virtual void f(); @@ -66,7 +66,7 @@ namespace test2 { void f(bar *b) { // CHECK: call void @_ZN5test23foo1fEv - // CHECK: call void @_ZN5test23fooD1Ev + // CHECK: call %"struct.test2::foo"* @_ZN5test23fooD1Ev b->foo::f(); b->foo::~foo(); } diff --git a/test/CodeGenCXX/enum.cpp b/test/CodeGenCXX/enum.cpp index cfcd264bd347a..3985e96ab9fe7 100644 --- a/test/CodeGenCXX/enum.cpp +++ b/test/CodeGenCXX/enum.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -emit-llvm-only -verify %s +// expected-no-diagnostics enum A { a } __attribute((packed)); int func(A x) { return x==a; } diff --git a/test/CodeGenCXX/exceptions.cpp b/test/CodeGenCXX/exceptions.cpp index 8c20c9e9ce21f..723e8d1393c11 100644 --- a/test/CodeGenCXX/exceptions.cpp +++ b/test/CodeGenCXX/exceptions.cpp @@ -365,6 +365,7 @@ namespace test7 { // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_( // CHECK: store i1 false, i1* [[OUTER_NEW]] // CHECK: phi + // CHECK-NEXT: store [[B]]* // Destroy the inner A object. // CHECK-NEXT: load i1* [[INNER_A]] diff --git a/test/CodeGenCXX/fastcall.cpp b/test/CodeGenCXX/fastcall.cpp new file mode 100644 index 0000000000000..c0a9106672746 --- /dev/null +++ b/test/CodeGenCXX/fastcall.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s + +void __attribute__((fastcall)) foo1(int &y); +void bar1(int &y) { + // CHECK: define void @_Z4bar1Ri + // CHECK: call x86_fastcallcc void @_Z4foo1Ri(i32* inreg % + foo1(y); +} + +struct S1 { + int x; + S1(const S1 &y); +}; + +void __attribute__((fastcall)) foo2(S1 a, int b); +void bar2(S1 a, int b) { + // CHECK: define void @_Z4bar22S1i + // CHECK: call x86_fastcallcc void @_Z4foo22S1i(%struct.S1* inreg %{{.*}}, i32 inreg % + foo2(a, b); +} diff --git a/test/CodeGenCXX/for-range.cpp b/test/CodeGenCXX/for-range.cpp index 0f35dda737feb..926fe445a5ba5 100644 --- a/test/CodeGenCXX/for-range.cpp +++ b/test/CodeGenCXX/for-range.cpp @@ -27,10 +27,8 @@ struct D { B *end(); }; -namespace std { - B *begin(C&); - B *end(C&); -} +B *begin(C&); +B *end(C&); extern B array[5]; @@ -42,7 +40,7 @@ void for_array() { // CHECK-NOT: 5begin // CHECK-NOT: 3end // CHECK: getelementptr {{.*}}, i32 0 - // CHECK: getelementptr {{.*}}, i64 5 + // CHECK: getelementptr {{.*}}, i64 1, i64 0 // CHECK: br label %[[COND:.*]] // CHECK: [[COND]]: @@ -69,8 +67,8 @@ void for_range() { A a; for (B b : C()) { // CHECK: call void @_ZN1CC1Ev( - // CHECK: = call %struct.B* @_ZSt5beginR1C( - // CHECK: = call %struct.B* @_ZSt3endR1C( + // CHECK: = call %struct.B* @_Z5beginR1C( + // CHECK: = call %struct.B* @_Z3endR1C( // CHECK: br label %[[COND:.*]] // CHECK: [[COND]]: diff --git a/test/CodeGenCXX/implicit-copy-constructor.cpp b/test/CodeGenCXX/implicit-copy-constructor.cpp index 8bc84a534b365..8a3a422e0ba88 100644 --- a/test/CodeGenCXX/implicit-copy-constructor.cpp +++ b/test/CodeGenCXX/implicit-copy-constructor.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -std=c++11 | FileCheck %s struct A { A(); @@ -80,3 +80,29 @@ namespace test3 { y = x; } } + +namespace test4 { + // When determining whether to implement an array copy as a memcpy, look at + // whether the *selected* constructor is trivial. + struct S { + int arr[5][5]; + S(S &); + S(const S &) = default; + }; + // CHECK: @_ZN5test42f1 + void f1(S a) { + // CHECK-NOT: memcpy + // CHECK: call void @_ZN5test41SC1ERS0_ + // CHECK-NOT: memcpy + S b(a); + // CHECK: } + } + // CHECK: @_ZN5test42f2 + void f2(const S a) { + // CHECK-NOT: call void @_ZN5test41SC1ERS0_ + // CHECK: memcpy + // CHECK-NOT: call void @_ZN5test41SC1ERS0_ + S b(a); + // CHECK: } + } +} diff --git a/test/CodeGenCXX/incomplete-types.cpp b/test/CodeGenCXX/incomplete-types.cpp index 1d4f430e5cb5c..802ed4628d9e5 100644 --- a/test/CodeGenCXX/incomplete-types.cpp +++ b/test/CodeGenCXX/incomplete-types.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -emit-llvm-only -verify +// expected-no-diagnostics // PR5489 template<typename E> diff --git a/test/CodeGenCXX/init-priority-attr.cpp b/test/CodeGenCXX/init-priority-attr.cpp new file mode 100644 index 0000000000000..ef9343ceade99 --- /dev/null +++ b/test/CodeGenCXX/init-priority-attr.cpp @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s +// PR + +void foo(int); + +class A { +public: + A() { foo(1); } +}; + +class A1 { +public: + A1() { foo(2); } +}; + +class B { +public: + B() { foo(3); } +}; + +class C { +public: + static A a; + C() { foo(4); } +}; + + +A C::a = A(); + +// CHECK: @llvm.global_ctors = appending global [3 x { i32, void ()* }] [{ i32, void ()* } { i32 200, void ()* @_GLOBAL__I_000200 }, { i32, void ()* } { i32 300, void ()* @_GLOBAL__I_000300 }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }] + +// CHECK: _GLOBAL__I_000200() +// CHECK_NEXT: _Z3fooi(i32 3) + +// CHECK: _GLOBAL__I_000300() +// CHECK_NEXT: _Z3fooi(i32 2) +// CHECK_NEXT: _Z3fooi(i32 1) + +// CHECK: _GLOBAL__I_a() +// CHECK_NEXT: _Z3fooi(i32 1) +// CHECK_NEXT: _Z3fooi(i32 4) + +C c; +A1 a1 __attribute__((init_priority (300))); +A a __attribute__((init_priority (300))); +B b __attribute__((init_priority (200))); diff --git a/test/CodeGenCXX/instantiate-init-list.cpp b/test/CodeGenCXX/instantiate-init-list.cpp index 49c6f51c77510..e498d2476c015 100644 --- a/test/CodeGenCXX/instantiate-init-list.cpp +++ b/test/CodeGenCXX/instantiate-init-list.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -emit-llvm-only -verify +// expected-no-diagnostics struct F { void (*x)(); diff --git a/test/CodeGenCXX/lambda-expressions.cpp b/test/CodeGenCXX/lambda-expressions.cpp index e872cc494bc62..cee4f172a000b 100644 --- a/test/CodeGenCXX/lambda-expressions.cpp +++ b/test/CodeGenCXX/lambda-expressions.cpp @@ -71,6 +71,15 @@ void f() { int (*fp)(int, int) = [](int x, int y){ return x + y; }; } +static int k; +int g() { + int &r = k; + // CHECK: define internal i32 @"_ZZ1gvENK3$_6clEv"( + // CHECK-NOT: } + // CHECK: load i32* @_ZL1k, + return [] { return r; } (); +}; + // CHECK: define internal i32 @"_ZZ1fvEN3$_58__invokeEii" // CHECK: store i32 // CHECK-NEXT: store i32 diff --git a/test/CodeGenCXX/mangle-exprs.cpp b/test/CodeGenCXX/mangle-exprs.cpp index 30da4fbbcdf94..2d7a883526dbb 100644 --- a/test/CodeGenCXX/mangle-exprs.cpp +++ b/test/CodeGenCXX/mangle-exprs.cpp @@ -190,4 +190,11 @@ namespace test4 { // CHECK: void @_ZN5test43tf3INS_1XEEEvDTnw_T_ilLi1EEE template void tf3<X>(X*); + +} + +namespace test5 { + template <typename T> void a(decltype(noexcept(T()))) {} + template void a<int>(decltype(noexcept(int()))); + // CHECK: void @_ZN5test51aIiEEvDTnxcvT__EE( } diff --git a/test/CodeGenCXX/mangle-extern-local.cpp b/test/CodeGenCXX/mangle-extern-local.cpp index ed91da4e2e37a..1394c8f2a1329 100644 --- a/test/CodeGenCXX/mangle-extern-local.cpp +++ b/test/CodeGenCXX/mangle-extern-local.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple i386-unknown-unknown -emit-llvm -o - | FileCheck %s // CHECK: @var1 = external global i32 // CHECK: @_ZN1N4var2E = external global i32 diff --git a/test/CodeGenCXX/mangle-lambdas.cpp b/test/CodeGenCXX/mangle-lambdas.cpp index 16ddf4838ea7b..0bd5ad2a02ca9 100644 --- a/test/CodeGenCXX/mangle-lambdas.cpp +++ b/test/CodeGenCXX/mangle-lambdas.cpp @@ -172,6 +172,33 @@ template<typename...T> int PR12917<T...>::n[3] = { PR12917<int, char, double> pr12917; int *pr12917_p = PR12917<int, int>::n; +namespace std { + struct type_info; +} +namespace PR12123 { + struct A { virtual ~A(); } g; + struct B { + void f(const std::type_info& x = typeid([]()->A& { return g; }())); + void h(); + }; + void B::h() { f(); } +} +// CHECK: define linkonce_odr %"struct.PR12123::A"* @_ZZN7PR121231B1fERKSt9type_infoEd_NKUlvE_clEv + +namespace PR12808 { + template <typename> struct B { + int a; + template <typename L> constexpr B(L&& x) : a(x()) { } + }; + template <typename> void b(int) { + [&]{ (void)B<int>([&]{ return 1; }); }(); + } + void f() { + b<int>(1); + } + // CHECK: define linkonce_odr void @_ZZN7PR128081bIiEEviENKS0_IiEUlvE_clEv + // CHECK: define linkonce_odr i32 @_ZZZN7PR128081bIiEEviENKS0_IiEUlvE_clEvENKUlvE_clEv +} // CHECK: define linkonce_odr void @_Z1fIZZNK23TestNestedInstantiationclEvENKUlvE_clEvEUlvE_EvT_ diff --git a/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp b/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp new file mode 100644 index 0000000000000..0ac9b3f121f33 --- /dev/null +++ b/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s + +void foo(const unsigned int) {} +// CHECK: "\01?foo@@YAXI@Z" + +void foo(const double) {} +// CHECK: "\01?foo@@YAXN@Z" + +void bar(const volatile double) {} +// CHECK: "\01?bar@@YAXN@Z" + +void foo_pad(char * x) {} +// CHECK: "\01?foo_pad@@YAXPAD@Z" + +void foo_pbd(const char * x) {} +// CHECK: "\01?foo_pbd@@YAXPBD@Z" + +void foo_pcd(volatile char * x) {} +// CHECK: "\01?foo_pcd@@YAXPCD@Z" + +void foo_qad(char * const x) {} +// CHECK: "\01?foo_qad@@YAXQAD@Z" + +void foo_rad(char * volatile x) {} +// CHECK: "\01?foo_rad@@YAXRAD@Z" + +void foo_sad(char * const volatile x) {} +// CHECK: "\01?foo_sad@@YAXSAD@Z" + +void foo_papad(char ** x) {} +// CHECK: "\01?foo_papad@@YAXPAPAD@Z" + +void foo_papbd(char const ** x) {} +// CHECK: "\01?foo_papbd@@YAXPAPBD@Z" + +void foo_papcd(char volatile ** x) {} +// CHECK: "\01?foo_papcd@@YAXPAPCD@Z" + +void foo_pbqad(char * const* x) {} +// CHECK: "\01?foo_pbqad@@YAXPBQAD@Z" + +void foo_pcrad(char * volatile* x) {} +// CHECK: "\01?foo_pcrad@@YAXPCRAD@Z" + +void foo_qapad(char ** const x) {} +// CHECK: "\01?foo_qapad@@YAXQAPAD@Z" + +void foo_rapad(char ** volatile x) {} +// CHECK: "\01?foo_rapad@@YAXRAPAD@Z" + +void foo_pbqbd(const char * const* x) {} +// CHECK: "\01?foo_pbqbd@@YAXPBQBD@Z" + +void foo_pbqcd(volatile char * const* x) {} +// CHECK: "\01?foo_pbqcd@@YAXPBQCD@Z" + +void foo_pcrbd(const char * volatile* x) {} +// CHECK: "\01?foo_pcrbd@@YAXPCRBD@Z" + +void foo_pcrcd(volatile char * volatile* x) {} +// CHECK: "\01?foo_pcrcd@@YAXPCRCD@Z" + +typedef double Vector[3]; + +void foo(Vector*) {} +// CHECK: "\01?foo@@YAXPAY02N@Z" + +void foo(Vector) {} +// CHECK: "\01?foo@@YAXQAN@Z" + +void foo_const(const Vector) {} +// CHECK: "\01?foo_const@@YAXQBN@Z" + +void foo_volatile(volatile Vector) {} +// CHECK: "\01?foo_volatile@@YAXQCN@Z" + +void foo(Vector*, const Vector, const double) {} +// CHECK: "\01?foo@@YAXPAY02NQBNN@Z" diff --git a/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp b/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp index a5d03b343526d..63bc4a9eb3c66 100644 --- a/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp +++ b/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp @@ -167,7 +167,4 @@ function_pointer* g3() { return 0; } // CHECK: "\01?g3@@YAPAP6AHH@ZXZ" const function_pointer* g4() { return 0; } -// The mangling of g4 is currently "\01?g4@@YAPQ6AHH@ZXZ" which is wrong. -// This looks related to http://llvm.org/PR13444 -// FIXME: replace CHECK-NOT with CHECK once it is fixed. -// CHECK-NOT: "\01?g4@@YAPBQ6AHH@ZXZ" +// CHECK: "\01?g4@@YAPBQ6AHH@ZXZ" diff --git a/test/CodeGenCXX/mangle-ms-template-callback.cpp b/test/CodeGenCXX/mangle-ms-template-callback.cpp new file mode 100644 index 0000000000000..687814875132b --- /dev/null +++ b/test/CodeGenCXX/mangle-ms-template-callback.cpp @@ -0,0 +1,72 @@ +// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s + +template<typename Signature> +class C; + +template<typename Ret> +class C<Ret(void)> {}; +typedef C<void(void)> C0; + +template<typename Ret, typename Arg1> +class C<Ret(Arg1)> {}; + +template<typename Ret, typename Arg1, typename Arg2> +class C<Ret(Arg1, Arg2)> {}; + +C0 callback_void; +// CHECK: "\01?callback_void@@3V?$C@$$A6AXXZ@@A" + +volatile C0 callback_void_volatile; +// CHECK: "\01?callback_void_volatile@@3V?$C@$$A6AXXZ@@C" + +class Type {}; + +C<int(void)> callback_int; +// CHECK: "\01?callback_int@@3V?$C@$$A6AHXZ@@A" +C<Type(void)> callback_Type; +// CHECK: "\01?callback_Type@@3V?$C@$$A6A?AVType@@XZ@@A" + +C<void(int)> callback_void_int; +// CHECK: "\01?callback_void_int@@3V?$C@$$A6AXH@Z@@A" +C<int(int)> callback_int_int; +// CHECK: "\01?callback_int_int@@3V?$C@$$A6AHH@Z@@A" +C<void(Type)> callback_void_Type; +// CHECK: "\01?callback_void_Type@@3V?$C@$$A6AXVType@@@Z@@A" + +void foo(C0 c) {} +// CHECK: "\01?foo@@YAXV?$C@$$A6AXXZ@@@Z" + +// Here be dragons! +// Let's face the magic of template partial specialization... + +void function(C<void(void)>) {} +// CHECK: "\01?function@@YAXV?$C@$$A6AXXZ@@@Z" + +template<typename Ret> class C<Ret(*)(void)> {}; +void function_pointer(C<void(*)(void)>) {} +// CHECK: "\01?function_pointer@@YAXV?$C@P6AXXZ@@@Z" + +// Block equivalent to the previous definitions. +template<typename Ret> class C<Ret(^)(void)> {}; +void block(C<void(^)(void)>) {} +// CHECK: "\01?block@@YAXV?$C@P_EAXXZ@@@Z" +// FYI blocks are not present in MSVS, so we're free to choose the spec. + +template<typename T> class C<void (T::*)(void)> {}; +class Z { + public: + void method() {} +}; +void member_pointer(C<void (Z::*)(void)>) {} +// CHECK: "\01?member_pointer@@YAXV?$C@P8Z@@AEXXZ@@@Z" + +template<typename T> void bar(T) {} + +void call_bar() { + bar<int (*)(int)>(0); +// CHECK: "\01??$bar@P6AHH@Z@@YAXP6AHH@Z@Z" + + bar<int (^)(int)>(0); +// CHECK: "\01??$bar@P_EAHH@Z@@YAXP_EAHH@Z@Z" +// FYI blocks are not present in MSVS, so we're free to choose the spec. +} diff --git a/test/CodeGenCXX/mangle-ms-templates.cpp b/test/CodeGenCXX/mangle-ms-templates.cpp index 977ef353dabc6..e16fe936bc2ec 100644 --- a/test/CodeGenCXX/mangle-ms-templates.cpp +++ b/test/CodeGenCXX/mangle-ms-templates.cpp @@ -48,12 +48,24 @@ void template_mangling() { // CHECK: call {{.*}} @"\01??0?$BoolTemplate@$00@@QAE@XZ" // CHECK: call {{.*}} @"\01??$Foo@H@?$BoolTemplate@$00@@QAEXH@Z" + IntTemplate<0> zero; +// CHECK: call {{.*}} @"\01??0?$IntTemplate@$0A@@@QAE@XZ" + IntTemplate<5> five; // CHECK: call {{.*}} @"\01??0?$IntTemplate@$04@@QAE@XZ" IntTemplate<11> eleven; // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0L@@@QAE@XZ" + IntTemplate<256> _256; +// CHECK: call {{.*}} @"\01??0?$IntTemplate@$0BAA@@@QAE@XZ" + + IntTemplate<513> _513; +// CHECK: call {{.*}} @"\01??0?$IntTemplate@$0CAB@@@QAE@XZ" + + IntTemplate<1026> _1026; +// CHECK: call {{.*}} @"\01??0?$IntTemplate@$0EAC@@@QAE@XZ" + IntTemplate<65535> ffff; // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0PPPP@@@QAE@XZ" } diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp index f392c1701edd4..0edb4b4339aa6 100644 --- a/test/CodeGenCXX/mangle-ms.cpp +++ b/test/CodeGenCXX/mangle-ms.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fms-extensions -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s +// RUN: %clang_cc1 -fms-compatibility -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s // CHECK: @"\01?a@@3HA" // CHECK: @"\01?b@N@@3HA" @@ -7,16 +8,17 @@ // CHECK: @"\01?e@foo@@1JC" // CHECK: @"\01?f@foo@@2DD" // CHECK: @"\01?g@bar@@2HA" -// CHECK: @"\01?h@@3QAHA" +// CHECK: @"\01?h1@@3QAHA" +// CHECK: @"\01?h2@@3QBHB" // CHECK: @"\01?i@@3PAY0BE@HA" // CHECK: @"\01?j@@3P6GHCE@ZA" // CHECK: @"\01?k@@3PTfoo@@DA" // CHECK: @"\01?l@@3P8foo@@AEHH@ZA" // CHECK: @"\01?color1@@3PANA" +// CHECK: @"\01?color2@@3QBNB" -// FIXME: The following three tests currently fail, see PR13182. +// FIXME: The following three tests currently fail, see http://llvm.org/PR13182 // Replace "CHECK-NOT" with "CHECK" when it is fixed. -// CHECK-NOT: @"\01?color2@@3QBNB" // CHECK-NOT: @"\01?color3@@3QAY02$$CBNA" // CHECK-NOT: @"\01?color4@@3QAY02$$CBNA" @@ -87,7 +89,8 @@ const volatile char foo::f = 'C'; int bar::g; -extern int * const h = &a; +extern int * const h1 = &a; +extern const int * const h2 = &a; int i[10][20]; @@ -107,6 +110,7 @@ bool __fastcall beta(long long a, wchar_t b) throw(signed char, unsigned char) { } // CHECK: @"\01?alpha@@YGXMN@Z" +// X64: @"\01?alpha@@YAXMN@Z" // Make sure tag-type mangling works. void gamma(class foo, struct bar, union baz, enum quux) {} @@ -128,6 +132,10 @@ void zeta(int (*)(int, int)) {} void eta(int (^)(int, int)) {} // CHECK: @"\01?eta@@YAXP_EAHHH@Z@Z" +typedef int theta_arg(int,int); +void theta(theta_arg^ block) {} +// CHECK: @"\01?theta@@YAXP_EAHHH@Z@Z" + void operator_new_delete() { char *ptr = new char; // CHECK: @"\01??2@YAPAXI@Z" @@ -147,7 +155,7 @@ void (redundant_parens)(); void redundant_parens_use() { redundant_parens(); } // CHECK: @"\01?redundant_parens@@YAXXZ" -// PR13182, PR13047 +// PR13047 typedef double RGB[3]; RGB color1; extern const RGB color2 = {}; @@ -162,3 +170,24 @@ E fooE() { return E(); } class X {}; // CHECK: "\01?fooX@@YA?AVX@@XZ" X fooX() { return X(); } + +namespace PR13182 { + extern char s0[]; + // CHECK: @"\01?s0@PR13182@@3PADA" + extern char s1[42]; + // CHECK: @"\01?s1@PR13182@@3PADA" + extern const char s2[]; + // CHECK: @"\01?s2@PR13182@@3QBDB" + extern const char s3[42]; + // CHECK: @"\01?s3@PR13182@@3QBDB" + extern volatile char s4[]; + // CHECK: @"\01?s4@PR13182@@3RCDC" + extern const volatile char s5[]; + // CHECK: @"\01?s5@PR13182@@3SDDD" + extern const char* const* s6; + // CHECK: @"\01?s6@PR13182@@3PBQBDB" + + char foo() { + return s0[0] + s1[0] + s2[0] + s3[0] + s4[0] + s5[0] + s6[0][0]; + } +} diff --git a/test/CodeGenCXX/mangle-nullptr-arg.cpp b/test/CodeGenCXX/mangle-nullptr-arg.cpp index 393de0b0ece94..07bf52fc9067e 100644 --- a/test/CodeGenCXX/mangle-nullptr-arg.cpp +++ b/test/CodeGenCXX/mangle-nullptr-arg.cpp @@ -11,3 +11,6 @@ template<int X::*pm> struct PM {}; // CHECK: define void @_Z5test22PMILM1Xi0EE void test2(PM<nullptr>) { } +// CHECK: define void @_Z5test316DependentTypePtrIPiLS0_0EE +template<typename T, T x> struct DependentTypePtr {}; +void test3(DependentTypePtr<int*,nullptr>) { } diff --git a/test/CodeGenCXX/mangle-template.cpp b/test/CodeGenCXX/mangle-template.cpp index 05c3a5851e4a1..15a85c7bd2e53 100644 --- a/test/CodeGenCXX/mangle-template.cpp +++ b/test/CodeGenCXX/mangle-template.cpp @@ -162,11 +162,23 @@ namespace test12 { void use() { // CHECK: define internal void @_ZN6test124testIFivEXadL_ZNS_L1fEvEEEEvv( test<int(), &f>(); - // CHECK: define internal void @_ZN6test124testIRFivEXadL_ZNS_L1fEvEEEEvv( + // CHECK: define internal void @_ZN6test124testIRFivELZNS_L1fEvEEEvv( test<int(&)(), f>(); // CHECK: define internal void @_ZN6test124testIPKiXadL_ZNS_L1nEEEEEvv( test<const int*, &n>(); - // CHECK: define internal void @_ZN6test124testIRKiXadL_ZNS_L1nEEEEEvv( + // CHECK: define internal void @_ZN6test124testIRKiLZNS_L1nEEEEvv( test<const int&, n>(); } } + +// rdar://problem/12072531 +// Test the boundary condition of minimal signed integers. +namespace test13 { + template <char c> char returnChar() { return c; } + template char returnChar<-128>(); + // CHECK: @_ZN6test1310returnCharILcn128EEEcv() + + template <short s> short returnShort() { return s; } + template short returnShort<-32768>(); + // CHECK: @_ZN6test1311returnShortILsn32768EEEsv() +} diff --git a/test/CodeGenCXX/mangle-valist.cpp b/test/CodeGenCXX/mangle-valist.cpp new file mode 100644 index 0000000000000..73fd58e75e8ac --- /dev/null +++ b/test/CodeGenCXX/mangle-valist.cpp @@ -0,0 +1,44 @@ +#include "stdarg.h" + +namespace test1 { + void test1(const char *fmt, va_list ap) { + } +} + +class Test2 { +public: + void test2(const char *fmt, va_list ap); +}; + +void Test2::test2(const char *fmt, va_list ap) { +} + +// RUN: %clang_cc1 %s -emit-llvm -o - \ +// RUN: -triple armv7-unknown-linux \ +// RUN: | FileCheck -check-prefix=MANGLE-ARM-AAPCS %s +// CHECK-MANGLE-ARM-AAPCS: @_ZN5test15test1EPKcSt9__va_list +// CHECK-MANGLE-ARM-AAPCS: @_ZN5Test25test2EPKcSt9__va_list + +// RUN: %clang_cc1 %s -emit-llvm -o - \ +// RUN: -triple armv7-unknown-linux -target-abi apcs-gnu \ +// RUN: | FileCheck -check-prefix=MANGLE-ARM-APCS %s +// CHECK-MANGLE-ARM-APCS: @_ZN5test15test1EPKcPv +// CHECK-MANGLE-ARM-APCS: @_ZN5Test25test2EPKcPv + +// RUN: %clang_cc1 %s -emit-llvm -o - \ +// RUN: -triple mipsel-unknown-linux \ +// RUN: | FileCheck -check-prefix=MANGLE-MIPSEL %s +// CHECK-MANGLE-MIPSEL: @_ZN5test15test1EPKcPv +// CHECK-MANGLE-MIPSEL: @_ZN5Test25test2EPKcPv + +// RUN: %clang_cc1 %s -emit-llvm -o - \ +// RUN: -triple i686-unknown-linux \ +// RUN: | FileCheck -check-prefix=MANGLE-X86 %s +// CHECK-MANGLE-X86: @_ZN5test15test1EPKcPc +// CHECK-MANGLE-X86: @_ZN5Test25test2EPKcPc + +// RUN: %clang_cc1 %s -emit-llvm -o - \ +// RUN: -triple x86_64-unknown-linux \ +// RUN: | FileCheck -check-prefix=MANGLE-X86-64 %s +// CHECK-MANGLE-X86-64: @_ZN5test15test1EPKcP13__va_list_tag +// CHECK-MANGLE-X86-64: @_ZN5Test25test2EPKcP13__va_list_tag diff --git a/test/CodeGenCXX/member-alignment.cpp b/test/CodeGenCXX/member-alignment.cpp index 8e120f7125073..78026d4e0419c 100644 --- a/test/CodeGenCXX/member-alignment.cpp +++ b/test/CodeGenCXX/member-alignment.cpp @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s -// XFAIL: arm,powerpc // rdar://7268289 diff --git a/test/CodeGenCXX/member-call-parens.cpp b/test/CodeGenCXX/member-call-parens.cpp index 2054137fe9411..3def43ebc05d2 100644 --- a/test/CodeGenCXX/member-call-parens.cpp +++ b/test/CodeGenCXX/member-call-parens.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -emit-llvm-only -verify %s +// expected-no-diagnostics struct A { int a(); }; typedef int B; diff --git a/test/CodeGenCXX/member-functions.cpp b/test/CodeGenCXX/member-functions.cpp index b95763c0ffac3..1310eb08d3d1a 100644 --- a/test/CodeGenCXX/member-functions.cpp +++ b/test/CodeGenCXX/member-functions.cpp @@ -35,6 +35,9 @@ struct S { static void g() { } static void f(); + + // RUN: grep "define linkonce_odr void @_ZN1S1vEv.*unnamed_addr" %t + virtual void v() {} }; // RUN: grep "define void @_ZN1S1fEv" %t diff --git a/test/CodeGenCXX/member-init-assignment.cpp b/test/CodeGenCXX/member-init-assignment.cpp index 84c4a36fe2dba..acc7084670021 100644 --- a/test/CodeGenCXX/member-init-assignment.cpp +++ b/test/CodeGenCXX/member-init-assignment.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple i386-unknown-unknown -emit-llvm -o - | FileCheck %s // PR7291 struct Foo { diff --git a/test/CodeGenCXX/member-init-struct.cpp b/test/CodeGenCXX/member-init-struct.cpp index 688d92d74b8ea..d509b0ebac289 100644 --- a/test/CodeGenCXX/member-init-struct.cpp +++ b/test/CodeGenCXX/member-init-struct.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -emit-llvm-only -verify +// expected-no-diagnostics struct A {int a;}; struct B {float a;}; diff --git a/test/CodeGenCXX/member-init-union.cpp b/test/CodeGenCXX/member-init-union.cpp index 2c50e18b6ffa8..be171a365b011 100644 --- a/test/CodeGenCXX/member-init-union.cpp +++ b/test/CodeGenCXX/member-init-union.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -emit-llvm-only -verify +// expected-no-diagnostics union x { int a; diff --git a/test/CodeGenCXX/microsoft-abi-constructors.cpp b/test/CodeGenCXX/microsoft-abi-constructors.cpp index ac27f13308d80..89731ff38e976 100644 --- a/test/CodeGenCXX/microsoft-abi-constructors.cpp +++ b/test/CodeGenCXX/microsoft-abi-constructors.cpp @@ -9,13 +9,16 @@ class A { void no_contstructor_destructor_infinite_recursion() { A a; -// Make sure that the constructor doesn't call itself: -// CHECK: define {{.*}} @"\01??0A@@QAE@XZ" -// CHECK-NOT: call void @"\01??0A@@QAE@XZ" -// CHECK: ret +// CHECK: define linkonce_odr x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ"(%class.A* %this) +// CHECK: [[THIS_ADDR:%[.0-9A-Z_a-z]+]] = alloca %class.A*, align 4 +// CHECK-NEXT: store %class.A* %this, %class.A** [[THIS_ADDR]], align 4 +// CHECK-NEXT: [[T1:%[.0-9A-Z_a-z]+]] = load %class.A** [[THIS_ADDR]] +// CHECK-NEXT: ret %class.A* [[T1]] +// CHECK-NEXT: } // Make sure that the destructor doesn't call itself: // CHECK: define {{.*}} @"\01??1A@@QAE@XZ" // CHECK-NOT: call void @"\01??1A@@QAE@XZ" // CHECK: ret } + diff --git a/test/CodeGenCXX/microsoft-abi-default-cc.cpp b/test/CodeGenCXX/microsoft-abi-default-cc.cpp new file mode 100644 index 0000000000000..d0d25ce5efb1b --- /dev/null +++ b/test/CodeGenCXX/microsoft-abi-default-cc.cpp @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck -check-prefix GCABI %s +// RUN: %clang_cc1 -emit-llvm %s -o - -DMS_ABI -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck -check-prefix MSABI %s + +#ifdef MS_ABI +# define METHOD_CC __thiscall +#else +# define METHOD_CC __attribute__ ((cdecl)) +#endif + +// Test that it's OK to have multiple function declarations with the default CC +// both mentioned explicitly and implied. +void foo(); +void __cdecl foo(); +void __cdecl foo() {} +// GCABI: define void @_Z3foov() +// MSABI: define void @"\01?foo@@YAXXZ" + +void __cdecl bar(); +void bar(); +void bar() {} +// GCABI: define void @_Z3barv() +// MSABI: define void @"\01?bar@@YAXXZ" + +// Test that it's OK to mark either the method declaration or method definition +// with a default CC explicitly. +class A { +public: + void baz(); + void METHOD_CC qux(); + + void static_baz(); + void __cdecl static_qux(); +}; + +void METHOD_CC A::baz() {} +// GCABI: define void @_ZN1A3bazEv +// MSABI: define x86_thiscallcc void @"\01?baz@A@@QAEXXZ" +void A::qux() {} +// GCABI: define void @_ZN1A3quxEv +// MSABI: define x86_thiscallcc void @"\01?qux@A@@QAEXXZ" + +void __cdecl static_baz() {} +// GCABI: define void @_Z10static_bazv +// MSABI: define void @"\01?static_baz@@YAXXZ" +void static_qux() {} +// GCABI: define void @_Z10static_quxv +// MSABI: define void @"\01?static_qux@@YAXXZ" diff --git a/test/CodeGenCXX/microsoft-abi-methods.cpp b/test/CodeGenCXX/microsoft-abi-methods.cpp index 6b7f00495d2b9..c996ba5b8473e 100644 --- a/test/CodeGenCXX/microsoft-abi-methods.cpp +++ b/test/CodeGenCXX/microsoft-abi-methods.cpp @@ -71,8 +71,8 @@ void constructors() { Child c; // Make sure that the Base constructor call in the Child constructor uses // the right calling convention: -// CHECK: define linkonce_odr x86_thiscallcc void @"\01??0Child@@QAE@XZ" -// CHECK: call x86_thiscallcc void @"\01??0Base@@QAE@XZ" +// CHECK: define linkonce_odr x86_thiscallcc %class.Child* @"\01??0Child@@QAE@XZ" +// CHECK: %{{[.0-9A-Z_a-z]+}} = call x86_thiscallcc %class.Base* @"\01??0Base@@QAE@XZ" // CHECK: ret // Make sure that the Base destructor call in the Child denstructor uses @@ -85,5 +85,5 @@ void constructors() { // CHECK: define linkonce_odr x86_thiscallcc void @"\01??1Base@@QAE@XZ" // Make sure that the Base constructor definition uses the right CC: -// CHECK: define linkonce_odr x86_thiscallcc void @"\01??0Base@@QAE@XZ" +// CHECK: define linkonce_odr x86_thiscallcc %class.Base* @"\01??0Base@@QAE@XZ" } diff --git a/test/CodeGenCXX/microsoft-abi-static-initializers.cpp b/test/CodeGenCXX/microsoft-abi-static-initializers.cpp index d8b789943a430..448f1eeeb91f7 100644 --- a/test/CodeGenCXX/microsoft-abi-static-initializers.cpp +++ b/test/CodeGenCXX/microsoft-abi-static-initializers.cpp @@ -6,7 +6,7 @@ struct S { } s; // CHECK: define internal void [[INIT_s:@.*global_var.*]] nounwind -// CHECK: call x86_thiscallcc void @"\01??0S@@QAE@XZ" +// CHECK: %{{[.0-9A-Z_a-z]+}} = call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ" // CHECK: call i32 @atexit(void ()* @"__dtor_\01?s@@3US@@A") // CHECK: ret void @@ -34,11 +34,11 @@ void force_usage() { } // CHECK: define internal void [[INIT_foo:@.*global_var.*]] nounwind -// CHECK: call x86_thiscallcc void @"\01??0A@@QAE@XZ" +// CHECK: %{{[.0-9A-Z_a-z]+}} = call x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ" // CHECK: call i32 @atexit(void ()* [[FOO_DTOR:@"__dtor_.*foo@.*]]) // CHECK: ret void -// CHECK: define linkonce_odr x86_thiscallcc void @"\01??0A@@QAE@XZ" +// CHECK: define linkonce_odr x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ" // CHECK: define linkonce_odr x86_thiscallcc void @"\01??1A@@QAE@XZ" diff --git a/test/CodeGenCXX/microsoft-interface.cpp b/test/CodeGenCXX/microsoft-interface.cpp new file mode 100644 index 0000000000000..0b44bab738545 --- /dev/null +++ b/test/CodeGenCXX/microsoft-interface.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -std=c++11 -fms-extensions -Wno-microsoft -triple=i386-pc-win32 -emit-llvm %s -o - | FileCheck %s + +__interface I { + int test() { + return 1; + } +}; + +struct S : I { + virtual int test() override { + return I::test(); + } +}; + +int fn() { + S s; + return s.test(); +} + +// CHECK: @_ZTV1S = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1S to i8*), i8* bitcast (i32 (%struct.S*)* @_ZN1S4testEv to i8*)] + +// CHECK: define i32 @_Z2fnv() +// CHECK: call void @_ZN1SC1Ev(%struct.S* %s) +// CHECK: %{{[.0-9A-Z_a-z]+}} = call i32 @_ZN1S4testEv(%struct.S* %s) + +// CHECK: define linkonce_odr void @_ZN1SC1Ev(%struct.S* %this) +// CHECK: call void @_ZN1SC2Ev(%struct.S* %{{[.0-9A-Z_a-z]+}}) + +// CHECK: define linkonce_odr i32 @_ZN1S4testEv(%struct.S* %this) +// CHECK: %{{[.0-9A-Z_a-z]+}} = call i32 @_ZN1I4testEv(%__interface.I* %{{[.0-9A-Z_a-z]+}}) + +// CHECK: define linkonce_odr i32 @_ZN1I4testEv(%__interface.I* %this) +// CHECK: ret i32 1 + +// CHECK: define linkonce_odr void @_ZN1SC2Ev(%struct.S* %this) +// CHECK: call void @_ZN1IC2Ev(%__interface.I* %{{[.0-9A-Z_a-z]+}}) +// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1S, i64 0, i64 2), i8*** %{{[.0-9A-Z_a-z]+}} + +// CHECK: define linkonce_odr void @_ZN1IC2Ev(%__interface.I* %this) +// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1I, i64 0, i64 2), i8*** %{{[.0-9A-Z_a-z]+}} + +// CHECK-NOT: define linkonce_odr %__interface.I* @_ZN1IaSERKS_(%__interface.I* %this, %__interface.I*) +// CHECK-NOT: define linkonce_odr %__interface.I* @_ZN1IaSEOS_(%__interface.I* %this, %__interface.I*) diff --git a/test/CodeGenCXX/microsoft-uuidof-unsupported-target.cpp b/test/CodeGenCXX/microsoft-uuidof-unsupported-target.cpp new file mode 100644 index 0000000000000..4f68aa34772c9 --- /dev/null +++ b/test/CodeGenCXX/microsoft-uuidof-unsupported-target.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-macosx10.8.0 -fms-extensions -verify + +typedef struct _GUID +{ + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8]; +} GUID; + +struct __declspec(uuid("87654321-4321-4321-4321-ba0987654321")) S { }; + +GUID g = __uuidof(S); // expected-error {{__uuidof codegen is not supported on this architecture}} diff --git a/test/CodeGenCXX/microsoft-uuidof.cpp b/test/CodeGenCXX/microsoft-uuidof.cpp new file mode 100644 index 0000000000000..8eeb4490ac110 --- /dev/null +++ b/test/CodeGenCXX/microsoft-uuidof.cpp @@ -0,0 +1,72 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -fms-extensions | FileCheck %s + +typedef struct _GUID +{ + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8]; +} GUID; + +struct __declspec(uuid("12345678-1234-1234-1234-1234567890ab")) S1 { } s1; +struct __declspec(uuid("87654321-4321-4321-4321-ba0987654321")) S2 { }; + +// This gets initialized in a static initializer. +// CHECK: @g = global %struct._GUID zeroinitializer, align 4 +GUID g = __uuidof(S1); + +// First global use of __uuidof(S1) forces the creation of the global. +// CHECK: @__uuid_12345678-1234-1234-1234-1234567890ab = private unnamed_addr constant %struct._GUID { i32 305419896, i16 4660, i16 4660, [8 x i8] c"\124\124Vx\90\AB" } +// CHECK: @gr = constant %struct._GUID* @__uuid_12345678-1234-1234-1234-1234567890ab, align 4 +const GUID& gr = __uuidof(S1); + +// CHECK: @gp = global %struct._GUID* @__uuid_12345678-1234-1234-1234-1234567890ab, align 4 +const GUID* gp = &__uuidof(S1); + +// Special case: _uuidof(0) +// CHECK: @zeroiid = constant %struct._GUID* @__uuid_00000000-0000-0000-0000-000000000000, align 4 +const GUID& zeroiid = __uuidof(0); + +// __uuidof(S2) hasn't been used globally yet, so it's emitted when it's used +// in a function and is emitted at the end of the globals section. +// CHECK: @__uuid_87654321-4321-4321-4321-ba0987654321 = private unnamed_addr constant %struct._GUID { i32 -2023406815, i16 17185, i16 17185, [8 x i8] c"C!\BA\09\87eC!" } + +// The static initializer for g. +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* bitcast (%struct._GUID* @g to i8*), i8* bitcast (%struct._GUID* @__uuid_12345678-1234-1234-1234-1234567890ab to i8*), i32 16, i32 4, i1 false) + +void fun() { + // CHECK: %s1_1 = alloca %struct._GUID, align 4 + // CHECK: %s1_2 = alloca %struct._GUID, align 4 + // CHECK: %s1_3 = alloca %struct._GUID, align 4 + + // CHECK: [[U1:%.+]] = bitcast %struct._GUID* %s1_1 to i8* + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[U1]], i8* bitcast (%struct._GUID* @__uuid_12345678-1234-1234-1234-1234567890ab to i8*), i32 16, i32 4, i1 false) + GUID s1_1 = __uuidof(S1); + + // CHECK: [[U2:%.+]] = bitcast %struct._GUID* %s1_2 to i8* + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[U2]], i8* bitcast (%struct._GUID* @__uuid_12345678-1234-1234-1234-1234567890ab to i8*), i32 16, i32 4, i1 false) + GUID s1_2 = __uuidof(S1); + + // CHECK: [[U3:%.+]] = bitcast %struct._GUID* %s1_3 to i8* + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[U3]], i8* bitcast (%struct._GUID* @__uuid_12345678-1234-1234-1234-1234567890ab to i8*), i32 16, i32 4, i1 false) + GUID s1_3 = __uuidof(s1); +} + +void gun() { + // CHECK: %s2_1 = alloca %struct._GUID, align 4 + // CHECK: %s2_2 = alloca %struct._GUID, align 4 + // CHECK: %r = alloca %struct._GUID*, align 4 + // CHECK: %p = alloca %struct._GUID*, align 4 + // CHECK: %zeroiid = alloca %struct._GUID*, align 4 + GUID s2_1 = __uuidof(S2); + GUID s2_2 = __uuidof(S2); + + // CHECK: store %struct._GUID* @__uuid_87654321-4321-4321-4321-ba0987654321, %struct._GUID** %r, align 4 + const GUID& r = __uuidof(S2); + // CHECK: store %struct._GUID* @__uuid_87654321-4321-4321-4321-ba0987654321, %struct._GUID** %p, align 4 + const GUID* p = &__uuidof(S2); + + // Special case _uuidof(0), local scope version. + // CHECK: store %struct._GUID* @__uuid_00000000-0000-0000-0000-000000000000, %struct._GUID** %zeroiid, align 4 + const GUID& zeroiid = __uuidof(0); +} diff --git a/test/CodeGenCXX/new-operator-phi.cpp b/test/CodeGenCXX/new-operator-phi.cpp index 49859acf4fa60..641734d223ad7 100644 --- a/test/CodeGenCXX/new-operator-phi.cpp +++ b/test/CodeGenCXX/new-operator-phi.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -emit-llvm-only -verify %s +// expected-no-diagnostics // PR5454 #include <stddef.h> diff --git a/test/CodeGenCXX/new.cpp b/test/CodeGenCXX/new.cpp index 8d9f641ba1cc9..e0523909a3dbf 100644 --- a/test/CodeGenCXX/new.cpp +++ b/test/CodeGenCXX/new.cpp @@ -250,3 +250,13 @@ namespace PR11757 { // CHECK-NEXT: call void @_ZN7PR117571XC1Ev({{.*}}* [[CASTED]]) // CHECK-NEXT: ret {{.*}} [[CASTED]] } + +namespace PR13380 { + struct A { A() {} }; + struct B : public A { int x; }; + // CHECK: define i8* @_ZN7PR133801fEv + // CHECK: call noalias i8* @_Znam( + // CHECK: call void @llvm.memset.p0i8 + // CHECK-NEXT: call void @_ZN7PR133801BC1Ev + void* f() { return new B[2](); } +} diff --git a/test/CodeGenCXX/nrvo.cpp b/test/CodeGenCXX/nrvo.cpp index 2feaf682413cb..8ff7dd7d09093 100644 --- a/test/CodeGenCXX/nrvo.cpp +++ b/test/CodeGenCXX/nrvo.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -emit-llvm -O1 -o - %s | FileCheck %s -// RUN: %clang_cc1 -emit-llvm -O1 -fcxx-exceptions -fexceptions -o - %s | FileCheck --check-prefix=CHECK-EH %s +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -o - %s | FileCheck --check-prefix=CHECK-EH %s // Test code generation for the named return value optimization. class X { diff --git a/test/CodeGenCXX/override-layout.cpp b/test/CodeGenCXX/override-layout.cpp index d432885c58484..aba4c9179a6d2 100644 --- a/test/CodeGenCXX/override-layout.cpp +++ b/test/CodeGenCXX/override-layout.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fdump-record-layouts-simple %s 2> %t.layouts // RUN: %clang_cc1 -fdump-record-layouts-simple %s > %t.before 2>&1 // RUN: %clang_cc1 -DPACKED= -DALIGNED16= -fdump-record-layouts-simple -foverride-record-layout=%t.layouts %s > %t.after 2>&1 -// RUN: diff %t.before %t.after +// RUN: diff -u %t.before %t.after // RUN: FileCheck %s < %t.after // If not explicitly disabled, set PACKED to the packed attribute. @@ -54,11 +54,24 @@ struct PACKED X4 { X4(); }; +// CHECK: Type: struct X5 +struct PACKED X5 { + union { + long a; + long b; + }; + short l; + short r; +}; + void use_structs() { X0 x0s[sizeof(X0)]; X1 x1s[sizeof(X1)]; X2 x2s[sizeof(X2)]; X3 x3s[sizeof(X3)]; X4 x4s[sizeof(X4)]; + X5 x5s[sizeof(X5)]; x4s[1].a = 1; + x5s[1].a = 17; } + diff --git a/test/CodeGenCXX/pr12251.cpp b/test/CodeGenCXX/pr12251.cpp index a9920c073388d..f3f2ec417e39a 100644 --- a/test/CodeGenCXX/pr12251.cpp +++ b/test/CodeGenCXX/pr12251.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 %s -emit-llvm -O1 -relaxed-aliasing -fstrict-enums -std=c++11 -o - | FileCheck %s -// RUN: %clang_cc1 %s -emit-llvm -O1 -relaxed-aliasing -std=c++11 -o - | FileCheck --check-prefix=NO-STRICT-ENUMS %s +// RUN: %clang_cc1 %s -triple i386-unknown-unknown -emit-llvm -O1 -relaxed-aliasing -fstrict-enums -std=c++11 -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple i386-unknown-unknown -emit-llvm -O1 -relaxed-aliasing -std=c++11 -o - | FileCheck --check-prefix=NO-STRICT-ENUMS %s bool f(bool *x) { return *x; diff --git a/test/CodeGenCXX/pragma-visibility.cpp b/test/CodeGenCXX/pragma-visibility.cpp index 11a38c1d5fb96..0640d4244eba2 100644 --- a/test/CodeGenCXX/pragma-visibility.cpp +++ b/test/CodeGenCXX/pragma-visibility.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s #pragma GCC visibility push(hidden) struct x { diff --git a/test/CodeGenCXX/reference-bind-default-argument.cpp b/test/CodeGenCXX/reference-bind-default-argument.cpp index acce962b1953f..5cf279f62a185 100644 --- a/test/CodeGenCXX/reference-bind-default-argument.cpp +++ b/test/CodeGenCXX/reference-bind-default-argument.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -emit-llvm-only -verify +// expected-no-diagnostics struct A {}; struct B : A {}; diff --git a/test/CodeGenCXX/reference-init.cpp b/test/CodeGenCXX/reference-init.cpp index 9469c84eb5d04..d47b1f37489c7 100644 --- a/test/CodeGenCXX/reference-init.cpp +++ b/test/CodeGenCXX/reference-init.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -emit-llvm-only -verify %s +// expected-no-diagnostics struct XPTParamDescriptor {}; struct nsXPTParamInfo { diff --git a/test/CodeGenCXX/regparm.cpp b/test/CodeGenCXX/regparm.cpp index f0ebd2be41675..2196c798bf3e6 100644 --- a/test/CodeGenCXX/regparm.cpp +++ b/test/CodeGenCXX/regparm.cpp @@ -4,3 +4,35 @@ // CHECK: _Z3fooRi(i32* inreg void __attribute__ ((regparm (1))) foo(int &a) { } + +struct S1 { + int x; + S1(const S1 &y); +}; + +void __attribute__((regparm(3))) foo2(S1 a, int b); +// CHECK: declare void @_Z4foo22S1i(%struct.S1* inreg, i32 inreg) +void bar2(S1 a, int b) { + foo2(a, b); +} + +struct S2 { + int x; +}; + +void __attribute__((regparm(3))) foo3(struct S2 a, int b); +// CHECK: declare void @_Z4foo32S2i(i32 inreg, i32 inreg) +void bar3(struct S2 a, int b) { + foo3(a, b); +} + +struct S3 { + struct { + struct {} b[0]; + } a; +}; +__attribute((regparm(2))) void foo4(S3 a, int b); +// CHECK: declare void @_Z4foo42S3i(%struct.S3* byval align 4, i32 inreg) +void bar3(S3 a, int b) { + foo4(a, b); +} diff --git a/test/CodeGenCXX/reinterpret-cast.cpp b/test/CodeGenCXX/reinterpret-cast.cpp index dafa67529f770..63c5a2adc64da 100644 --- a/test/CodeGenCXX/reinterpret-cast.cpp +++ b/test/CodeGenCXX/reinterpret-cast.cpp @@ -1,4 +1,6 @@ // RUN: %clang_cc1 -emit-llvm -o - %s -std=c++11 +// REQUIRES: LP64 + void *f1(unsigned long l) { return reinterpret_cast<void *>(l); } diff --git a/test/CodeGenCXX/return.cpp b/test/CodeGenCXX/return.cpp new file mode 100644 index 0000000000000..43d40ae986ee8 --- /dev/null +++ b/test/CodeGenCXX/return.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm -O0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -O -o - %s | FileCheck %s --check-prefix=CHECK-OPT + +// CHECK: @_Z9no_return +// CHECK-OPT: @_Z9no_return +int no_return() { + // CHECK: call void @llvm.trap + // CHECK-NEXT: unreachable + + // CHECK-OPT-NOT: call void @llvm.trap + // CHECK-OPT: unreachable +} diff --git a/test/CodeGenCXX/static-assert.cpp b/test/CodeGenCXX/static-assert.cpp index 53dc9a73805f6..ff82f6dc54909 100644 --- a/test/CodeGenCXX/static-assert.cpp +++ b/test/CodeGenCXX/static-assert.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -emit-llvm -o - -std=c++11 -verify +// expected-no-diagnostics static_assert(true, ""); diff --git a/test/CodeGenCXX/static-init-2.cpp b/test/CodeGenCXX/static-init-2.cpp index 768e6de92c0f0..354fcd4dda538 100644 --- a/test/CodeGenCXX/static-init-2.cpp +++ b/test/CodeGenCXX/static-init-2.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -emit-llvm-only -verify %s +// expected-no-diagnostics // Make sure we don't crash generating y; its value is constant, but the // initializer has side effects, so EmitConstantExpr should fail. diff --git a/test/CodeGenCXX/switch-case-folding-2.cpp b/test/CodeGenCXX/switch-case-folding-2.cpp index 7c0283fa2a529..930bfeb64d8d7 100644 --- a/test/CodeGenCXX/switch-case-folding-2.cpp +++ b/test/CodeGenCXX/switch-case-folding-2.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s // CHECK that we don't crash. extern int printf(const char*, ...); diff --git a/test/CodeGenCXX/throw-expression-cleanup.cpp b/test/CodeGenCXX/throw-expression-cleanup.cpp index 0c41bc65bc3c2..e1ecd3804679f 100644 --- a/test/CodeGenCXX/throw-expression-cleanup.cpp +++ b/test/CodeGenCXX/throw-expression-cleanup.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -emit-llvm -fcxx-exceptions -fexceptions -std=c++11 -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple x86_64-none-linux-gnu -emit-llvm -fcxx-exceptions -fexceptions -std=c++11 -o - | FileCheck %s // PR13359 struct X { diff --git a/test/CodeGenCXX/throw-expression-dtor.cpp b/test/CodeGenCXX/throw-expression-dtor.cpp index 0de6683f88d11..cb4a6c69bdddf 100644 --- a/test/CodeGenCXX/throw-expression-dtor.cpp +++ b/test/CodeGenCXX/throw-expression-dtor.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -emit-llvm-only -verify -fcxx-exceptions -fexceptions +// expected-no-diagnostics // PR7281 class A { diff --git a/test/CodeGenCXX/throw-expressions.cpp b/test/CodeGenCXX/throw-expressions.cpp index 2515acb48ee72..f04185b23f1b9 100644 --- a/test/CodeGenCXX/throw-expressions.cpp +++ b/test/CodeGenCXX/throw-expressions.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -emit-llvm-only -verify %s -Wno-unreachable-code +// expected-no-diagnostics int val = 42; int& test1() { diff --git a/test/CodeGenCXX/thunk-linkonce-odr.cpp b/test/CodeGenCXX/thunk-linkonce-odr.cpp index 4f4d61d5a9a8a..82f2148e0b557 100644 --- a/test/CodeGenCXX/thunk-linkonce-odr.cpp +++ b/test/CodeGenCXX/thunk-linkonce-odr.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple i386-unknown-unknown -emit-llvm -o - | FileCheck %s // <rdar://problem/7929157> & <rdar://problem/8104369> struct A { diff --git a/test/CodeGenCXX/thunks.cpp b/test/CodeGenCXX/thunks.cpp index 04d0820da7a31..0659259c1799f 100644 --- a/test/CodeGenCXX/thunks.cpp +++ b/test/CodeGenCXX/thunks.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -fhidden-weak-vtables -emit-llvm -o - | FileCheck -check-prefix=HIDDEN %s +// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -fhidden-weak-vtables -emit-llvm -o - | FileCheck -check-prefix=HIDDEN %s namespace Test1 { @@ -301,6 +301,47 @@ namespace Test12 { // CHECK: getelementptr inbounds i8* {{.*}}, i64 8 } +// PR13832 +namespace Test13 { + struct B1 { + virtual B1 &foo1(); + }; + struct Pad1 { + virtual ~Pad1(); + }; + struct Proxy1 : Pad1, B1 { + virtual ~Proxy1(); + }; + struct D : virtual Proxy1 { + virtual ~D(); + virtual D &foo1(); + }; + D& D::foo1() { + return *this; + } + // CHECK: define {{.*}} @_ZTcvn8_n32_v8_n24_N6Test131D4foo1Ev + // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8 + // CHECK: getelementptr inbounds i8* {{.*}}, i64 -32 + // CHECK: getelementptr inbounds i8* {{.*}}, i64 -24 + // CHECK: getelementptr inbounds i8* {{.*}}, i64 8 + // CHECK: ret %"struct.Test13::D"* +} + +namespace Test14 { + class A { + virtual void f(); + }; + class B { + virtual void f(); + }; + class C : public A, public B { + virtual void f(); + }; + void C::f() { + } + // CHECK: define void @_ZThn8_N6Test141C1fEv({{.*}}) {{.*}} uwtable +} + /**** The following has to go at the end of the file ****/ // This is from Test5: diff --git a/test/CodeGenCXX/typeid-cxx11.cpp b/test/CodeGenCXX/typeid-cxx11.cpp index 940274e96575b..4e32d2dcb5a52 100644 --- a/test/CodeGenCXX/typeid-cxx11.cpp +++ b/test/CodeGenCXX/typeid-cxx11.cpp @@ -18,13 +18,15 @@ struct A { virtual ~A(); }; struct B : virtual A {}; struct C { int n; }; -// FIXME: check we produce a constant array for this, once we support IRGen of -// folded structs and arrays. +// CHECK: @_ZN5Test1L5itemsE = internal constant [4 x {{.*}}] [{{.*}} @_ZTIN5Test11AE {{.*}}, {{.*}}, {{.*}} @_ZN5Test19make_implINS_1AEEEPvv }, {{.*}} @_ZTIN5Test11BE {{.*}} @_ZN5Test19make_implINS_1BEEEPvv {{.*}} @_ZTIN5Test11CE {{.*}} @_ZN5Test19make_implINS_1CEEEPvv {{.*}} @_ZTIi {{.*}} @_ZN5Test19make_implIiEEPvv }] constexpr Item items[] = { item<A>("A"), item<B>("B"), item<C>("C"), item<int>("int") }; -// CHECK: @_ZN5Test11xE = constant %"class.std::type_info"* bitcast (i8** @_ZTIN5Test11AE to %"class.std::type_info"*), align 8 +// CHECK: @_ZN5Test11xE = constant %"class.std::type_info"* bitcast ({{.*}}* @_ZTIN5Test11AE to %"class.std::type_info"*), align 8 constexpr auto &x = items[0].ti; +// CHECK: @_ZN5Test11yE = constant %"class.std::type_info"* bitcast ({{.*}}* @_ZTIN5Test11BE to %"class.std::type_info"*), align 8 +constexpr auto &y = typeid(B{}); + } diff --git a/test/CodeGenCXX/unary-type-trait.cpp b/test/CodeGenCXX/unary-type-trait.cpp index a11c67e128909..3c6f9c03aa413 100644 --- a/test/CodeGenCXX/unary-type-trait.cpp +++ b/test/CodeGenCXX/unary-type-trait.cpp @@ -1,3 +1,4 @@ // RUN: %clang_cc1 -emit-llvm-only -verify %s +// expected-no-diagnostics bool a() { return __is_pod(int); } diff --git a/test/CodeGenCXX/virtual-operator-call.cpp b/test/CodeGenCXX/virtual-operator-call.cpp index 42d38e55a04f3..72d49c2300939 100644 --- a/test/CodeGenCXX/virtual-operator-call.cpp +++ b/test/CodeGenCXX/virtual-operator-call.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple i386-unknown-unknown -emit-llvm -o - | FileCheck %s struct A { virtual int operator-() = 0; diff --git a/test/CodeGenCXX/visibility-inlines-hidden.cpp b/test/CodeGenCXX/visibility-inlines-hidden.cpp index 2bb13485e922b..8519c8ced8950 100644 --- a/test/CodeGenCXX/visibility-inlines-hidden.cpp +++ b/test/CodeGenCXX/visibility-inlines-hidden.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-optzns | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-unknown -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-optzns | FileCheck %s // The trickery with optimization in the run line is to get IR // generation to emit available_externally function bodies, but not @@ -126,3 +126,12 @@ namespace test3 { // CHECK: define linkonce_odr hidden void @_ZN5test33fooEv // CHECK: define linkonce_odr hidden void @_ZN5test33zedIiEEvv } + +namespace test4 { + extern inline __attribute__ ((__gnu_inline__)) + void foo() {} + void bar() { + foo(); + } + // CHECK: define available_externally void @_ZN5test43fooE +} diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp index d7644b98ae094..1e831d2d8349a 100644 --- a/test/CodeGenCXX/vtable-layout.cpp +++ b/test/CodeGenCXX/vtable-layout.cpp @@ -43,6 +43,7 @@ // RUN: FileCheck --check-prefix=CHECK-42 %s < %t // RUN: FileCheck --check-prefix=CHECK-43 %s < %t // RUN: FileCheck --check-prefix=CHECK-44 %s < %t +// RUN: FileCheck --check-prefix=CHECK-45 %s < %t // For now, just verify this doesn't crash. namespace test0 { @@ -1727,3 +1728,23 @@ namespace Test38 { void *B::foo() { return 0; } } + +namespace Test39 { + struct A { + virtual void foo() = delete; + }; + + // CHECK-45: Vtable for 'Test39::B' (4 entries). + // CHECK-45-NEXT: 0 | offset_to_top (0) + // CHECK-45-NEXT: 1 | Test39::B RTTI + // CHECK-45-NEXT: -- (Test39::A, 0) vtable address -- + // CHECK-45-NEXT: -- (Test39::B, 0) vtable address -- + // CHECK-45-NEXT: 2 | void Test39::A::foo() [deleted] + // CHECK-45-NEXT: 3 | void Test39::B::foo2() + struct B: A { + virtual void foo2(); + }; + + void B::foo2() { + } +} diff --git a/test/CodeGenCXX/vtt-layout.cpp b/test/CodeGenCXX/vtt-layout.cpp index ace7b74b2deeb..abc2477f5b130 100644 --- a/test/CodeGenCXX/vtt-layout.cpp +++ b/test/CodeGenCXX/vtt-layout.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - | FileCheck %s // Test1::B should just have a single entry in its VTT, which points to the vtable. namespace Test1 { @@ -58,7 +58,29 @@ namespace Test4 { D d; } +namespace Test5 { + struct A { + virtual void f() = 0; + virtual void anchor(); + }; + + void A::anchor() { + } +} + +namespace Test6 { + struct A { + virtual void f() = delete; + virtual void anchor(); + }; + + void A::anchor() { + } +} + // CHECK: @_ZTTN5Test11BE = unnamed_addr constant [1 x i8*] [i8* bitcast (i8** getelementptr inbounds ([4 x i8*]* @_ZTVN5Test11BE, i64 0, i64 3) to i8*)] +// CHECK: @_ZTVN5Test51AE = unnamed_addr constant [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTIN5Test51AE to i8*), i8* bitcast (void ()* @__cxa_pure_virtual to i8*), i8* bitcast (void (%"struct.Test5::A"*)* @_ZN5Test51A6anchorEv to i8*)] +// CHECK: @_ZTVN5Test61AE = unnamed_addr constant [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTIN5Test61AE to i8*), i8* bitcast (void ()* @__cxa_deleted_virtual to i8*), i8* bitcast (void (%"struct.Test6::A"*)* @_ZN5Test61A6anchorEv to i8*)] // CHECK: @_ZTTN5Test41DE = linkonce_odr unnamed_addr constant [19 x i8*] [i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 10) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 12) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 15) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 18) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 17) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 20) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 1, i64 0) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test41DE40_NS_2V1E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test41DE40_NS_2V1E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 10) to i8*)] // CHECK: @_ZTTN5Test31DE = linkonce_odr unnamed_addr constant [13 x i8*] [i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 5) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE0_NS_2C1E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE0_NS_2C1E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 10) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 15) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 11) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 11) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 1, i64 0) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE64_NS_2V2E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE64_NS_2V2E, i64 0, i64 6) to i8*)] // CHECK: @_ZTTN5Test21CE = linkonce_odr unnamed_addr constant [2 x i8*] [i8* bitcast (i8** getelementptr inbounds ([5 x i8*]* @_ZTVN5Test21CE, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([5 x i8*]* @_ZTVN5Test21CE, i64 0, i64 4) to i8*)] |
