aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenCXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenCXX')
-rw-r--r--test/CodeGenCXX/anonymous-namespaces.cpp9
-rw-r--r--test/CodeGenCXX/anonymous-union-member-initializer.cpp32
-rw-r--r--test/CodeGenCXX/arm64-constructor-return.cpp2
-rw-r--r--test/CodeGenCXX/atomic-align.cpp30
-rw-r--r--test/CodeGenCXX/atomic-inline.cpp69
-rw-r--r--test/CodeGenCXX/blocks.cpp1
-rw-r--r--test/CodeGenCXX/catch-undef-behavior.cpp91
-rw-r--r--test/CodeGenCXX/cfi-blacklist.cpp16
-rw-r--r--test/CodeGenCXX/cfi-icall.cpp19
-rw-r--r--test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp29
-rw-r--r--test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp27
-rw-r--r--test/CodeGenCXX/cfi-vcall-no-trap.cpp15
-rw-r--r--test/CodeGenCXX/cxx11-extern-constexpr.cpp68
-rw-r--r--test/CodeGenCXX/cxx11-special-members.cpp4
-rw-r--r--test/CodeGenCXX/cxx1y-variable-template.cpp6
-rw-r--r--test/CodeGenCXX/cxx1z-aligned-allocation.cpp16
-rw-r--r--test/CodeGenCXX/cxx1z-copy-omission.cpp26
-rw-r--r--test/CodeGenCXX/cxx1z-inline-variables.cpp30
-rw-r--r--test/CodeGenCXX/cxx2a-destroying-delete.cpp161
-rw-r--r--test/CodeGenCXX/cxx2a-three-way-comparison.cpp29
-rw-r--r--test/CodeGenCXX/debug-info-anon-namespace.cpp18
-rw-r--r--test/CodeGenCXX/debug-info-codeview-display-name.cpp7
-rw-r--r--test/CodeGenCXX/debug-info-codeview-nested-types.cpp25
-rw-r--r--test/CodeGenCXX/debug-info-fwd-template-param.cpp20
-rw-r--r--test/CodeGenCXX/debug-info-inheriting-constructor.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-inlined.cpp50
-rw-r--r--test/CodeGenCXX/debug-info-method.cpp3
-rw-r--r--test/CodeGenCXX/debug-info-ms-abi.cpp9
-rw-r--r--test/CodeGenCXX/debug-info-nested-exprs.cpp202
-rw-r--r--test/CodeGenCXX/debug-info-static-member.cpp6
-rw-r--r--test/CodeGenCXX/debug-info-template-member.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-template.cpp6
-rw-r--r--test/CodeGenCXX/debug-info.cpp5
-rw-r--r--test/CodeGenCXX/default_calling_conv.cpp18
-rw-r--r--test/CodeGenCXX/dllexport-vtable-thunks.cpp23
-rw-r--r--test/CodeGenCXX/dllexport.cpp25
-rw-r--r--test/CodeGenCXX/dllimport-dtor-thunks.cpp49
-rw-r--r--test/CodeGenCXX/dllimport-members.cpp4
-rw-r--r--test/CodeGenCXX/dllimport.cpp11
-rw-r--r--test/CodeGenCXX/eh.cpp4
-rw-r--r--test/CodeGenCXX/exceptions-seh.cpp21
-rw-r--r--test/CodeGenCXX/explicit-instantiation.cpp19
-rw-r--r--test/CodeGenCXX/extern-section-attribute.cpp11
-rw-r--r--test/CodeGenCXX/finegrain-bitfield-access.cpp162
-rw-r--r--test/CodeGenCXX/float16-declarations.cpp149
-rw-r--r--test/CodeGenCXX/fp16-mangle.cpp4
-rw-r--r--test/CodeGenCXX/inline-dllexport-member.cpp2
-rw-r--r--test/CodeGenCXX/instrument-functions.cpp18
-rw-r--r--test/CodeGenCXX/invariant.group-for-vptrs.cpp2
-rw-r--r--test/CodeGenCXX/mangle-exprs.cpp32
-rw-r--r--test/CodeGenCXX/mangle-fail.cpp6
-rw-r--r--test/CodeGenCXX/mangle-lambdas.cpp28
-rw-r--r--test/CodeGenCXX/mangle-ms-cxx11.cpp7
-rw-r--r--test/CodeGenCXX/mangle.cpp3
-rw-r--r--test/CodeGenCXX/member-expr-references-variable.cpp104
-rw-r--r--test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp4
-rw-r--r--test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp43
-rw-r--r--test/CodeGenCXX/microsoft-abi-static-initializers.cpp2
-rw-r--r--test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp9
-rw-r--r--test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp1
-rw-r--r--test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp53
-rw-r--r--test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp10
-rw-r--r--test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp15
-rw-r--r--test/CodeGenCXX/microsoft-inaccessible-base.cpp20
-rw-r--r--test/CodeGenCXX/mingw-w64-exceptions.c22
-rw-r--r--test/CodeGenCXX/mingw-w64-seh-exceptions.cpp3
-rw-r--r--test/CodeGenCXX/ms-eh-personality.cpp20
-rw-r--r--test/CodeGenCXX/ms-inline-asm-return.cpp4
-rw-r--r--test/CodeGenCXX/new-overflow.cpp16
-rw-r--r--test/CodeGenCXX/new.cpp2
-rw-r--r--test/CodeGenCXX/noescape.cpp67
-rw-r--r--test/CodeGenCXX/pr29160.cpp41
-rw-r--r--test/CodeGenCXX/regcall.cpp12
-rw-r--r--test/CodeGenCXX/rtti-mingw64.cpp5
-rw-r--r--test/CodeGenCXX/runtime-dllstorage.cpp2
-rw-r--r--test/CodeGenCXX/sanitize-dtor-callback.cpp3
-rw-r--r--test/CodeGenCXX/static-init-wasm.cpp12
-rw-r--r--test/CodeGenCXX/static-initializer-branch-weights.cpp126
-rw-r--r--test/CodeGenCXX/stmtexpr.cpp2
-rw-r--r--test/CodeGenCXX/strict-vtable-pointers.cpp58
-rw-r--r--test/CodeGenCXX/tmp-md-nodes1.cpp18
-rw-r--r--test/CodeGenCXX/tmp-md-nodes2.cpp33
-rw-r--r--test/CodeGenCXX/ubsan-devirtualized-calls.cpp9
-rw-r--r--test/CodeGenCXX/ubsan-suppress-checks.cpp12
-rw-r--r--test/CodeGenCXX/ubsan-type-checks.cpp51
-rw-r--r--test/CodeGenCXX/ubsan-vtable-checks.cpp4
-rw-r--r--test/CodeGenCXX/virt-dtor-key.cpp4
-rw-r--r--test/CodeGenCXX/visibility-inlines-hidden.cpp13
-rw-r--r--test/CodeGenCXX/vla.cpp31
-rw-r--r--test/CodeGenCXX/vtable-available-externally.cpp4
-rw-r--r--test/CodeGenCXX/warn-padded-packed.cpp93
91 files changed, 2295 insertions, 266 deletions
diff --git a/test/CodeGenCXX/anonymous-namespaces.cpp b/test/CodeGenCXX/anonymous-namespaces.cpp
index abc700fef6c2..b2857ff41714 100644
--- a/test/CodeGenCXX/anonymous-namespaces.cpp
+++ b/test/CodeGenCXX/anonymous-namespaces.cpp
@@ -6,7 +6,8 @@ int f();
namespace {
// CHECK-1: @_ZN12_GLOBAL__N_11bE = internal global i32 0
- // CHECK-1: @_ZN12_GLOBAL__N_1L1cE = internal global i32 0
+ // CHECK-1: @_ZN12_GLOBAL__N_11cE = internal global i32 0
+ // CHECK-1: @_ZN12_GLOBAL__N_12c2E = internal global i32 0
// CHECK-1: @_ZN12_GLOBAL__N_11D1dE = internal global i32 0
// CHECK-1: @_ZN12_GLOBAL__N_11aE = internal global i32 0
int a = 0;
@@ -15,6 +16,12 @@ namespace {
static int c = f();
+ // Note, we can't use an 'L' mangling for c or c2 (like GCC does) based on
+ // the 'static' specifier, because the variable can be redeclared without it.
+ extern int c2;
+ int g() { return c2; }
+ static int c2 = f();
+
class D {
static int d;
};
diff --git a/test/CodeGenCXX/anonymous-union-member-initializer.cpp b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
index 69fa61c2155c..e8c4480b4906 100644
--- a/test/CodeGenCXX/anonymous-union-member-initializer.cpp
+++ b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
@@ -80,37 +80,37 @@ namespace PR10512 {
};
// CHECK-LABEL: define void @_ZN7PR105121AC2Ev
- // CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
- // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]]
- // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]*, [[A]]** [[THISADDR]]
+ // CHECK: [[THISADDR:%[a-zA-Z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
+ // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-Z0-9.]+]], [[A]]** [[THISADDR]]
+ // CHECK-NEXT: [[THIS1:%[a-zA-Z0-9.]+]] = load [[A]]*, [[A]]** [[THISADDR]]
// CHECK-NEXT: ret void
A::A() {}
// CHECK-LABEL: define void @_ZN7PR105121AC2Ei
- // CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
- // CHECK-NEXT: [[XADDR:%[a-zA-z0-9.]+]] = alloca i32
- // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]]
- // CHECK-NEXT: store i32 [[X:%[a-zA-z0-9.]+]], i32* [[XADDR]]
- // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]*, [[A]]** [[THISADDR]]
+ // CHECK: [[THISADDR:%[a-zA-Z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
+ // CHECK-NEXT: [[XADDR:%[a-zA-Z0-9.]+]] = alloca i32
+ // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-Z0-9.]+]], [[A]]** [[THISADDR]]
+ // CHECK-NEXT: store i32 [[X:%[a-zA-Z0-9.]+]], i32* [[XADDR]]
+ // CHECK-NEXT: [[THIS1:%[a-zA-Z0-9.]+]] = load [[A]]*, [[A]]** [[THISADDR]]
// CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
// CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
// CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
- // CHECK-NEXT: [[TMP:%[a-zA-z0-9.]+]] = load i32, i32* [[XADDR]]
+ // CHECK-NEXT: [[TMP:%[a-zA-Z0-9.]+]] = load i32, i32* [[XADDR]]
// CHECK-NEXT: store i32 [[TMP]]
// CHECK-NEXT: ret void
A::A(int x) : x(x) { }
// CHECK-LABEL: define void @_ZN7PR105121AC2El
- // CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
- // CHECK-NEXT: [[XADDR:%[a-zA-z0-9.]+]] = alloca i64
- // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]]
- // CHECK-NEXT: store i64 [[X:%[a-zA-z0-9.]+]], i64* [[XADDR]]
- // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]*, [[A]]** [[THISADDR]]
+ // CHECK: [[THISADDR:%[a-zA-Z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
+ // CHECK-NEXT: [[XADDR:%[a-zA-Z0-9.]+]] = alloca i64
+ // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-Z0-9.]+]], [[A]]** [[THISADDR]]
+ // CHECK-NEXT: store i64 [[X:%[a-zA-Z0-9.]+]], i64* [[XADDR]]
+ // CHECK-NEXT: [[THIS1:%[a-zA-Z0-9.]+]] = load [[A]]*, [[A]]** [[THISADDR]]
// CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
// CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 1}}
// CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
- // CHECK-NEXT: [[TMP:%[a-zA-z0-9.]+]] = load i64, i64* [[XADDR]]
- // CHECK-NEXT: [[CONV:%[a-zA-z0-9.]+]] = trunc i64 [[TMP]] to i32
+ // CHECK-NEXT: [[TMP:%[a-zA-Z0-9.]+]] = load i64, i64* [[XADDR]]
+ // CHECK-NEXT: [[CONV:%[a-zA-Z0-9.]+]] = trunc i64 [[TMP]] to i32
// CHECK-NEXT: store i32 [[CONV]]
// CHECK-NEXT: ret void
A::A(long y) : y(y) { }
diff --git a/test/CodeGenCXX/arm64-constructor-return.cpp b/test/CodeGenCXX/arm64-constructor-return.cpp
index 3adc1b7a280e..cbe66ab0e251 100644
--- a/test/CodeGenCXX/arm64-constructor-return.cpp
+++ b/test/CodeGenCXX/arm64-constructor-return.cpp
@@ -13,7 +13,7 @@ S::S() {
// CHECK: %struct.S* @_ZN1SC2Ev(%struct.S* returned %this)
// CHECK: %struct.S* @_ZN1SC1Ev(%struct.S* returned %this)
-// CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca %struct.S*
+// CHECK: [[THISADDR:%[a-zA-Z0-9.]+]] = alloca %struct.S*
// CHECK: store %struct.S* %this, %struct.S** [[THISADDR]]
// CHECK: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THISADDR]]
// CHECK: ret %struct.S* [[THIS1]]
diff --git a/test/CodeGenCXX/atomic-align.cpp b/test/CodeGenCXX/atomic-align.cpp
new file mode 100644
index 000000000000..9852ac38a6c8
--- /dev/null
+++ b/test/CodeGenCXX/atomic-align.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=x86_64-linux-gnu | FileCheck %s
+
+struct AM {
+ int f1, f2;
+};
+alignas(8) AM m;
+AM load1() {
+ AM am;
+ // m is declared to align to 8bytes, so generate load atomic instead
+ // of libcall.
+ // CHECK-LABEL: @_Z5load1v
+ // CHECK: load atomic {{.*}} monotonic
+ __atomic_load(&m, &am, 0);
+ return am;
+}
+
+struct BM {
+ int f1;
+ alignas(8) AM f2;
+};
+BM bm;
+AM load2() {
+ AM am;
+ // BM::f2 is declared to align to 8bytes, so generate load atomic instead
+ // of libcall.
+ // CHECK-LABEL: @_Z5load2v
+ // CHECK: load atomic {{.*}} monotonic
+ __atomic_load(&bm.f2, &am, 0);
+ return am;
+}
diff --git a/test/CodeGenCXX/atomic-inline.cpp b/test/CodeGenCXX/atomic-inline.cpp
new file mode 100644
index 000000000000..fe727589d2e2
--- /dev/null
+++ b/test/CodeGenCXX/atomic-inline.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=x86_64-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=x86_64-linux-gnu -target-cpu core2 | FileCheck %s --check-prefix=CORE2
+// Check the atomic code generation for cpu targets w/wo cx16 support.
+
+struct alignas(8) AM8 {
+ int f1, f2;
+};
+AM8 m8;
+AM8 load8() {
+ AM8 am;
+ // CHECK-LABEL: @_Z5load8v
+ // CHECK: load atomic i64, {{.*}} monotonic
+ // CORE2-LABEL: @_Z5load8v
+ // CORE2: load atomic i64, {{.*}} monotonic
+ __atomic_load(&m8, &am, 0);
+ return am;
+}
+
+AM8 s8;
+void store8() {
+ // CHECK-LABEL: @_Z6store8v
+ // CHECK: store atomic i64 {{.*}} monotonic
+ // CORE2-LABEL: @_Z6store8v
+ // CORE2: store atomic i64 {{.*}} monotonic
+ __atomic_store(&m8, &s8, 0);
+}
+
+bool cmpxchg8() {
+ AM8 am;
+ // CHECK-LABEL: @_Z8cmpxchg8v
+ // CHECK: cmpxchg i64* {{.*}} monotonic
+ // CORE2-LABEL: @_Z8cmpxchg8v
+ // CORE2: cmpxchg i64* {{.*}} monotonic
+ return __atomic_compare_exchange(&m8, &s8, &am, 0, 0, 0);
+}
+
+struct alignas(16) AM16 {
+ long f1, f2;
+};
+
+AM16 m16;
+AM16 load16() {
+ AM16 am;
+ // CHECK-LABEL: @_Z6load16v
+ // CHECK: call void @__atomic_load
+ // CORE2-LABEL: @_Z6load16v
+ // CORE2: load atomic i128, {{.*}} monotonic
+ __atomic_load(&m16, &am, 0);
+ return am;
+}
+
+AM16 s16;
+void store16() {
+ // CHECK-LABEL: @_Z7store16v
+ // CHECK: call void @__atomic_store
+ // CORE2-LABEL: @_Z7store16v
+ // CORE2: store atomic i128 {{.*}} monotonic
+ __atomic_store(&m16, &s16, 0);
+}
+
+bool cmpxchg16() {
+ AM16 am;
+ // CHECK-LABEL: @_Z9cmpxchg16v
+ // CHECK: call zeroext i1 @__atomic_compare_exchange
+ // CORE2-LABEL: @_Z9cmpxchg16v
+ // CORE2: cmpxchg i128* {{.*}} monotonic
+ return __atomic_compare_exchange(&m16, &s16, &am, 0, 0, 0);
+}
+
diff --git a/test/CodeGenCXX/blocks.cpp b/test/CodeGenCXX/blocks.cpp
index 5b7c7e6e46bb..37219d3f7abd 100644
--- a/test/CodeGenCXX/blocks.cpp
+++ b/test/CodeGenCXX/blocks.cpp
@@ -122,7 +122,6 @@ namespace test4 {
// CHECK-LABEL: define internal void @___ZN5test44testEv_block_invoke
// CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1
// CHECK-NEXT: store i8* [[BLOCKDESC:%.*]], i8** {{.*}}, align 8
- // CHECK-NEXT: load i8*, i8**
// CHECK-NEXT: bitcast i8* [[BLOCKDESC]] to <{ i8*, i32, i32, i8*, %struct.__block_descriptor* }>*
// CHECK: call void @_ZN5test41AC1Ev([[A]]* [[TMP]])
// CHECK-NEXT: call void @_ZN5test43fooENS_1AE([[A]]* [[TMP]])
diff --git a/test/CodeGenCXX/catch-undef-behavior.cpp b/test/CodeGenCXX/catch-undef-behavior.cpp
index d58853c47f75..e8287538982b 100644
--- a/test/CodeGenCXX/catch-undef-behavior.cpp
+++ b/test/CodeGenCXX/catch-undef-behavior.cpp
@@ -16,6 +16,10 @@ struct S {
// Check that type mismatch handler is not modified by ASan.
// CHECK-ASAN: private unnamed_addr global { { [{{.*}} x i8]*, i32, i32 }, { i16, i16, [4 x i8] }*, i8*, i8 } { {{.*}}, { i16, i16, [4 x i8] }* [[TYPE_DESCR]], {{.*}} }
+// CHECK: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*)
+// CHECK-X86: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*)
+// CHECK-X32: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*)
+
struct T : S {};
// CHECK-LABEL: @_Z17reference_binding
@@ -395,26 +399,93 @@ void downcast_reference(B &b) {
// CHECK-NEXT: br i1 [[AND]]
}
-// CHECK-LABEL: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i8* }> <{ i32 1413876459, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) }>
-// CHECK-X32: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i8* }> <{ i32 1413875435, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) }>
-// CHECK-X86: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i8* }> <{ i32 1413875435, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) }>
+//
+// CHECK-LABEL: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i32 }> <{ i32 846595819, i32 trunc (i64 sub (i64 ptrtoint (i8** {{.*}} to i64), i64 ptrtoint (void (void (i32)*)* @_Z22indirect_function_callPFviE to i64)) to i32) }>
+// CHECK-X32: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i32 }> <{ i32 846595819, i32 sub (i32 ptrtoint (i8** [[IndirectRTTI_ZTIFvPFviEE]] to i32), i32 ptrtoint (void (void (i32)*)* @_Z22indirect_function_callPFviE to i32)) }>
+// CHECK-X86: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i32 }> <{ i32 846595819, i32 sub (i32 ptrtoint (i8** [[IndirectRTTI_ZTIFvPFviEE]] to i32), i32 ptrtoint (void (void (i32)*)* @_Z22indirect_function_callPFviE to i32)) }>
void indirect_function_call(void (*p)(int)) {
- // CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i8* }>*
+ // CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i32 }>*
// Signature check
- // CHECK-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i8* }>, <{ i32, i8* }>* [[PTR]], i32 0, i32 0
+ // CHECK-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 }>* [[PTR]], i32 0, i32 0
// CHECK-NEXT: [[SIG:%.+]] = load i32, i32* [[SIGPTR]]
- // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 1413876459
+ // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 846595819
// CHECK-NEXT: br i1 [[SIGCMP]]
// RTTI pointer check
- // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i8* }>, <{ i32, i8* }>* [[PTR]], i32 0, i32 1
- // CHECK-NEXT: [[RTTI:%.+]] = load i8*, i8** [[RTTIPTR]]
+ // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 }>* [[PTR]], i32 0, i32 1
+ // CHECK-NEXT: [[RTTIEncIntTrunc:%.+]] = load i32, i32* [[RTTIPTR]]
+ // CHECK-NEXT: [[RTTIEncInt:%.+]] = sext i32 [[RTTIEncIntTrunc]] to i64
+ // CHECK-NEXT: [[FuncAddrInt:%.+]] = ptrtoint void (i32)* {{.*}} to i64
+ // CHECK-NEXT: [[IndirectGVInt:%.+]] = add i64 [[RTTIEncInt]], [[FuncAddrInt]]
+ // CHECK-NEXT: [[IndirectGV:%.+]] = inttoptr i64 [[IndirectGVInt]] to i8**
+ // CHECK-NEXT: [[RTTI:%.+]] = load i8*, i8** [[IndirectGV]], align 8
// CHECK-NEXT: [[RTTICMP:%.+]] = icmp eq i8* [[RTTI]], bitcast ({ i8*, i8* }* @_ZTIFviE to i8*)
// CHECK-NEXT: br i1 [[RTTICMP]]
+
p(42);
}
+namespace FunctionSanitizerVirtualCalls {
+struct A {
+ virtual void f() {}
+ virtual void g() {}
+ void h() {}
+};
+
+struct B : virtual A {
+ virtual void b() {}
+ virtual void f();
+ void g() final {}
+ static void q() {}
+};
+
+void B::f() {}
+
+void force_irgen() {
+ A a;
+ a.g();
+ a.h();
+
+ B b;
+ b.f();
+ b.b();
+ b.g();
+ B::q();
+}
+
+// CHECK-LABEL: define void @_ZN29FunctionSanitizerVirtualCalls1B1fEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define void @_ZTv0_n24_N29FunctionSanitizerVirtualCalls1B1fEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define void @_ZN29FunctionSanitizerVirtualCalls11force_irgenEv()
+// CHECK: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1AC1Ev
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1A1gEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1A1hEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1BC1Ev
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1bEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1gEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1qEv
+// CHECK: prologue
+
+}
+
namespace UpcastPointerTest {
struct S {};
struct T : S { double d; };
@@ -454,7 +525,7 @@ struct ThisAlign {
void this_align_lambda_2();
};
void ThisAlign::this_align_lambda() {
- // CHECK-LABEL: define {{.*}}@"_ZZN9ThisAlign17this_align_lambdaEvENK3$_0clEv"
+ // CHECK-LABEL: define internal %struct.ThisAlign* @"_ZZN9ThisAlign17this_align_lambdaEvENK3$_0clEv"
// CHECK-SAME: (%{{.*}}* %[[this:[^)]*]])
// CHECK: %[[this_addr:.*]] = alloca
// CHECK: store %{{.*}}* %[[this]], %{{.*}}** %[[this_addr]],
@@ -555,7 +626,7 @@ namespace CopyValueRepresentation {
}
void ThisAlign::this_align_lambda_2() {
- // CHECK-LABEL: define {{.*}}@"_ZZN9ThisAlign19this_align_lambda_2EvENK3$_1clEv"
+ // CHECK-LABEL: define internal void @"_ZZN9ThisAlign19this_align_lambda_2EvENK3$_1clEv"
// CHECK-SAME: (%{{.*}}* %[[this:[^)]*]])
// CHECK: %[[this_addr:.*]] = alloca
// CHECK: store %{{.*}}* %[[this]], %{{.*}}** %[[this_addr]],
diff --git a/test/CodeGenCXX/cfi-blacklist.cpp b/test/CodeGenCXX/cfi-blacklist.cpp
index af8a10601d29..c01e5fcd9260 100644
--- a/test/CodeGenCXX/cfi-blacklist.cpp
+++ b/test/CodeGenCXX/cfi-blacklist.cpp
@@ -1,6 +1,18 @@
// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOBL %s
-// RUN: echo "type:std::*" > %t.txt
-// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOSTD %s
+
+// Check that blacklisting cfi and cfi-vcall work correctly
+// RUN: echo "[cfi-vcall]" > %t.vcall.txt
+// RUN: echo "type:std::*" >> %t.vcall.txt
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.vcall.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOSTD %s
+//
+// RUN: echo "[cfi]" > %t.cfi.txt
+// RUN: echo "type:std::*" >> %t.cfi.txt
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.cfi.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOSTD %s
+
+// Check that blacklisting non-vcall modes does not affect vcalls
+// RUN: echo "[cfi-icall|cfi-nvcall|cfi-cast-strict|cfi-derived-cast|cfi-unrelated-cast]" > %t.other.txt
+// RUN: echo "type:std::*" >> %t.other.txt
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.other.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOBL %s
struct S1 {
virtual void f();
diff --git a/test/CodeGenCXX/cfi-icall.cpp b/test/CodeGenCXX/cfi-icall.cpp
index c3c6ed309cc6..5f5778fc1f7c 100644
--- a/test/CodeGenCXX/cfi-icall.cpp
+++ b/test/CodeGenCXX/cfi-icall.cpp
@@ -8,19 +8,22 @@ namespace {
struct S {};
-void f(S *s) {
+void f(S s) {
}
}
void g() {
- void (*fp)(S *) = f;
- // CHECK: call i1 @llvm.type.test(i8* {{.*}}, metadata [[VOIDS:![0-9]+]])
- fp(0);
+ struct S s;
+ void (*fp)(S) = f;
+ // CHECK: call i1 @llvm.type.test(i8* {{.*}}, metadata [[VOIDS1:![0-9]+]])
+ fp(s);
}
-// ITANIUM: define internal void @_ZN12_GLOBAL__N_11fEPNS_1SE({{.*}} !type [[TS:![0-9]+]]
-// MS: define internal void @"\01?f@?A@@YAXPEAUS@?A@@@Z"({{.*}} !type [[TS:![0-9]+]]
+// ITANIUM: define internal void @_ZN12_GLOBAL__N_11fENS_1SE({{.*}} !type [[TS1:![0-9]+]] !type [[TS2:![0-9]+]]
+// MS: define internal void @"\01?f@?A@@YAXUS@?A@@@Z"({{.*}} !type [[TS1:![0-9]+]] !type [[TS2:![0-9]+]]
-// CHECK: [[VOIDS]] = distinct !{}
-// CHECK: [[TS]] = !{i64 0, [[VOIDS]]}
+// CHECK: [[VOIDS1]] = distinct !{}
+// CHECK: [[TS1]] = !{i64 0, [[VOIDS1]]}
+// CHECK: [[TS2]] = !{i64 0, [[VOIDS2:![0-9]+]]}
+// CHECK: [[VOIDS2]] = distinct !{}
diff --git a/test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp b/test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp
new file mode 100644
index 000000000000..3276d8f33edc
--- /dev/null
+++ b/test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -flto -flto-unit -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-derived-cast -fsanitize-trap=cfi-derived-cast | FileCheck %s
+
+struct foo {
+ virtual ~foo() {}
+ virtual void f() = 0;
+};
+
+template <typename T>
+struct bar : virtual public foo {
+ void f() {
+ // CHECK: define{{.*}}@"\01?f@?$bar@Ubaz@@@@UEAAXXZ"
+ // Load "this", vbtable, vbase offset and vtable.
+ // CHECK: load
+ // CHECK: load
+ // CHECK: load
+ // CHECK: load
+ // CHECK: @llvm.type.test{{.*}}!"?AUfoo@@"
+ static_cast<T&>(*this);
+ }
+};
+
+struct baz : public bar<baz> {
+ virtual ~baz() {}
+};
+
+int main() {
+ baz *z = new baz;
+ z->f();
+}
diff --git a/test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp b/test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp
new file mode 100644
index 000000000000..ab610628232e
--- /dev/null
+++ b/test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -flto -flto-unit -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-nvcall -fsanitize-trap=cfi-nvcall | FileCheck %s
+
+struct foo {
+ virtual ~foo() {}
+ virtual void f() = 0;
+};
+
+template <typename T>
+struct bar : virtual public foo {
+ void f() {}
+};
+
+struct baz : public bar<baz> {
+ virtual ~baz() {}
+ void g() {}
+};
+
+void f(baz *z) {
+ // CHECK: define{{.*}}@"\01?f@@YAXPEAUbaz@@@Z"
+ // Load z, vbtable, vbase offset and vtable.
+ // CHECK: load
+ // CHECK: load
+ // CHECK: load
+ // CHECK: load
+ // CHECK: @llvm.type.test{{.*}}!"?AUfoo@@"
+ z->g();
+}
diff --git a/test/CodeGenCXX/cfi-vcall-no-trap.cpp b/test/CodeGenCXX/cfi-vcall-no-trap.cpp
new file mode 100644
index 000000000000..b7ef1426a91d
--- /dev/null
+++ b/test/CodeGenCXX/cfi-vcall-no-trap.cpp
@@ -0,0 +1,15 @@
+// Only output llvm.assume(llvm.type.test()) if cfi-vcall is disabled and whole-program-vtables is enabled
+// RUN: %clang_cc1 -flto -fvisibility hidden -fsanitize=cfi-vcall -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=CFI %s
+// RUN: %clang_cc1 -flto -fvisibility hidden -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOCFI %s
+
+struct S1 {
+ virtual void f();
+};
+
+// CHECK: define{{.*}}s1f
+// CHECK: llvm.type.test
+// CFI-NOT: llvm.assume
+// NOCFI: llvm.assume
+void s1f(S1 *s1) {
+ s1->f();
+}
diff --git a/test/CodeGenCXX/cxx11-extern-constexpr.cpp b/test/CodeGenCXX/cxx11-extern-constexpr.cpp
new file mode 100644
index 000000000000..6c520038e941
--- /dev/null
+++ b/test/CodeGenCXX/cxx11-extern-constexpr.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK --check-prefix=CXX11
+// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK --check-prefix=CXX17
+
+struct A {
+ static const int Foo = 123;
+};
+// CHECK: @_ZN1A3FooE = constant i32 123, align 4
+const int *p = &A::Foo; // emit available_externally
+const int A::Foo; // convert to full definition
+
+struct PODWithInit {
+ int g = 42;
+ char h = 43;
+};
+struct CreatePOD {
+ // Deferred initialization of the structure here requires changing
+ // the type of the global variable: the initializer list does not include
+ // the tail padding.
+ // CXX11: @_ZN9CreatePOD3podE = available_externally constant { i32, i8 } { i32 42, i8 43 },
+ static constexpr PODWithInit pod{};
+};
+const int *p_pod = &CreatePOD::pod.g;
+
+struct Bar {
+ int b;
+};
+
+struct MutableBar {
+ mutable int b;
+};
+
+struct Foo {
+ // CXX11: @_ZN3Foo21ConstexprStaticMemberE = available_externally constant i32 42,
+ // CXX17: @_ZN3Foo21ConstexprStaticMemberE = linkonce_odr constant i32 42,
+ static constexpr int ConstexprStaticMember = 42;
+ // CHECK: @_ZN3Foo17ConstStaticMemberE = available_externally constant i32 43,
+ static const int ConstStaticMember = 43;
+
+ // CXX11: @_ZN3Foo23ConstStaticStructMemberE = available_externally constant %struct.Bar { i32 44 },
+ // CXX17: @_ZN3Foo23ConstStaticStructMemberE = linkonce_odr constant %struct.Bar { i32 44 },
+ static constexpr Bar ConstStaticStructMember = {44};
+
+ // CXX11: @_ZN3Foo34ConstexprStaticMutableStructMemberE = external global %struct.MutableBar,
+ // CXX17: @_ZN3Foo34ConstexprStaticMutableStructMemberE = linkonce_odr global %struct.MutableBar { i32 45 },
+ static constexpr MutableBar ConstexprStaticMutableStructMember = {45};
+};
+// CHECK: @_ZL15ConstStaticexpr = internal constant i32 46,
+static constexpr int ConstStaticexpr = 46;
+// CHECK: @_ZL9ConstExpr = internal constant i32 46, align 4
+static const int ConstExpr = 46;
+
+// CHECK: @_ZL21ConstexprStaticStruct = internal constant %struct.Bar { i32 47 },
+static constexpr Bar ConstexprStaticStruct = {47};
+
+// CHECK: @_ZL28ConstexprStaticMutableStruct = internal global %struct.MutableBar { i32 48 },
+static constexpr MutableBar ConstexprStaticMutableStruct = {48};
+
+void use(const int &);
+void foo() {
+ use(Foo::ConstexprStaticMember);
+ use(Foo::ConstStaticMember);
+ use(Foo::ConstStaticStructMember.b);
+ use(Foo::ConstexprStaticMutableStructMember.b);
+ use(ConstStaticexpr);
+ use(ConstExpr);
+ use(ConstexprStaticStruct.b);
+ use(ConstexprStaticMutableStruct.b);
+}
diff --git a/test/CodeGenCXX/cxx11-special-members.cpp b/test/CodeGenCXX/cxx11-special-members.cpp
index 037e59a6408f..96109ba5bac1 100644
--- a/test/CodeGenCXX/cxx11-special-members.cpp
+++ b/test/CodeGenCXX/cxx11-special-members.cpp
@@ -39,7 +39,9 @@ void f3() {
C<0> a;
D b;
}
-// CHECK: define {{.*}} @_ZN1CILi0EEC1Ev
+// Trivial default ctor, might or might not be defined, but we must not expect
+// someone else ot define it.
+// CHECK-NOT: declare {{.*}} @_ZN1CILi0EEC1Ev
// CHECK: define {{.*}} @_ZN1DC1Ev
// CHECK: define {{.*}} @_ZN1BC2EOS_(
diff --git a/test/CodeGenCXX/cxx1y-variable-template.cpp b/test/CodeGenCXX/cxx1y-variable-template.cpp
index cd73817d8508..dd8f28e42992 100644
--- a/test/CodeGenCXX/cxx1y-variable-template.cpp
+++ b/test/CodeGenCXX/cxx1y-variable-template.cpp
@@ -18,6 +18,12 @@ int init_arr();
template<typename T> template<typename U> template<typename V> int Outer<T>::Inner<U>::arr[sizeof(T) + sizeof(U) + sizeof(V)] = { init_arr() };
int *p = Outer<char[100]>::Inner<char[20]>::arr<char[3]>;
+namespace PR35456 {
+// CHECK: @_ZN7PR354561nILi0EEE = linkonce_odr global i32 0
+template<int> int n;
+int *p = &n<0>;
+}
+
// CHECK: @_ZN5OuterIA100_cE5InnerIA20_cE3arrIA3_cEE = linkonce_odr global [123 x i32] zeroinitializer
// CHECK: @_ZGVN5OuterIA100_cE5InnerIA20_cE3arrIA3_cEE = linkonce_odr global
diff --git a/test/CodeGenCXX/cxx1z-aligned-allocation.cpp b/test/CodeGenCXX/cxx1z-aligned-allocation.cpp
index 437597d963b0..4c579978cb96 100644
--- a/test/CodeGenCXX/cxx1z-aligned-allocation.cpp
+++ b/test/CodeGenCXX/cxx1z-aligned-allocation.cpp
@@ -4,6 +4,8 @@
// RUN: %clang_cc1 -std=c++14 -fexceptions -fsized-deallocation -faligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s
// RUN: %clang_cc1 -std=c++1z -fexceptions -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++1z -fexceptions -fsized-deallocation %s -emit-llvm -triple x86_64-windows-msvc -o - | FileCheck %s --check-prefix=CHECK-MS
+
// Check that we don't used aligned (de)allocation without -faligned-allocation or C++1z.
// RUN: %clang_cc1 -std=c++14 -DUNALIGNED -fexceptions %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED
// RUN: %clang_cc1 -std=c++1z -DUNALIGNED -fexceptions -fno-aligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED
@@ -27,14 +29,28 @@ struct OVERALIGNED A { A(); int n[128]; };
// CHECK-LABEL: define {{.*}} @_Z2a0v()
// CHECK: %[[ALLOC:.*]] = call i8* @_ZnwmSt11align_val_t(i64 512, i64 32)
// CHECK: call void @_ZdlPvSt11align_val_t(i8* %[[ALLOC]], i64 32)
+// CHECK-MS-LABEL: define {{.*}} @"\01?a0@@YAPEAXXZ"()
+// CHECK-MS: %[[ALLOC:.*]] = call i8* @"\01??2@YAPEAX_KW4align_val_t@std@@@Z"(i64 512, i64 32)
+// CHECK-MS: cleanuppad
+// CHECK-MS: call void @"\01??3@YAXPEAXW4align_val_t@std@@@Z"(i8* %[[ALLOC]], i64 32)
void *a0() { return new A; }
+// FIXME: Why don't we call the sized array deallocation overload in this case?
+// The size is known.
+//
// CHECK-LABEL: define {{.*}} @_Z2a1l(
// CHECK: %[[ALLOC:.*]] = call i8* @_ZnamSt11align_val_t(i64 %{{.*}}, i64 32)
// No array cookie.
// CHECK-NOT: store
// CHECK: invoke void @_ZN1AC1Ev(
// CHECK: call void @_ZdaPvSt11align_val_t(i8* %[[ALLOC]], i64 32)
+// CHECK-MS-LABEL: define {{.*}} @"\01?a1@@YAPEAXJ@Z"(
+// CHECK-MS: %[[ALLOC:.*]] = call i8* @"\01??_U@YAPEAX_KW4align_val_t@std@@@Z"(i64 %{{.*}}, i64 32)
+// No array cookie.
+// CHECK-MS-NOT: store
+// CHECK-MS: invoke %struct.A* @"\01??0A@@QEAA@XZ"(
+// CHECK-MS: cleanuppad
+// CHECK-MS: call void @"\01??_V@YAXPEAXW4align_val_t@std@@@Z"(i8* %[[ALLOC]], i64 32)
void *a1(long n) { return new A[n]; }
// CHECK-LABEL: define {{.*}} @_Z2a2P1A(
diff --git a/test/CodeGenCXX/cxx1z-copy-omission.cpp b/test/CodeGenCXX/cxx1z-copy-omission.cpp
index 234e4b12589c..b33a21808175 100644
--- a/test/CodeGenCXX/cxx1z-copy-omission.cpp
+++ b/test/CodeGenCXX/cxx1z-copy-omission.cpp
@@ -6,6 +6,8 @@ struct A {
A(const A&);
~A();
+ operator bool();
+
int arr[10];
};
@@ -79,3 +81,27 @@ void i() {
// CHECK-LABEL: }
}
+
+// CHECK-LABEL: define {{.*}} @_Z1jv(
+void j() {
+ // CHECK: alloca %{{.*}}*
+ // CHECK: %[[OUTERTEMP:.*]] = alloca %{{.*}}
+ // CHECK: %[[INNERTEMP:.*]] = alloca %{{.*}}
+ // CHECK: call void @_ZN1AC1Ei(%{{.*}} %[[INNERTEMP]], i32 1)
+ // CHECK: call zeroext i1 @_ZN1AcvbEv(%{{.*}} %[[INNERTEMP]])
+ // CHECK: br i1
+ //
+ // CHECK: call void @_ZN1AC1EOS_(%{{.*}} %[[OUTERTEMP]], %{{.*}} %[[INNERTEMP]])
+ // CHECK: br label
+ //
+ // CHECK: call void @_ZN1AC1Ei(%{{.*}} %[[OUTERTEMP]], i32 2)
+ // CHECK: br label
+ //
+ // CHECK: call void @_ZN1AD1Ev(%{{.*}} %[[INNERTEMP]])
+ A &&a = A(1) ?: A(2);
+
+ // CHECK: call void @_Z1iv()
+ i();
+
+ // CHECK: call void @_ZN1AD1Ev(%{{.*}} %[[OUTERTEMP]])
+}
diff --git a/test/CodeGenCXX/cxx1z-inline-variables.cpp b/test/CodeGenCXX/cxx1z-inline-variables.cpp
index 183709373d12..2d16acd8a8c2 100644
--- a/test/CodeGenCXX/cxx1z-inline-variables.cpp
+++ b/test/CodeGenCXX/cxx1z-inline-variables.cpp
@@ -31,18 +31,28 @@ struct compat {
static constexpr int b = 2;
static constexpr int c = 3;
static inline constexpr int d = 4;
+ static const int e = 5;
+ static const int f = 6;
+ static const int g = 7;
};
const int &compat_use_before_redecl = compat::b;
const int compat::a;
const int compat::b;
const int compat::c;
const int compat::d;
+const int compat::e;
+constexpr int compat::f;
+constexpr inline int compat::g;
const int &compat_use_after_redecl1 = compat::c;
const int &compat_use_after_redecl2 = compat::d;
-// CHECK: @_ZN6compat1bE = weak_odr constant i32 2
-// CHECK: @_ZN6compat1aE = weak_odr constant i32 1
-// CHECK: @_ZN6compat1cE = weak_odr constant i32 3
-// CHECK: @_ZN6compat1dE = linkonce_odr constant i32 4
+const int &compat_use_after_redecl3 = compat::g;
+// CHECK-DAG: @_ZN6compat1bE = weak_odr constant i32 2
+// CHECK-DAG: @_ZN6compat1aE = weak_odr constant i32 1
+// CHECK-DAG: @_ZN6compat1cE = weak_odr constant i32 3
+// CHECK-DAG: @_ZN6compat1dE = linkonce_odr constant i32 4
+// CHECK-DAG: @_ZN6compat1eE = constant i32 5
+// CHECK-DAG: @_ZN6compat1fE = weak_odr constant i32 6
+// CHECK-DAG: @_ZN6compat1gE = linkonce_odr constant i32 7
template<typename T> struct X {
static int a;
@@ -57,6 +67,18 @@ int &use3 = X<int>::a;
template<> int X<int>::b = 20;
template<> inline int X<int>::c = 30;
+template<typename T> struct Y;
+template<> struct Y<int> {
+ static constexpr int a = 123;
+ static constexpr int b = 456;
+ static constexpr int c = 789;
+};
+// CHECK: @_ZN1YIiE1aE = weak_odr constant i32 123
+constexpr int Y<int>::a;
+// CHECK: @_ZN1YIiE1bE = linkonce_odr constant i32 456
+const int &yib = Y<int>::b;
+// CHECK-NOT: @_ZN1YIiE1cE
+
// CHECK-LABEL: define {{.*}}global_var_init
// CHECK: call i32 @_Z1fv
diff --git a/test/CodeGenCXX/cxx2a-destroying-delete.cpp b/test/CodeGenCXX/cxx2a-destroying-delete.cpp
new file mode 100644
index 000000000000..2e4d40715e15
--- /dev/null
+++ b/test/CodeGenCXX/cxx2a-destroying-delete.cpp
@@ -0,0 +1,161 @@
+// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ITANIUM
+// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -triple x86_64-windows -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-MSABI
+
+namespace std {
+ using size_t = decltype(sizeof(0));
+ enum class align_val_t : size_t;
+ struct destroying_delete_t {};
+}
+
+struct A {
+ void *data;
+ ~A();
+ void operator delete(A*, std::destroying_delete_t);
+};
+void delete_A(A *a) { delete a; }
+// CHECK-LABEL: define {{.*}}delete_A
+// CHECK: %[[a:.*]] = load
+// CHECK: icmp eq %{{.*}} %[[a]], null
+// CHECK: br i1
+//
+// Ensure that we call the destroying delete and not the destructor.
+// CHECK-NOT: call
+// CHECK-ITANIUM: call void @_ZN1AdlEPS_St19destroying_delete_t(%{{.*}}* %[[a]])
+// CHECK-MSABI: call void @"\01??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* %[[a]], i8
+// CHECK-NOT: call
+// CHECK: }
+
+struct B {
+ virtual ~B();
+ void operator delete(B*, std::destroying_delete_t);
+};
+void delete_B(B *b) { delete b; }
+// CHECK-LABEL: define {{.*}}delete_B
+// CHECK: %[[b:.*]] = load
+// CHECK: icmp eq %{{.*}} %[[b]], null
+// CHECK: br i1
+//
+// Ensure that we call the virtual destructor and not the operator delete.
+// CHECK-NOT: call
+// CHECK: %[[VTABLE:.*]] = load
+// CHECK: %[[DTOR:.*]] = load
+// CHECK: call {{void|i8\*}} %[[DTOR]](%{{.*}}* %[[b]]
+// CHECK-MSABI-SAME: , i32 1)
+// CHECK-NOT: call
+// CHECK: }
+
+struct Padding {
+ virtual void f();
+};
+
+struct C : Padding, A {};
+void delete_C(C *c) { delete c; }
+// Check that we perform a derived-to-base conversion on the parameter to 'operator delete'.
+// CHECK-LABEL: define {{.*}}delete_C
+// CHECK: %[[c:.*]] = load
+// CHECK: icmp eq %{{.*}} %[[c]], null
+// CHECK: br i1
+//
+// CHECK: %[[base:.*]] = getelementptr {{.*}}, i64 8
+// CHECK: %[[castbase:.*]] = bitcast {{.*}} %[[base]]
+//
+// CHECK: %[[a:.*]] = phi {{.*}} %[[castbase]]
+// CHECK: icmp eq %{{.*}} %[[a]], null
+// CHECK: br i1
+//
+// CHECK-NOT: call
+// CHECK-ITANIUM: call void @_ZN1AdlEPS_St19destroying_delete_t(%{{.*}}* %[[a]])
+// CHECK-MSABI: call void @"\01??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* %[[a]], i8
+// CHECK-NOT: call
+// CHECK: }
+
+struct VDel { virtual ~VDel(); };
+struct D : Padding, VDel, B {};
+void delete_D(D *d) { delete d; }
+// CHECK-LABEL: define {{.*}}delete_D
+// CHECK: %[[d:.*]] = load
+// CHECK: icmp eq %{{.*}} %[[d]], null
+// CHECK: br i1
+//
+// CHECK-NOT: call
+// CHECK: %[[VTABLE:.*]] = load
+// CHECK: %[[DTOR:.*]] = load
+//
+// For MS, we don't add a new vtable slot to the primary vtable for the virtual
+// destructor. Instead we cast to the VDel base class.
+// CHECK-MSABI: bitcast {{.*}} %[[d]]
+// CHECK-MSABI-NEXT: getelementptr {{.*}}, i64 8
+// CHECK-MSABI-NEXT: %[[d:.*]] = bitcast i8*
+//
+// CHECK: call {{void|i8\*}} %[[DTOR]](%{{.*}}* %[[d]]
+// CHECK-MSABI-SAME: , i32 1)
+// CHECK-NOT: call
+// CHECK: }
+
+struct E { void *data; };
+struct F { void operator delete(F *, std::destroying_delete_t, std::size_t, std::align_val_t); void *data; };
+struct alignas(16) G : E, F { void *data; };
+
+void delete_G(G *g) { delete g; }
+// CHECK-LABEL: define {{.*}}delete_G
+// CHECK-NOT: call
+// CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t(%{{.*}}* %[[a]], i64 32, i64 16)
+// CHECK-MSABI: call void @"\01??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"(%{{.*}}* %[[a]], i8 {{[^,]*}}, i64 32, i64 16)
+// CHECK-NOT: call
+// CHECK: }
+
+void call_in_dtor();
+
+struct H : G { virtual ~H(); } h;
+H::~H() { call_in_dtor(); }
+// CHECK-ITANIUM-LABEL: define void @_ZN1HD0Ev(
+// CHECK-ITANIUM-NOT: call
+// CHECK-ITANIUM: getelementptr {{.*}}, i64 24
+// CHECK-ITANIUM-NOT: call
+// CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t({{.*}}, i64 48, i64 16)
+// CHECK-ITANIUM-NOT: call
+// CHECK-ITANIUM: }
+
+// CHECK-MSABI: define {{.*}} @"\01??_GH@@UEAAPEAXI@Z"(
+// CHECK-MSABI-NOT: call{{ }}
+// CHECK-MSABI: load i32
+// CHECK-MSABI: icmp eq i32 {{.*}}, 0
+// CHECK-MSABI: br i1
+//
+// CHECK-MSABI-NOT: call{{ }}
+// CHECK-MSABI: getelementptr {{.*}}, i64 24
+// CHECK-MSABI-NOT: call{{ }}
+// CHECK-MSABI: call void @"\01??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 48, i64 16)
+// CHECK-MSABI: br label %[[RETURN:.*]]
+//
+// CHECK-MSABI: call void @"\01??_DH@@QEAAXXZ"(
+// CHECK-MSABI: br label %[[RETURN]]
+//
+// CHECK-MSABI: }
+
+struct I : H { virtual ~I(); alignas(32) char buffer[32]; } i;
+I::~I() { call_in_dtor(); }
+// CHECK-ITANIUM-LABEL: define void @_ZN1ID0Ev(
+// CHECK-ITANIUM-NOT: call
+// CHECK-ITANIUM: getelementptr {{.*}}, i64 24
+// CHECK-ITANIUM-NOT: call
+// CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t({{.*}}, i64 96, i64 32)
+// CHECK-ITANIUM-NOT: call
+// CHECK-ITANIUM: }
+
+// CHECK-MSABI: define {{.*}} @"\01??_GI@@UEAAPEAXI@Z"(
+// CHECK-MSABI-NOT: call{{ }}
+// CHECK-MSABI: load i32
+// CHECK-MSABI: icmp eq i32 {{.*}}, 0
+// CHECK-MSABI: br i1
+//
+// CHECK-MSABI-NOT: call{{ }}
+// CHECK-MSABI: getelementptr {{.*}}, i64 24
+// CHECK-MSABI-NOT: call{{ }}
+// CHECK-MSABI: call void @"\01??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 96, i64 32)
+// CHECK-MSABI: br label %[[RETURN:.*]]
+//
+// CHECK-MSABI: call void @"\01??_DI@@QEAAXXZ"(
+// CHECK-MSABI: br label %[[RETURN]]
+//
+// CHECK-MSABI: }
diff --git a/test/CodeGenCXX/cxx2a-three-way-comparison.cpp b/test/CodeGenCXX/cxx2a-three-way-comparison.cpp
new file mode 100644
index 000000000000..fd72d4a39cb3
--- /dev/null
+++ b/test/CodeGenCXX/cxx2a-three-way-comparison.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %itanium_abi_triple | FileCheck %s --check-prefix=ITANIUM
+// RUN: not %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %ms_abi_triple 2>&1 | FileCheck %s --check-prefix=MSABI
+// RUN: not %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %itanium_abi_triple -DBUILTIN 2>&1 | FileCheck %s --check-prefix=BUILTIN
+// MSABI: cannot mangle this three-way comparison operator yet
+
+struct A {
+ void operator<=>(int);
+};
+
+// ITANIUM: define {{.*}}@_ZN1AssEi(
+void A::operator<=>(int) {}
+
+// ITANIUM: define {{.*}}@_Zssi1A(
+void operator<=>(int, A) {}
+
+int operator<=>(A, A);
+
+// ITANIUM: define {{.*}}_Z1f1A(
+int f(A a) {
+ // ITANIUM: %[[RET:.*]] = call {{.*}}_Zss1AS_(
+ // ITANIUM: ret i32 %[[RET]]
+ return a <=> a;
+}
+
+#ifdef BUILTIN
+void builtin(int a) {
+ a <=> a; // BUILTIN: cannot compile this scalar expression yet
+}
+#endif
diff --git a/test/CodeGenCXX/debug-info-anon-namespace.cpp b/test/CodeGenCXX/debug-info-anon-namespace.cpp
index 3f4ef2a38360..56c8528abdee 100644
--- a/test/CodeGenCXX/debug-info-anon-namespace.cpp
+++ b/test/CodeGenCXX/debug-info-anon-namespace.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-scei-ps4 -O0 %s -o - | FileCheck --check-prefix=PS4 %s
-// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-unknown-linux-gnu -O0 %s -o - | FileCheck --check-prefix=NON-PS4 %s
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -dwarf-explicit-import -O0 %s -o - | FileCheck --check-prefix=IMPORT %s
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -O0 %s -o - | FileCheck --check-prefix=NOIMPORT %s
namespace
{
@@ -17,11 +17,9 @@ namespace
int *b1 = &a1;
int *b2 = &a2;
-
-// PS4: [[NS:![0-9]+]] = !DINamespace
-// PS4: [[CU:![0-9]+]] = distinct !DICompileUnit
-// PS4: [[NS2:![0-9]+]] = !DINamespace
-// PS4: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CU]], entity: [[NS]], file: {{![0-9]+}})
-// PS4: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[NS]], entity: [[NS2]], file: {{![0-9]+}}, line: {{[0-9]+}})
-// NON-PS4-NOT: !DIImportedEntity
-
+// IMPORT: [[NS:![0-9]+]] = !DINamespace
+// IMPORT: [[CU:![0-9]+]] = distinct !DICompileUnit
+// IMPORT: [[NS2:![0-9]+]] = !DINamespace
+// IMPORT: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CU]], entity: [[NS]], file: {{![0-9]+}})
+// IMPORT: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[NS]], entity: [[NS2]], file: {{![0-9]+}}, line: {{[0-9]+}})
+// NOIMPORT-NOT: !DIImportedEntity
diff --git a/test/CodeGenCXX/debug-info-codeview-display-name.cpp b/test/CodeGenCXX/debug-info-codeview-display-name.cpp
index b1b5a1e9acb8..17049d506fa6 100644
--- a/test/CodeGenCXX/debug-info-codeview-display-name.cpp
+++ b/test/CodeGenCXX/debug-info-codeview-display-name.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -fblocks -debug-info-kind=limited -gcodeview -emit-llvm %s \
// RUN: -o - -triple=x86_64-pc-win32 -std=c++98 | \
-// RUN: grep 'DISubprogram' | sed -e 's/.*name: "\([^"]*\)".*/"\1"/' | \
+// RUN: grep 'DISubprogram\|DICompositeType' | sed -e 's/.*name: "\([^"]*\)".*/"\1"/' | \
// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=UNQUAL
// RUN: %clang_cc1 -fblocks -debug-info-kind=line-tables-only -gcodeview -emit-llvm %s \
// RUN: -o - -triple=x86_64-pc-win32 -std=c++98 | \
@@ -91,3 +91,8 @@ void fn_tmpl() {}
template void fn_tmpl<int, freefunc>();
// CHECK-DAG: "fn_tmpl<int,&freefunc>"
+
+template <typename A, typename B, typename C> struct ClassTemplate { A a; B b; C c; };
+ClassTemplate<char, short, ClassTemplate<int, int, int> > f;
+// This will only show up in normal debug builds.
+// UNQUAL-DAG: "ClassTemplate<char,short,ClassTemplate<int,int,int> >"
diff --git a/test/CodeGenCXX/debug-info-codeview-nested-types.cpp b/test/CodeGenCXX/debug-info-codeview-nested-types.cpp
new file mode 100644
index 000000000000..7c8f78e7a001
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-codeview-nested-types.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-pc-windows-msvc -debug-info-kind=limited -gcodeview -emit-llvm -o - | FileCheck %s
+
+struct HasNested {
+ enum InnerEnum { _BUF_SIZE = 1 };
+ typedef int InnerTypedef;
+ enum { InnerEnumerator = 2 };
+ struct InnerStruct { };
+};
+HasNested f;
+
+// CHECK: ![[INNERENUM:[0-9]+]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "InnerEnum", {{.*}})
+// CHECK: ![[HASNESTED:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "HasNested",
+// CHECK-SAME: elements: ![[MEMBERS:[0-9]+]],
+//
+// CHECK: ![[MEMBERS]] = !{![[INNERENUM]], ![[INNERTYPEDEF:[0-9]+]], ![[UNNAMEDENUM:[0-9]+]], ![[INNERSTRUCT:[0-9]+]]}
+//
+// CHECK: ![[INNERTYPEDEF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "InnerTypedef", scope: ![[HASNESTED]]{{.*}})
+//
+// CHECK: ![[UNNAMEDENUM]] = !DICompositeType(tag: DW_TAG_enumeration_type, scope: ![[HASNESTED]],
+// CHECK-SAME: elements: ![[UNNAMEDMEMBERS:[0-9]+]],
+// CHECK: ![[UNNAMEDMEMBERS]] = !{![[INNERENUMERATOR:[0-9]+]]}
+// CHECK: ![[INNERENUMERATOR]] = !DIEnumerator(name: "InnerEnumerator", value: 2)
+//
+// CHECK: ![[INNERSTRUCT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "InnerStruct"
+// CHECK-SAME: flags: DIFlagFwdDecl
diff --git a/test/CodeGenCXX/debug-info-fwd-template-param.cpp b/test/CodeGenCXX/debug-info-fwd-template-param.cpp
new file mode 100644
index 000000000000..2983f842744a
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-fwd-template-param.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -triple=%itanium_abi_triple -debug-info-kind=limited -debug-forward-template-params -emit-llvm -o - | FileCheck --check-prefix=CHILD %s
+// RUN: %clang_cc1 %s -triple=%itanium_abi_triple -debug-info-kind=limited -emit-llvm -o - | FileCheck --check-prefix=NONE %s
+// A DWARF forward declaration of a template instantiation should have template
+// parameter children (if we ask for them).
+
+template<typename T> class A;
+A<int> *p;
+
+// CHILD: !DICompositeType(tag: DW_TAG_class_type, name: "A<int>"
+// CHILD-SAME: flags: DIFlagFwdDecl
+// CHILD-SAME: templateParams: [[PARAM_LIST:![0-9]*]]
+// CHILD: [[PARAM_LIST]] = !{[[PARAM:![0-9]*]]}
+// CHILD: [[PARAM]] = !DITemplateTypeParameter(name: "T",
+// CHILD-SAME: type: [[BTYPE:![0-9]*]]
+// CHILD: [[BTYPE]] = !DIBasicType(name: "int"
+
+// NONE: !DICompositeType(tag: DW_TAG_class_type, name: "A<int>"
+// NONE-SAME: flags: DIFlagFwdDecl
+// NONE-NOT: templateParams:
+// NONE-SAME: )
diff --git a/test/CodeGenCXX/debug-info-inheriting-constructor.cpp b/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
index e3708e2080f0..8e47a0da6dff 100644
--- a/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
+++ b/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
@@ -13,7 +13,7 @@ A::A(int i, ...) {}
// CHECK: call void @llvm.dbg.declare
// CHECK-NOT ret void
// CHECK: call void @llvm.dbg.declare(metadata %{{.*}}** %{{[^,]+}},
-// CHECK-SAME: metadata ![[THIS:[0-9]+]], metadata !{{[0-9]+}}), !dbg ![[LOC:[0-9]+]]
+// CHECK-SAME: metadata ![[THIS:[0-9]+]], metadata !DIExpression()), !dbg ![[LOC:[0-9]+]]
// CHECK: ret void, !dbg ![[NOINL:[0-9]+]]
// CHECK: ![[FOO:.*]] = distinct !DISubprogram(name: "foo"
// CHECK-DAG: ![[A:.*]] = distinct !DISubprogram(name: "A", linkageName: "_ZN1BCI11AEiz"
diff --git a/test/CodeGenCXX/debug-info-inlined.cpp b/test/CodeGenCXX/debug-info-inlined.cpp
index 9969ef79ca7e..53e2cc9289c2 100644
--- a/test/CodeGenCXX/debug-info-inlined.cpp
+++ b/test/CodeGenCXX/debug-info-inlined.cpp
@@ -1,45 +1,29 @@
// RUN: %clang_cc1 -emit-llvm -triple i686-pc-windows-msvc19.0.24213 -gcodeview -debug-info-kind=limited -std=c++14 %s -o - | FileCheck %s
// PR33997.
-struct already_AddRefed {
- ~already_AddRefed();
+struct WithDtor {
+ ~WithDtor();
};
-struct RefPtr {
- operator int *();
+struct Base {
+ Base(WithDtor);
};
-struct ServoCssRulesStrong {
- already_AddRefed Consume();
+class Forward : Base {
+ using Base::Base;
};
-struct GroupRule {
- GroupRule(already_AddRefed);
+class A : Forward {
+ A();
};
-class ConditionRule : GroupRule {
- using GroupRule::GroupRule;
+class B : Forward {
+ B();
};
-class CSSMediaRule : ConditionRule {
- using ConditionRule::ConditionRule;
-};
-class CSSMozDocumentRule : ConditionRule {
- using ConditionRule::ConditionRule;
-};
-class ServoDocumentRule : CSSMozDocumentRule {
- ServoDocumentRule(RefPtr);
-};
-class ServoMediaRule : CSSMediaRule {
- ServoMediaRule(RefPtr);
-};
-ServoCssRulesStrong Servo_MediaRule_GetRules(int *);
-ServoCssRulesStrong Servo_DocumentRule_GetRules(int *);
-ServoDocumentRule::ServoDocumentRule(RefPtr aRawRule)
- : CSSMozDocumentRule(Servo_DocumentRule_GetRules(aRawRule).Consume()) {}
+A::A() : Forward(WithDtor()) {}
-ServoMediaRule::ServoMediaRule(RefPtr aRawRule)
- : CSSMediaRule(Servo_MediaRule_GetRules(aRawRule).Consume()) {}
+B::B() : Forward(WithDtor()) {}
-// CHECK: define{{.*}}ServoMediaRule
+// CHECK: define{{.*}}A
// CHECK-NOT: {{ ret }}
-// CHECK: store %class.ConditionRule* %
-// CHECK-SAME: %class.ConditionRule** %
+// CHECK: store %class.Forward* %
+// CHECK-SAME: %class.Forward** %
// CHECK-SAME: !dbg ![[INL:[0-9]+]]
-// CHECK: ![[INL]] = !DILocation(line: 16, scope: ![[SP:[0-9]+]], inlinedAt:
-// CHECK: ![[SP]] = distinct !DISubprogram(name: "GroupRule", {{.*}}isDefinition: true
+// CHECK: ![[INL]] = !DILocation(line: 10, scope: ![[SP:[0-9]+]], inlinedAt:
+// CHECK: ![[SP]] = distinct !DISubprogram(name: "Base", {{.*}}isDefinition: true
diff --git a/test/CodeGenCXX/debug-info-method.cpp b/test/CodeGenCXX/debug-info-method.cpp
index e0f9a284f2cf..af7103e57528 100644
--- a/test/CodeGenCXX/debug-info-method.cpp
+++ b/test/CodeGenCXX/debug-info-method.cpp
@@ -20,6 +20,7 @@ union {
class A {
protected:
void foo(int, A, decltype(u));
+ void bar();
};
void A::foo(int, A, decltype(u)) {
@@ -29,3 +30,5 @@ A a;
int A::*x = 0;
int (A::*y)(int) = 0;
+
+void A::bar() { foo(0, *this, u); }
diff --git a/test/CodeGenCXX/debug-info-ms-abi.cpp b/test/CodeGenCXX/debug-info-ms-abi.cpp
index 1bf8bab5f41c..e83d7e94230d 100644
--- a/test/CodeGenCXX/debug-info-ms-abi.cpp
+++ b/test/CodeGenCXX/debug-info-ms-abi.cpp
@@ -6,6 +6,7 @@ struct Foo {
virtual void f();
virtual void g();
virtual void h();
+ static void i(int, int);
struct Nested {};
};
Foo f;
@@ -18,7 +19,7 @@ Foo::Nested n;
// CHECK-SAME: elements: ![[elements:[0-9]+]]
// CHECK-SAME: identifier: ".?AUFoo@@"
-// CHECK: ![[elements]] = !{![[vshape:[0-9]+]], ![[vptr:[0-9]+]], ![[Nested]], ![[f:[0-9]+]], ![[g:[0-9]+]], ![[h:[0-9]+]]}
+// CHECK: ![[elements]] = !{![[vshape:[0-9]+]], ![[vptr:[0-9]+]], ![[Nested]], ![[f:[0-9]+]], ![[g:[0-9]+]], ![[h:[0-9]+]], ![[i:[0-9]+]]}
// CHECK: ![[vshape]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__vtbl_ptr_type", baseType: null, size: 96)
@@ -38,3 +39,9 @@ Foo::Nested n;
// CHECK: ![[h]] = !DISubprogram(name: "h",
// CHECK-SAME: containingType: ![[Foo]], virtuality: DW_VIRTUALITY_virtual, virtualIndex: 2,
// CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual,
+
+// CHECK: ![[i]] = !DISubprogram(name: "i",
+// CHECK-SAME: flags: DIFlagPrototyped | DIFlagStaticMember
+// CHECK-NEXT: ![[dummy:[0-9]+]] = !DISubroutineType(types: ![[Signature:[0-9]+]])
+// CHECK: ![[Signature]] = !{null, ![[BasicInt:[0-9]+]], ![[BasicInt]]}
+// CHECK: ![[BasicInt]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
diff --git a/test/CodeGenCXX/debug-info-nested-exprs.cpp b/test/CodeGenCXX/debug-info-nested-exprs.cpp
new file mode 100644
index 000000000000..bd70373e2285
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-nested-exprs.cpp
@@ -0,0 +1,202 @@
+// RUN: %clang_cc1 -triple=x86_64-pc-windows-msvc -debug-info-kind=limited \
+// RUN: -std=c++11 -gcodeview -emit-llvm -o - %s \
+// RUN: | FileCheck -check-prefix=NONEST %s
+// RUN: %clang_cc1 -triple=x86_64-pc-windows-msvc -debug-info-kind=limited \
+// RUN: -std=c++11 -gcodeview -dwarf-column-info -emit-llvm -o - %s \
+// RUN: | FileCheck -check-prefix=COLUMNS %s
+// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -debug-info-kind=limited \
+// RUN: -std=c++11 -emit-llvm -o - %s | FileCheck -check-prefix=NESTED %s
+// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -debug-info-kind=limited \
+// RUN: -std=c++11 -dwarf-column-info -emit-llvm -o - %s \
+// RUN: | FileCheck -check-prefix=COLUMNS %s
+
+class Foo {
+public:
+ static Foo create();
+ void func();
+ int *begin();
+ int *end();
+};
+
+int bar(int x, int y);
+int baz(int x, int y);
+int qux(int x, int y);
+int onearg(int x);
+int noargs();
+int noargs1();
+Foo range(int x);
+
+int foo(int x, int y, int z) {
+ int a = bar(x, y) +
+ baz(x, z) +
+ qux(y, z);
+ // NONEST: call i32 @{{.*}}bar{{.*}}, !dbg ![[LOC:[0-9]+]]
+ // NONEST: call i32 @{{.*}}baz{{.*}}, !dbg ![[LOC]]
+ // NONEST: call i32 @{{.*}}qux{{.*}}, !dbg ![[LOC]]
+ // NONEST: store i32 {{.*}}, i32* %a,{{.*}} !dbg ![[LOC]]
+ // NESTED: call i32 @{{.*}}bar{{.*}}, !dbg ![[BAR:[0-9]+]]
+ // NESTED: call i32 @{{.*}}baz{{.*}}, !dbg ![[BAZ:[0-9]+]]
+ // NESTED: call i32 @{{.*}}qux{{.*}}, !dbg ![[QUX:[0-9]+]]
+ // NESTED: store i32 {{.*}}, i32* %a,{{.*}} !dbg ![[BAR]]
+ // COLUMNS: call i32 @{{.*}}bar{{.*}}, !dbg ![[BAR:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}baz{{.*}}, !dbg ![[BAZ:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}qux{{.*}}, !dbg ![[QUX:[0-9]+]]
+ // COLUMNS: store i32 {{.*}}, i32* %a,{{.*}} !dbg ![[DECLA:[0-9]+]]
+
+ int i = 1, b = 0, c = 0;
+ // NONEST: store i32 1, i32* %i,{{.*}} !dbg ![[ILOC:[0-9]+]]
+ // NONEST: store i32 0, i32* %b,{{.*}} !dbg ![[ILOC]]
+ // NONEST: store i32 0, i32* %c,{{.*}} !dbg ![[ILOC]]
+ // NESTED: store i32 1, i32* %i,{{.*}} !dbg ![[ILOC:[0-9]+]]
+ // NESTED: store i32 0, i32* %b,{{.*}} !dbg ![[ILOC]]
+ // NESTED: store i32 0, i32* %c,{{.*}} !dbg ![[ILOC]]
+ // COLUMNS: store i32 1, i32* %i,{{.*}} !dbg ![[ILOC:[0-9]+]]
+ // COLUMNS: store i32 0, i32* %b,{{.*}} !dbg ![[BLOC:[0-9]+]]
+ // COLUMNS: store i32 0, i32* %c,{{.*}} !dbg ![[CLOC:[0-9]+]]
+
+ while (i > 0) {
+ b = bar(a, b);
+ --i;
+ }
+ // NONEST: call i32 @{{.*}}bar{{.*}}, !dbg ![[WHILE1:[0-9]+]]
+ // NONEST: store i32 %{{[^,]+}}, i32* %i,{{.*}} !dbg ![[WHILE2:[0-9]+]]
+ // NESTED: call i32 @{{.*}}bar{{.*}}, !dbg ![[WHILE1:[0-9]+]]
+ // NESTED: store i32 %{{[^,]+}}, i32* %i,{{.*}} !dbg ![[WHILE2:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}bar{{.*}}, !dbg ![[WHILE1:[0-9]+]]
+ // COLUMNS: store i32 %{{[^,]+}}, i32* %i,{{.*}} !dbg ![[WHILE2:[0-9]+]]
+
+ for (i = 0; i < 1; i++) {
+ b = bar(a, b);
+ c = qux(a, c);
+ }
+ // NONEST: call i32 @{{.*}}bar{{.*}}, !dbg ![[FOR1:[0-9]+]]
+ // NONEST: call i32 @{{.*}}qux{{.*}}, !dbg ![[FOR2:[0-9]+]]
+ // NESTED: call i32 @{{.*}}bar{{.*}}, !dbg ![[FOR1:[0-9]+]]
+ // NESTED: call i32 @{{.*}}qux{{.*}}, !dbg ![[FOR2:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}bar{{.*}}, !dbg ![[FOR1:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}qux{{.*}}, !dbg ![[FOR2:[0-9]+]]
+
+ if (a < b) {
+ int t = a;
+ a = b;
+ b = t;
+ }
+ // NONEST: store i32 %{{[^,]+}}, i32* %t,{{.*}} !dbg ![[IF1:[0-9]+]]
+ // NONEST: store i32 %{{[^,]+}}, i32* %a,{{.*}} !dbg ![[IF2:[0-9]+]]
+ // NONEST: store i32 %{{[^,]+}}, i32* %b,{{.*}} !dbg ![[IF3:[0-9]+]]
+ // NESTED: store i32 %{{[^,]+}}, i32* %t,{{.*}} !dbg ![[IF1:[0-9]+]]
+ // NESTED: store i32 %{{[^,]+}}, i32* %a,{{.*}} !dbg ![[IF2:[0-9]+]]
+ // NESTED: store i32 %{{[^,]+}}, i32* %b,{{.*}} !dbg ![[IF3:[0-9]+]]
+ // COLUMNS: store i32 %{{[^,]+}}, i32* %t,{{.*}} !dbg ![[IF1:[0-9]+]]
+ // COLUMNS: store i32 %{{[^,]+}}, i32* %a,{{.*}} !dbg ![[IF2:[0-9]+]]
+ // COLUMNS: store i32 %{{[^,]+}}, i32* %b,{{.*}} !dbg ![[IF3:[0-9]+]]
+
+ int d = onearg(
+ noargs());
+ // NONEST: call i32 @{{.*}}noargs{{.*}}, !dbg ![[DECLD:[0-9]+]]
+ // NONEST: call i32 @{{.*}}onearg{{.*}}, !dbg ![[DECLD]]
+ // NONEST: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[DECLD]]
+ // NESTED: call i32 @{{.*}}noargs{{.*}}, !dbg ![[DNOARGS:[0-9]+]]
+ // NESTED: call i32 @{{.*}}onearg{{.*}}, !dbg ![[DECLD:[0-9]+]]
+ // NESTED: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[DECLD]]
+ // COLUMNS: call i32 @{{.*}}noargs{{.*}}, !dbg ![[DNOARGS:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}onearg{{.*}}, !dbg ![[DONEARG:[0-9]+]]
+ // COLUMNS: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[DECLD:[0-9]+]]
+
+ d = onearg(noargs());
+ // NONEST: call i32 @{{.*}}noargs{{.*}}, !dbg ![[SETD:[0-9]+]]
+ // NONEST: call i32 @{{.*}}onearg{{.*}}, !dbg ![[SETD]]
+ // NONEST: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[SETD]]
+ // NESTED: call i32 @{{.*}}noargs{{.*}}, !dbg ![[SETD:[0-9]+]]
+ // NESTED: call i32 @{{.*}}onearg{{.*}}, !dbg ![[SETD]]
+ // NESTED: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[SETD]]
+ // COLUMNS: call i32 @{{.*}}noargs{{.*}}, !dbg ![[SETDNOARGS:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}onearg{{.*}}, !dbg ![[SETDONEARG:[0-9]+]]
+ // COLUMNS: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[SETD:[0-9]+]]
+
+ for (const auto x : range(noargs())) noargs1();
+ // NONEST: call i32 @{{.*}}noargs{{.*}}, !dbg ![[RANGEFOR:[0-9]+]]
+ // NONEST: call {{.+}} @{{.*}}range{{.*}}, !dbg ![[RANGEFOR]]
+ // NONEST: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[RANGEFOR_BODY:[0-9]+]]
+ // NESTED: call i32 @{{.*}}noargs{{.*}}, !dbg ![[RANGEFOR:[0-9]+]]
+ // NESTED: call {{.+}} @{{.*}}range{{.*}}, !dbg ![[RANGEFOR]]
+ // NESTED: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[RANGEFOR_BODY:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}noargs{{.*}}, !dbg ![[RANGEFOR_NOARGS:[0-9]+]]
+ // COLUMNS: call {{.+}} @{{.*}}range{{.*}}, !dbg ![[RANGEFOR_RANGE:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[RANGEFOR_BODY:[0-9]+]]
+
+ if (noargs() && noargs1()) {
+ Foo::create().func();
+ }
+ // NONEST: call i32 @{{.*}}noargs{{.*}}, !dbg ![[AND:[0-9]+]]
+ // NONEST: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[AND]]
+ // NONEST: call {{.+}} @{{.*}}create{{.*}}, !dbg ![[AND_BODY:[0-9]+]]
+ // NONEST: call void @{{.*}}func{{.*}}, !dbg ![[AND_BODY]]
+ // NESTED: call i32 @{{.*}}noargs{{.*}}, !dbg ![[AND:[0-9]+]]
+ // NESTED: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[AND]]
+ // NESTED: call {{.+}} @{{.*}}create{{.*}}, !dbg ![[AND_BODY:[0-9]+]]
+ // NESTED: call void @{{.*}}func{{.*}}, !dbg ![[AND_BODY]]
+ // COLUMNS: call i32 @{{.*}}noargs{{.*}}, !dbg ![[ANDLHS:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[ANDRHS:[0-9]+]]
+ // COLUMNS: call {{.+}} @{{.*}}create{{.*}}, !dbg ![[AND_CREATE:[0-9]+]]
+ // COLUMNS: call void @{{.*}}func{{.*}}, !dbg ![[AND_FUNC:[0-9]+]]
+
+ return a -
+ (b * z);
+ // NONEST: mul nsw i32 {{.*}}, !dbg ![[RETLOC:[0-9]+]]
+ // NONEST: sub nsw i32 {{.*}}, !dbg ![[RETLOC]]
+ // NONEST: ret i32 {{.*}}, !dbg ![[RETLOC]]
+ // NESTED: mul nsw i32 {{.*}}, !dbg ![[RETMUL:[0-9]+]]
+ // NESTED: sub nsw i32 {{.*}}, !dbg ![[RETSUB:[0-9]+]]
+ // NESTED: ret i32 {{.*}}, !dbg !
+ // COLUMNS: mul nsw i32 {{.*}}, !dbg ![[RETMUL:[0-9]+]]
+ // COLUMNS: sub nsw i32 {{.*}}, !dbg ![[RETSUB:[0-9]+]]
+ // COLUMNS: ret i32 {{.*}}, !dbg !
+}
+
+// NONEST: ![[WHILE1]] = !DILocation(
+// NONEST: ![[WHILE2]] = !DILocation(
+// NONEST: ![[FOR1]] = !DILocation(
+// NONEST: ![[FOR2]] = !DILocation(
+// NONEST: ![[IF1]] = !DILocation(
+// NONEST: ![[IF2]] = !DILocation(
+// NONEST: ![[IF3]] = !DILocation(
+// NONEST: ![[RANGEFOR]] = !DILocation(
+// NONEST-SAME: line: [[RANGEFOR_LINE:[0-9]+]]
+// NONEST: ![[RANGEFOR_BODY]] = !DILocation(
+// NONEST-SAME: line: [[RANGEFOR_LINE]]
+
+// NESTED: ![[BAR]] = !DILocation(
+// NESTED: ![[BAZ]] = !DILocation(
+// NESTED: ![[QUX]] = !DILocation(
+// NESTED: ![[DECLD]] = !DILocation
+// NESTED: ![[DNOARGS]] = !DILocation
+// NESTED: ![[RANGEFOR]] = !DILocation(
+// NESTED-SAME: line: [[RANGEFOR_LINE:[0-9]+]]
+// NESTED: ![[RANGEFOR_BODY]] = !DILocation(
+// NESTED-SAME: line: [[RANGEFOR_LINE]]
+// NESTED: ![[RETSUB]] = !DILocation(
+// NESTED: ![[RETMUL]] = !DILocation(
+
+// COLUMNS: ![[DECLA]] = !DILocation(
+// COLUMNS: ![[BAR]] = !DILocation(
+// COLUMNS: ![[BAZ]] = !DILocation(
+// COLUMNS: ![[QUX]] = !DILocation(
+// COLUMNS: ![[ILOC]] = !DILocation(
+// COLUMNS: ![[BLOC]] = !DILocation(
+// COLUMNS: ![[CLOC]] = !DILocation(
+// COLUMNS: ![[DECLD]] = !DILocation(
+// COLUMNS: ![[DNOARGS]] = !DILocation(
+// COLUMNS: ![[DONEARG]] = !DILocation(
+// COLUMNS: ![[SETDNOARGS]] = !DILocation(
+// COLUMNS: ![[SETDONEARG]] = !DILocation(
+// COLUMNS: ![[SETD]] = !DILocation(
+// COLUMNS: ![[RANGEFOR_NOARGS]] = !DILocation(
+// COLUMNS: ![[RANGEFOR_RANGE]] = !DILocation(
+// COLUMNS: ![[RANGEFOR_BODY]] = !DILocation(
+// COLUMNS: ![[ANDLHS]] = !DILocation
+// COLUMNS: ![[ANDRHS]] = !DILocation
+// COLUMNS: ![[AND_CREATE]] = !DILocation
+// COLUMNS: ![[AND_FUNC]] = !DILocation
+// COLUNMS: ![[RETSUB]] = !DILocation(
+// COLUMNS: ![[RETMUL]] = !DILocation(
diff --git a/test/CodeGenCXX/debug-info-static-member.cpp b/test/CodeGenCXX/debug-info-static-member.cpp
index c777ccb2aba2..3537754ced76 100644
--- a/test/CodeGenCXX/debug-info-static-member.cpp
+++ b/test/CodeGenCXX/debug-info-static-member.cpp
@@ -32,7 +32,7 @@ public:
// why the definition of "a" comes before the declarations while
// "b" and "c" come after.
-// CHECK: [[A]] = !DIGlobalVariableExpression(var: [[AV:.*]])
+// CHECK: [[A]] = !DIGlobalVariableExpression(var: [[AV:.*]], expr: !DIExpression())
// CHECK: [[AV]] = distinct !DIGlobalVariable(name: "a",
// CHECK-SAME: declaration: ![[DECL_A:[0-9]+]])
//
@@ -45,7 +45,7 @@ public:
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "static_decl_templ_var"
int C::a = 4;
-// CHECK: [[B]] = !DIGlobalVariableExpression(var: [[BV:.*]])
+// CHECK: [[B]] = !DIGlobalVariableExpression(var: [[BV:.*]], expr: !DIExpression())
// CHECK: [[BV]] = distinct !DIGlobalVariable(name: "b",
// CHECK-SAME: declaration: ![[DECL_B:[0-9]+]])
// CHECK: ![[DECL_B]] = !DIDerivedType(tag: DW_TAG_member, name: "b"
@@ -93,7 +93,7 @@ int C::a = 4;
// CHECK-SAME: flags: DIFlagPublic | DIFlagStaticMember)
int C::b = 2;
-// CHECK: [[C]] = !DIGlobalVariableExpression(var: [[CV:.*]])
+// CHECK: [[C]] = !DIGlobalVariableExpression(var: [[CV:.*]], expr: !DIExpression())
// CHECK: [[CV]] = distinct !DIGlobalVariable(name: "c", {{.*}} declaration: ![[DECL_C]])
int C::c = 1;
diff --git a/test/CodeGenCXX/debug-info-template-member.cpp b/test/CodeGenCXX/debug-info-template-member.cpp
index 2b840745ffeb..a6aa1a05a256 100644
--- a/test/CodeGenCXX/debug-info-template-member.cpp
+++ b/test/CodeGenCXX/debug-info-template-member.cpp
@@ -19,7 +19,7 @@ inline int add3(int x) {
}
// The compile unit pulls in the global variables first.
-// CHECK: [[X]] = !DIGlobalVariableExpression(var: [[XV:.*]])
+// CHECK: [[X]] = !DIGlobalVariableExpression(var: [[XV:.*]], expr: !DIExpression())
// CHECK: [[XV]] = distinct !DIGlobalVariable(name: "x",
// CHECK-SAME: type: ![[OUTER_FOO_INNER_ID:[0-9]+]]
diff --git a/test/CodeGenCXX/debug-info-template.cpp b/test/CodeGenCXX/debug-info-template.cpp
index 54fac0b36eec..0c3414516215 100644
--- a/test/CodeGenCXX/debug-info-template.cpp
+++ b/test/CodeGenCXX/debug-info-template.cpp
@@ -25,7 +25,7 @@ struct TC {
int glb;
void func();
-// CHECK: [[TCI]] = !DIGlobalVariableExpression(var: [[TCIV:.*]])
+// CHECK: [[TCI]] = !DIGlobalVariableExpression(var: [[TCIV:.*]], expr: !DIExpression())
// CHECK: [[TCIV]] = distinct !DIGlobalVariable(name: "tci",
// CHECK-SAME: type: ![[TCNESTED:[0-9]+]]
// CHECK: ![[TCNESTED]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "nested",
@@ -84,7 +84,7 @@ TC
// CHECK: [[TCARG7_3]] = !DITemplateValueParameter(type: [[INT]], value: i32 3)
3>::nested tci;
-// CHECK: [[TCN]] = !DIGlobalVariableExpression(var: [[TCNV:.*]])
+// CHECK: [[TCN]] = !DIGlobalVariableExpression(var: [[TCNV:.*]], expr: !DIExpression())
// CHECK: [[TCNV]] = distinct !DIGlobalVariable(name: "tcn"
// CHECK-SAME: type: ![[TCNT:[0-9]+]]
TC
@@ -125,7 +125,7 @@ template <template <typename> class tmpl, int &lvr, int &&rvr>
struct NN {
};
-// CHECK: [[NN]] = !DIGlobalVariableExpression(var: [[NNV:.*]])
+// CHECK: [[NN]] = !DIGlobalVariableExpression(var: [[NNV:.*]], expr: !DIExpression())
// CHECK: [[NNV]] = distinct !DIGlobalVariable(name: "nn"
// CHECK-SAME: type: ![[NNT:[0-9]+]]
diff --git a/test/CodeGenCXX/debug-info.cpp b/test/CodeGenCXX/debug-info.cpp
index 2b86150b52b5..6d6d0c7d19cf 100644
--- a/test/CodeGenCXX/debug-info.cpp
+++ b/test/CodeGenCXX/debug-info.cpp
@@ -4,11 +4,11 @@
// CHECK: @_ZN6pr96081xE = global [3 x i8]* null, align 8, !dbg [[X:![0-9]+]]
// CHECK: define void @_ZN7pr147634funcENS_3fooE
-// CHECK: call void @llvm.dbg.declare({{.*}}, metadata ![[F:[0-9]+]], metadata ![[EXPR:[0-9]+]])
+// CHECK: call void @llvm.dbg.declare({{.*}}, metadata ![[F:[0-9]+]], metadata !DIExpression())
// !llvm.dbg.cu pulls in globals and their types first.
// CHECK-NOT: !DIGlobalVariable(name: "c"
-// CHECK: [[X]] = !DIGlobalVariableExpression(var: [[XV:!.*]])
+// CHECK: [[X]] = !DIGlobalVariableExpression(var: [[XV:!.*]], expr: !DIExpression())
// CHECK: [[XV]] = distinct !DIGlobalVariable(name: "x", linkageName: "_ZN6pr96081xE"
// CHECK-SAME: type: [[INCARRAYPTR:![0-9]*]]
// CHECK: [[INCARRAYPTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[INCARRAY:![0-9]+]]
@@ -21,7 +21,6 @@
// CHECK: ![[INCTYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "incomplete"
// CHECK-SAME: DIFlagFwdDecl
-// CHECK: ![[EXPR]] = !DIExpression()
template<typename T> struct Identity {
typedef T Type;
diff --git a/test/CodeGenCXX/default_calling_conv.cpp b/test/CodeGenCXX/default_calling_conv.cpp
index 95c214a223d4..b5b0f47ceb98 100644
--- a/test/CodeGenCXX/default_calling_conv.cpp
+++ b/test/CodeGenCXX/default_calling_conv.cpp
@@ -3,13 +3,23 @@
// RUN: %clang_cc1 -triple i486-unknown-linux-gnu -fdefault-calling-conv=stdcall -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL
// RUN: %clang_cc1 -triple i486-unknown-linux-gnu -mrtd -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL
// RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=vectorcall -emit-llvm -o - %s | FileCheck %s --check-prefix=VECTORCALL --check-prefix=ALL
+// RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=regcall -emit-llvm -o - %s | FileCheck %s --check-prefix=REGCALL --check-prefix=ALL
// CDECL: define void @_Z5test1v
// FASTCALL: define x86_fastcallcc void @_Z5test1v
// STDCALL: define x86_stdcallcc void @_Z5test1v
// VECTORCALL: define x86_vectorcallcc void @_Z5test1v
+// REGCALL: define x86_regcallcc void @_Z17__regcall3__test1v
void test1() {}
+// fastcall, stdcall, vectorcall and regcall do not support variadic functions.
+// CDECL: define void @_Z12testVariadicz
+// FASTCALL: define void @_Z12testVariadicz
+// STDCALL: define void @_Z12testVariadicz
+// VECTORCALL: define void @_Z12testVariadicz
+// REGCALL: define void @_Z12testVariadicz
+void testVariadic(...){}
+
// ALL: define void @_Z5test2v
void __attribute__((cdecl)) test2() {}
@@ -22,6 +32,9 @@ void __attribute__((stdcall)) test4() {}
// ALL: define x86_vectorcallcc void @_Z5test5v
void __attribute__((vectorcall)) test5() {}
+// ALL: define x86_regcallcc void @_Z17__regcall3__test6v
+void __attribute__((regcall)) test6() {}
+
// ALL: define linkonce_odr void @_ZN1A11test_memberEv
class A {
public:
@@ -32,3 +45,8 @@ void test() {
A a;
a.test_member();
}
+
+// ALL: define i32 @main
+int main() {
+ return 1;
+}
diff --git a/test/CodeGenCXX/dllexport-vtable-thunks.cpp b/test/CodeGenCXX/dllexport-vtable-thunks.cpp
new file mode 100644
index 000000000000..81811ace2ee6
--- /dev/null
+++ b/test/CodeGenCXX/dllexport-vtable-thunks.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -fdeclspec -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows-itanium -fdeclspec -emit-llvm -o - %s | FileCheck %s
+
+struct __declspec(dllexport) A {
+ virtual void m();
+};
+struct __declspec(dllexport) B {
+ virtual void m();
+};
+struct __declspec(dllexport) C : A, B {
+ virtual void m();
+};
+void C::m() {}
+// CHECK: define dllexport void @_ZThn8_N1C1mEv
+
+struct Base {
+ virtual void m();
+};
+struct __declspec(dllexport) Derived : virtual Base {
+ virtual void m();
+};
+void Derived::m() {}
+// CHECK: define dllexport void @_ZTv0_n24_N7Derived1mEv
diff --git a/test/CodeGenCXX/dllexport.cpp b/test/CodeGenCXX/dllexport.cpp
index bdef2eb06e69..a446147b6cdc 100644
--- a/test/CodeGenCXX/dllexport.cpp
+++ b/test/CodeGenCXX/dllexport.cpp
@@ -102,15 +102,9 @@ inline int __declspec(dllexport) inlineStaticLocalsFunc() {
// Declarations are not exported.
-// dllexport implies a definition.
-// MSC-NOT: @"\01??$VarTmplDef@UExplicitInst_Exported@@@@3HA"
-// GNU-NOT: @_Z10VarTmplDefI21ExplicitInst_ExportedE
-template<typename T> __declspec(dllexport) int VarTmplDef;
-INSTVAR(VarTmplDef<ExplicitInst_Exported>)
-
// MSC-DAG: @"\01??$VarTmplImplicitDef@UImplicitInst_Exported@@@@3HA" = external global
// GNU-DAG: @_Z18VarTmplImplicitDefI21ImplicitInst_ExportedE = external global
-template<typename T> __declspec(dllexport) int VarTmplImplicitDef;
+template<typename T> __declspec(dllexport) extern int VarTmplImplicitDef;
USEVAR(VarTmplImplicitDef<ImplicitInst_Exported>)
// Export definition.
@@ -826,11 +820,26 @@ struct __declspec(dllexport) B {
// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FB@pr26490@@QAEXXZ"
}
-// dllexport trumps dllexport on an explicit instantiation.
+// dllexport trumps dllimport on an explicit instantiation.
template <typename T> struct ExplicitInstantiationTwoAttributes { void f() {} };
template struct __declspec(dllexport) __declspec(dllimport) ExplicitInstantiationTwoAttributes<int>;
// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationTwoAttributes@H@@QAEXXZ"
+namespace pr34849 {
+// Specializations of exported class template member functions get exported.
+template <typename> struct __declspec(dllexport) ExportedClassTemplate { void foo(); };
+template<> void ExportedClassTemplate<int>::foo() {}
+template struct ExportedClassTemplate<int>;
+// M32-DAG: define dllexport x86_thiscallcc void @"\01?foo@?$ExportedClassTemplate@H@pr34849@@QAEXXZ"
+
+// Specializations of exported class member template functions do not get exported.
+struct __declspec(dllexport) ExportedClass { template <typename> void bar() ; };
+template<> void ExportedClass::bar<int>() {}
+// M32-DAG: define x86_thiscallcc void @"\01??$bar@H@ExportedClass@pr34849@@QAEXXZ"
+template <typename> struct __declspec(dllexport) ExportedClassTemplate2 { template <typename> void baz(); };
+template<> template<> void ExportedClassTemplate2<int>::baz<int>() {}
+// M32-DAG: define x86_thiscallcc void @"\01??$baz@H@?$ExportedClassTemplate2@H@pr34849@@QAEXXZ"
+}
//===----------------------------------------------------------------------===//
// Classes with template base classes
diff --git a/test/CodeGenCXX/dllimport-dtor-thunks.cpp b/test/CodeGenCXX/dllimport-dtor-thunks.cpp
new file mode 100644
index 000000000000..b381fff450da
--- /dev/null
+++ b/test/CodeGenCXX/dllimport-dtor-thunks.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -mconstructor-aliases %s -triple x86_64-windows-msvc -fms-extensions -emit-llvm -o - | FileCheck %s
+
+// FIXME: We should really consider removing -mconstructor-aliases for MS C++
+// ABI. The risk of bugs introducing ABI incompatibility under
+// -mno-constructor-aliases is too high.
+
+// PR32990
+
+// Introduces the virtual destructor. We should use the base destructor
+// directly, no thunk needed.
+struct __declspec(dllimport) ImportIntroVDtor {
+ virtual ~ImportIntroVDtor() {}
+};
+
+struct BaseClass {
+ virtual ~BaseClass() {}
+};
+
+// Non-virtually inherits from a non-dllimport base class. We should again call
+// the derived base constructor directly. No need for the complete (aka vbase)
+// destructor.
+struct __declspec(dllimport) ImportOverrideVDtor : public BaseClass {
+ virtual ~ImportOverrideVDtor() {}
+};
+
+// Virtually inherits from a non-dllimport base class. This time we need to call
+// the complete destructor and emit it inline. It's not exported from the DLL,
+// and it must be emitted.
+struct __declspec(dllimport) ImportVBaseOverrideVDtor
+ : public virtual BaseClass {
+ virtual ~ImportVBaseOverrideVDtor() {}
+};
+
+extern "C" void testit() {
+ ImportIntroVDtor t1;
+ ImportOverrideVDtor t2;
+ ImportVBaseOverrideVDtor t3;
+}
+
+// The destructors are called in reverse order of construction. Only the third
+// needs the complete destructor (_D).
+// CHECK-LABEL: define void @testit()
+// CHECK: call void @"\01??_DImportVBaseOverrideVDtor@@QEAAXXZ"(%struct.ImportVBaseOverrideVDtor* %{{.*}})
+// CHECK: call void @"\01??1ImportOverrideVDtor@@UEAA@XZ"(%struct.ImportOverrideVDtor* %{{.*}})
+// CHECK: call void @"\01??1ImportIntroVDtor@@UEAA@XZ"(%struct.ImportIntroVDtor* %{{.*}})
+
+// CHECK-LABEL: define linkonce_odr void @"\01??_DImportVBaseOverrideVDtor@@QEAAXXZ"
+// CHECK-LABEL: declare dllimport void @"\01??1ImportOverrideVDtor@@UEAA@XZ"
+// CHECK-LABEL: declare dllimport void @"\01??1ImportIntroVDtor@@UEAA@XZ"
diff --git a/test/CodeGenCXX/dllimport-members.cpp b/test/CodeGenCXX/dllimport-members.cpp
index 19d9e1dfe7b6..ff7868382d8c 100644
--- a/test/CodeGenCXX/dllimport-members.cpp
+++ b/test/CodeGenCXX/dllimport-members.cpp
@@ -836,7 +836,7 @@ USEMV(MemVarTmpl, ImportedStaticVar<ImplicitInst_Imported>)
// Import explicit instantiation declaration of an imported member variable
// template.
-// MSC-DAG: @"\01??$ImportedStaticVar@UExplicitDecl_Imported@@@MemVarTmpl@@2HB" = external dllimport constant i32
+// MSC-DAG: @"\01??$ImportedStaticVar@UExplicitDecl_Imported@@@MemVarTmpl@@2HB" = available_externally dllimport constant i32 1
// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI21ExplicitDecl_ImportedEE = external dllimport constant i32
extern template const int MemVarTmpl::ImportedStaticVar<ExplicitDecl_Imported>;
USEMV(MemVarTmpl, ImportedStaticVar<ExplicitDecl_Imported>)
@@ -861,7 +861,7 @@ USEMV(MemVarTmpl, ImportedStaticVar<ExplicitSpec_NotImported>)
// Import explicit instantiation declaration of a non-imported member variable
// template.
-// MSC-DAG: @"\01??$StaticVar@UExplicitDecl_Imported@@@MemVarTmpl@@2HB" = external dllimport constant i32
+// MSC-DAG: @"\01??$StaticVar@UExplicitDecl_Imported@@@MemVarTmpl@@2HB" = available_externally dllimport constant i32 1
// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitDecl_ImportedEE = external dllimport constant i32
extern template __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitDecl_Imported>;
USEMV(MemVarTmpl, StaticVar<ExplicitDecl_Imported>)
diff --git a/test/CodeGenCXX/dllimport.cpp b/test/CodeGenCXX/dllimport.cpp
index 372a96ba2efe..14558aec39a4 100644
--- a/test/CodeGenCXX/dllimport.cpp
+++ b/test/CodeGenCXX/dllimport.cpp
@@ -579,7 +579,7 @@ USE(inlineFuncTmpl<ExplicitDecl_Imported>)
// MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
// GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
// GNU-DAG: define weak_odr void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
-// MO1-DAG: define available_externally dllimport void @"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
+// MO1-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
// GO1-DAG: define available_externally dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
// GO1-DAG: define weak_odr void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
@@ -609,6 +609,15 @@ USE(funcTmpl<ExplicitSpec_Imported>)
template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
USE(funcTmpl<ExplicitSpec_InlineDef_Imported>)
+#ifdef MSABI
+namespace pr35435 {
+struct X;
+template <typename T> struct __declspec(dllimport) S {
+ void foo(T *t) { t->problem(); }
+};
+template void S<X>::foo(X*); // Cannot be instantiated because X is incomplete; dllimport means it's treated as an instantiation decl.
+}
+#endif
//===----------------------------------------------------------------------===//
diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp
index db0576a1baeb..dfbe48c37239 100644
--- a/test/CodeGenCXX/eh.cpp
+++ b/test/CodeGenCXX/eh.cpp
@@ -461,12 +461,12 @@ class DerivedException: public BaseException {
int foo() {
throw DerivedException();
- // The alignment passed to memset is 8, not 16, on Darwin.
+ // The alignment passed to memset is 16 on Darwin.
// CHECK: [[T0:%.*]] = call i8* @__cxa_allocate_exception(i64 16)
// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to %"class.test17::DerivedException"*
// CHECK-NEXT: [[T2:%.*]] = bitcast %"class.test17::DerivedException"* [[T1]] to i8*
- // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T2]], i8 0, i64 16, i32 8, i1 false)
+ // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T2]], i8 0, i64 16, i32 16, i1 false)
}
}
diff --git a/test/CodeGenCXX/exceptions-seh.cpp b/test/CodeGenCXX/exceptions-seh.cpp
index 4f7eacd66720..fa2d834c1e38 100644
--- a/test/CodeGenCXX/exceptions-seh.cpp
+++ b/test/CodeGenCXX/exceptions-seh.cpp
@@ -76,6 +76,27 @@ extern "C" void use_seh() {
// CHECK: [[cont]]
// CHECK: br label %[[ret]]
+extern "C" void nested_finally() {
+ __try {
+ might_throw();
+ } __finally {
+ __try {
+ might_throw();
+ } __finally {
+ }
+ }
+}
+
+// CHECK-LABEL: define void @nested_finally() #{{[0-9]+}}
+// CHECK-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+// CHECK: invoke void @might_throw()
+// CHECK: call void @"\01?fin$0@0@nested_finally@@"(i8 1, i8* {{.*}})
+
+// CHECK-LABEL: define internal void @"\01?fin$0@0@nested_finally@@"
+// CHECK-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+// CHECK: invoke void @might_throw()
+// CHECK: call void @"\01?fin$1@0@nested_finally@@"(i8 1, i8* {{.*}})
+
void use_seh_in_lambda() {
([]() {
__try {
diff --git a/test/CodeGenCXX/explicit-instantiation.cpp b/test/CodeGenCXX/explicit-instantiation.cpp
index 85857fb6fb8c..ad20abde8f11 100644
--- a/test/CodeGenCXX/explicit-instantiation.cpp
+++ b/test/CodeGenCXX/explicit-instantiation.cpp
@@ -170,3 +170,22 @@ void use() {
f<int>();
}
}
+
+namespace DefaultedMembers {
+ struct B { B(); B(const B&); ~B(); };
+ template<typename T> struct A : B {
+ A() = default;
+ ~A() = default;
+ };
+ extern template struct A<int>;
+
+ // CHECK-LABEL: define {{.*}} @_ZN16DefaultedMembers1AIiEC2Ev
+ // CHECK-LABEL: define {{.*}} @_ZN16DefaultedMembers1AIiED2Ev
+ A<int> ai;
+
+ // CHECK-LABEL: define {{.*}} @_ZN16DefaultedMembers1AIiEC2ERKS1_
+ A<int> ai2(ai);
+
+ // CHECK-NOT: @_ZN16DefaultedMembers1AIcE
+ template struct A<char>;
+}
diff --git a/test/CodeGenCXX/extern-section-attribute.cpp b/test/CodeGenCXX/extern-section-attribute.cpp
new file mode 100644
index 000000000000..fa0227e6fe1a
--- /dev/null
+++ b/test/CodeGenCXX/extern-section-attribute.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-linux-gnu | FileCheck %s
+
+extern int aa __attribute__((section(".sdata")));
+// CHECK-DAG: @aa = external global i32, section ".sdata", align 4
+
+extern int bb __attribute__((section(".sdata"))) = 1;
+// CHECK-DAG: @bb = global i32 1, section ".sdata", align 4
+
+int foo() {
+ return aa + bb;
+}
diff --git a/test/CodeGenCXX/finegrain-bitfield-access.cpp b/test/CodeGenCXX/finegrain-bitfield-access.cpp
new file mode 100644
index 000000000000..2973f9f73c4e
--- /dev/null
+++ b/test/CodeGenCXX/finegrain-bitfield-access.cpp
@@ -0,0 +1,162 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffine-grained-bitfield-accesses \
+// RUN: -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffine-grained-bitfield-accesses \
+// RUN: -emit-llvm -fsanitize=address -o - %s | FileCheck %s --check-prefix=SANITIZE
+// Check -fsplit-bitfields will be ignored since sanitizer is enabled.
+
+struct S1 {
+ unsigned f1:2;
+ unsigned f2:6;
+ unsigned f3:8;
+ unsigned f4:4;
+ unsigned f5:8;
+};
+
+S1 a1;
+unsigned read8_1() {
+ // CHECK-LABEL: @_Z7read8_1v
+ // CHECK: %bf.load = load i8, i8* getelementptr inbounds (%struct.S1, %struct.S1* @a1, i32 0, i32 1), align 1
+ // CHECK-NEXT: %bf.cast = zext i8 %bf.load to i32
+ // CHECK-NEXT: ret i32 %bf.cast
+ // SANITIZE-LABEL: @_Z7read8_1v
+ // SANITIZE: %bf.load = load i32, i32* getelementptr inbounds {{.*}}, align 4
+ // SANITIZE: %bf.lshr = lshr i32 %bf.load, 8
+ // SANITIZE: %bf.clear = and i32 %bf.lshr, 255
+ // SANITIZE: ret i32 %bf.clear
+ return a1.f3;
+}
+void write8_1() {
+ // CHECK-LABEL: @_Z8write8_1v
+ // CHECK: store i8 3, i8* getelementptr inbounds (%struct.S1, %struct.S1* @a1, i32 0, i32 1), align 1
+ // CHECK-NEXT: ret void
+ // SANITIZE-LABEL: @_Z8write8_1v
+ // SANITIZE: %bf.load = load i32, i32* getelementptr inbounds {{.*}}, align 4
+ // SANITIZE-NEXT: %bf.clear = and i32 %bf.load, -65281
+ // SANITIZE-NEXT: %bf.set = or i32 %bf.clear, 768
+ // SANITIZE-NEXT: store i32 %bf.set, i32* getelementptr inbounds {{.*}}, align 4
+ // SANITIZE-NEXT: ret void
+ a1.f3 = 3;
+}
+
+unsigned read8_2() {
+ // CHECK-LABEL: @_Z7read8_2v
+ // CHECK: %bf.load = load i16, i16* getelementptr inbounds (%struct.S1, %struct.S1* @a1, i32 0, i32 2), align 2
+ // CHECK-NEXT: %bf.lshr = lshr i16 %bf.load, 4
+ // CHECK-NEXT: %bf.clear = and i16 %bf.lshr, 255
+ // CHECK-NEXT: %bf.cast = zext i16 %bf.clear to i32
+ // CHECK-NEXT: ret i32 %bf.cast
+ // SANITIZE-LABEL: @_Z7read8_2v
+ // SANITIZE: %bf.load = load i32, i32* getelementptr inbounds {{.*}}, align 4
+ // SANITIZE-NEXT: %bf.lshr = lshr i32 %bf.load, 20
+ // SANITIZE-NEXT: %bf.clear = and i32 %bf.lshr, 255
+ // SANITIZE-NEXT: ret i32 %bf.clear
+ return a1.f5;
+}
+void write8_2() {
+ // CHECK-LABEL: @_Z8write8_2v
+ // CHECK: %bf.load = load i16, i16* getelementptr inbounds (%struct.S1, %struct.S1* @a1, i32 0, i32 2), align 2
+ // CHECK-NEXT: %bf.clear = and i16 %bf.load, -4081
+ // CHECK-NEXT: %bf.set = or i16 %bf.clear, 48
+ // CHECK-NEXT: store i16 %bf.set, i16* getelementptr inbounds (%struct.S1, %struct.S1* @a1, i32 0, i32 2), align 2
+ // CHECK-NEXT: ret void
+ // SANITIZE-LABEL: @_Z8write8_2v
+ // SANITIZE: %bf.load = load i32, i32* getelementptr inbounds {{.*}}, align 4
+ // SANITIZE-NEXT: %bf.clear = and i32 %bf.load, -267386881
+ // SANITIZE-NEXT: %bf.set = or i32 %bf.clear, 3145728
+ // SANITIZE-NEXT: store i32 %bf.set, i32* getelementptr inbounds {{.*}}, align 4
+ // SANITIZE-NEXT: ret void
+ a1.f5 = 3;
+}
+
+struct S2 {
+ unsigned long f1:16;
+ unsigned long f2:16;
+ unsigned long f3:6;
+};
+
+S2 a2;
+unsigned read16_1() {
+ // CHECK-LABEL: @_Z8read16_1v
+ // CHECK: %bf.load = load i16, i16* getelementptr inbounds (%struct.S2, %struct.S2* @a2, i32 0, i32 0), align 8
+ // CHECK-NEXT: %bf.cast = zext i16 %bf.load to i64
+ // CHECK-NEXT: %conv = trunc i64 %bf.cast to i32
+ // CHECK-NEXT: ret i32 %conv
+ // SANITIZE-LABEL: @_Z8read16_1v
+ // SANITIZE: %bf.load = load i64, i64* bitcast {{.*}}, align 8
+ // SANITIZE-NEXT: %bf.clear = and i64 %bf.load, 65535
+ // SANITIZE-NEXT: %conv = trunc i64 %bf.clear to i32
+ // SANITIZE-NEXT: ret i32 %conv
+ return a2.f1;
+}
+unsigned read16_2() {
+ // CHECK-LABEL: @_Z8read16_2v
+ // CHECK: %bf.load = load i16, i16* getelementptr inbounds (%struct.S2, %struct.S2* @a2, i32 0, i32 1), align 2
+ // CHECK-NEXT: %bf.cast = zext i16 %bf.load to i64
+ // CHECK-NEXT: %conv = trunc i64 %bf.cast to i32
+ // CHECK-NEXT: ret i32 %conv
+ // SANITIZE-LABEL: @_Z8read16_2v
+ // SANITIZE: %bf.load = load i64, i64* bitcast {{.*}}, align 8
+ // SANITIZE-NEXT: %bf.lshr = lshr i64 %bf.load, 16
+ // SANITIZE-NEXT: %bf.clear = and i64 %bf.lshr, 65535
+ // SANITIZE-NEXT: %conv = trunc i64 %bf.clear to i32
+ // SANITIZE-NEXT: ret i32 %conv
+ return a2.f2;
+}
+
+void write16_1() {
+ // CHECK-LABEL: @_Z9write16_1v
+ // CHECK: store i16 5, i16* getelementptr inbounds (%struct.S2, %struct.S2* @a2, i32 0, i32 0), align 8
+ // CHECK-NEXT: ret void
+ // SANITIZE-LABEL: @_Z9write16_1v
+ // SANITIZE: %bf.load = load i64, i64* bitcast {{.*}}, align 8
+ // SANITIZE-NEXT: %bf.clear = and i64 %bf.load, -65536
+ // SANITIZE-NEXT: %bf.set = or i64 %bf.clear, 5
+ // SANITIZE-NEXT: store i64 %bf.set, i64* bitcast {{.*}}, align 8
+ // SANITIZE-NEXT: ret void
+ a2.f1 = 5;
+}
+void write16_2() {
+ // CHECK-LABEL: @_Z9write16_2v
+ // CHECK: store i16 5, i16* getelementptr inbounds (%struct.S2, %struct.S2* @a2, i32 0, i32 1), align 2
+ // CHECK-NEXT: ret void
+ // SANITIZE-LABEL: @_Z9write16_2v
+ // SANITIZE: %bf.load = load i64, i64* bitcast {{.*}}, align 8
+ // SANITIZE-NEXT: %bf.clear = and i64 %bf.load, -4294901761
+ // SANITIZE-NEXT: %bf.set = or i64 %bf.clear, 327680
+ // SANITIZE-NEXT: store i64 %bf.set, i64* bitcast {{.*}}, align 8
+ // SANITIZE-NEXT: ret void
+ a2.f2 = 5;
+}
+
+struct S3 {
+ unsigned long f1:14;
+ unsigned long f2:18;
+ unsigned long f3:32;
+};
+
+S3 a3;
+unsigned read32_1() {
+ // CHECK-LABEL: @_Z8read32_1v
+ // CHECK: %bf.load = load i32, i32* getelementptr inbounds (%struct.S3, %struct.S3* @a3, i32 0, i32 1), align 4
+ // CHECK-NEXT: %bf.cast = zext i32 %bf.load to i64
+ // CHECK-NEXT: %conv = trunc i64 %bf.cast to i32
+ // CHECK-NEXT: ret i32 %conv
+ // SANITIZE-LABEL: @_Z8read32_1v
+ // SANITIZE: %bf.load = load i64, i64* getelementptr inbounds {{.*}}, align 8
+ // SANITIZE-NEXT: %bf.lshr = lshr i64 %bf.load, 32
+ // SANITIZE-NEXT: %conv = trunc i64 %bf.lshr to i32
+ // SANITIZE-NEXT: ret i32 %conv
+ return a3.f3;
+}
+void write32_1() {
+ // CHECK-LABEL: @_Z9write32_1v
+ // CHECK: store i32 5, i32* getelementptr inbounds (%struct.S3, %struct.S3* @a3, i32 0, i32 1), align 4
+ // CHECK-NEXT: ret void
+ // SANITIZE-LABEL: @_Z9write32_1v
+ // SANITIZE: %bf.load = load i64, i64* getelementptr inbounds {{.*}}, align 8
+ // SANITIZE-NEXT: %bf.clear = and i64 %bf.load, 4294967295
+ // SANITIZE-NEXT: %bf.set = or i64 %bf.clear, 21474836480
+ // SANITIZE-NEXT: store i64 %bf.set, i64* getelementptr inbounds {{.*}}, align 8
+ // SANITIZE-NEXT: ret void
+ a3.f3 = 5;
+}
diff --git a/test/CodeGenCXX/float16-declarations.cpp b/test/CodeGenCXX/float16-declarations.cpp
new file mode 100644
index 000000000000..87ef139f8634
--- /dev/null
+++ b/test/CodeGenCXX/float16-declarations.cpp
@@ -0,0 +1,149 @@
+// RUN: %clang -std=c++11 --target=aarch64-arm--eabi -S -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-AARCH64
+// RUN: %clang -std=c++11 --target=x86_64 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-X86
+
+/* Various contexts where type _Float16 can appear. */
+
+
+/* Namespace */
+
+namespace {
+ _Float16 f1n;
+// CHECK-DAG: @_ZN12_GLOBAL__N_13f1nE = internal global half 0xH0000, align 2
+
+ _Float16 f2n = 33.f16;
+// CHECK-DAG: @_ZN12_GLOBAL__N_13f2nE = internal global half 0xH5020, align 2
+
+ _Float16 arr1n[10];
+// CHECK-AARCH64-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x half] zeroinitializer, align 2
+// CHECK-X86-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x half] zeroinitializer, align 16
+
+ _Float16 arr2n[] = { 1.2, 3.0, 3.e4 };
+// CHECK-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x half] [half 0xH3CCD, half 0xH4200, half 0xH7753], align 2
+
+ const volatile _Float16 func1n(const _Float16 &arg) {
+ return arg + f2n + arr1n[4] - arr2n[1];
+ }
+}
+
+
+/* File */
+
+_Float16 f1f;
+// CHECK-AARCH64-DAG: @f1f = global half 0xH0000, align 2
+// CHECK-X86-DAG: @f1f = global half 0xH0000, align 2
+
+_Float16 f2f = 32.4;
+// CHECK-DAG: @f2f = global half 0xH500D, align 2
+
+_Float16 arr1f[10];
+// CHECK-AARCH64-DAG: @arr1f = global [10 x half] zeroinitializer, align 2
+// CHECK-X86-DAG: @arr1f = global [10 x half] zeroinitializer, align 16
+
+_Float16 arr2f[] = { -1.2, -3.0, -3.e4 };
+// CHECK-DAG: @arr2f = global [3 x half] [half 0xHBCCD, half 0xHC200, half 0xHF753], align 2
+
+_Float16 func1f(_Float16 arg);
+
+
+/* Class */
+
+class C1 {
+ _Float16 f1c;
+
+ static const _Float16 f2c;
+// CHECK-DAG: @_ZN2C13f2cE = external constant half, align 2
+
+ volatile _Float16 f3c;
+
+public:
+ C1(_Float16 arg) : f1c(arg), f3c(arg) { }
+// Check that we mangle _Float16 to DF16_
+// CHECK-DAG: define linkonce_odr void @_ZN2C1C2EDF16_(%class.C1*{{.*}}, half{{.*}})
+
+ _Float16 func1c(_Float16 arg ) {
+ return f1c + arg;
+ }
+// CHECK-DAG: define linkonce_odr half @_ZN2C16func1cEDF16_(%class.C1*{{.*}}, half{{.*}})
+
+ static _Float16 func2c(_Float16 arg) {
+ return arg * C1::f2c;
+ }
+// CHECK-DAG: define linkonce_odr half @_ZN2C16func2cEDF16_(half{{.*}})
+};
+
+/* Template */
+
+template <class C> C func1t(C arg) {
+ return arg * 2.f16;
+}
+// CHECK-DAG: define linkonce_odr half @_Z6func1tIDF16_ET_S0_(half{{.*}})
+
+template <class C> struct S1 {
+ C mem1;
+};
+
+template <> struct S1<_Float16> {
+ _Float16 mem2;
+};
+
+
+/* Local */
+
+extern int printf (const char *__restrict __format, ...);
+
+int main(void) {
+ _Float16 f1l = 1e3f16;
+// CHECK-DAG: store half 0xH63D0, half* %{{.*}}, align 2
+
+ _Float16 f2l = -0.f16;
+// CHECK-DAG: store half 0xH8000, half* %{{.*}}, align 2
+
+ _Float16 f3l = 1.000976562;
+// CHECK-DAG: store half 0xH3C01, half* %{{.*}}, align 2
+
+ C1 c1(f1l);
+// CHECK-DAG: [[F1L:%[a-z0-9]+]] = load half, half* %{{.*}}, align 2
+// CHECK-DAG: call void @_ZN2C1C2EDF16_(%class.C1* %{{.*}}, half %{{.*}})
+
+ S1<_Float16> s1 = { 132.f16 };
+// CHECK-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { half 0xH5820 }, align 2
+// CHECK-DAG: [[S1:%[0-9]+]] = bitcast %struct.S1* %{{.*}} to i8*
+// CHECK-DAG: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[S1]], i8* bitcast (%struct.S1* @_ZZ4mainE2s1 to i8*), i64 2, i32 2, i1 false)
+
+ _Float16 f4l = func1n(f1l) + func1f(f2l) + c1.func1c(f3l) + c1.func2c(f1l) +
+ func1t(f1l) + s1.mem2 - f1n + f2n;
+
+ auto f5l = -1.f16, *f6l = &f2l, f7l = func1t(f3l);
+// CHECK-DAG: store half 0xHBC00, half* %{{.*}}, align 2
+// CHECK-DAG: store half* %{{.*}}, half** %{{.*}}, align 8
+
+ _Float16 f8l = f4l++;
+// CHECK-DAG: %{{.*}} = load half, half* %{{.*}}, align 2
+// CHECK-DAG: [[INC:%[a-z0-9]+]] = fadd half {{.*}}, 0xH3C00
+// CHECK-DAG: store half [[INC]], half* %{{.*}}, align 2
+
+ _Float16 arr1l[] = { -1.f16, -0.f16, -11.f16 };
+// CHECK-DAG: @_ZZ4mainE5arr1l = private unnamed_addr constant [3 x half] [half 0xHBC00, half 0xH8000, half 0xHC980], align 2
+
+ float cvtf = f2n;
+//CHECK-DAG: [[H2F:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to float
+//CHECK-DAG: store float [[H2F]], float* %{{.*}}, align 4
+
+ double cvtd = f2n;
+//CHECK-DAG: [[H2D:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to double
+//CHECK-DAG: store double [[H2D]], double* %{{.*}}, align 8
+
+
+ long double cvtld = f2n;
+//CHECK-AARCh64-DAG: [[H2LD:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to fp128
+//CHECK-AARCh64-DAG: store fp128 [[H2LD]], fp128* %{{.*}}, align 16
+//CHECK-X86-DAG: [[H2LD:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to x86_fp80
+//CHECK-X86-DAG: store x86_fp80 [[H2LD]], x86_fp80* %{{.*}}, align 16
+
+ _Float16 f2h = 42.0f;
+//CHECK-DAG: store half 0xH5140, half* %{{.*}}, align 2
+ _Float16 d2h = 42.0;
+//CHECK-DAG: store half 0xH5140, half* %{{.*}}, align 2
+ _Float16 ld2h = 42.0l;
+//CHECK-DAG:store half 0xH5140, half* %{{.*}}, align 2
+}
diff --git a/test/CodeGenCXX/fp16-mangle.cpp b/test/CodeGenCXX/fp16-mangle.cpp
index bd5a3194112c..5827fd549dc2 100644
--- a/test/CodeGenCXX/fp16-mangle.cpp
+++ b/test/CodeGenCXX/fp16-mangle.cpp
@@ -4,9 +4,9 @@
template <typename T, typename U> struct S { static int i; };
template <> int S<__fp16, __fp16>::i = 3;
-// CHECK-LABEL: define void @_Z1fPDh(i16* %x)
+// CHECK-LABEL: define void @_Z1fPDh(half* %x)
void f (__fp16 *x) { }
-// CHECK-LABEL: define void @_Z1gPDhS_(i16* %x, i16* %y)
+// CHECK-LABEL: define void @_Z1gPDhS_(half* %x, half* %y)
void g (__fp16 *x, __fp16 *y) { }
diff --git a/test/CodeGenCXX/inline-dllexport-member.cpp b/test/CodeGenCXX/inline-dllexport-member.cpp
index 66ef459bd80b..a98f5601d3bc 100644
--- a/test/CodeGenCXX/inline-dllexport-member.cpp
+++ b/test/CodeGenCXX/inline-dllexport-member.cpp
@@ -7,7 +7,7 @@ struct __declspec(dllexport) s {
static const unsigned int ui = 0;
};
-// CHECK: [[UI]] = !DIGlobalVariableExpression(var: [[UIV:.*]])
+// CHECK: [[UI]] = !DIGlobalVariableExpression(var: [[UIV:.*]], expr: !DIExpression())
// CHECK: [[UIV]] = distinct !DIGlobalVariable(name: "ui", linkageName: "\01?ui@s@@2IB", scope: ![[SCOPE:[0-9]+]],
// CHECK: ![[SCOPE]] = distinct !DICompileUnit(
diff --git a/test/CodeGenCXX/instrument-functions.cpp b/test/CodeGenCXX/instrument-functions.cpp
index 587b6389c9a9..45ae48235a9d 100644
--- a/test/CodeGenCXX/instrument-functions.cpp
+++ b/test/CodeGenCXX/instrument-functions.cpp
@@ -1,22 +1,26 @@
-// RUN: %clang_cc1 -S -emit-llvm -triple %itanium_abi_triple -o - %s -finstrument-functions | FileCheck %s
+// RUN: %clang_cc1 -S -emit-llvm -triple %itanium_abi_triple -o - %s -finstrument-functions -disable-llvm-passes | FileCheck %s
-// CHECK: @_Z5test1i
int test1(int x) {
-// CHECK: __cyg_profile_func_enter
-// CHECK: __cyg_profile_func_exit
+// CHECK: @_Z5test1i(i32 {{.*}}%x) #[[ATTR1:[0-9]+]]
// CHECK: ret
return x;
}
-// CHECK: @_Z5test2i
int test2(int) __attribute__((no_instrument_function));
int test2(int x) {
-// CHECK-NOT: __cyg_profile_func_enter
-// CHECK-NOT: __cyg_profile_func_exit
+// CHECK: @_Z5test2i(i32 {{.*}}%x) #[[ATTR2:[0-9]+]]
// CHECK: ret
return x;
}
+// CHECK: attributes #[[ATTR1]] =
+// CHECK-SAME: "instrument-function-entry"="__cyg_profile_func_enter"
+// CHECK-SAME: "instrument-function-exit"="__cyg_profile_func_exit"
+
+// CHECK: attributes #[[ATTR2]] =
+// CHECK-NOT: "instrument-function-entry"
+
+
// This test case previously crashed code generation. It exists solely
// to test -finstrument-function does not crash codegen for this trivial
// case.
diff --git a/test/CodeGenCXX/invariant.group-for-vptrs.cpp b/test/CodeGenCXX/invariant.group-for-vptrs.cpp
index 4e5d9b49d985..45671e5a2c2a 100644
--- a/test/CodeGenCXX/invariant.group-for-vptrs.cpp
+++ b/test/CodeGenCXX/invariant.group-for-vptrs.cpp
@@ -56,7 +56,7 @@ void testInternallyVisible(bool p) {
// Checking D::D()
// CHECK-LABEL: define linkonce_odr void @_ZN1DC2Ev(
-// CHECK: = call i8* @llvm.invariant.group.barrier(i8*
+// CHECK: = call i8* @llvm.invariant.group.barrier.p0i8(i8*
// CHECK: call void @_ZN1AC2Ev(%struct.A*
// CHECK: store {{.*}} !invariant.group ![[MD]]
diff --git a/test/CodeGenCXX/mangle-exprs.cpp b/test/CodeGenCXX/mangle-exprs.cpp
index ee7594b2fdd2..6c4640269403 100644
--- a/test/CodeGenCXX/mangle-exprs.cpp
+++ b/test/CodeGenCXX/mangle-exprs.cpp
@@ -314,6 +314,19 @@ namespace test7 {
template<class T> decltype(F{{1,2}},T()) fF1(T t) {}
template<class T> decltype(F({1,2}),T()) fF2(T t) {}
+ template<class T> decltype(T{}) fT1(T t) {}
+ template<class T> decltype(T()) fT2(T t) {}
+ template<class T> decltype(T{1}) fT3(T t) {}
+ template<class T> decltype(T(1)) fT4(T t) {}
+ template<class T> decltype(T{1,2}) fT5(T t) {}
+ template<class T> decltype(T(1,2)) fT6(T t) {}
+ template<class T> decltype(T{{}}) fT7(T t) {}
+ template<class T> decltype(T({})) fT8(T t) {}
+ template<class T> decltype(T{{1}}) fT9(T t) {}
+ template<class T> decltype(T({1})) fTA(T t) {}
+ template<class T> decltype(T{{1,2}}) fTB(T t) {}
+ template<class T> decltype(T({1,2})) fTC(T t) {}
+
int main() {
fA1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fA1IiEEDTcmtlNS_1AELi1ELi2EEcvT__EES2_
fA2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fA2IiEEDTcmcvNS_1AEilLi1ELi2EEcvT__EES2_
@@ -327,6 +340,18 @@ namespace test7 {
fE2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fE2IiEEDTcmcvNS_1EEilLi1ELi2EEcvT__EES2_
fF1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fF1IiEEDTcmtlNS_1FEilLi1ELi2EEEcvT__EES2_
fF2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fF2IiEEDTcmcvNS_1FEilLi1ELi2EEcvT__EES2_
+ fT1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fT1IiEEDTtlT_EES1_(
+ fT2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fT2IiEEDTcvT__EES1_(
+ fT3(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fT3IiEEDTtlT_Li1EEES1_(
+ fT4(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fT4IiEEDTcvT_Li1EES1_(
+ fT5(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fT5INS_1BEEEDTtlT_Li1ELi2EEES2_(
+ fT6(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fT6INS_1BEEEDTcvT__Li1ELi2EEES2_(
+ fT7(A{}); // CHECK-LABEL: define {{.*}} @_ZN5test73fT7INS_1AEEEDTtlT_ilEEES2_(
+ fT8(A{}); // CHECK-LABEL: define {{.*}} @_ZN5test73fT8INS_1AEEEDTcvT_ilEES2_(
+ fT9(A{}); // CHECK-LABEL: define {{.*}} @_ZN5test73fT9INS_1AEEEDTtlT_ilLi1EEEES2_(
+ fTA(A{}); // CHECK-LABEL: define {{.*}} @_ZN5test73fTAINS_1AEEEDTcvT_ilLi1EEES2_(
+ fTB<C>(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fTBINS_1CEEEDTtlT_ilLi1ELi2EEEES2_(
+ fTC<C>(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fTCINS_1CEEEDTcvT_ilLi1ELi2EEES2_(
}
}
@@ -341,3 +366,10 @@ namespace test8 {
// CHECK-LABEL: define weak_odr i32 @_ZNK5test81XIiE3barIiEEDTcl3fooIT_EEEv
template int X<int>::bar<int>() const;
}
+
+namespace designated_init {
+ struct A { struct B { int b[5][5]; } a; };
+ // CHECK-LABEL: define {{.*}} @_ZN15designated_init1fINS_1AEEEvDTtlT_di1adi1bdxLi3EdXLi1ELi4ELi9EEE(
+ template<typename T> void f(decltype(T{.a.b[3][1 ... 4] = 9}) x) {}
+ void use_f(A a) { f<A>(a); }
+}
diff --git a/test/CodeGenCXX/mangle-fail.cpp b/test/CodeGenCXX/mangle-fail.cpp
index 02548964efc9..b588d57749fa 100644
--- a/test/CodeGenCXX/mangle-fail.cpp
+++ b/test/CodeGenCXX/mangle-fail.cpp
@@ -1,6 +1,5 @@
// RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple %itanium_abi_triple -verify %s -DN=1
// RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple %itanium_abi_triple -verify %s -DN=2
-// RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple %itanium_abi_triple -verify %s -DN=3
struct A { int a; };
@@ -14,11 +13,6 @@ template void test<int>(int (&)[sizeof(int)]);
template<class T> void test(int (&)[sizeof((A){}, T())]) {} // expected-error {{cannot yet mangle}}
template void test<int>(int (&)[sizeof(A)]);
-#elif N == 3
-// DesignatedInitExpr
-template<class T> void test(int (&)[sizeof(A{.a = 10}, T())]) {} // expected-error {{cannot yet mangle}}
-template void test<int>(int (&)[sizeof(A)]);
-
// FIXME: There are several more cases we can't yet mangle.
#else
diff --git a/test/CodeGenCXX/mangle-lambdas.cpp b/test/CodeGenCXX/mangle-lambdas.cpp
index 15987ebe46bd..d49ed4b2a5e1 100644
--- a/test/CodeGenCXX/mangle-lambdas.cpp
+++ b/test/CodeGenCXX/mangle-lambdas.cpp
@@ -26,6 +26,24 @@ void call_inline_func() {
inline_func(17);
}
+// CHECK-LABEL: define linkonce_odr i32* @_ZNK10inline_varMUlvE_clEv(
+// CHECK: @_ZZNK10inline_varMUlvE_clEvE1n
+inline auto inline_var = [] {
+ static int n = 5;
+ return &n;
+};
+
+int *use_inline_var = inline_var();
+
+// CHECK-LABEL: define linkonce_odr i32* @_ZNK12var_templateIiEMUlvE_clEv(
+// CHECK: @_ZZNK12var_templateIiEMUlvE_clEvE1n
+template<typename T> auto var_template = [] {
+ static int n = 9;
+ return &n;
+};
+
+int *use_var_template = var_template<int>();
+
struct S {
void f(int = []{return 1;}()
+ []{return 2;}(),
@@ -118,7 +136,7 @@ T StaticMembers<T>::z = accept_lambda([]{return 4;});
template<typename T>
int (*StaticMembers<T>::f)() = []{return 5;};
-// CHECK-LABEL: define internal void @__cxx_global_var_init()
+// CHECK-LABEL: define internal void @__cxx_global_var_init
// CHECK: call i32 @_ZNK13StaticMembersIfE1xMUlvE_clEv
// CHECK-NEXT: call i32 @_ZNK13StaticMembersIfE1xMUlvE0_clEv
// CHECK-NEXT: add nsw
@@ -128,23 +146,23 @@ int (*StaticMembers<T>::f)() = []{return 5;};
// CHECK: ret i32 2
template float StaticMembers<float>::x;
-// CHECK-LABEL: define internal void @__cxx_global_var_init.1()
+// CHECK-LABEL: define internal void @__cxx_global_var_init
// CHECK: call i32 @_ZNK13StaticMembersIfE1yMUlvE_clEv
// CHECK-LABEL: define linkonce_odr i32 @_ZNK13StaticMembersIfE1yMUlvE_clEv
// CHECK: ret i32 3
template float StaticMembers<float>::y;
-// CHECK-LABEL: define internal void @__cxx_global_var_init.2()
+// CHECK-LABEL: define internal void @__cxx_global_var_init
// CHECK: call i32 @_Z13accept_lambdaIN13StaticMembersIfE1zMUlvE_EEiT_
// CHECK: declare i32 @_Z13accept_lambdaIN13StaticMembersIfE1zMUlvE_EEiT_()
template float StaticMembers<float>::z;
-// CHECK-LABEL: define internal void @__cxx_global_var_init.3()
+// CHECK-LABEL: define internal void @__cxx_global_var_init
// CHECK: call {{.*}} @_ZNK13StaticMembersIfE1fMUlvE_cvPFivEEv
// CHECK-LABEL: define linkonce_odr i32 ()* @_ZNK13StaticMembersIfE1fMUlvE_cvPFivEEv
template int (*StaticMembers<float>::f)();
-// CHECK-LABEL: define internal void @__cxx_global_var_init.4
+// CHECK-LABEL: define internal void @__cxx_global_var_init
// CHECK: call i32 @"_ZNK13StaticMembersIdE3$_2clEv"
// CHECK-LABEL: define internal i32 @"_ZNK13StaticMembersIdE3$_2clEv"
// CHECK: ret i32 42
diff --git a/test/CodeGenCXX/mangle-ms-cxx11.cpp b/test/CodeGenCXX/mangle-ms-cxx11.cpp
index 819b0d9c9d0d..b22c04698ea2 100644
--- a/test/CodeGenCXX/mangle-ms-cxx11.cpp
+++ b/test/CodeGenCXX/mangle-ms-cxx11.cpp
@@ -160,6 +160,8 @@ struct { } a;
decltype(a) fun(decltype(a) x, decltype(a)) { return x; }
// CHECK-DAG: @"\01?fun@PR18022@@YA?AU<unnamed-type-a>@1@U21@0@Z"
+void use_fun() { fun(a, a); }
+
}
inline int define_lambda() {
@@ -280,7 +282,7 @@ void g() {
namespace PR18204 {
template <typename T>
-int f(T *);
+int f(T *) { return 0; }
static union {
int n = f(this);
};
@@ -346,4 +348,5 @@ int call_it = (A::default_args(), 1);
enum { enumerator };
void f(decltype(enumerator)) {}
-// CHECK-DAG: define void @"\01?f@@YAXW4<unnamed-enum-enumerator>@@@Z"(
+// CHECK-DAG: define internal void @"\01?f@@YAXW4<unnamed-enum-enumerator>@@@Z"(
+void use_f() { f(enumerator); }
diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp
index 91fe6aeef298..919f8afb1607 100644
--- a/test/CodeGenCXX/mangle.cpp
+++ b/test/CodeGenCXX/mangle.cpp
@@ -893,7 +893,8 @@ namespace test39 {
struct {} a;
} *foo;
template<typename T> void func(T) {}
- void test(foo x) {
+ void test() {
+ foo x;
func(x->a);
}
}
diff --git a/test/CodeGenCXX/member-expr-references-variable.cpp b/test/CodeGenCXX/member-expr-references-variable.cpp
new file mode 100644
index 000000000000..8c1dded800f6
--- /dev/null
+++ b/test/CodeGenCXX/member-expr-references-variable.cpp
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -std=c++11 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+struct Agg { const char * x; const char * y; constexpr Agg() : x(0), y(0) {} };
+
+struct Struct {
+ constexpr static const char *name = "foo";
+
+ constexpr static __complex float complexValue = 42.0;
+
+ static constexpr const Agg &agg = Agg();
+
+ Struct();
+ Struct(int x);
+};
+
+void use(int n, const char *c);
+
+Struct *getPtr();
+
+// CHECK: @[[STR:.*]] = private unnamed_addr constant [4 x i8] c"foo\00", align 1
+
+void scalarStaticVariableInMemberExpr(Struct *ptr, Struct &ref) {
+ use(1, Struct::name);
+// CHECK: call void @_Z3useiPKc(i32 1, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+ Struct s;
+ use(2, s.name);
+// CHECK: call void @_Z3useiPKc(i32 2, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+ use(3, ptr->name);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: call void @_Z3useiPKc(i32 3, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+ use(4, ref.name);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: call void @_Z3useiPKc(i32 4, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+ use(5, Struct(2).name);
+// CHECK: call void @_ZN6StructC1Ei(%struct.Struct* %{{.*}}, i32 2)
+// CHECK: call void @_Z3useiPKc(i32 5, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+ use(6, getPtr()->name);
+// CHECK: call %struct.Struct* @_Z6getPtrv()
+// CHECK: call void @_Z3useiPKc(i32 6, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+}
+
+void use(int n, __complex float v);
+
+void complexStaticVariableInMemberExpr(Struct *ptr, Struct &ref) {
+ use(1, Struct::complexValue);
+// CHECK: store float 4.200000e+01, float* %[[coerce0:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce0]].{{.*}}, align 4
+// CHECK: %[[cast0:.*]] = bitcast { float, float }* %[[coerce0]] to <2 x float>*
+// CHECK: %[[vector0:.*]] = load <2 x float>, <2 x float>* %[[cast0]], align 4
+// CHECK: call void @_Z3useiCf(i32 1, <2 x float> %[[vector0]])
+ Struct s;
+ use(2, s.complexValue);
+// CHECK: store float 4.200000e+01, float* %[[coerce1:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce1]].{{.*}}, align 4
+// CHECK: %[[cast1:.*]] = bitcast { float, float }* %[[coerce1]] to <2 x float>*
+// CHECK: %[[vector1:.*]] = load <2 x float>, <2 x float>* %[[cast1]], align 4
+// CHECK: call void @_Z3useiCf(i32 2, <2 x float> %[[vector1]])
+ use(3, ptr->complexValue);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: store float 4.200000e+01, float* %[[coerce2:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce2]].{{.*}}, align 4
+// CHECK: %[[cast2:.*]] = bitcast { float, float }* %[[coerce2]] to <2 x float>*
+// CHECK: %[[vector2:.*]] = load <2 x float>, <2 x float>* %[[cast2]], align 4
+// CHECK: call void @_Z3useiCf(i32 3, <2 x float> %[[vector2]])
+ use(4, ref.complexValue);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: store float 4.200000e+01, float* %[[coerce3:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce3]].{{.*}}, align 4
+// CHECK: %[[cast3:.*]] = bitcast { float, float }* %[[coerce3]] to <2 x float>*
+// CHECK: %[[vector3:.*]] = load <2 x float>, <2 x float>* %[[cast3]], align 4
+// CHECK: call void @_Z3useiCf(i32 4, <2 x float> %[[vector3]])
+ use(5, Struct(2).complexValue);
+// CHECK: call void @_ZN6StructC1Ei(%struct.Struct* %{{.*}}, i32 2)
+// CHECK: store float 4.200000e+01, float* %[[coerce4:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce4]].{{.*}}, align 4
+// CHECK: %[[cast4:.*]] = bitcast { float, float }* %[[coerce4]] to <2 x float>*
+// CHECK: %[[vector4:.*]] = load <2 x float>, <2 x float>* %[[cast4]], align 4
+// CHECK: call void @_Z3useiCf(i32 5, <2 x float> %[[vector4]])
+ use(6, getPtr()->complexValue);
+// CHECK: call %struct.Struct* @_Z6getPtrv()
+// CHECK: store float 4.200000e+01, float* %[[coerce5:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce5]].{{.*}}, align 4
+// CHECK: %[[cast5:.*]] = bitcast { float, float }* %[[coerce5]] to <2 x float>*
+// CHECK: %[[vector5:.*]] = load <2 x float>, <2 x float>* %[[cast5]], align 4
+// CHECK: call void @_Z3useiCf(i32 6, <2 x float> %[[vector5]])
+}
+
+void aggregateRefInMemberExpr(Struct *ptr, Struct &ref) {
+ use(1, Struct::agg.x);
+// CHECK: %[[value0:.*]] = load i8*, i8** getelementptr inbounds (%struct.Agg, %struct.Agg* @_ZGRN6Struct3aggE_, i32 0, i32 0), align 8
+// CHECK: call void @_Z3useiPKc(i32 1, i8* %[[value0]])
+ Struct s;
+ use(2, s.agg.x);
+// CHECK: %[[value1:.*]] = load i8*, i8** getelementptr inbounds (%struct.Agg, %struct.Agg* @_ZGRN6Struct3aggE_, i32 0, i32 0), align 8
+// CHECK: call void @_Z3useiPKc(i32 2, i8* %[[value1]])
+ use(3, ptr->agg.x);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: %[[value2:.*]] = load i8*, i8** getelementptr inbounds (%struct.Agg, %struct.Agg* @_ZGRN6Struct3aggE_, i32 0, i32 0), align 8
+// CHECK: call void @_Z3useiPKc(i32 3, i8* %[[value2]])
+ use(4, ref.agg.x);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: %[[value3:.*]] = load i8*, i8** getelementptr inbounds (%struct.Agg, %struct.Agg* @_ZGRN6Struct3aggE_, i32 0, i32 0), align 8
+// CHECK: call void @_Z3useiPKc(i32 4, i8* %[[value3]])
+}
diff --git a/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp b/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
index f3e43079c3eb..8d75ed4d9d69 100644
--- a/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
+++ b/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
@@ -78,7 +78,7 @@ T* test6(B* x) { return dynamic_cast<T*>(x); }
// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
// CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[DELTA]]
-// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[DELTA]], i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 0)
+// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* nonnull [[ADJ]], i32 [[DELTA]], i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 0)
// CHECK-NEXT: [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T*
// CHECK-NEXT: br label
// CHECK: [[RET:%.*]] = phi %struct.T*
@@ -117,7 +117,7 @@ void* test9(B* x) { return dynamic_cast<void*>(x); }
// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
// CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[DELTA]]
-// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTCastToVoid(i8* [[ADJ]])
+// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTCastToVoid(i8* nonnull [[ADJ]])
// CHECK-NEXT: br label
// CHECK: [[RET:%.*]] = phi i8*
// CHECK-NEXT: ret i8* [[RET]]
diff --git a/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
index f9db2680e336..5bed69ff117f 100644
--- a/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
@@ -19,7 +19,7 @@ struct ChildOverride : Left, Right {
extern "C" void foo(void *);
void call_left_no_override(ChildNoOverride *child) {
-// CHECK: define void @"\01?call_left_no_override
+// CHECK-LABEL: define void @"\01?call_left_no_override
// CHECK: %[[CHILD:.*]] = load %struct.ChildNoOverride
child->left();
@@ -34,7 +34,8 @@ void call_left_no_override(ChildNoOverride *child) {
}
void ChildOverride::left() {
-// CHECK: define x86_thiscallcc void @"\01?left@ChildOverride@@UAEXXZ"(%struct.ChildOverride* %[[THIS:.*]])
+// CHECK-LABEL: define x86_thiscallcc void @"\01?left@ChildOverride@@UAEXXZ"
+// CHECK-SAME: (%struct.ChildOverride* %[[THIS:.*]])
//
// No need to adjust 'this' as the ChildOverride's layout begins with Left.
// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.ChildOverride*, align 4
@@ -48,7 +49,7 @@ void ChildOverride::left() {
}
void call_left_override(ChildOverride *child) {
-// CHECK: define void @"\01?call_left_override
+// CHECK-LABEL: define void @"\01?call_left_override
// CHECK: %[[CHILD:.*]] = load %struct.ChildOverride
child->left();
@@ -62,7 +63,7 @@ void call_left_override(ChildOverride *child) {
}
void call_right_no_override(ChildNoOverride *child) {
-// CHECK: define void @"\01?call_right_no_override
+// CHECK-LABEL: define void @"\01?call_right_no_override
// CHECK: %[[CHILD:.*]] = load %struct.ChildNoOverride
child->right();
@@ -82,25 +83,27 @@ void call_right_no_override(ChildNoOverride *child) {
}
void ChildOverride::right() {
-// CHECK: define x86_thiscallcc void @"\01?right@ChildOverride@@UAEXXZ"(i8*
+// CHECK-LABEL: define x86_thiscallcc void @"\01?right@ChildOverride@@UAEXXZ"(i8*
//
// ChildOverride::right gets 'this' cast to Right* in ECX (i.e. this+4) so we
// need to adjust 'this' before use.
//
// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.ChildOverride*, align 4
-// CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX:.*]], i32 -4
-// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.ChildOverride*
-// CHECK: store %struct.ChildOverride* %[[THIS]], %struct.ChildOverride** %[[THIS_ADDR]], align 4
+// CHECK: %[[THIS_INIT:.*]] = bitcast i8* %[[ECX:.*]] to %struct.ChildOverride*
+// CHECK: store %struct.ChildOverride* %[[THIS_INIT]], %struct.ChildOverride** %[[THIS_ADDR]], align 4
+// CHECK: %[[THIS_RELOAD:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_ADDR]]
+// CHECK: %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS_RELOAD]] to i8*
+// CHECK: %[[THIS_ADJUSTED:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 -4
+// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJUSTED]] to %struct.ChildOverride*
foo(this);
-// CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_ADDR]]
// CHECK: %[[THIS_PARAM:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8*
// CHECK: call void @foo(i8* %[[THIS_PARAM]])
// CHECK: ret
}
void call_right_override(ChildOverride *child) {
-// CHECK: define void @"\01?call_right_override
+// CHECK-LABEL: define void @"\01?call_right_override
// CHECK: %[[CHILD:.*]] = load %struct.ChildOverride
child->right();
@@ -127,15 +130,17 @@ struct GrandchildOverride : ChildOverride {
};
void GrandchildOverride::right() {
-// CHECK: define x86_thiscallcc void @"\01?right@GrandchildOverride@@UAEXXZ"(i8*
+// CHECK-LABEL: define x86_thiscallcc void @"\01?right@GrandchildOverride@@UAEXXZ"(i8*
//
// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.GrandchildOverride*, align 4
-// CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX:.*]], i32 -4
-// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.GrandchildOverride*
-// CHECK: store %struct.GrandchildOverride* %[[THIS]], %struct.GrandchildOverride** %[[THIS_ADDR]], align 4
+// CHECK: %[[THIS_INIT:.*]] = bitcast i8* %[[ECX:.*]] to %struct.GrandchildOverride*
+// CHECK: store %struct.GrandchildOverride* %[[THIS_INIT]], %struct.GrandchildOverride** %[[THIS_ADDR]], align 4
+// CHECK: %[[THIS_RELOAD:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride** %[[THIS_ADDR]]
+// CHECK: %[[THIS_i8:.*]] = bitcast %struct.GrandchildOverride* %[[THIS_RELOAD]] to i8*
+// CHECK: %[[THIS_ADJUSTED:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 -4
+// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJUSTED]] to %struct.GrandchildOverride*
foo(this);
-// CHECK: %[[THIS:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride** %[[THIS_ADDR]]
// CHECK: %[[THIS_PARAM:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i8*
// CHECK: call void @foo(i8* %[[THIS_PARAM]])
// CHECK: ret
@@ -148,19 +153,19 @@ void call_grandchild_right(GrandchildOverride *obj) {
void emit_ctors() {
Left l;
- // CHECK: define {{.*}} @"\01??0Left@@QAE@XZ"
+ // CHECK-LABEL: define {{.*}} @"\01??0Left@@QAE@XZ"
// CHECK-NOT: getelementptr
// CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7Left@@6B@" to i32 (...)**)
// CHECK: ret
Right r;
- // CHECK: define {{.*}} @"\01??0Right@@QAE@XZ"
+ // CHECK-LABEL: define {{.*}} @"\01??0Right@@QAE@XZ"
// CHECK-NOT: getelementptr
// CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7Right@@6B@" to i32 (...)**)
// CHECK: ret
ChildOverride co;
- // CHECK: define {{.*}} @"\01??0ChildOverride@@QAE@XZ"
+ // CHECK-LABEL: define {{.*}} @"\01??0ChildOverride@@QAE@XZ"
// CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride**
// CHECK: %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i32 (...)***
// CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7ChildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
@@ -171,7 +176,7 @@ void emit_ctors() {
// CHECK: ret
GrandchildOverride gc;
- // CHECK: define {{.*}} @"\01??0GrandchildOverride@@QAE@XZ"
+ // CHECK-LABEL: define {{.*}} @"\01??0GrandchildOverride@@QAE@XZ"
// CHECK: %[[THIS:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride**
// CHECK: %[[VFPTR:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i32 (...)***
// CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7GrandchildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
diff --git a/test/CodeGenCXX/microsoft-abi-static-initializers.cpp b/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
index 57a72d4e2a6c..0b84f07e1154 100644
--- a/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
+++ b/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
@@ -146,7 +146,7 @@ inline S &getS() {
// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.S* @"\01?getS@@YAAAUS@@XZ"() {{.*}} comdat
// CHECK: load i32, i32* @"\01??_B?1??getS@@YAAAUS@@XZ@51"
// CHECK: and i32 {{.*}}, 1
-// CHECK: icmp ne i32 {{.*}}, 0
+// CHECK: icmp eq i32 {{.*}}, 0
// CHECK: br i1
// init:
// CHECK: or i32 {{.*}}, 1
diff --git a/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp b/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp
index 0202586c8a62..3f53e631c964 100644
--- a/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp
+++ b/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp
@@ -24,8 +24,8 @@ extern inline S &f() {
static thread_local S s;
// CHECK: %[[guard:.*]] = load i32, i32* @"\01??__J?1??f@@YAAAUS@@XZ@51"
// CHECK-NEXT: %[[mask:.*]] = and i32 %[[guard]], 1
-// CHECK-NEXT: %[[cmp:.*]] = icmp ne i32 %[[mask]], 0
-// CHECK-NEXT: br i1 %[[cmp]], label %[[init_end:.*]], label %[[init:.*]]
+// CHECK-NEXT: %[[cmp:.*]] = icmp eq i32 %[[mask]], 0
+// CHECK-NEXT: br i1 %[[cmp]], label %[[init:.*]], label %[[init_end:.*]], !prof ![[unlikely_threadlocal:.*]]
//
// CHECK: [[init]]:
// CHECK-NEXT: %[[or:.*]] = or i32 %[[guard]], 1
@@ -56,7 +56,7 @@ extern inline S &g() {
// CHECK: %[[guard:.*]] = load atomic i32, i32* @"\01?$TSS0@?1??g@@YAAAUS@@XZ@4HA" unordered, align 4
// CHECK-NEXT: %[[epoch:.*]] = load i32, i32* @_Init_thread_epoch
// CHECK-NEXT: %[[cmp:.*]] = icmp sgt i32 %[[guard]], %[[epoch]]
-// CHECK-NEXT: br i1 %[[cmp]], label %[[init_attempt:.*]], label %[[init_end:.*]]
+// CHECK-NEXT: br i1 %[[cmp]], label %[[init_attempt:.*]], label %[[init_end:.*]], !prof ![[unlikely_staticlocal:.*]]
//
// CHECK: [[init_attempt]]:
// CHECK-NEXT: call void @_Init_thread_header(i32* @"\01?$TSS0@?1??g@@YAAAUS@@XZ@4HA")
@@ -95,3 +95,6 @@ int g1() {
static int i = f1();
return i;
}
+
+// CHECK-DAG: ![[unlikely_threadlocal]] = !{!"branch_weights", i32 1, i32 1023}
+// CHECK-DAG: ![[unlikely_staticlocal]] = !{!"branch_weights", i32 1, i32 1048575}
diff --git a/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp b/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
index bb73f8773ccb..2f141b2a66ec 100644
--- a/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
+++ b/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
@@ -24,6 +24,7 @@ struct D : virtual C {
D::D() {} // Forces vftable emission.
// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f@D@@$4PPPPPPPM@A@AEXXZ"
+// Note that the vtordisp is applied before really adjusting to D*.
// CHECK: %[[ECX:.*]] = load %struct.D*, %struct.D** %{{.*}}
// CHECK: %[[ECX_i8:.*]] = bitcast %struct.D* %[[ECX]] to i8*
// CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX_i8]], i32 -4
diff --git a/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
index 20ecaf431650..c9dd1dd7d8e2 100644
--- a/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o %t
+// RUN: %clang_cc1 %s -fno-rtti -std=c++11 -Wno-inaccessible-base -triple=i386-pc-win32 -emit-llvm -o %t
// RUN: FileCheck %s < %t
// RUN: FileCheck --check-prefix=CHECK2 %s < %t
// For now, just make sure x86_64 doesn't crash.
-// RUN: %clang_cc1 %s -fno-rtti -triple=x86_64-pc-win32 -emit-llvm -o %t
+// RUN: %clang_cc1 %s -fno-rtti -std=c++11 -Wno-inaccessible-base -triple=x86_64-pc-win32 -emit-llvm -o %t
struct VBase {
virtual ~VBase();
@@ -52,12 +52,14 @@ B::B() {
B::~B() {
// CHECK-LABEL: define x86_thiscallcc void @"\01??1B@@UAE@XZ"
- // Adjust the this parameter:
- // CHECK: %[[THIS_PARAM_i8:.*]] = bitcast %struct.B* {{.*}} to i8*
- // CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_PARAM_i8]], i32 -8
- // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B*
- // CHECK: store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR:.*]], align 4
- // CHECK: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
+ // Store initial this:
+ // CHECK: %[[THIS_ADDR:.*]] = alloca %struct.B*
+ // CHECK: store %struct.B* %{{.*}}, %struct.B** %[[THIS_ADDR]], align 4
+ // Reload and adjust the this parameter:
+ // CHECK: %[[THIS_RELOAD:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
+ // CHECK: %[[THIS_UNADJ_i8:.*]] = bitcast %struct.B* %[[THIS_RELOAD]] to i8*
+ // CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -8
+ // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %struct.B*
// Restore the vfptr that could have been changed by a subclass.
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
@@ -97,11 +99,11 @@ B::~B() {
// CHECK2: ret
// CHECK2-LABEL: define linkonce_odr x86_thiscallcc i8* @"\01??_GB@@UAEPAXI@Z"
- // CHECK2: %[[THIS_PARAM_i8:.*]] = bitcast %struct.B* {{.*}} to i8*
+ // CHECK2: store %struct.B* %{{.*}}, %struct.B** %[[THIS_ADDR:.*]], align 4
+ // CHECK2: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
+ // CHECK2: %[[THIS_PARAM_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
// CHECK2: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_PARAM_i8:.*]], i32 -8
// CHECK2: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B*
- // CHECK2: store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR:.*]], align 4
- // CHECK2: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
// CHECK2: call x86_thiscallcc void @"\01??_DB@@QAEXXZ"(%struct.B* %[[THIS]])
// ...
// CHECK2: ret
@@ -113,13 +115,17 @@ void B::foo() {
// B::foo gets 'this' cast to VBase* in ECX (i.e. this+8) so we
// need to adjust 'this' before use.
//
-// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.B*, align 4
-// CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX:.*]], i32 -8
-// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B*
-// CHECK: store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR]], align 4
+// Store initial this:
+// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.B*
+// CHECK: store %struct.B* %{{.*}}, %struct.B** %[[THIS_ADDR]], align 4
+//
+// Reload and adjust the this parameter:
+// CHECK: %[[THIS_RELOAD:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
+// CHECK: %[[THIS_UNADJ_i8:.*]] = bitcast %struct.B* %[[THIS_RELOAD]] to i8*
+// CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -8
+// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %struct.B*
field = 42;
-// CHECK: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
// CHECK: %[[THIS8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS8]], i32 0
// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
@@ -284,11 +290,16 @@ struct D : virtual Z, B, C {
D::~D() {
// CHECK-LABEL: define x86_thiscallcc void @"\01??1D@diamond@@UAE@XZ"(%"struct.diamond::D"*{{.*}})
- // CHECK: %[[ARG_i8:.*]] = bitcast %"struct.diamond::D"* %{{.*}} to i8*
- // CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ARG_i8]], i32 -24
- // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %"struct.diamond::D"*
- // CHECK: store %"struct.diamond::D"* %[[THIS]], %"struct.diamond::D"** %[[THIS_VAL:.*]], align 4
- // CHECK: %[[THIS:.*]] = load %"struct.diamond::D"*, %"struct.diamond::D"** %[[THIS_VAL]]
+ // Store initial this:
+ // CHECK: %[[THIS_ADDR:.*]] = alloca %"struct.diamond::D"*
+ // CHECK: store %"struct.diamond::D"* %{{.*}}, %"struct.diamond::D"** %[[THIS_ADDR]], align 4
+ //
+ // Reload and adjust the this parameter:
+ // CHECK: %[[THIS_RELOAD:.*]] = load %"struct.diamond::D"*, %"struct.diamond::D"** %[[THIS_ADDR]]
+ // CHECK: %[[THIS_UNADJ_i8:.*]] = bitcast %"struct.diamond::D"* %[[THIS_RELOAD]] to i8*
+ // CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -24
+ // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %"struct.diamond::D"*
+ //
// CHECK: %[[D_i8:.*]] = bitcast %"struct.diamond::D"* %[[THIS]] to i8*
// CHECK: %[[C_i8:.*]] = getelementptr inbounds i8, i8* %[[D_i8]], i32 4
// CHECK: %[[C:.*]] = bitcast i8* %[[C_i8]] to %"struct.diamond::C"*
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp
index b97c432f5e02..385e9cc17b1b 100644
--- a/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp
@@ -196,7 +196,11 @@ void C::g(NonTrivial o) {
}
// BITCODE-LABEL: define void @"\01?g@C@pr30293@@UAAXUNonTrivial@2@@Z"(<{ i8*, %"struct.pr30293::NonTrivial" }>* inalloca)
-// BITCODE: %[[this1:[^ ]*]] = load i8*, i8** %[[thisaddr:[^ ]*]], align 4
-// BITCODE-NEXT: %[[this2:[^ ]*]] = getelementptr inbounds i8, i8* %[[this1]], i32 -4
-// BITCODE-NEXT: store i8* %[[this2]], i8** %[[thisaddr]], align 4
+// BITCODE: %[[thisaddr:[^ ]*]] = getelementptr inbounds <{ i8*, %"struct.pr30293::NonTrivial" }>, <{ i8*, %"struct.pr30293::NonTrivial" }>* {{.*}}, i32 0, i32 0
+// BITCODE: %[[thisaddr1:[^ ]*]] = bitcast i8** %[[thisaddr]] to %"struct.pr30293::C"**
+// BITCODE: %[[this1:[^ ]*]] = load %"struct.pr30293::C"*, %"struct.pr30293::C"** %[[thisaddr1]], align 4
+// BITCODE: %[[this2:[^ ]*]] = bitcast %"struct.pr30293::C"* %[[this1]] to i8*
+// BITCODE: %[[this3:[^ ]*]] = getelementptr inbounds i8, i8* %[[this2]], i32 -4
+// BITCODE: %[[this4:[^ ]*]] = bitcast i8* %[[this3]] to %"struct.pr30293::C"*
+// BITCODE: store %"struct.pr30293::C"* %[[this4]], %"struct.pr30293::C"** @"\01?whatsthis@pr30293@@3PAUC@1@A", align 4
}
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp b/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
index 2bf7da58ea9c..feba91c50556 100644
--- a/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
@@ -201,3 +201,18 @@ D::D() {}
// GLOBALS: @"\01?fn@D@test3@@$4PPPPPPPM@A@AEPAUB@2@XZ"
// GLOBALS: @"\01?fn@D@test3@@$4PPPPPPPM@A@AEPAU12@XZ"
}
+
+namespace pr34302 {
+// C::f is lives in the vftable inside its virtual B subobject. In the MS ABI,
+// covariant return type virtual methods extend vftables from virtual bases,
+// even though that can make it impossible to implement certain diamond
+// hierarchies correctly.
+struct A { virtual ~A(); };
+struct B : A { virtual B *f(); };
+struct C : virtual B { C *f(); };
+C c;
+// VFTABLES-LABEL: VFTable indices for 'pr34302::C' (2 entries).
+// VFTABLES-NEXT: -- accessible via vbtable index 1, vfptr at offset 0 --
+// VFTABLES-NEXT: 0 | pr34302::C::~C() [scalar deleting]
+// VFTABLES-NEXT: 2 | pr34302::C *pr34302::C::f()
+}
diff --git a/test/CodeGenCXX/microsoft-inaccessible-base.cpp b/test/CodeGenCXX/microsoft-inaccessible-base.cpp
new file mode 100644
index 000000000000..2c0d124eb01e
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-inaccessible-base.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fms-compatibility -triple x86_64-windows-msvc %s -emit-llvm -o - | FileCheck %s
+
+// Make sure we choose the *direct* base path when doing these conversions.
+
+// CHECK: %struct.C = type { %struct.A, %struct.B }
+// CHECK: %struct.D = type { %struct.B, %struct.A }
+
+struct A { int a; };
+struct B : A { int b; };
+
+struct C : A, B { };
+extern "C" A *a_from_c(C *p) { return p; }
+// CHECK-LABEL: define %struct.A* @a_from_c(%struct.C* %{{.*}})
+// CHECK: bitcast %struct.C* %{{.*}} to %struct.A*
+
+struct D : B, A { };
+extern "C" A *a_from_d(D *p) { return p; }
+// CHECK-LABEL: define %struct.A* @a_from_d(%struct.D* %{{.*}})
+// CHECK: %[[p_i8:[^ ]*]] = bitcast %struct.D* %{{.*}} to i8*
+// CHECK: getelementptr inbounds i8, i8* %[[p_i8]], i64 8
diff --git a/test/CodeGenCXX/mingw-w64-exceptions.c b/test/CodeGenCXX/mingw-w64-exceptions.c
new file mode 100644
index 000000000000..e980ebd33505
--- /dev/null
+++ b/test/CodeGenCXX/mingw-w64-exceptions.c
@@ -0,0 +1,22 @@
+// RUN: %clang -target x86_64-windows-gnu -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SEH
+// RUN: %clang -target i686-windows-gnu -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DWARF
+
+// RUN: %clang -target x86_64-windows-gnu -fsjlj-exceptions -c %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-SJLJ
+
+// RUN: %clang -target x86_64-windows-gnu -fdwarf-exceptions -c %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-DWARF
+
+// RUN: %clang -target x86_64-windows-gnu -fsjlj-exceptions -fseh-exceptions -c %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-SEH
+
+// RUN: %clang -target x86_64-windows-gnu -fseh-exceptions -fsjlj-exceptions -c %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-SJLJ
+
+// RUN: %clang -target x86_64-windows-gnu -fseh-exceptions -fdwarf-exceptions -c %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-DWARF
+
+// CHECK-SEH: "-fseh-exceptions"
+// CHECK-SJLJ: "-fsjlj-exceptions"
+// CHECK-DWARF-NOT: "-fsjlj-exceptions"
+// CHECK-DWARF-NOT: "-fseh-exceptions"
diff --git a/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp b/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp
index 9025f877c551..046c4a815f46 100644
--- a/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp
+++ b/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -fexceptions -emit-llvm -triple x86_64-w64-windows-gnu -o - | FileCheck %s --check-prefix=X64
+// RUN: %clang_cc1 %s -fexceptions -fseh-exceptions -emit-llvm -triple x86_64-w64-windows-gnu -o - | FileCheck %s --check-prefix=X64
+// RUN: %clang_cc1 %s -fexceptions -fdwarf-exceptions -emit-llvm -triple i686-w64-windows-gnu -o - | FileCheck %s --check-prefix=X86
// RUN: %clang_cc1 %s -fexceptions -emit-llvm -triple i686-w64-windows-gnu -o - | FileCheck %s --check-prefix=X86
extern "C" void foo();
diff --git a/test/CodeGenCXX/ms-eh-personality.cpp b/test/CodeGenCXX/ms-eh-personality.cpp
new file mode 100644
index 000000000000..592ab69efaf2
--- /dev/null
+++ b/test/CodeGenCXX/ms-eh-personality.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fexceptions -fcxx-exceptions %s -emit-llvm -o - | FileCheck %s --check-prefix=MSVC
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fexceptions -fcxx-exceptions -fsjlj-exceptions %s -emit-llvm -o - | FileCheck %s --check-prefix=SJLJ
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fexceptions -fcxx-exceptions -fseh-exceptions %s -emit-llvm -o - | FileCheck %s --check-prefix=MSVC
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fexceptions -fcxx-exceptions -fdwarf-exceptions %s -emit-llvm -o - | FileCheck %s --check-prefix=DWARF
+
+// MSVC: define void @f(){{.*}}@__CxxFrameHandler3
+// SJLJ: define void @f(){{.*}}@__gxx_personality_sj0
+// DWARF: define void @f(){{.*}}@__gxx_personality_v0
+
+struct Cleanup {
+ Cleanup();
+ ~Cleanup();
+ int x = 0;
+};
+
+void g();
+extern "C" void f() {
+ Cleanup c;
+ g();
+}
diff --git a/test/CodeGenCXX/ms-inline-asm-return.cpp b/test/CodeGenCXX/ms-inline-asm-return.cpp
index 51671c0bcdaa..837f1b437a4c 100644
--- a/test/CodeGenCXX/ms-inline-asm-return.cpp
+++ b/test/CodeGenCXX/ms-inline-asm-return.cpp
@@ -70,7 +70,7 @@ FourChars f_s4() {
}
}
// CHECK-LABEL: define i32 @f_s4()
-// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$0x01010101", "={eax},~{eax},{{.*}}"
+// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$16843009", "={eax},~{eax},{{.*}}"
// CHECK: store i32 %[[r]], i32* %{{.*}}
// CHECK: %[[r_i32:[^ ]*]] = load i32, i32* %{{.*}}
// CHECK: ret i32 %[[r_i32]]
@@ -85,7 +85,7 @@ EightChars f_s8() {
}
}
// CHECK-LABEL: define i64 @f_s8()
-// CHECK: %[[r:[^ ]*]] = call i64 asm sideeffect inteldialect "mov eax, $$01010101h\0A\09mov edx, $$01010101b", "=A,~{eax},{{.*}}"
+// CHECK: %[[r:[^ ]*]] = call i64 asm sideeffect inteldialect "mov eax, $$16843009\0A\09mov edx, $$85", "=A,~{eax},{{.*}}"
// CHECK: store i64 %[[r]], i64* %{{.*}}
// CHECK: %[[r_i64:[^ ]*]] = load i64, i64* %{{.*}}
// CHECK: ret i64 %[[r_i64]]
diff --git a/test/CodeGenCXX/new-overflow.cpp b/test/CodeGenCXX/new-overflow.cpp
index 0c4c3c823d19..b27984f66ab6 100644
--- a/test/CodeGenCXX/new-overflow.cpp
+++ b/test/CodeGenCXX/new-overflow.cpp
@@ -85,9 +85,7 @@ namespace test4 {
// CHECK: define [[A:%.*]]* @_ZN5test44testEs(i16 signext
// CHECK: [[N:%.*]] = sext i16 {{%.*}} to i32
- // CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[N]], 0
- // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 -1, i32 [[N]]
- // CHECK-NEXT: call i8* @_Znaj(i32 [[T1]])
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[N]])
// CHECK: getelementptr inbounds {{.*}}, i32 [[N]]
elt *test(short s) {
return new elt[s];
@@ -104,9 +102,7 @@ namespace test5 {
// CHECK: define [[A:%.*]]* @_ZN5test54testEi(i32
// CHECK: [[N:%.*]] = load i32, i32*
- // CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[N]], 0
- // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 -1, i32 [[N]]
- // CHECK-NEXT: call i8* @_Znaj(i32 [[T1]])
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[N]])
// CHECK: getelementptr inbounds {{.*}}, i32 [[N]]
elt *test(int s) {
return new elt[s];
@@ -169,13 +165,11 @@ namespace test8 {
// CHECK: define [[A:%.*]]* @_ZN5test84testEx(i64
// CHECK: [[N:%.*]] = load i64, i64*
- // CHECK-NEXT: [[T0:%.*]] = icmp uge i64 [[N]], 4294967296
// CHECK-NEXT: [[T1:%.*]] = trunc i64 [[N]] to i32
// CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 4)
// CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 1
- // CHECK-NEXT: [[T4:%.*]] = or i1 [[T0]], [[T3]]
// CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0
- // CHECK-NEXT: [[T6:%.*]] = select i1 [[T4]], i32 -1, i32 [[T5]]
+ // CHECK-NEXT: [[T6:%.*]] = select i1 [[T3]], i32 -1, i32 [[T5]]
// CHECK-NEXT: call i8* @_Znaj(i32 [[T6]])
// CHECK: getelementptr inbounds {{.*}}, i32 [[T1]]
elt *test(long long s) {
@@ -194,13 +188,11 @@ namespace test9 {
// CHECK: define [[A:%.*]]* @_ZN5test94testEy(i64
// CHECK: [[N:%.*]] = load i64, i64*
- // CHECK-NEXT: [[T0:%.*]] = icmp uge i64 [[N]], 4294967296
// CHECK-NEXT: [[T1:%.*]] = trunc i64 [[N]] to i32
// CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 4)
// CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 1
- // CHECK-NEXT: [[T4:%.*]] = or i1 [[T0]], [[T3]]
// CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0
- // CHECK-NEXT: [[T6:%.*]] = select i1 [[T4]], i32 -1, i32 [[T5]]
+ // CHECK-NEXT: [[T6:%.*]] = select i1 [[T3]], i32 -1, i32 [[T5]]
// CHECK-NEXT: call i8* @_Znaj(i32 [[T6]])
// CHECK: getelementptr inbounds {{.*}}, i32 [[T1]]
elt *test(unsigned long long s) {
diff --git a/test/CodeGenCXX/new.cpp b/test/CodeGenCXX/new.cpp
index ae2ec1505c5d..3bebc2ab8ac8 100644
--- a/test/CodeGenCXX/new.cpp
+++ b/test/CodeGenCXX/new.cpp
@@ -255,8 +255,6 @@ namespace test15 {
// CHECK-LABEL: define void @_ZN6test155test2EPvi(
// CHECK: [[N:%.*]] = load i32, i32*
// CHECK-NEXT: [[T0:%.*]] = sext i32 [[N]] to i64
- // CHECK-NEXT: [[T1:%.*]] = icmp slt i64 [[T0]], 0
- // CHECK-NEXT: [[T2:%.*]] = select i1 [[T1]], i64 -1, i64 [[T0]]
// CHECK-NEXT: [[P:%.*]] = load i8*, i8**
// CHECK: [[BEGIN:%.*]] = bitcast i8* [[P]] to [[A:%.*]]*
// CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq i64 [[T0]], 0
diff --git a/test/CodeGenCXX/noescape.cpp b/test/CodeGenCXX/noescape.cpp
new file mode 100644
index 000000000000..90d24de3da29
--- /dev/null
+++ b/test/CodeGenCXX/noescape.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+struct S {
+ int a[4];
+ S(int *, int * __attribute__((noescape)));
+ S &operator=(int * __attribute__((noescape)));
+ void m0(int *, int * __attribute__((noescape)));
+ virtual void vm1(int *, int * __attribute__((noescape)));
+};
+
+// CHECK: define void @_ZN1SC2EPiS0_(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture)
+// CHECK: define void @_ZN1SC1EPiS0_(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture) {{.*}} {
+// CHECK: call void @_ZN1SC2EPiS0_(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture {{.*}})
+
+S::S(int *, int * __attribute__((noescape))) {}
+
+// CHECK: define {{.*}} %struct.S* @_ZN1SaSEPi(%struct.S* {{.*}}, {{.*}} nocapture)
+S &S::operator=(int * __attribute__((noescape))) { return *this; }
+
+// CHECK: define void @_ZN1S2m0EPiS0_(%struct.S* {{.*}}, {{.*}} nocapture)
+void S::m0(int *, int * __attribute__((noescape))) {}
+
+// CHECK: define void @_ZN1S3vm1EPiS0_(%struct.S* {{.*}}, {{.*}} nocapture)
+void S::vm1(int *, int * __attribute__((noescape))) {}
+
+// CHECK-LABEL: define void @_Z5test0P1SPiS1_(
+// CHECK: call void @_ZN1SC1EPiS0_(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture {{.*}})
+// CHECK: call {{.*}} %struct.S* @_ZN1SaSEPi(%struct.S* {{.*}}, {{.*}} nocapture {{.*}})
+// CHECK: call void @_ZN1S2m0EPiS0_(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture {{.*}})
+// CHECK: call void {{.*}}(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture {{.*}})
+void test0(S *s, int *p0, int *p1) {
+ S t(p0, p1);
+ t = p1;
+ s->m0(p0, p1);
+ s->vm1(p0, p1);
+}
+
+namespace std {
+ typedef decltype(sizeof(0)) size_t;
+}
+
+// CHECK: define {{.*}} @_ZnwmPv({{.*}}, {{.*}} nocapture {{.*}})
+void *operator new(std::size_t, void * __attribute__((noescape)) p) {
+ return p;
+}
+
+// CHECK-LABEL: define i8* @_Z5test1Pv(
+// CHECK : %call = call {{.*}} @_ZnwmPv({{.*}}, {{.*}} nocapture {{.*}})
+void *test1(void *p0) {
+ return ::operator new(16, p0);
+}
+
+// CHECK-LABEL: define void @_Z5test2PiS_(
+// CHECK: call void @"_ZZ5test2PiS_ENK3$_0clES_S_"({{.*}}, {{.*}}, {{.*}} nocapture {{.*}})
+// CHECK: define internal void @"_ZZ5test2PiS_ENK3$_0clES_S_"({{.*}}, {{.*}}, {{.*}} nocapture)
+void test2(int *p0, int *p1) {
+ auto t = [](int *, int * __attribute__((noescape))){};
+ t(p0, p1);
+}
+
+// CHECK-LABEL: define void @_Z5test3PFvU8noescapePiES_(
+// CHECK: call void {{.*}}(i32* nocapture {{.*}})
+typedef void (*NoEscapeFunc)(__attribute__((noescape)) int *);
+
+void test3(NoEscapeFunc f, int *p) {
+ f(p);
+}
diff --git a/test/CodeGenCXX/pr29160.cpp b/test/CodeGenCXX/pr29160.cpp
new file mode 100644
index 000000000000..09cf2a637072
--- /dev/null
+++ b/test/CodeGenCXX/pr29160.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -std=c++11 -triple i686-linux-gnu %s -o /dev/null -S -emit-llvm
+//
+// This test's failure mode is running ~forever. (For some value of "forever"
+// that's greater than 25 minutes on my machine)
+
+template <typename... Ts>
+struct Foo {
+ template <typename... T>
+ static void ignore() {}
+ Foo() { ignore<Ts...>(); }
+};
+
+struct Base {
+ Base();
+ ~Base();
+};
+
+#define STAMP(thiz, prev) using thiz = Foo< \
+ prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, \
+ prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, \
+ prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, prev \
+ >;
+STAMP(A, Base);
+STAMP(B, A);
+STAMP(C, B);
+STAMP(D, C);
+STAMP(E, D);
+STAMP(F, E);
+STAMP(G, F);
+STAMP(H, G);
+STAMP(I, H);
+STAMP(J, I);
+STAMP(K, J);
+STAMP(L, K);
+STAMP(M, L);
+STAMP(N, M);
+STAMP(O, N);
+STAMP(P, O);
+STAMP(Q, P);
+
+int main() { Q q; }
diff --git a/test/CodeGenCXX/regcall.cpp b/test/CodeGenCXX/regcall.cpp
index 0ff6fdf12a58..2b7b9e2a6eff 100644
--- a/test/CodeGenCXX/regcall.cpp
+++ b/test/CodeGenCXX/regcall.cpp
@@ -73,8 +73,8 @@ bool __regcall operator ==(const test_class&, const test_class&){ --x; return fa
// CHECK-WIN64-DAG: define x86_regcallcc zeroext i1 @"\01??8@Yw_NAEBVtest_class@@0@Z"
// CHECK-WIN32-DAG: define x86_regcallcc zeroext i1 @"\01??8@Yw_NABVtest_class@@0@Z"
-test_class __regcall operator""_test_class (unsigned long long) { ++x; return test_class{};}
-// CHECK-LIN64-DAG: define x86_regcallcc %class.test_class @_Zli11_test_classy(i64)
+test_class __regcall operator""_test_class (unsigned long long) { ++x; return test_class{};}
+// CHECK-LIN64-DAG: define x86_regcallcc void @_Zli11_test_classy(%class.test_class* noalias sret %agg.result, i64)
// CHECK-LIN32-DAG: define x86_regcallcc void @_Zli11_test_classy(%class.test_class* inreg noalias sret %agg.result, i64)
// CHECK-WIN64-DAG: \01??__K_test_class@@Yw?AVtest_class@@_K@Z"
// CHECK-WIN32-DAG: \01??__K_test_class@@Yw?AVtest_class@@_K@Z"
@@ -95,3 +95,11 @@ void force_gen() {
freeTempFunc(1);
t3.do_thing();
}
+
+long double _Complex __regcall foo(long double _Complex f) {
+ return f;
+}
+// CHECK-LIN64-DAG: define x86_regcallcc void @_Z15__regcall3__fooCe({ x86_fp80, x86_fp80 }* noalias sret %agg.result, { x86_fp80, x86_fp80 }* byval align 16 %f)
+// CHECK-LIN32-DAG: define x86_regcallcc void @_Z15__regcall3__fooCe({ x86_fp80, x86_fp80 }* inreg noalias sret %agg.result, { x86_fp80, x86_fp80 }* byval align 4 %f)
+// CHECK-WIN64-DAG: define x86_regcallcc { double, double } @"\01?foo@@YwU?$_Complex@O@__clang@@U12@@Z"(double %f.0, double %f.1)
+// CHECK-WIN32-DAG: define x86_regcallcc { double, double } @"\01?foo@@YwU?$_Complex@O@__clang@@U12@@Z"(double %f.0, double %f.1)
diff --git a/test/CodeGenCXX/rtti-mingw64.cpp b/test/CodeGenCXX/rtti-mingw64.cpp
index 818b11b64bc5..9f3e03961e89 100644
--- a/test/CodeGenCXX/rtti-mingw64.cpp
+++ b/test/CodeGenCXX/rtti-mingw64.cpp
@@ -2,7 +2,12 @@
struct A { int a; };
struct B : virtual A { int b; };
B b;
+class C {
+ virtual ~C();
+};
+C::~C() {}
+// CHECK: @_ZTI1C = linkonce_odr
// CHECK: @_ZTI1B = linkonce_odr constant { i8*, i8*, i32, i32, i8*, i64 }
// CHECK-SAME: i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2) to i8*),
// CHECK-SAME: i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZTS1B, i32 0, i32 0),
diff --git a/test/CodeGenCXX/runtime-dllstorage.cpp b/test/CodeGenCXX/runtime-dllstorage.cpp
index 76c002c0e407..8ccf0291687c 100644
--- a/test/CodeGenCXX/runtime-dllstorage.cpp
+++ b/test/CodeGenCXX/runtime-dllstorage.cpp
@@ -12,7 +12,7 @@
// %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -fno-use-cxa-atexit -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA -check-prefix CHECK-DYNAMIC-IA-ATEXIT
// %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -fno-use-cxa-atexit -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA -check-prefix CHECK-STATIC-IA-ATEXIT
-// RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA
+// RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
// RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
// RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA
// RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
diff --git a/test/CodeGenCXX/sanitize-dtor-callback.cpp b/test/CodeGenCXX/sanitize-dtor-callback.cpp
index e208a6f7e5a5..ecb0f2b2d13b 100644
--- a/test/CodeGenCXX/sanitize-dtor-callback.cpp
+++ b/test/CodeGenCXX/sanitize-dtor-callback.cpp
@@ -55,16 +55,19 @@ Defaulted_Non_Trivial def_non_trivial;
// to confirm that all invoked dtors have member poisoning
// instrumentation inserted.
// CHECK-LABEL: define {{.*}}SimpleD2Ev
+// CHECK-NOT: store i{{[0-9]+}} 0, {{.*}}@__msan_param_tls
// CHECK: call void @__sanitizer_dtor_callback
// CHECK-NOT: call void @__sanitizer_dtor_callback
// CHECK: ret void
// CHECK-LABEL: define {{.*}}InlinedD2Ev
+// CHECK-NOT: store i{{[0-9]+}} 0, {{.*}}@__msan_param_tls
// CHECK: call void @__sanitizer_dtor_callback
// CHECK-NOT: call void @__sanitizer_dtor_callback
// CHECK: ret void
// CHECK-LABEL: define {{.*}}Defaulted_Non_TrivialD2Ev
+// CHECK-NOT: store i{{[0-9]+}} 0, {{.*}}@__msan_param_tls
// CHECK: call void @__sanitizer_dtor_callback
// CHECK-NOT: call void @__sanitizer_dtor_callback
// CHECK: ret void
diff --git a/test/CodeGenCXX/static-init-wasm.cpp b/test/CodeGenCXX/static-init-wasm.cpp
index 289c3ea6024d..68d139157e2d 100644
--- a/test/CodeGenCXX/static-init-wasm.cpp
+++ b/test/CodeGenCXX/static-init-wasm.cpp
@@ -20,7 +20,7 @@ void g() {
// WEBASSEMBLY32: %[[R0:.+]] = load atomic i8, i8* bitcast (i32* @_ZGVZ1gvE1a to i8*) acquire, align 4
// WEBASSEMBLY32-NEXT: %[[R1:.+]] = and i8 %[[R0]], 1
// WEBASSEMBLY32-NEXT: %[[R2:.+]] = icmp eq i8 %[[R1]], 0
-// WEBASSEMBLY32-NEXT: br i1 %[[R2]], label %[[CHECK:.+]], label %[[END:.+]]
+// WEBASSEMBLY32-NEXT: br i1 %[[R2]], label %[[CHECK:.+]], label %[[END:.+]],
// WEBASSEMBLY32: [[CHECK]]
// WEBASSEMBLY32: call i32 @__cxa_guard_acquire
// WEBASSEMBLY32: [[END]]
@@ -30,7 +30,7 @@ void g() {
// WEBASSEMBLY64: %[[R0:.+]] = load atomic i8, i8* bitcast (i64* @_ZGVZ1gvE1a to i8*) acquire, align 8
// WEBASSEMBLY64-NEXT: %[[R1:.+]] = and i8 %[[R0]], 1
// WEBASSEMBLY64-NEXT: %[[R2:.+]] = icmp eq i8 %[[R1]], 0
-// WEBASSEMBLY64-NEXT: br i1 %[[R2]], label %[[CHECK:.+]], label %[[END:.+]]
+// WEBASSEMBLY64-NEXT: br i1 %[[R2]], label %[[CHECK:.+]], label %[[END:.+]],
// WEBASSEMBLY64: [[CHECK]]
// WEBASSEMBLY64: call i32 @__cxa_guard_acquire
// WEBASSEMBLY64: [[END]]
@@ -43,12 +43,12 @@ struct A {
A theA;
-// WEBASSEMBLY32: define internal void @__cxx_global_var_init() #3 section ".text.__startup" {
+// WEBASSEMBLY32: define internal void @__cxx_global_var_init() #3 {
// WEBASSEMBLY32: call %struct.A* @_ZN1AC1Ev(%struct.A* @theA)
-// WEBASSEMBLY32: define internal void @_GLOBAL__sub_I_static_init_wasm.cpp() #3 section ".text.__startup" {
+// WEBASSEMBLY32: define internal void @_GLOBAL__sub_I_static_init_wasm.cpp() #3 {
// WEBASSEMBLY32: call void @__cxx_global_var_init()
//
-// WEBASSEMBLY64: define internal void @__cxx_global_var_init() #3 section ".text.__startup" {
+// WEBASSEMBLY64: define internal void @__cxx_global_var_init() #3 {
// WEBASSEMBLY64: call %struct.A* @_ZN1AC1Ev(%struct.A* @theA)
-// WEBASSEMBLY64: define internal void @_GLOBAL__sub_I_static_init_wasm.cpp() #3 section ".text.__startup" {
+// WEBASSEMBLY64: define internal void @_GLOBAL__sub_I_static_init_wasm.cpp() #3 {
// WEBASSEMBLY64: call void @__cxx_global_var_init()
diff --git a/test/CodeGenCXX/static-initializer-branch-weights.cpp b/test/CodeGenCXX/static-initializer-branch-weights.cpp
new file mode 100644
index 000000000000..f9e77812714c
--- /dev/null
+++ b/test/CodeGenCXX/static-initializer-branch-weights.cpp
@@ -0,0 +1,126 @@
+// RUN: %clang_cc1 -emit-llvm -std=c++1z %s -o - -triple=x86_64-linux-gnu | FileCheck %s
+
+struct S { S(); ~S(); };
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK-NOT: br
+// CHECK: call void @_ZN1SC1Ev({{.*}}* @global)
+S global;
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// FIXME: Do we really need thread-safe initialization here? We don't run
+// global ctors on multiple threads. (If we were to do so, we'd need thread-safe
+// init for B<int>::member and B<int>::inline_member too.)
+// CHECK: load atomic i8, i8* bitcast (i64* @_ZGV13inline_global to i8*) acquire,
+// CHECK: icmp eq i8 {{.*}}, 0
+// CHECK: br i1
+// CHECK-NOT: !prof
+// CHECK: call void @_ZN1SC1Ev({{.*}}* @inline_global)
+inline S inline_global;
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK-NOT: br
+// CHECK: call void @_ZN1SC1Ev({{.*}}* @thread_local_global)
+thread_local S thread_local_global;
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK: load i8, i8* bitcast (i64* @_ZGV26thread_local_inline_global to i8*)
+// CHECK: icmp eq i8 {{.*}}, 0
+// CHECK: br i1
+// CHECK-NOT: !prof
+// CHECK: call void @_ZN1SC1Ev({{.*}}* @thread_local_inline_global)
+thread_local inline S thread_local_inline_global;
+
+struct A {
+ static S member;
+ static thread_local S thread_local_member;
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: load atomic i8, i8* bitcast (i64* @_ZGVN1A13inline_memberE to i8*) acquire,
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1
+ // CHECK-NOT: !prof
+ // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1A13inline_memberE)
+ static inline S inline_member;
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: load i8, i8* bitcast (i64* @_ZGVN1A26thread_local_inline_memberE to i8*)
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1
+ // CHECK-NOT: !prof
+ // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1A26thread_local_inline_memberE)
+ static thread_local inline S thread_local_inline_member;
+};
+
+// CHECK-LABEL: define void @_Z1fv()
+void f() {
+ // CHECK: load atomic i8, i8* bitcast (i64* @_ZGVZ1fvE12static_local to i8*) acquire,
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1 {{.*}}, !prof ![[WEIGHTS_LOCAL:[0-9]*]]
+ static S static_local;
+
+ // CHECK: load i8, i8* @_ZGVZ1fvE19static_thread_local,
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1 {{.*}}, !prof ![[WEIGHTS_THREAD_LOCAL:[0-9]*]]
+ static thread_local S static_thread_local;
+}
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK-NOT: br
+// CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1A6memberE)
+S A::member;
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK-NOT: br
+// CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1A19thread_local_memberE)
+thread_local S A::thread_local_member;
+
+template <typename T> struct B {
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: load i8, i8* bitcast (i64* @_ZGVN1BIiE6memberE to i8*)
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1
+ // CHECK-NOT: !prof
+ // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1BIiE6memberE)
+ static S member;
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: load i8, i8* bitcast (i64* @_ZGVN1BIiE13inline_memberE to i8*)
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1
+ // CHECK-NOT: !prof
+ // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1BIiE13inline_memberE)
+ static inline S inline_member;
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: load i8, i8* bitcast (i64* @_ZGVN1BIiE19thread_local_memberE to i8*)
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1
+ // CHECK-NOT: !prof
+ // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1BIiE19thread_local_memberE)
+ static thread_local S thread_local_member;
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: load i8, i8* bitcast (i64* @_ZGVN1BIiE26thread_local_inline_memberE to i8*)
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1
+ // CHECK-NOT: !prof
+ // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1BIiE26thread_local_inline_memberE)
+ static thread_local inline S thread_local_inline_member;
+};
+template<typename T> S B<T>::member;
+template<typename T> thread_local S B<T>::thread_local_member;
+
+template<typename ...T> void use(T &...);
+void use_b() {
+ use(B<int>::member, B<int>::inline_member, B<int>::thread_local_member,
+ B<int>::thread_local_inline_member);
+}
+
+// CHECK-LABEL: define {{.*}}tls_init()
+// CHECK: load i8, i8* @__tls_guard, align 1
+// CHECK: icmp eq i8 {{.*}}, 0
+// CHECK: br i1 {{.*}}, !prof ![[WEIGHTS_THREAD_LOCAL]]
+
+// CHECK-DAG: ![[WEIGHTS_THREAD_LOCAL]] = !{!"branch_weights", i32 1, i32 1023}
+// CHECK-DAG: ![[WEIGHTS_LOCAL]] = !{!"branch_weights", i32 1, i32 1048575}
diff --git a/test/CodeGenCXX/stmtexpr.cpp b/test/CodeGenCXX/stmtexpr.cpp
index 5bd9908d6c25..4586a3c38fff 100644
--- a/test/CodeGenCXX/stmtexpr.cpp
+++ b/test/CodeGenCXX/stmtexpr.cpp
@@ -173,7 +173,7 @@ extern "C" int cleanup_exit_lvalue_local(bool cond) {
_Complex float bar_complex(A, int);
extern "C" int cleanup_exit_complex(bool b) {
_Complex float v = bar_complex(A(1), ({ if (b) return 42; 13; }));
- return v;
+ return (float)v;
}
// CHECK-LABEL: define{{.*}} i32 @cleanup_exit_complex({{.*}})
diff --git a/test/CodeGenCXX/strict-vtable-pointers.cpp b/test/CodeGenCXX/strict-vtable-pointers.cpp
index c3798920abdd..c45e7a60fa8f 100644
--- a/test/CodeGenCXX/strict-vtable-pointers.cpp
+++ b/test/CodeGenCXX/strict-vtable-pointers.cpp
@@ -53,7 +53,7 @@ struct DynamicFrom2Virtuals :
};
// CHECK-NEW-LABEL: define void @_Z12LocalObjectsv()
-// CHECK-NEW-NOT: @llvm.invariant.group.barrier(
+// CHECK-NEW-NOT: @llvm.invariant.group.barrier.p0i8(
// CHECK-NEW-LABEL: {{^}}}
void LocalObjects() {
DynamicBase1 DB;
@@ -81,20 +81,20 @@ void LocalObjects() {
struct DynamicFromVirtualStatic1;
// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN25DynamicFromVirtualStatic1C1Ev
-// CHECK-CTORS-NOT: @llvm.invariant.group.barrier(
+// CHECK-CTORS-NOT: @llvm.invariant.group.barrier.p0i8(
// CHECK-CTORS-LABEL: {{^}}}
struct DynamicFrom2Virtuals;
// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN20DynamicFrom2VirtualsC1Ev
-// CHECK-CTORS: call i8* @llvm.invariant.group.barrier(
+// CHECK-CTORS: call i8* @llvm.invariant.group.barrier.p0i8(
// CHECK-CTORS-LABEL: {{^}}}
// CHECK-NEW-LABEL: define void @_Z9Pointers1v()
-// CHECK-NEW-NOT: @llvm.invariant.group.barrier(
+// CHECK-NEW-NOT: @llvm.invariant.group.barrier.p0i8(
// CHECK-NEW-LABEL: call void @_ZN12DynamicBase1C1Ev(
-// CHECK-NEW: %[[THIS3:.*]] = call i8* @llvm.invariant.group.barrier(i8* %[[THIS2:.*]])
+// CHECK-NEW: %[[THIS3:.*]] = call i8* @llvm.invariant.group.barrier.p0i8(i8* %[[THIS2:.*]])
// CHECK-NEW: %[[THIS4:.*]] = bitcast i8* %[[THIS3]] to %[[DynamicDerived:.*]]*
// CHECK-NEW: call void @_ZN14DynamicDerivedC1Ev(%[[DynamicDerived:.*]]* %[[THIS4]])
// CHECK-NEW-LABEL: {{^}}}
@@ -109,9 +109,9 @@ void Pointers1() {
// CHECK-NEW-LABEL: define void @_Z14HackingObjectsv()
// CHECK-NEW: call void @_ZN12DynamicBase1C1Ev
-// CHECK-NEW: call i8* @llvm.invariant.group.barrier(
+// CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(
// CHECK-NEW: call void @_ZN14DynamicDerivedC1Ev(
-// CHECK-NEW: call i8* @llvm.invariant.group.barrier(
+// CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(
// CHECK-NEW: call void @_ZN12DynamicBase1C1Ev(
// CHECK-NEW-LABEL: {{^}}}
void HackingObjects() {
@@ -131,7 +131,7 @@ void HackingObjects() {
/*** Testing Constructors ***/
struct DynamicBase1;
// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase1C2Ev(
-// CHECK-CTORS-NOT: call i8* @llvm.invariant.group.barrier(
+// CHECK-CTORS-NOT: call i8* @llvm.invariant.group.barrier.p0i8(
// CHECK-CTORS-LABEL: {{^}}}
@@ -140,7 +140,7 @@ struct DynamicDerived;
// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN14DynamicDerivedC2Ev(
// CHECK-CTORS: %[[THIS0:.*]] = load %[[DynamicDerived:.*]]*, %[[DynamicDerived]]** {{.*}}
// CHECK-CTORS: %[[THIS1:.*]] = bitcast %[[DynamicDerived:.*]]* %[[THIS0]] to i8*
-// CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.invariant.group.barrier(i8* %[[THIS1:.*]])
+// CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.invariant.group.barrier.p0i8(i8* %[[THIS1:.*]])
// CHECK-CTORS: %[[THIS3:.*]] = bitcast i8* %[[THIS2]] to %[[DynamicDerived]]*
// CHECK-CTORS: %[[THIS4:.*]] = bitcast %[[DynamicDerived]]* %[[THIS3]] to %[[DynamicBase:.*]]*
// CHECK-CTORS: call void @_ZN12DynamicBase1C2Ev(%[[DynamicBase]]* %[[THIS4]])
@@ -154,15 +154,15 @@ struct DynamicDerivedMultiple;
// CHECK-CTORS: %[[THIS0:.*]] = load %[[CLASS:.*]]*, %[[CLASS]]** {{.*}}
// CHECK-CTORS: %[[THIS1:.*]] = bitcast %[[CLASS:.*]]* %[[THIS0]] to i8*
-// CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.invariant.group.barrier(i8* %[[THIS1]])
+// CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.invariant.group.barrier.p0i8(i8* %[[THIS1]])
// CHECK-CTORS: %[[THIS3:.*]] = bitcast i8* %[[THIS2]] to %[[CLASS]]*
// CHECK-CTORS: %[[THIS4:.*]] = bitcast %[[CLASS]]* %[[THIS3]] to %[[BASE_CLASS:.*]]*
// CHECK-CTORS: call void @_ZN12DynamicBase1C2Ev(%[[BASE_CLASS]]* %[[THIS4]])
-// CHECK-CTORS: call i8* @llvm.invariant.group.barrier(
+// CHECK-CTORS: call i8* @llvm.invariant.group.barrier.p0i8(
// CHECK-CTORS: call void @_ZN12DynamicBase2C2Ev(
-// CHECK-CTORS-NOT: @llvm.invariant.group.barrier
+// CHECK-CTORS-NOT: @llvm.invariant.group.barrier.p0i8
// CHECK-CTORS: %[[THIS10:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i32 (...)***
@@ -177,7 +177,7 @@ struct DynamicDerivedMultiple;
struct DynamicFromStatic;
// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN17DynamicFromStaticC2Ev(
-// CHECK-CTORS-NOT: @llvm.invariant.group.barrier(
+// CHECK-CTORS-NOT: @llvm.invariant.group.barrier.p0i8(
// CHECK-CTORS-LABEL: {{^}}}
struct A {
@@ -206,15 +206,15 @@ void g2(A *a) {
void UnionsBarriers(U *u) {
// CHECK-NEW: call void @_Z9changeToBP1U(
changeToB(u);
- // CHECK-NEW: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(i8*
// CHECK-NEW: call void @_Z2g2P1A(%struct.A*
g2(&u->b);
// CHECK-NEW: call void @_Z9changeToAP1U(%union.U*
changeToA(u);
- // CHECK-NEW: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(i8*
// call void @_Z2g2P1A(%struct.A* %a)
g2(&u->a);
- // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier.p0i8(i8*
}
struct HoldingVirtuals {
@@ -233,10 +233,10 @@ void take(AnotherEmpty &);
// CHECK-NEW-LABEL: noBarriers
void noBarriers(NoVptrs &noVptrs) {
- // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier.p0i8(i8*
// CHECK-NEW: 42
noVptrs.a += 42;
- // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier.p0i8(i8*
// CHECK-NEW: call void @_Z4takeR12AnotherEmpty(
take(noVptrs.empty);
}
@@ -249,10 +249,10 @@ void take(HoldingVirtuals &);
// CHECK-NEW-LABEL: define void @_Z15UnionsBarriers2R2U2
void UnionsBarriers2(U2 &u) {
- // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier.p0i8(i8*
// CHECK-NEW: 42
u.z += 42;
- // CHECK-NEW: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(i8*
// CHECK-NEW: call void @_Z4takeR15HoldingVirtuals(
take(u.h);
}
@@ -279,24 +279,24 @@ void take(VirtualInVBase &);
void take(VirtualInheritance &);
void UnionsBarrier3(U3 &u) {
- // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier.p0i8(i8*
// CHECK-NEW: 42
u.z += 42;
- // CHECK-NEW: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(i8*
// CHECK-NEW: call void @_Z4takeR13VirtualInBase(
take(u.v1);
- // CHECK-NEW: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(i8*
// CHECK-NEW: call void @_Z4takeR13VirtualInBase(
take(u.v2);
- // CHECK-NEW: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(i8*
// CHECK-NEW: call void @_Z4takeR18VirtualInheritance(
take(u.v3);
}
/** DTORS **/
// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN10StaticBaseD2Ev(
-// CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier(
+// CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier.p0i8(
// CHECK-DTORS-LABEL: {{^}}}
@@ -305,22 +305,22 @@ void UnionsBarrier3(U3 &u) {
// CHECK-DTORS-LABEL: {{^}}}
// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN17DynamicFromStaticD2Ev
-// CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier(
+// CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier.p0i8(
// CHECK-DTORS-LABEL: {{^}}}
// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN22DynamicDerivedMultipleD2Ev(
// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase2D2Ev(
-// CHECK-DTORS: call i8* @llvm.invariant.group.barrier(
+// CHECK-DTORS: call i8* @llvm.invariant.group.barrier.p0i8(
// CHECK-DTORS-LABEL: {{^}}}
// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase1D2Ev
-// CHECK-DTORS: call i8* @llvm.invariant.group.barrier(
+// CHECK-DTORS: call i8* @llvm.invariant.group.barrier.p0i8(
// CHECK-DTORS-LABEL: {{^}}}
// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN14DynamicDerivedD2Ev
-// CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier(
+// CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier.p0i8(
// CHECK-DTORS-LABEL: {{^}}}
diff --git a/test/CodeGenCXX/tmp-md-nodes1.cpp b/test/CodeGenCXX/tmp-md-nodes1.cpp
new file mode 100644
index 000000000000..41a0159b0fc4
--- /dev/null
+++ b/test/CodeGenCXX/tmp-md-nodes1.cpp
@@ -0,0 +1,18 @@
+// REQUIRES: asserts
+// RUN: %clang_cc1 -O0 -triple %itanium_abi_triple -debug-info-kind=limited -S -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+
+// This test simply checks that the varargs thunk is created. The failing test
+// case asserts.
+
+struct Alpha {
+ virtual void bravo(...);
+};
+struct Charlie {
+ virtual ~Charlie() {}
+};
+struct CharlieImpl : Charlie, Alpha {
+ void bravo(...) {}
+} delta;
+
+// CHECK: define {{.*}} void @_ZThn{{[48]}}_N11CharlieImpl5bravoEz(
diff --git a/test/CodeGenCXX/tmp-md-nodes2.cpp b/test/CodeGenCXX/tmp-md-nodes2.cpp
new file mode 100644
index 000000000000..e50220cfb7c3
--- /dev/null
+++ b/test/CodeGenCXX/tmp-md-nodes2.cpp
@@ -0,0 +1,33 @@
+// REQUIRES: asserts
+// RUN: %clang_cc1 -O0 -triple %itanium_abi_triple -debug-info-kind=limited -S -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+
+// This test simply checks that the varargs thunk is created. The failing test
+// case asserts.
+
+typedef signed char __int8_t;
+typedef int BOOL;
+class CMsgAgent;
+
+class CFs {
+public:
+ typedef enum {} CACHE_HINT;
+ virtual BOOL ReqCacheHint( CMsgAgent* p_ma, CACHE_HINT hint, ... ) ;
+};
+
+typedef struct {} _Lldiv_t;
+
+class CBdVfs {
+public:
+ virtual ~CBdVfs( ) {}
+};
+
+class CBdVfsImpl : public CBdVfs, public CFs {
+ BOOL ReqCacheHint( CMsgAgent* p_ma, CACHE_HINT hint, ... );
+};
+
+BOOL CBdVfsImpl::ReqCacheHint( CMsgAgent* p_ma, CACHE_HINT hint, ... ) {
+ return true;
+}
+
+// CHECK: define {{.*}} @_ZThn{{[48]}}_N10CBdVfsImpl12ReqCacheHintEP9CMsgAgentN3CFs10CACHE_HINTEz(
diff --git a/test/CodeGenCXX/ubsan-devirtualized-calls.cpp b/test/CodeGenCXX/ubsan-devirtualized-calls.cpp
index bc8861aa8314..f4ccdbf6474a 100644
--- a/test/CodeGenCXX/ubsan-devirtualized-calls.cpp
+++ b/test/CodeGenCXX/ubsan-devirtualized-calls.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm -fsanitize=vptr %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm -fsanitize=null,vptr %s -o - | FileCheck %s
struct Base1 {
virtual void f1() {}
@@ -64,6 +64,11 @@ void t4() {
// CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED3]] {{.*}}, i{{[0-9]+}} %[[P1]]
static_cast<Base1 *>(badp)->f1(); //< No devirt, test 'badp isa Base1'.
+ // We were able to skip the null check on the first type check because 'p'
+ // is backed by an alloca. We can't skip the second null check because 'badp'
+ // is a (bitcast (load ...)).
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ //
// CHECK: %[[BADP1:[0-9]+]] = ptrtoint %struct.Base1* {{%[0-9]+}} to i{{[0-9]+}}, !nosanitize
// CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_BASE1]] {{.*}}, i{{[0-9]+}} %[[BADP1]]
}
@@ -76,6 +81,8 @@ void t5() {
// CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED4_1]] {{.*}}, i{{[0-9]+}} %[[P1]]
static_cast<Base1 *>(badp)->f1(); //< Devirt Base1::f1 to Derived4::f1.
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ //
// CHECK: %[[BADP1:[0-9]+]] = ptrtoint %struct.Derived4* {{%[0-9]+}} to i{{[0-9]+}}, !nosanitize
// CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED4_2]] {{.*}}, i{{[0-9]+}} %[[BADP1]]
}
diff --git a/test/CodeGenCXX/ubsan-suppress-checks.cpp b/test/CodeGenCXX/ubsan-suppress-checks.cpp
index ae7c94b34f29..fa7ea29d94f2 100644
--- a/test/CodeGenCXX/ubsan-suppress-checks.cpp
+++ b/test/CodeGenCXX/ubsan-suppress-checks.cpp
@@ -17,6 +17,17 @@ void load_non_null_pointers() {
// CHECK: ret void
}
+// CHECK-LABEL: define void @_Z31use_us16_aligned_array_elementsv
+void use_us16_aligned_array_elements() {
+ static const unsigned short Arr[] = {0, 1, 2};
+ auto use_array = [](const unsigned short(&X)[3]) -> void {};
+ use_array(Arr);
+
+ // CHECK-NOT: br i1 true
+ // ALIGN-NOT: call void @__ubsan_handle_type_mismatch
+ // CHECK: ret void
+}
+
struct A {
int foo;
@@ -229,4 +240,5 @@ void force_irgen() {
d->load_member_3();
load_non_null_pointers();
+ use_us16_aligned_array_elements();
}
diff --git a/test/CodeGenCXX/ubsan-type-checks.cpp b/test/CodeGenCXX/ubsan-type-checks.cpp
index 786d049dfb56..e53ab2466e73 100644
--- a/test/CodeGenCXX/ubsan-type-checks.cpp
+++ b/test/CodeGenCXX/ubsan-type-checks.cpp
@@ -1,6 +1,8 @@
// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=alignment | FileCheck %s -check-prefixes=ALIGN,COMMON
// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null | FileCheck %s -check-prefixes=NULL,COMMON
// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=object-size | FileCheck %s -check-prefixes=OBJSIZE,COMMON
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null,vptr | FileCheck %s -check-prefixes=VPTR
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=vptr | FileCheck %s -check-prefixes=VPTR_NO_NULL
struct A {
// COMMON-LABEL: define linkonce_odr void @_ZN1A10do_nothingEv
@@ -24,13 +26,60 @@ struct B {
// NULL: icmp ne %struct.B* %{{.*}}, null, !nosanitize
// OBJSIZE-NOT: call i64 @llvm.objectsize
+ // OBJSIZE: ret void
}
};
-void force_irgen() {
+struct Animal {
+ virtual const char *speak() = 0;
+};
+
+struct Cat : Animal {
+ const char *speak() override { return "meow"; }
+};
+
+struct Dog : Animal {
+ const char *speak() override { return "woof"; }
+};
+
+// VPTR-LABEL: define void @_Z12invalid_castP3Cat
+void invalid_cast(Cat *cat = nullptr) {
+ // If -fsanitize=null is available, we'll reuse its check:
+ //
+ // VPTR: [[ICMP:%.*]] = icmp ne %struct.Dog* {{.*}}, null
+ // VPTR-NEXT: br i1 [[ICMP]]
+ // VPTR: call void @__ubsan_handle_type_mismatch
+ // VPTR-NOT: icmp ne %struct.Dog* {{.*}}, null
+ // VPTR: br i1 [[ICMP]]
+ // VPTR: call void @__ubsan_handle_dynamic_type_cache_miss
+ //
+ // Fall back to the vptr sanitizer's null check when -fsanitize=null isn't
+ // available.
+ //
+ // VPTR_NO_NULL-NOT: call void @__ubsan_handle_type_mismatch
+ // VPTR_NO_NULL: [[ICMP:%.*]] = icmp ne %struct.Dog* {{.*}}, null
+ // VPTR_NO_NULL-NEXT: br i1 [[ICMP]]
+ // VPTR_NO_NULL: call void @__ubsan_handle_dynamic_type_cache_miss
+ auto *badDog = reinterpret_cast<Dog *>(cat);
+ badDog->speak();
+}
+
+// VPTR_NO_NULL-LABEL: define void @_Z13invalid_cast2v
+void invalid_cast2() {
+ // We've got a pointer to an alloca, so there's no run-time null check needed.
+ // VPTR_NO_NULL-NOT: call void @__ubsan_handle_type_mismatch
+ // VPTR_NO_NULL: call void @__ubsan_handle_dynamic_type_cache_miss
+ Cat cat;
+ cat.speak();
+}
+
+int main() {
A a;
a.do_nothing();
B b;
b.do_nothing();
+
+ invalid_cast();
+ return 0;
}
diff --git a/test/CodeGenCXX/ubsan-vtable-checks.cpp b/test/CodeGenCXX/ubsan-vtable-checks.cpp
index e684ae9180f1..5e17913a2c89 100644
--- a/test/CodeGenCXX/ubsan-vtable-checks.cpp
+++ b/test/CodeGenCXX/ubsan-vtable-checks.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm -fsanitize=null %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NULL --check-prefix=ITANIUM
// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm -fsanitize=null %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NULL --check-prefix=MSABI
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm -fsanitize=vptr %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VPTR --check-prefix=ITANIUM
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm -fsanitize=vptr %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VPTR --check-prefix=MSABI
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm -fsanitize=null,vptr %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VPTR --check-prefix=ITANIUM
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm -fsanitize=null,vptr %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VPTR --check-prefix=MSABI
struct T {
virtual ~T() {}
virtual int v() { return 1; }
diff --git a/test/CodeGenCXX/virt-dtor-key.cpp b/test/CodeGenCXX/virt-dtor-key.cpp
index 40c5a537cc53..d1055d4e30ca 100644
--- a/test/CodeGenCXX/virt-dtor-key.cpp
+++ b/test/CodeGenCXX/virt-dtor-key.cpp
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i386-linux -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i386-windows-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-MINGW
// CHECK: @_ZTI3foo = constant
+// CHECK-MINGW: @_ZTI3foo = linkonce_odr
class foo {
foo();
virtual ~foo();
diff --git a/test/CodeGenCXX/visibility-inlines-hidden.cpp b/test/CodeGenCXX/visibility-inlines-hidden.cpp
index 6ea234807ec2..20e4a1f45e3c 100644
--- a/test/CodeGenCXX/visibility-inlines-hidden.cpp
+++ b/test/CodeGenCXX/visibility-inlines-hidden.cpp
@@ -162,3 +162,16 @@ namespace test6 {
C::g();
}
}
+
+namespace PR34811 {
+ template <typename T> void tf() {}
+
+ // CHECK-LABEL: define linkonce_odr hidden i8* @_ZN7PR348111fEv(
+ inline void *f() {
+ auto l = []() {};
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN7PR348112tfIZNS_1fEvEUlvE_EEvv(
+ return (void *)&tf<decltype(l)>;
+ }
+
+ void *p = (void *)f;
+}
diff --git a/test/CodeGenCXX/vla.cpp b/test/CodeGenCXX/vla.cpp
index 957a9f9568b3..b8652f8329a5 100644
--- a/test/CodeGenCXX/vla.cpp
+++ b/test/CodeGenCXX/vla.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck -check-prefixes=X64,CHECK %s
+// RUN: %clang_cc1 -std=c++11 -triple amdgcn---amdgiz %s -emit-llvm -o - | FileCheck -check-prefixes=AMD,CHECK %s
template<typename T>
struct S {
@@ -9,7 +10,7 @@ template<typename T> int S<T>::n = 5;
int f() {
// Make sure that the reference here is enough to trigger the instantiation of
// the static data member.
- // CHECK: @_ZN1SIiE1nE = linkonce_odr global i32 5
+ // CHECK: @_ZN1SIiE1nE = linkonce_odr{{.*}} global i32 5
int a[S<int>::n];
return sizeof a;
}
@@ -17,10 +18,18 @@ int f() {
// rdar://problem/9506377
void test0(void *array, int n) {
// CHECK-LABEL: define void @_Z5test0Pvi(
- // CHECK: [[ARRAY:%.*]] = alloca i8*, align 8
- // CHECK-NEXT: [[N:%.*]] = alloca i32, align 4
- // CHECK-NEXT: [[REF:%.*]] = alloca i16*, align 8
- // CHECK-NEXT: [[S:%.*]] = alloca i16, align 2
+ // X64: [[ARRAY:%.*]] = alloca i8*, align 8
+ // AMD: [[ARRAY0:%.*]] = alloca i8*, align 8, addrspace(5)
+ // AMD-NEXT: [[ARRAY:%.*]] = addrspacecast i8* addrspace(5)* [[ARRAY0]] to i8**
+ // X64-NEXT: [[N:%.*]] = alloca i32, align 4
+ // AMD: [[N0:%.*]] = alloca i32, align 4, addrspace(5)
+ // AMD-NEXT: [[N:%.*]] = addrspacecast i32 addrspace(5)* [[N0]] to i32*
+ // X64-NEXT: [[REF:%.*]] = alloca i16*, align 8
+ // AMD: [[REF0:%.*]] = alloca i16*, align 8, addrspace(5)
+ // AMD-NEXT: [[REF:%.*]] = addrspacecast i16* addrspace(5)* [[REF0]] to i16**
+ // X64-NEXT: [[S:%.*]] = alloca i16, align 2
+ // AMD: [[S0:%.*]] = alloca i16, align 2, addrspace(5)
+ // AMD-NEXT: [[S:%.*]] = addrspacecast i16 addrspace(5)* [[S0]] to i16*
// CHECK-NEXT: store i8*
// CHECK-NEXT: store i32
@@ -59,6 +68,8 @@ void test0(void *array, int n) {
void test2(int b) {
// CHECK-LABEL: define void {{.*}}test2{{.*}}(i32 %b)
int varr[b];
+ // AMD: %__end = alloca i32*, align 8, addrspace(5)
+ // AMD: [[END:%.*]] = addrspacecast i32* addrspace(5)* %__end to i32**
// get the address of %b by checking the first store that stores it
//CHECK: store i32 %b, i32* [[PTR_B:%.*]]
@@ -75,13 +86,16 @@ void test2(int b) {
//CHECK: [[VLA_SIZEOF:%.*]] = mul nuw i64 4, [[VLA_NUM_ELEMENTS_PRE]]
//CHECK-NEXT: [[VLA_NUM_ELEMENTS_POST:%.*]] = udiv i64 [[VLA_SIZEOF]], 4
//CHECK-NEXT: [[VLA_END_PTR:%.*]] = getelementptr inbounds i32, i32* {{%.*}}, i64 [[VLA_NUM_ELEMENTS_POST]]
- //CHECK-NEXT: store i32* [[VLA_END_PTR]], i32** %__end
+ //X64-NEXT: store i32* [[VLA_END_PTR]], i32** %__end
+ //AMD-NEXT: store i32* [[VLA_END_PTR]], i32** [[END]]
for (int d : varr) 0;
}
void test3(int b, int c) {
// CHECK-LABEL: define void {{.*}}test3{{.*}}(i32 %b, i32 %c)
int varr[b][c];
+ // AMD: %__end = alloca i32*, align 8, addrspace(5)
+ // AMD: [[END:%.*]] = addrspacecast i32* addrspace(5)* %__end to i32**
// get the address of %b by checking the first store that stores it
//CHECK: store i32 %b, i32* [[PTR_B:%.*]]
//CHECK-NEXT: store i32 %c, i32* [[PTR_C:%.*]]
@@ -105,7 +119,8 @@ void test3(int b, int c) {
//CHECK-NEXT: [[VLA_NUM_ELEMENTS:%.*]] = udiv i64 [[VLA_SIZEOF]], [[VLA_SIZEOF_DIM2]]
//CHECK-NEXT: [[VLA_END_INDEX:%.*]] = mul nsw i64 [[VLA_NUM_ELEMENTS]], [[VLA_DIM2_PRE]]
//CHECK-NEXT: [[VLA_END_PTR:%.*]] = getelementptr inbounds i32, i32* {{%.*}}, i64 [[VLA_END_INDEX]]
- //CHECK-NEXT: store i32* [[VLA_END_PTR]], i32** %__end
+ //X64-NEXT: store i32* [[VLA_END_PTR]], i32** %__end
+ //AMD-NEXT: store i32* [[VLA_END_PTR]], i32** [[END]]
for (auto &d : varr) 0;
}
diff --git a/test/CodeGenCXX/vtable-available-externally.cpp b/test/CodeGenCXX/vtable-available-externally.cpp
index 2e2cdbbfeff5..0e7e8b4a3226 100644
--- a/test/CodeGenCXX/vtable-available-externally.cpp
+++ b/test/CodeGenCXX/vtable-available-externally.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -o %t
-// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -O2 -disable-llvm-passes -emit-llvm -o %t.opt
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -emit-llvm -o %t
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.opt
// RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t
// RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t
// RUN: FileCheck --check-prefix=CHECK-TEST5 %s < %t
diff --git a/test/CodeGenCXX/warn-padded-packed.cpp b/test/CodeGenCXX/warn-padded-packed.cpp
index f2af60865e05..2cb049537348 100644
--- a/test/CodeGenCXX/warn-padded-packed.cpp
+++ b/test/CodeGenCXX/warn-padded-packed.cpp
@@ -17,7 +17,7 @@ struct S3 {
} __attribute__((packed));
struct S4 {
- int i; // expected-warning {{packed attribute is unnecessary for 'i'}}
+ int i;
char c;
} __attribute__((packed));
@@ -46,18 +46,18 @@ struct S8 : B {
int i; // expected-warning {{padding struct 'S8' with 3 bytes to align 'i'}}
};
-struct S9 { // expected-warning {{packed attribute is unnecessary for 'S9'}}
- int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
- int y; // expected-warning {{packed attribute is unnecessary for 'y'}}
+struct S9 {
+ int x;
+ int y;
} __attribute__((packed));
-struct S10 { // expected-warning {{packed attribute is unnecessary for 'S10'}}
- int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
+struct S10 {
+ int x;
char a,b,c,d;
} __attribute__((packed));
-struct S11 {
+struct S11 { // expected-warning {{packed attribute is unnecessary for 'S11'}}
bool x;
char a,b,c,d;
} __attribute__((packed));
@@ -72,5 +72,82 @@ struct S13 { // expected-warning {{padding size of 'S13' with 6 bits to alignmen
bool b : 10;
};
+struct S14 { // expected-warning {{packed attribute is unnecessary for 'S14'}}
+ char a,b,c,d;
+} __attribute__((packed));
+
+struct S15 { // expected-warning {{packed attribute is unnecessary for 'S15'}}
+ struct S14 s;
+ char a;
+} __attribute__((packed));
+
+struct S16 { // expected-warning {{padding size of 'S16' with 2 bytes to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S16'}}
+ char a,b;
+} __attribute__((packed, aligned(4)));
+
+struct S17 {
+ struct S16 s;
+ char a,b;
+} __attribute__((packed, aligned(2)));
+
+struct S18 { // expected-warning {{padding size of 'S18' with 2 bytes to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S18'}}
+ struct S16 s;
+ char a,b;
+} __attribute__((packed, aligned(4)));
+
+struct S19 { // expected-warning {{packed attribute is unnecessary for 'S19'}}
+ bool b;
+ char a;
+} __attribute__((packed, aligned(1)));
+
+struct S20 {
+ int i;
+ char a;
+} __attribute__((packed, aligned(1)));
+
+struct S21 { // expected-warning {{padding size of 'S21' with 4 bits to alignment boundary}}
+ unsigned char a : 6;
+ unsigned char b : 6;
+} __attribute__((packed, aligned(1)));
+
+struct S22 { // expected-warning {{packed attribute is unnecessary for 'S22'}}
+ unsigned char a : 4;
+ unsigned char b : 4;
+} __attribute__((packed));
+
+struct S23 { // expected-warning {{padding size of 'S23' with 4 bits to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S23'}}
+ unsigned char a : 2;
+ unsigned char b : 2;
+} __attribute__((packed));
+
+struct S24 {
+ unsigned char a : 6;
+ unsigned char b : 6;
+ unsigned char c : 6;
+ unsigned char d : 6;
+ unsigned char e : 6;
+ unsigned char f : 6;
+ unsigned char g : 6;
+ unsigned char h : 6;
+} __attribute__((packed));
+
+struct S25 { // expected-warning {{padding size of 'S25' with 7 bits to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S25'}}
+ unsigned char a;
+ unsigned char b : 1;
+} __attribute__((packed));
+
+struct S26 { // expected-warning {{packed attribute is unnecessary for 'S26'}}
+ unsigned char a : 1;
+ unsigned char b; //expected-warning {{padding struct 'S26' with 7 bits to align 'b'}}
+} __attribute__((packed));
+
+struct S27 { // expected-warning {{padding size of 'S27' with 7 bits to alignment boundary}}
+ unsigned char a : 1;
+ unsigned char b : 8;
+} __attribute__((packed));
+
+
// The warnings are emitted when the layout of the structs is computed, so we have to use them.
-void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*) { }
+void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*,
+ S14*, S15*, S16*, S17*, S18*, S19*, S20*, S21*, S22*, S23*, S24*, S25*,
+ S26*, S27*){}