aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenCXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenCXX')
-rw-r--r--test/CodeGenCXX/Inputs/override-layout-packed-base.layout10
-rw-r--r--test/CodeGenCXX/Inputs/profile-remap.map2
-rw-r--r--test/CodeGenCXX/Inputs/profile-remap.proftext7
-rw-r--r--test/CodeGenCXX/Inputs/profile-remap.samples3
-rw-r--r--test/CodeGenCXX/PR20038.cpp4
-rw-r--r--test/CodeGenCXX/aarch64-sign-return-address-static-ctor.cpp41
-rw-r--r--test/CodeGenCXX/address-space-cast-coerce.cpp53
-rw-r--r--test/CodeGenCXX/address-space-cast.cpp56
-rw-r--r--test/CodeGenCXX/always_destroy.cpp31
-rw-r--r--test/CodeGenCXX/amdgcn-string-literal.cpp2
-rw-r--r--test/CodeGenCXX/atomic-inline.cpp61
-rw-r--r--test/CodeGenCXX/attr-cpuspecific.cpp26
-rw-r--r--test/CodeGenCXX/attr-exclude_from_explicit_instantiation.dont_assume_extern_instantiation.cpp84
-rw-r--r--test/CodeGenCXX/attr-no-destroy-d54344.cpp42
-rw-r--r--test/CodeGenCXX/attr-target-mv-diff-ns.cpp108
-rw-r--r--test/CodeGenCXX/attr-target-mv-func-ptrs.cpp25
-rw-r--r--test/CodeGenCXX/attr-target-mv-inalloca.cpp81
-rw-r--r--test/CodeGenCXX/attr-target-mv-member-funcs.cpp225
-rw-r--r--test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp56
-rw-r--r--test/CodeGenCXX/attr-target-mv-overloads.cpp104
-rw-r--r--test/CodeGenCXX/auto-var-init.cpp1350
-rw-r--r--test/CodeGenCXX/block-byref-cxx-objc.cpp48
-rw-r--r--test/CodeGenCXX/block-byref.cpp15
-rw-r--r--test/CodeGenCXX/block-capture.cpp2
-rw-r--r--test/CodeGenCXX/blocks.cpp57
-rw-r--r--test/CodeGenCXX/builtin-constant-p.cpp24
-rw-r--r--test/CodeGenCXX/builtin-launder.cpp321
-rw-r--r--test/CodeGenCXX/castexpr-basepathsize-threshold.cpp6
-rw-r--r--test/CodeGenCXX/catch-implicit-integer-sign-changes-true-negatives.cpp149
-rw-r--r--test/CodeGenCXX/catch-implicit-integer-truncations.cpp6
-rw-r--r--test/CodeGenCXX/catch-undef-behavior.cpp47
-rw-r--r--test/CodeGenCXX/cfi-cross-dso.cpp2
-rw-r--r--test/CodeGenCXX/cfi-icall.cpp2
-rw-r--r--test/CodeGenCXX/conditional-temporaries.cpp164
-rw-r--r--test/CodeGenCXX/const-init-cxx11.cpp4
-rw-r--r--test/CodeGenCXX/crash.cpp1
-rw-r--r--test/CodeGenCXX/cxx-block-objects.cpp4
-rw-r--r--test/CodeGenCXX/cxx11-thread-local.cpp2
-rw-r--r--test/CodeGenCXX/cxx1y-init-captures.cpp13
-rw-r--r--test/CodeGenCXX/cxx2a-init-statement.cpp10
-rw-r--r--test/CodeGenCXX/dbg-info-all-calls-described.cpp61
-rw-r--r--test/CodeGenCXX/debug-info-access.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-blocks.cpp10
-rw-r--r--test/CodeGenCXX/debug-info-byval.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-class-limited-plugin.test2
-rw-r--r--test/CodeGenCXX/debug-info-ctor2.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-cxx1y.cpp4
-rw-r--r--test/CodeGenCXX/debug-info-decl-nested.cpp12
-rw-r--r--test/CodeGenCXX/debug-info-enum-class.cpp7
-rw-r--r--test/CodeGenCXX/debug-info-function-context.cpp8
-rw-r--r--test/CodeGenCXX/debug-info-gline-tables-only.cpp3
-rw-r--r--test/CodeGenCXX/debug-info-global-ctor-dtor.cpp16
-rw-r--r--test/CodeGenCXX/debug-info-inlined.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-lambda.cpp16
-rw-r--r--test/CodeGenCXX/debug-info-line.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-member.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-method-spec.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-ms-abi.cpp13
-rw-r--r--test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp1
-rw-r--r--test/CodeGenCXX/debug-info-namespace.cpp13
-rw-r--r--test/CodeGenCXX/debug-info-static-fns.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-template-explicit-specialization.cpp3
-rw-r--r--test/CodeGenCXX/debug-info-template-member.cpp25
-rw-r--r--test/CodeGenCXX/debug-info-thunk-msabi.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-thunk.cpp4
-rw-r--r--test/CodeGenCXX/debug-info-vla.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-windows-dtor.cpp1
-rw-r--r--test/CodeGenCXX/debug-info.cpp2
-rw-r--r--test/CodeGenCXX/debug-lambda-expressions.cpp8
-rw-r--r--test/CodeGenCXX/debug-prefix-map-lambda.cpp10
-rw-r--r--test/CodeGenCXX/dllexport-missing-key.cpp22
-rw-r--r--test/CodeGenCXX/dllexport-no-dllexport-inlines.cpp133
-rw-r--r--test/CodeGenCXX/dllexport.cpp18
-rw-r--r--test/CodeGenCXX/dllimport-members.cpp2
-rw-r--r--test/CodeGenCXX/dllimport.cpp27
-rw-r--r--test/CodeGenCXX/dso-local-executable.cpp18
-rw-r--r--test/CodeGenCXX/empty-struct-init-list.cpp12
-rw-r--r--test/CodeGenCXX/exceptions-seh-filter-captures.cpp6
-rw-r--r--test/CodeGenCXX/float128-declarations.cpp35
-rw-r--r--test/CodeGenCXX/float16-declarations.cpp6
-rw-r--r--test/CodeGenCXX/globalinit-loc.cpp4
-rw-r--r--test/CodeGenCXX/inalloca-lambda.cpp11
-rw-r--r--test/CodeGenCXX/inheriting-constructor-cleanup.cpp52
-rw-r--r--test/CodeGenCXX/inline-template-hint.cpp34
-rw-r--r--test/CodeGenCXX/lifetime-asan.cpp42
-rw-r--r--test/CodeGenCXX/linetable-fnbegin.cpp2
-rw-r--r--test/CodeGenCXX/linetable-virtual-variadic.cpp1
-rw-r--r--test/CodeGenCXX/mangle-address-space.cpp55
-rw-r--r--test/CodeGenCXX/mangle-long-double.cpp4
-rw-r--r--test/CodeGenCXX/mangle-ms-exception-spec.cpp42
-rw-r--r--test/CodeGenCXX/mangle-ms-templates.cpp30
-rw-r--r--test/CodeGenCXX/mangle-ms-thunks-covariant.cpp29
-rw-r--r--test/CodeGenCXX/mangle-ms-vector-types.cpp4
-rw-r--r--test/CodeGenCXX/mangle-ms.cpp2
-rw-r--r--test/CodeGenCXX/mangle-win-ccs.cpp70
-rw-r--r--test/CodeGenCXX/mangle-win64-ccs.cpp26
-rw-r--r--test/CodeGenCXX/merge-functions.cpp6
-rw-r--r--test/CodeGenCXX/microsoft-abi-static-initializers.cpp10
-rw-r--r--test/CodeGenCXX/microsoft-abi-structors.cpp4
-rw-r--r--test/CodeGenCXX/microsoft-abi-throw.cpp4
-rw-r--r--test/CodeGenCXX/microsoft-abi-thunks.cpp2
-rw-r--r--test/CodeGenCXX/microsoft-abi-vbtables.cpp2
-rw-r--r--test/CodeGenCXX/microsoft-abi-vftables.cpp6
-rw-r--r--test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp8
-rw-r--r--test/CodeGenCXX/msabi-swiftcall-cc.cpp8
-rw-r--r--test/CodeGenCXX/no-lto-unit.cpp2
-rw-r--r--test/CodeGenCXX/no_destroy.cpp31
-rw-r--r--test/CodeGenCXX/noescape.cpp31
-rw-r--r--test/CodeGenCXX/override-layout-packed-base.cpp20
-rw-r--r--test/CodeGenCXX/pragma-init_seg.cpp8
-rw-r--r--test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp32
-rw-r--r--test/CodeGenCXX/pragma-loop-safety-nested.cpp27
-rw-r--r--test/CodeGenCXX/pragma-loop-safety-outer.cpp22
-rw-r--r--test/CodeGenCXX/pragma-loop-safety.cpp32
-rw-r--r--test/CodeGenCXX/pragma-pipeline.cpp47
-rw-r--r--test/CodeGenCXX/pragma-unroll-and-jam.cpp55
-rw-r--r--test/CodeGenCXX/profile-remap.cpp29
-rw-r--r--test/CodeGenCXX/speculative-vtt.cpp13
-rw-r--r--test/CodeGenCXX/static-init-wasm.cpp2
-rw-r--r--test/CodeGenCXX/thunk-returning-memptr.cpp27
-rw-r--r--test/CodeGenCXX/trivial-auto-var-init-attribute.cpp23
-rw-r--r--test/CodeGenCXX/trivial-auto-var-init.cpp216
-rw-r--r--test/CodeGenCXX/trivial_abi.cpp19
-rw-r--r--test/CodeGenCXX/type-metadata-thinlto.cpp4
-rw-r--r--test/CodeGenCXX/type-metadata.cpp14
-rw-r--r--test/CodeGenCXX/ubsan-check-debuglocs.cpp17
-rw-r--r--test/CodeGenCXX/visibility-inlines-hidden-staticvar.cpp111
-rw-r--r--test/CodeGenCXX/vtable-align.cpp5
-rw-r--r--test/CodeGenCXX/vtable-debug-info.cpp2
-rw-r--r--test/CodeGenCXX/vtable-linkage.cpp28
-rw-r--r--test/CodeGenCXX/wasm-args-returns.cpp26
131 files changed, 4610 insertions, 457 deletions
diff --git a/test/CodeGenCXX/Inputs/override-layout-packed-base.layout b/test/CodeGenCXX/Inputs/override-layout-packed-base.layout
index 949215ab849d..2ebcb98819b7 100644
--- a/test/CodeGenCXX/Inputs/override-layout-packed-base.layout
+++ b/test/CodeGenCXX/Inputs/override-layout-packed-base.layout
@@ -3,16 +3,26 @@
Type: class B<0>
Layout: <ASTRecordLayout
+ Size:40
FieldOffsets: [0, 32]>
*** Dumping AST Record Layout
Type: class B<1>
Layout: <ASTRecordLayout
+ Size:40
FieldOffsets: [0, 32]>
*** Dumping AST Record Layout
Type: class C
Layout: <ASTRecordLayout
+ Size:88
FieldOffsets: [80]>
+
+*** Dumping AST Record Layout
+Type: class D
+
+Layout: <ASTRecordLayout
+ Size:120
+ FieldOffsets: [32]>
diff --git a/test/CodeGenCXX/Inputs/profile-remap.map b/test/CodeGenCXX/Inputs/profile-remap.map
new file mode 100644
index 000000000000..50b812a9165e
--- /dev/null
+++ b/test/CodeGenCXX/Inputs/profile-remap.map
@@ -0,0 +1,2 @@
+name 3Foo 3Bar
+type N3Foo1XE N3Baz1YE
diff --git a/test/CodeGenCXX/Inputs/profile-remap.proftext b/test/CodeGenCXX/Inputs/profile-remap.proftext
new file mode 100644
index 000000000000..a1f90cfa6e9e
--- /dev/null
+++ b/test/CodeGenCXX/Inputs/profile-remap.proftext
@@ -0,0 +1,7 @@
+:ir
+_ZN3Foo8functionENS_1XE
+29667547796
+2
+10
+90
+
diff --git a/test/CodeGenCXX/Inputs/profile-remap.samples b/test/CodeGenCXX/Inputs/profile-remap.samples
new file mode 100644
index 000000000000..45e599470cc5
--- /dev/null
+++ b/test/CodeGenCXX/Inputs/profile-remap.samples
@@ -0,0 +1,3 @@
+_ZN3Bar8functionEN3Baz1YE:100:0
+ 2: 10
+ 4: 90
diff --git a/test/CodeGenCXX/PR20038.cpp b/test/CodeGenCXX/PR20038.cpp
index 095705f389bf..195e4e521240 100644
--- a/test/CodeGenCXX/PR20038.cpp
+++ b/test/CodeGenCXX/PR20038.cpp
@@ -6,9 +6,9 @@ struct C {
extern bool b;
// CHECK: call {{.*}}, !dbg [[DTOR_CALL1_LOC:![0-9]*]]
// CHECK: call {{.*}}, !dbg [[DTOR_CALL2_LOC:![0-9]*]]
-// CHECK: [[FUN1:.*]] = distinct !DISubprogram(name: "fun1",{{.*}} isDefinition: true
+// CHECK: [[FUN1:.*]] = distinct !DISubprogram(name: "fun1",{{.*}} DISPFlagDefinition
// CHECK: [[DTOR_CALL1_LOC]] = !DILocation(line: [[@LINE+1]], scope: [[FUN1]])
void fun1() { b && (C(), 1); }
-// CHECK: [[FUN2:.*]] = distinct !DISubprogram(name: "fun2",{{.*}} isDefinition: true
+// CHECK: [[FUN2:.*]] = distinct !DISubprogram(name: "fun2",{{.*}} DISPFlagDefinition
// CHECK: [[DTOR_CALL2_LOC]] = !DILocation(line: [[@LINE+1]], scope: [[FUN2]])
bool fun2() { return (C(), b) && 0; }
diff --git a/test/CodeGenCXX/aarch64-sign-return-address-static-ctor.cpp b/test/CodeGenCXX/aarch64-sign-return-address-static-ctor.cpp
new file mode 100644
index 000000000000..3971c22287f9
--- /dev/null
+++ b/test/CodeGenCXX/aarch64-sign-return-address-static-ctor.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -msign-return-address=none %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NONE
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -msign-return-address=non-leaf %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-PARTIAL --check-prefix=CHECK-A-KEY
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -msign-return-address=all %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ALL --check-prefix=CHECK-A-KEY
+
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=none %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NONE
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=standard %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-PARTIAL --check-prefix=CHECK-A-KEY --check-prefix=CHECK-BTE
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=pac-ret %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-PARTIAL --check-prefix=CHECK-A-KEY
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=pac-ret+leaf %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ALL --check-prefix=CHECK-A-KEY
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=pac-ret+b-key %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-PARTIAL --check-prefix=CHECK-B-KEY
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=pac-ret+b-key+leaf %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ALL --check-prefix=CHECK-B-KEY
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=bti %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BTE
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=pac-ret+b-key+leaf+bti %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ALL --check-prefix=CHECK-B-KEY --check-prefix=BTE
+
+struct Foo {
+ Foo() {}
+ ~Foo() {}
+};
+
+Foo f;
+
+// CHECK: @llvm.global_ctors {{.*}}i32 65535, void ()* @[[CTOR_FN:.*]], i8* null
+
+// CHECK: @[[CTOR_FN]]() #[[ATTR:[0-9]*]]
+
+// CHECK-NONE-NOT: "sign-return-address"={{.*}}
+// CHECK-PARTIAL: "sign-return-address"="non-leaf"
+// CHECK-ALL: "sign-return-address"="all"
+// CHECK-A-KEY: "sign-return-address-key"="a_key"
+// CHECK-B-KEY: "sign-return-address-key"="b_key"
+// CHECK-BTE: "branch-target-enforcement"
diff --git a/test/CodeGenCXX/address-space-cast-coerce.cpp b/test/CodeGenCXX/address-space-cast-coerce.cpp
new file mode 100644
index 000000000000..940a4f55b47a
--- /dev/null
+++ b/test/CodeGenCXX/address-space-cast-coerce.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 %s -triple=amdgcn-amd-amdhsa -emit-llvm -o - | FileCheck %s
+
+template<typename T, unsigned int n> struct my_vector_base;
+
+ template<typename T>
+ struct my_vector_base<T, 1> {
+ typedef T Native_vec_ __attribute__((ext_vector_type(1)));
+
+ union {
+ Native_vec_ data;
+ struct {
+ T x;
+ };
+ };
+ };
+
+ template<typename T, unsigned int rank>
+ struct my_vector_type : public my_vector_base<T, rank> {
+ using my_vector_base<T, rank>::data;
+ using typename my_vector_base<T, rank>::Native_vec_;
+
+ template< typename U>
+ my_vector_type(U x) noexcept
+ {
+ for (auto i = 0u; i != rank; ++i) data[i] = x;
+ }
+ my_vector_type& operator+=(const my_vector_type& x) noexcept
+ {
+ data += x.data;
+ return *this;
+ }
+ };
+
+template<typename T, unsigned int n>
+ inline
+ my_vector_type<T, n> operator+(
+ const my_vector_type<T, n>& x, const my_vector_type<T, n>& y) noexcept
+ {
+ return my_vector_type<T, n>{x} += y;
+ }
+
+using char1 = my_vector_type<char, 1>;
+
+int mane() {
+
+ char1 f1{1};
+ char1 f2{1};
+
+// CHECK: %[[a:[^ ]+]] = addrspacecast i16 addrspace(5)* %{{[^ ]+}} to i16*
+// CHECK: %[[a:[^ ]+]] = addrspacecast %{{[^ ]+}} addrspace(5)* %{{[^ ]+}} to %{{[^ ]+}}
+
+ char1 f3 = f1 + f2;
+}
diff --git a/test/CodeGenCXX/address-space-cast.cpp b/test/CodeGenCXX/address-space-cast.cpp
index 334a1a63e627..e0cf3c199b88 100644
--- a/test/CodeGenCXX/address-space-cast.cpp
+++ b/test/CodeGenCXX/address-space-cast.cpp
@@ -3,13 +3,63 @@
#define __private__ __attribute__((address_space(5)))
void func_pchar(__private__ char *x);
+void func_pvoid(__private__ void *x);
+void func_pint(__private__ int *x);
-void test_cast(char *gen_ptr) {
+void test_cast(char *gen_char_ptr, void *gen_void_ptr, int *gen_int_ptr) {
// CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
// CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
- __private__ char *priv_ptr = (__private__ char *)gen_ptr;
+ __private__ char *priv_char_ptr = (__private__ char *)gen_char_ptr;
// CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
+ priv_char_ptr = (__private__ char *)gen_void_ptr;
+
+ // CHECK: %[[cast:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
+ priv_char_ptr = (__private__ char *)gen_int_ptr;
+
+ // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
+ __private__ void *priv_void_ptr = (__private__ void *)gen_char_ptr;
+
+ // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
+ priv_void_ptr = (__private__ void *)gen_void_ptr;
+
+ // CHECK: %[[cast:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
+ priv_void_ptr = (__private__ void *)gen_int_ptr;
+
+ // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i32 addrspace(5)*
+ // CHECK-NEXT: store i32 addrspace(5)* %[[cast]]
+ __private__ int *priv_int_ptr = (__private__ int *)gen_void_ptr;
+
+ // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: call void @_Z10func_pcharPU3AS5c(i8 addrspace(5)* %[[cast]])
+ func_pchar((__private__ char *)gen_char_ptr);
+
+ // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: call void @_Z10func_pcharPU3AS5c(i8 addrspace(5)* %[[cast]])
+ func_pchar((__private__ char *)gen_void_ptr);
+
+ // CHECK: %[[cast:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(5)*
// CHECK-NEXT: call void @_Z10func_pcharPU3AS5c(i8 addrspace(5)* %[[cast]])
- func_pchar((__private__ char *)gen_ptr);
+ func_pchar((__private__ char *)gen_int_ptr);
+
+ // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: call void @_Z10func_pvoidPU3AS5v(i8 addrspace(5)* %[[cast]])
+ func_pvoid((__private__ void *)gen_char_ptr);
+
+ // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: call void @_Z10func_pvoidPU3AS5v(i8 addrspace(5)* %[[cast]])
+ func_pvoid((__private__ void *)gen_void_ptr);
+
+ // CHECK: %[[cast:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: call void @_Z10func_pvoidPU3AS5v(i8 addrspace(5)* %[[cast]])
+ func_pvoid((__private__ void *)gen_int_ptr);
+
+ // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i32 addrspace(5)*
+ // CHECK-NEXT: call void @_Z9func_pintPU3AS5i(i32 addrspace(5)* %[[cast]])
+ func_pint((__private__ int *)gen_void_ptr);
}
diff --git a/test/CodeGenCXX/always_destroy.cpp b/test/CodeGenCXX/always_destroy.cpp
new file mode 100644
index 000000000000..e84c4cf02c52
--- /dev/null
+++ b/test/CodeGenCXX/always_destroy.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 %s -fno-c++-static-destructors -emit-llvm -triple x86_64-apple-macosx10.13.0 -o - | FileCheck %s
+
+struct NonTrivial {
+ ~NonTrivial();
+};
+
+// CHECK-NOT: __cxa_atexit{{.*}}_ZN10NonTrivialD1Ev
+NonTrivial nt1;
+// CHECK-NOT: _tlv_atexit{{.*}}_ZN10NonTrivialD1Ev
+thread_local NonTrivial nt2;
+
+struct NonTrivial2 {
+ ~NonTrivial2();
+};
+
+// CHECK: __cxa_atexit{{.*}}_ZN11NonTrivial2D1Ev
+[[clang::always_destroy]] NonTrivial2 nt21;
+// CHECK: _tlv_atexit{{.*}}_ZN11NonTrivial2D1Ev
+[[clang::always_destroy]] thread_local NonTrivial2 nt22;
+
+void f() {
+ // CHECK: __cxa_atexit{{.*}}_ZN11NonTrivial2D1Ev
+ [[clang::always_destroy]] static NonTrivial2 nt21;
+ // CHECK: _tlv_atexit{{.*}}_ZN11NonTrivial2D1Ev
+ [[clang::always_destroy]] thread_local NonTrivial2 nt22;
+}
+
+// CHECK-NOT: __cxa_atexit{{.*}}_ZN10NonTrivialD1Ev
+[[clang::no_destroy]] NonTrivial nt3;
+// CHECK-NOT: _tlv_atexit{{.*}}_ZN10NonTrivialD1Ev
+[[clang::no_destroy]] thread_local NonTrivial nt4;
diff --git a/test/CodeGenCXX/amdgcn-string-literal.cpp b/test/CodeGenCXX/amdgcn-string-literal.cpp
index 7fd05351c863..70be249433fb 100644
--- a/test/CodeGenCXX/amdgcn-string-literal.cpp
+++ b/test/CodeGenCXX/amdgcn-string-literal.cpp
@@ -4,7 +4,7 @@
// CHECK: @g_str = addrspace(1) global i8* addrspacecast (i8 addrspace(4)* getelementptr inbounds ([6 x i8], [6 x i8] addrspace(4)* @.str, i32 0, i32 0) to i8*), align 8
// CHECK: @g_array = addrspace(1) global [8 x i8] c"g_array\00", align 1
// CHECK: @.str.1 = private unnamed_addr addrspace(4) constant [6 x i8] c"l_str\00", align 1
-// CHECK: @_ZZ1fvE7l_array = private unnamed_addr addrspace(4) constant [8 x i8] c"l_array\00", align 1
+// CHECK: @__const._Z1fv.l_array = private unnamed_addr addrspace(4) constant [8 x i8] c"l_array\00", align 1
const char* g_str = "g_str";
char g_array[] = "g_array";
diff --git a/test/CodeGenCXX/atomic-inline.cpp b/test/CodeGenCXX/atomic-inline.cpp
index 327f85d5667f..fe727589d2e2 100644
--- a/test/CodeGenCXX/atomic-inline.cpp
+++ b/test/CodeGenCXX/atomic-inline.cpp
@@ -1,52 +1,6 @@
// 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
-// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=i386-linux-gnu -target-cpu i386 | FileCheck %s --check-prefix=I386
-// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=i386-linux-gnu -target-cpu i486 | FileCheck %s --check-prefix=I486
-// Check the atomic code generation for cpu targets w/wo cx, cx8 and cx16 support.
-
-struct alignas(4) AM4 {
- short f1, f2;
-};
-AM4 m4;
-AM4 load4() {
- AM4 am;
- // CHECK-LABEL: @_Z5load4v
- // CHECK: load atomic i32, {{.*}} monotonic
- // CORE2-LABEL: @_Z5load4v
- // CORE2: load atomic i32, {{.*}} monotonic
- // I386-LABEL: @_Z5load4v
- // I386: call i32 @__atomic_load_4
- // I486-LABEL: @_Z5load4v
- // I486: load atomic i32, {{.*}} monotonic
- __atomic_load(&m4, &am, 0);
- return am;
-}
-
-AM4 s4;
-void store4() {
- // CHECK-LABEL: @_Z6store4v
- // CHECK: store atomic i32 {{.*}} monotonic
- // CORE2-LABEL: @_Z6store4v
- // CORE2: store atomic i32 {{.*}} monotonic
- // I386-LABEL: @_Z6store4v
- // I386: call void @__atomic_store_4
- // I486-LABEL: @_Z6store4v
- // I486: store atomic i32 {{.*}} monotonic
- __atomic_store(&m4, &s4, 0);
-}
-
-bool cmpxchg4() {
- AM4 am;
- // CHECK-LABEL: @_Z8cmpxchg4v
- // CHECK: cmpxchg i32* {{.*}} monotonic
- // CORE2-LABEL: @_Z8cmpxchg4v
- // CORE2: cmpxchg i32* {{.*}} monotonic
- // I386-LABEL: @_Z8cmpxchg4v
- // I386: call zeroext i1 @__atomic_compare_exchange_4
- // I486-LABEL: @_Z8cmpxchg4v
- // I486: cmpxchg i32* {{.*}} monotonic
- return __atomic_compare_exchange(&m4, &s4, &am, 0, 0, 0);
-}
+// Check the atomic code generation for cpu targets w/wo cx16 support.
struct alignas(8) AM8 {
int f1, f2;
@@ -58,10 +12,6 @@ AM8 load8() {
// CHECK: load atomic i64, {{.*}} monotonic
// CORE2-LABEL: @_Z5load8v
// CORE2: load atomic i64, {{.*}} monotonic
- // I386-LABEL: @_Z5load8v
- // I386: call i64 @__atomic_load_8
- // I486-LABEL: @_Z5load8v
- // I486: call i64 @__atomic_load_8
__atomic_load(&m8, &am, 0);
return am;
}
@@ -72,10 +22,6 @@ void store8() {
// CHECK: store atomic i64 {{.*}} monotonic
// CORE2-LABEL: @_Z6store8v
// CORE2: store atomic i64 {{.*}} monotonic
- // I386-LABEL: @_Z6store8v
- // I386: call void @__atomic_store_8
- // I486-LABEL: @_Z6store8v
- // I486: call void @__atomic_store_8
__atomic_store(&m8, &s8, 0);
}
@@ -85,10 +31,6 @@ bool cmpxchg8() {
// CHECK: cmpxchg i64* {{.*}} monotonic
// CORE2-LABEL: @_Z8cmpxchg8v
// CORE2: cmpxchg i64* {{.*}} monotonic
- // I386-LABEL: @_Z8cmpxchg8v
- // I386: call zeroext i1 @__atomic_compare_exchange_8
- // I486-LABEL: @_Z8cmpxchg8v
- // I486: call zeroext i1 @__atomic_compare_exchange_8
return __atomic_compare_exchange(&m8, &s8, &am, 0, 0, 0);
}
@@ -124,3 +66,4 @@ bool cmpxchg16() {
// CORE2: cmpxchg i128* {{.*}} monotonic
return __atomic_compare_exchange(&m16, &s16, &am, 0, 0, 0);
}
+
diff --git a/test/CodeGenCXX/attr-cpuspecific.cpp b/test/CodeGenCXX/attr-cpuspecific.cpp
new file mode 100644
index 000000000000..bfee49ca34bd
--- /dev/null
+++ b/test/CodeGenCXX/attr-cpuspecific.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,LINUX
+// RUN: %clang_cc1 -triple x86_64-windows-pc -fms-compatibility -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,WINDOWS
+
+struct S {
+ __attribute__((cpu_specific(atom)))
+ void Func(){}
+ __attribute__((cpu_dispatch(ivybridge,atom)))
+ void Func(){}
+};
+
+void foo() {
+ S s;
+ s.Func();
+}
+
+// LINUX: define void (%struct.S*)* @_ZN1S4FuncEv.resolver
+// LINUX: ret void (%struct.S*)* @_ZN1S4FuncEv.S
+// LINUX: ret void (%struct.S*)* @_ZN1S4FuncEv.O
+// LINUX: declare void @_ZN1S4FuncEv.S
+// LINUX: define linkonce_odr void @_ZN1S4FuncEv.O
+
+// WINDOWS: define dso_local void @"?Func@S@@QEAAXXZ"(%struct.S*)
+// WINDOWS: musttail call void @"?Func@S@@QEAAXXZ.S"(%struct.S* %0)
+// WINDOWS: musttail call void @"?Func@S@@QEAAXXZ.O"(%struct.S* %0)
+// WINDOWS: declare dso_local void @"?Func@S@@QEAAXXZ.S"
+// WINDOWS: define linkonce_odr dso_local void @"?Func@S@@QEAAXXZ.O"
diff --git a/test/CodeGenCXX/attr-exclude_from_explicit_instantiation.dont_assume_extern_instantiation.cpp b/test/CodeGenCXX/attr-exclude_from_explicit_instantiation.dont_assume_extern_instantiation.cpp
new file mode 100644
index 000000000000..efbbb0cd6400
--- /dev/null
+++ b/test/CodeGenCXX/attr-exclude_from_explicit_instantiation.dont_assume_extern_instantiation.cpp
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -O0 -o - %s | FileCheck %s
+
+// Test that we do not assume that entities marked with the
+// exclude_from_explicit_instantiation attribute are instantiated
+// in another TU when an extern template instantiation declaration
+// is present. We test that by making sure that definitions are
+// generated in this TU despite there being an extern template
+// instantiation declaration, which is normally not the case.
+
+#define EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__((exclude_from_explicit_instantiation))
+
+template <class T>
+struct Foo {
+ EXCLUDE_FROM_EXPLICIT_INSTANTIATION inline void non_static_member_function1();
+ EXCLUDE_FROM_EXPLICIT_INSTANTIATION void non_static_member_function2();
+
+ EXCLUDE_FROM_EXPLICIT_INSTANTIATION static inline void static_member_function1();
+ EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void static_member_function2();
+
+ EXCLUDE_FROM_EXPLICIT_INSTANTIATION static int static_data_member;
+
+ struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION member_class1 {
+ static void static_member_function() { }
+ };
+
+ struct member_class2 {
+ EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void static_member_function() { }
+ };
+};
+
+template <class T> inline void Foo<T>::non_static_member_function1() { }
+template <class T> void Foo<T>::non_static_member_function2() { }
+
+template <class T> inline void Foo<T>::static_member_function1() { }
+template <class T> void Foo<T>::static_member_function2() { }
+
+template <class T> int Foo<T>::static_data_member = 0;
+
+extern template struct Foo<int>;
+
+void use() {
+ Foo<int> f;
+
+ // An inline non-static member function marked with the attribute is not
+ // part of the extern template declaration, so a definition must be emitted
+ // in this TU.
+ // CHECK-DAG: define linkonce_odr void @_ZN3FooIiE27non_static_member_function1Ev
+ f.non_static_member_function1();
+
+ // A non-inline non-static member function marked with the attribute is
+ // not part of the extern template declaration, so a definition must be
+ // emitted in this TU.
+ // CHECK-DAG: define linkonce_odr void @_ZN3FooIiE27non_static_member_function2Ev
+ f.non_static_member_function2();
+
+ // An inline static member function marked with the attribute is not
+ // part of the extern template declaration, so a definition must be
+ // emitted in this TU.
+ // CHECK-DAG: define linkonce_odr void @_ZN3FooIiE23static_member_function1Ev
+ Foo<int>::static_member_function1();
+
+ // A non-inline static member function marked with the attribute is not
+ // part of the extern template declaration, so a definition must be
+ // emitted in this TU.
+ // CHECK-DAG: define linkonce_odr void @_ZN3FooIiE23static_member_function2Ev
+ Foo<int>::static_member_function2();
+
+ // A static data member marked with the attribute is not part of the
+ // extern template declaration, so a definition must be emitted in this TU.
+ // CHECK-DAG: @_ZN3FooIiE18static_data_memberE = linkonce_odr global
+ int& odr_use = Foo<int>::static_data_member;
+
+ // A member class marked with the attribute is not part of the extern
+ // template declaration (it is not recursively instantiated), so its member
+ // functions must be emitted in this TU.
+ // CHECK-DAG: define linkonce_odr void @_ZN3FooIiE13member_class122static_member_functionEv
+ Foo<int>::member_class1::static_member_function();
+
+ // A member function marked with the attribute in a member class is not
+ // part of the extern template declaration of the parent class template, so
+ // it must be emitted in this TU.
+ // CHECK-DAG: define linkonce_odr void @_ZN3FooIiE13member_class222static_member_functionEv
+ Foo<int>::member_class2::static_member_function();
+}
diff --git a/test/CodeGenCXX/attr-no-destroy-d54344.cpp b/test/CodeGenCXX/attr-no-destroy-d54344.cpp
new file mode 100644
index 000000000000..2e004d6426d9
--- /dev/null
+++ b/test/CodeGenCXX/attr-no-destroy-d54344.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -std=c++2a -emit-llvm -O0 -triple x86_64-unknown-linux-gnu -DNOATTR %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++2a -emit-llvm -O0 -triple x86_64-unknown-linux-gnu %s -o - | FileCheck %s --check-prefix=CHECK-ATTR
+// RUN: %clang_cc1 -std=c++2a -emit-llvm -O0 -triple x86_64-unknown-linux-gnu -DNOATTR -fno-c++-static-destructors %s -o - | FileCheck %s --check-prefix=CHECK-FLAG
+
+// Regression test for D54344. Class with no user-defined destructor
+// that has an inherited member that has a non-trivial destructor
+// and a non-default constructor will attempt to emit a destructor
+// despite being marked as __attribute((no_destroy)) in which case
+// it would trigger an assertion due to an incorrect assumption.
+
+// This test is more reliable with asserts to work as without
+// the crash may (unlikely) could generate working but semantically
+// incorrect code.
+
+class a {
+public:
+ ~a();
+};
+class logger_base {
+ a d;
+};
+class e : logger_base {};
+#ifndef NOATTR
+__attribute((no_destroy))
+#endif
+e g;
+
+// In the absence of the attribute and flag, both ctor and dtor should
+// be emitted, check for that.
+// CHECK: @__cxx_global_var_init
+// CHECK: @__cxa_atexit
+
+// When attribute is enabled, the constructor should not be balanced
+// by a destructor. Make sure we have the ctor but not the dtor
+// registration.
+// CHECK-ATTR: @__cxx_global_var_init
+// CHECK-ATTR-NOT: @__cxa_atexit
+
+// Same scenario except with global flag (-fno-c++-static-destructors)
+// supressing it instead of the attribute.
+// CHECK-FLAG: @__cxx_global_var_init
+// CHECK-FLAG-NOT: @__cxa_atexit
diff --git a/test/CodeGenCXX/attr-target-mv-diff-ns.cpp b/test/CodeGenCXX/attr-target-mv-diff-ns.cpp
index 4dc2b67b4644..77e1ad771eca 100644
--- a/test/CodeGenCXX/attr-target-mv-diff-ns.cpp
+++ b/test/CodeGenCXX/attr-target-mv-diff-ns.cpp
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s
-// Test ensures that this properly differentiates between types in different
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS
+// Test ensures that this properly differentiates between types in different
// namespaces.
int __attribute__((target("sse4.2"))) foo(int) { return 0; }
int __attribute__((target("arch=sandybridge"))) foo(int);
@@ -17,38 +18,71 @@ int bar() {
return foo(1) + ns::foo(2);
}
-// CHECK: @_Z3fooi.ifunc = ifunc i32 (i32), i32 (i32)* ()* @_Z3fooi.resolver
-// CHECK: @_ZN2ns3fooEi.ifunc = ifunc i32 (i32), i32 (i32)* ()* @_ZN2ns3fooEi.resolver
-
-// CHECK: define i32 @_Z3fooi.sse4.2(i32)
-// CHECK: ret i32 0
-// CHECK: define i32 @_Z3fooi.arch_ivybridge(i32)
-// CHECK: ret i32 1
-// CHECK: define i32 @_Z3fooi(i32)
-// CHECK: ret i32 2
-
-// CHECK: define i32 @_ZN2ns3fooEi.sse4.2(i32)
-// CHECK: ret i32 0
-// CHECK: define i32 @_ZN2ns3fooEi.arch_ivybridge(i32)
-// CHECK: ret i32 1
-// CHECK: define i32 @_ZN2ns3fooEi(i32)
-// CHECK: ret i32 2
-
-// CHECK: define i32 @_Z3barv()
-// CHECK: call i32 @_Z3fooi.ifunc(i32 1)
-// CHECK: call i32 @_ZN2ns3fooEi.ifunc(i32 2)
-
-// CHECK: define i32 (i32)* @_Z3fooi.resolver() comdat
-// CHECK: ret i32 (i32)* @_Z3fooi.arch_sandybridge
-// CHECK: ret i32 (i32)* @_Z3fooi.arch_ivybridge
-// CHECK: ret i32 (i32)* @_Z3fooi.sse4.2
-// CHECK: ret i32 (i32)* @_Z3fooi
-//
-// CHECK: define i32 (i32)* @_ZN2ns3fooEi.resolver() comdat
-// CHECK: ret i32 (i32)* @_ZN2ns3fooEi.arch_sandybridge
-// CHECK: ret i32 (i32)* @_ZN2ns3fooEi.arch_ivybridge
-// CHECK: ret i32 (i32)* @_ZN2ns3fooEi.sse4.2
-// CHECK: ret i32 (i32)* @_ZN2ns3fooEi
-
-// CHECK: declare i32 @_Z3fooi.arch_sandybridge(i32)
-// CHECK: declare i32 @_ZN2ns3fooEi.arch_sandybridge(i32)
+// LINUX: @_Z3fooi.ifunc = ifunc i32 (i32), i32 (i32)* ()* @_Z3fooi.resolver
+// LINUX: @_ZN2ns3fooEi.ifunc = ifunc i32 (i32), i32 (i32)* ()* @_ZN2ns3fooEi.resolver
+
+// LINUX: define i32 @_Z3fooi.sse4.2(i32)
+// LINUX: ret i32 0
+// LINUX: define i32 @_Z3fooi.arch_ivybridge(i32)
+// LINUX: ret i32 1
+// LINUX: define i32 @_Z3fooi(i32)
+// LINUX: ret i32 2
+
+// WINDOWS: define dso_local i32 @"?foo@@YAHH@Z.sse4.2"(i32)
+// WINDOWS: ret i32 0
+// WINDOWS: define dso_local i32 @"?foo@@YAHH@Z.arch_ivybridge"(i32)
+// WINDOWS: ret i32 1
+// WINDOWS: define dso_local i32 @"?foo@@YAHH@Z"(i32)
+// WINDOWS: ret i32 2
+
+// LINUX: define i32 @_ZN2ns3fooEi.sse4.2(i32)
+// LINUX: ret i32 0
+// LINUX: define i32 @_ZN2ns3fooEi.arch_ivybridge(i32)
+// LINUX: ret i32 1
+// LINUX: define i32 @_ZN2ns3fooEi(i32)
+// LINUX: ret i32 2
+
+// WINDOWS: define dso_local i32 @"?foo@ns@@YAHH@Z.sse4.2"(i32)
+// WINDOWS: ret i32 0
+// WINDOWS: define dso_local i32 @"?foo@ns@@YAHH@Z.arch_ivybridge"(i32)
+// WINDOWS: ret i32 1
+// WINDOWS: define dso_local i32 @"?foo@ns@@YAHH@Z"(i32)
+// WINDOWS: ret i32 2
+
+// LINUX: define i32 @_Z3barv()
+// LINUX: call i32 @_Z3fooi.ifunc(i32 1)
+// LINUX: call i32 @_ZN2ns3fooEi.ifunc(i32 2)
+
+// WINDOWS: define dso_local i32 @"?bar@@YAHXZ"()
+// WINDOWS: call i32 @"?foo@@YAHH@Z.resolver"(i32 1)
+// WINDOWS: call i32 @"?foo@ns@@YAHH@Z.resolver"(i32 2)
+
+// LINUX: define i32 (i32)* @_Z3fooi.resolver() comdat
+// LINUX: ret i32 (i32)* @_Z3fooi.arch_sandybridge
+// LINUX: ret i32 (i32)* @_Z3fooi.arch_ivybridge
+// LINUX: ret i32 (i32)* @_Z3fooi.sse4.2
+// LINUX: ret i32 (i32)* @_Z3fooi
+
+// WINDOWS: define dso_local i32 @"?foo@@YAHH@Z.resolver"(i32) comdat
+// WINDOWS: call i32 @"?foo@@YAHH@Z.arch_sandybridge"(i32 %0)
+// WINDOWS: call i32 @"?foo@@YAHH@Z.arch_ivybridge"(i32 %0)
+// WINDOWS: call i32 @"?foo@@YAHH@Z.sse4.2"(i32 %0)
+// WINDOWS: call i32 @"?foo@@YAHH@Z"(i32 %0)
+
+// LINUX: define i32 (i32)* @_ZN2ns3fooEi.resolver() comdat
+// LINUX: ret i32 (i32)* @_ZN2ns3fooEi.arch_sandybridge
+// LINUX: ret i32 (i32)* @_ZN2ns3fooEi.arch_ivybridge
+// LINUX: ret i32 (i32)* @_ZN2ns3fooEi.sse4.2
+// LINUX: ret i32 (i32)* @_ZN2ns3fooEi
+
+// WINDOWS: define dso_local i32 @"?foo@ns@@YAHH@Z.resolver"(i32) comdat
+// WINDOWS: call i32 @"?foo@ns@@YAHH@Z.arch_sandybridge"(i32 %0)
+// WINDOWS: call i32 @"?foo@ns@@YAHH@Z.arch_ivybridge"(i32 %0)
+// WINDOWS: call i32 @"?foo@ns@@YAHH@Z.sse4.2"(i32 %0)
+// WINDOWS: call i32 @"?foo@ns@@YAHH@Z"(i32 %0)
+
+// LINUX: declare i32 @_Z3fooi.arch_sandybridge(i32)
+// LINUX: declare i32 @_ZN2ns3fooEi.arch_sandybridge(i32)
+
+// WINDOWS: declare dso_local i32 @"?foo@@YAHH@Z.arch_sandybridge"(i32)
+// WINDOWS: declare dso_local i32 @"?foo@ns@@YAHH@Z.arch_sandybridge"(i32)
diff --git a/test/CodeGenCXX/attr-target-mv-func-ptrs.cpp b/test/CodeGenCXX/attr-target-mv-func-ptrs.cpp
index 290d6b5c6489..6336e190426b 100644
--- a/test/CodeGenCXX/attr-target-mv-func-ptrs.cpp
+++ b/test/CodeGenCXX/attr-target-mv-func-ptrs.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS
void temp();
void temp(int);
using FP = void(*)(int);
@@ -31,15 +32,23 @@ int bar() {
return Free(1) + (s.*Member)(2);
}
+// LINUX: @_Z3fooi.ifunc
+// LINUX: @_ZN1S3fooEi.ifunc
-// CHECK: @_Z3fooi.ifunc
-// CHECK: @_ZN1S3fooEi.ifunc
-
-// CHECK: define i32 @_Z3barv()
+// LINUX: define i32 @_Z3barv()
// Store to Free of ifunc
-// CHECK: store i32 (i32)* @_Z3fooi.ifunc
+// LINUX: store i32 (i32)* @_Z3fooi.ifunc
// Store to Member of ifunc
-// CHECK: store { i64, i64 } { i64 ptrtoint (i32 (%struct.S*, i32)* @_ZN1S3fooEi.ifunc to i64), i64 0 }, { i64, i64 }* [[MEMBER:%[a-z]+]]
+// LINUX: store { i64, i64 } { i64 ptrtoint (i32 (%struct.S*, i32)* @_ZN1S3fooEi.ifunc to i64), i64 0 }, { i64, i64 }* [[MEMBER:%[a-z]+]]
// Call to 'f' with the ifunc
-// CHECK: call void @_Z1fPFiiEM1SFiiE(i32 (i32)* @_Z3fooi.ifunc
+// LINUX: call void @_Z1fPFiiEM1SFiiE(i32 (i32)* @_Z3fooi.ifunc
+
+// WINDOWS: define dso_local i32 @"?bar@@YAHXZ"()
+// Store to Free
+// WINDOWS: store i32 (i32)* @"?foo@@YAHH@Z.resolver", i32 (i32)**
+// Store to Member
+// WINDOWS: store i8* bitcast (i32 (%struct.S*, i32)* @"?foo@S@@QEAAHH@Z.resolver" to i8*), i8**
+
+// Call to 'f'
+// WINDOWS: call void @"?f@@YAXP6AHH@ZP8S@@EAAHH@Z@Z"(i32 (i32)* @"?foo@@YAHH@Z.resolver", i8* bitcast (i32 (%struct.S*, i32)* @"?foo@S@@QEAAHH@Z.resolver" to i8*))
diff --git a/test/CodeGenCXX/attr-target-mv-inalloca.cpp b/test/CodeGenCXX/attr-target-mv-inalloca.cpp
new file mode 100644
index 000000000000..0b656220273f
--- /dev/null
+++ b/test/CodeGenCXX/attr-target-mv-inalloca.cpp
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 -std=c++11 -triple i686-windows-msvc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS64
+
+struct Foo {
+ Foo();
+ Foo(const Foo &o);
+ ~Foo();
+ int x;
+};
+int __attribute__((target("default"))) bar(Foo o) { return o.x; }
+int __attribute__((target("sse4.2"))) bar(Foo o) { return o.x + 1; }
+int __attribute__((target("arch=ivybridge"))) bar(Foo o) { return o.x + 2; }
+
+void usage() {
+ Foo f;
+ bar(f);
+}
+
+// WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z"(<{ %struct.Foo }>* inalloca)
+// WINDOWS: %[[O:[0-9a-zA-Z]+]] = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %0, i32 0, i32 0
+// WINDOWS: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0
+// WINDOWS: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]]
+// WINDOWS: ret i32 %[[LOAD]]
+
+// WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z.sse4.2"(<{ %struct.Foo }>* inalloca)
+// WINDOWS: %[[O:[0-9a-zA-Z]+]] = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %0, i32 0, i32 0
+// WINDOWS: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0
+// WINDOWS: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]]
+// WINDOWS: %[[ADD:[0-9a-zA-Z]+]] = add nsw i32 %[[LOAD]], 1
+// WINDOWS: ret i32 %[[ADD]]
+
+// WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(<{ %struct.Foo }>* inalloca)
+// WINDOWS: %[[O:[0-9a-zA-Z]+]] = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %0, i32 0, i32 0
+// WINDOWS: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0
+// WINDOWS: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]]
+// WINDOWS: %[[ADD:[0-9a-zA-Z]+]] = add nsw i32 %[[LOAD]], 2
+// WINDOWS: ret i32 %[[ADD]]
+
+// WINDOWS: define dso_local void @"?usage@@YAXXZ"()
+// WINDOWS: %[[F:[0-9a-zA-Z]+]] = alloca %struct.Foo
+// WINDOWS: %[[ARGMEM:[0-9a-zA-Z]+]] = alloca inalloca <{ %struct.Foo }>
+// WINDOWS: %[[CALL:[0-9a-zA-Z]+]] = call i32 @"?bar@@YAHUFoo@@@Z.resolver"(<{ %struct.Foo }>* inalloca %[[ARGMEM]])
+
+// WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z.resolver"(<{ %struct.Foo }>*)
+// WINDOWS: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(<{ %struct.Foo }>* %0)
+// WINDOWS-NEXT: ret i32 %[[RET]]
+// WINDOWS: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z.sse4.2"(<{ %struct.Foo }>* %0)
+// WINDOWS-NEXT: ret i32 %[[RET]]
+// WINDOWS: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z"(<{ %struct.Foo }>* %0)
+// WINDOWS-NEXT: ret i32 %[[RET]]
+
+
+// WINDOWS64: define dso_local i32 @"?bar@@YAHUFoo@@@Z"(%struct.Foo* %[[O:[0-9a-zA-Z]+]])
+// WINDOWS64: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0
+// WINDOWS64: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]]
+// WINDOWS64: ret i32 %[[LOAD]]
+
+// WINDOWS64: define dso_local i32 @"?bar@@YAHUFoo@@@Z.sse4.2"(%struct.Foo* %[[O:[0-9a-zA-Z]+]])
+// WINDOWS64: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0
+// WINDOWS64: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]]
+// WINDOWS64: %[[ADD:[0-9a-zA-Z]+]] = add nsw i32 %[[LOAD]], 1
+// WINDOWS64: ret i32 %[[ADD]]
+
+// WINDOWS64: define dso_local i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(%struct.Foo* %[[O:[0-9a-zA-Z]+]])
+// WINDOWS64: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0
+// WINDOWS64: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]]
+// WINDOWS64: %[[ADD:[0-9a-zA-Z]+]] = add nsw i32 %[[LOAD]], 2
+// WINDOWS64: ret i32 %[[ADD]]
+
+// WINDOWS64: define dso_local void @"?usage@@YAXXZ"()
+// WINDOWS64: %[[F:[0-9a-zA-Z]+]] = alloca %struct.Foo
+// WINDOWS64: %[[ARG:[0-9a-zA-Z.]+]] = alloca %struct.Foo
+// WINDOWS64: %[[CALL:[0-9a-zA-Z]+]] = call i32 @"?bar@@YAHUFoo@@@Z.resolver"(%struct.Foo* %[[ARG]])
+
+// WINDOWS64: define dso_local i32 @"?bar@@YAHUFoo@@@Z.resolver"(%struct.Foo*)
+// WINDOWS64: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(%struct.Foo* %0)
+// WINDOWS64-NEXT: ret i32 %[[RET]]
+// WINDOWS64: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z.sse4.2"(%struct.Foo* %0)
+// WINDOWS64-NEXT: ret i32 %[[RET]]
+// WINDOWS64: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z"(%struct.Foo* %0)
+// WINDOWS64-NEXT: ret i32 %[[RET]]
diff --git a/test/CodeGenCXX/attr-target-mv-member-funcs.cpp b/test/CodeGenCXX/attr-target-mv-member-funcs.cpp
index 2e5db3b705e4..a63737ed0330 100644
--- a/test/CodeGenCXX/attr-target-mv-member-funcs.cpp
+++ b/test/CodeGenCXX/attr-target-mv-member-funcs.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS
struct S {
int __attribute__((target("sse4.2"))) foo(int) { return 0; }
@@ -64,74 +65,156 @@ int templ_use() {
return a.foo(1) + b.foo(2);
}
-// CHECK: @_ZN1SaSERKS_.ifunc = ifunc %struct.S* (%struct.S*, %struct.S*), %struct.S* (%struct.S*, %struct.S*)* ()* @_ZN1SaSERKS_.resolver
-// CHECK: @_ZNK9ConvertTocv1SEv.ifunc = ifunc void (%struct.ConvertTo*), void (%struct.ConvertTo*)* ()* @_ZNK9ConvertTocv1SEv.resolver
-// CHECK: @_ZN1S3fooEi.ifunc = ifunc i32 (%struct.S*, i32), i32 (%struct.S*, i32)* ()* @_ZN1S3fooEi.resolver
-// CHECK: @_ZN2S23fooEi.ifunc = ifunc i32 (%struct.S2*, i32), i32 (%struct.S2*, i32)* ()* @_ZN2S23fooEi.resolver
+// LINUX: @_ZN1SaSERKS_.ifunc = ifunc %struct.S* (%struct.S*, %struct.S*), %struct.S* (%struct.S*, %struct.S*)* ()* @_ZN1SaSERKS_.resolver
+// LINUX: @_ZNK9ConvertTocv1SEv.ifunc = ifunc void (%struct.ConvertTo*), void (%struct.ConvertTo*)* ()* @_ZNK9ConvertTocv1SEv.resolver
+// LINUX: @_ZN1S3fooEi.ifunc = ifunc i32 (%struct.S*, i32), i32 (%struct.S*, i32)* ()* @_ZN1S3fooEi.resolver
+// LINUX: @_ZN2S23fooEi.ifunc = ifunc i32 (%struct.S2*, i32), i32 (%struct.S2*, i32)* ()* @_ZN2S23fooEi.resolver
// Templates:
-// CHECK: @_ZN5templIiE3fooEi.ifunc = ifunc i32 (%struct.templ*, i32), i32 (%struct.templ*, i32)* ()* @_ZN5templIiE3fooEi.resolver
-// CHECK: @_ZN5templIdE3fooEi.ifunc = ifunc i32 (%struct.templ.0*, i32), i32 (%struct.templ.0*, i32)* ()* @_ZN5templIdE3fooEi.resolver
-
-// CHECK: define i32 @_Z3barv()
-// CHECK: %s = alloca %struct.S, align 1
-// CHECK: %s2 = alloca %struct.S, align 1
-// CHECK: %C = alloca %struct.ConvertTo, align 1
-// CHECK: call dereferenceable(1) %struct.S* @_ZN1SaSERKS_.ifunc(%struct.S* %s2
-// CHECK: call void @_ZNK9ConvertTocv1SEv.ifunc(%struct.ConvertTo* %C)
-// CHECK: call dereferenceable(1) %struct.S* @_ZN1SaSERKS_.ifunc(%struct.S* %s2
-// CHECK: call i32 @_ZN1S3fooEi.ifunc(%struct.S* %s, i32 0)
-
-// CHECK: define %struct.S* (%struct.S*, %struct.S*)* @_ZN1SaSERKS_.resolver() comdat
-// CHECK: ret %struct.S* (%struct.S*, %struct.S*)* @_ZN1SaSERKS_.arch_ivybridge
-// CHECK: ret %struct.S* (%struct.S*, %struct.S*)* @_ZN1SaSERKS_
-
-// CHECK: define void (%struct.ConvertTo*)* @_ZNK9ConvertTocv1SEv.resolver() comdat
-// CHECK: ret void (%struct.ConvertTo*)* @_ZNK9ConvertTocv1SEv.arch_ivybridge
-// CHECK: ret void (%struct.ConvertTo*)* @_ZNK9ConvertTocv1SEv
-
-// CHECK: define i32 (%struct.S*, i32)* @_ZN1S3fooEi.resolver() comdat
-// CHECK: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.arch_sandybridge
-// CHECK: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.arch_ivybridge
-// CHECK: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.sse4.2
-// CHECK: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi
-
-// CHECK: define i32 @_Z4bar2v()
-// CHECK:call i32 @_ZN2S23fooEi.ifunc
-// define i32 (%struct.S2*, i32)* @_ZN2S23fooEi.resolver() comdat
-// CHECK: ret i32 (%struct.S2*, i32)* @_ZN2S23fooEi.arch_sandybridge
-// CHECK: ret i32 (%struct.S2*, i32)* @_ZN2S23fooEi.arch_ivybridge
-// CHECK: ret i32 (%struct.S2*, i32)* @_ZN2S23fooEi.sse4.2
-// CHECK: ret i32 (%struct.S2*, i32)* @_ZN2S23fooEi
-
-// CHECK: define i32 @_ZN2S23fooEi.sse4.2(%struct.S2* %this, i32)
-// CHECK: define i32 @_ZN2S23fooEi.arch_ivybridge(%struct.S2* %this, i32)
-// CHECK: define i32 @_ZN2S23fooEi(%struct.S2* %this, i32)
-
-// CHECK: define i32 @_Z9templ_usev()
-// CHECK: call i32 @_ZN5templIiE3fooEi.ifunc
-// CHECK: call i32 @_ZN5templIdE3fooEi.ifunc
-
-
-// CHECK: define i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.resolver() comdat
-// CHECK: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.arch_sandybridge
-// CHECK: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.arch_ivybridge
-// CHECK: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.sse4.2
-// CHECK: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi
-//
-// CHECK: define i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.resolver() comdat
-// CHECK: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.arch_sandybridge
-// CHECK: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.arch_ivybridge
-// CHECK: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.sse4.2
-// CHECK: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi
-
-// CHECK: define linkonce_odr i32 @_ZN1S3fooEi.sse4.2(%struct.S* %this, i32)
-// CHECK: ret i32 0
-
-// CHECK: declare i32 @_ZN1S3fooEi.arch_sandybridge(%struct.S*, i32)
-
-// CHECK: define linkonce_odr i32 @_ZN1S3fooEi.arch_ivybridge(%struct.S* %this, i32)
-// CHECK: ret i32 1
-
-// CHECK: define linkonce_odr i32 @_ZN1S3fooEi(%struct.S* %this, i32)
-// CHECK: ret i32 2
-
+// LINUX: @_ZN5templIiE3fooEi.ifunc = ifunc i32 (%struct.templ*, i32), i32 (%struct.templ*, i32)* ()* @_ZN5templIiE3fooEi.resolver
+// LINUX: @_ZN5templIdE3fooEi.ifunc = ifunc i32 (%struct.templ.0*, i32), i32 (%struct.templ.0*, i32)* ()* @_ZN5templIdE3fooEi.resolver
+
+// LINUX: define i32 @_Z3barv()
+// LINUX: %s = alloca %struct.S, align 1
+// LINUX: %s2 = alloca %struct.S, align 1
+// LINUX: %C = alloca %struct.ConvertTo, align 1
+// LINUX: call dereferenceable(1) %struct.S* @_ZN1SaSERKS_.ifunc(%struct.S* %s2
+// LINUX: call void @_ZNK9ConvertTocv1SEv.ifunc(%struct.ConvertTo* %C)
+// LINUX: call dereferenceable(1) %struct.S* @_ZN1SaSERKS_.ifunc(%struct.S* %s2
+// LINUX: call i32 @_ZN1S3fooEi.ifunc(%struct.S* %s, i32 0)
+
+// WINDOWS: define dso_local i32 @"?bar@@YAHXZ"()
+// WINDOWS: %s = alloca %struct.S, align 1
+// WINDOWS: %s2 = alloca %struct.S, align 1
+// WINDOWS: %C = alloca %struct.ConvertTo, align 1
+// WINDOWS: call dereferenceable(1) %struct.S* @"??4S@@QEAAAEAU0@AEBU0@@Z.resolver"(%struct.S* %s2
+// WINDOWS: call void @"??BConvertTo@@QEBA?AUS@@XZ.resolver"(%struct.ConvertTo* %C
+// WINDOWS: call dereferenceable(1) %struct.S* @"??4S@@QEAAAEAU0@AEBU0@@Z.resolver"(%struct.S* %s2
+// WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.resolver"(%struct.S* %s, i32 0)
+
+// LINUX: define %struct.S* (%struct.S*, %struct.S*)* @_ZN1SaSERKS_.resolver() comdat
+// LINUX: ret %struct.S* (%struct.S*, %struct.S*)* @_ZN1SaSERKS_.arch_ivybridge
+// LINUX: ret %struct.S* (%struct.S*, %struct.S*)* @_ZN1SaSERKS_
+
+// WINDOWS: define dso_local %struct.S* @"??4S@@QEAAAEAU0@AEBU0@@Z.resolver"(%struct.S*, %struct.S*)
+// WINDOWS: call %struct.S* @"??4S@@QEAAAEAU0@AEBU0@@Z.arch_ivybridge"
+// WINDOWS: call %struct.S* @"??4S@@QEAAAEAU0@AEBU0@@Z"
+
+// LINUX: define void (%struct.ConvertTo*)* @_ZNK9ConvertTocv1SEv.resolver() comdat
+// LINUX: ret void (%struct.ConvertTo*)* @_ZNK9ConvertTocv1SEv.arch_ivybridge
+// LINUX: ret void (%struct.ConvertTo*)* @_ZNK9ConvertTocv1SEv
+
+// WINDOWS: define dso_local void @"??BConvertTo@@QEBA?AUS@@XZ.resolver"(%struct.ConvertTo*, %struct.S*)
+// WINDOWS: call void @"??BConvertTo@@QEBA?AUS@@XZ.arch_ivybridge"
+// WINDOWS: call void @"??BConvertTo@@QEBA?AUS@@XZ"
+
+// LINUX: define i32 (%struct.S*, i32)* @_ZN1S3fooEi.resolver() comdat
+// LINUX: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.arch_sandybridge
+// LINUX: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.arch_ivybridge
+// LINUX: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.sse4.2
+// LINUX: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi
+
+// WINDOWS: define dso_local i32 @"?foo@S@@QEAAHH@Z.resolver"(%struct.S*, i32)
+// WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.arch_sandybridge"
+// WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.arch_ivybridge"
+// WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.sse4.2"
+// WINDOWS: call i32 @"?foo@S@@QEAAHH@Z"
+
+// LINUX: define i32 @_Z4bar2v()
+// LINUX: call i32 @_ZN2S23fooEi.ifunc
+
+// WINDOWS: define dso_local i32 @"?bar2@@YAHXZ"()
+// WINDOWS: call i32 @"?foo@S2@@QEAAHH@Z.resolver"
+
+// LINUX: define i32 (%struct.S2*, i32)* @_ZN2S23fooEi.resolver() comdat
+// LINUX: ret i32 (%struct.S2*, i32)* @_ZN2S23fooEi.arch_sandybridge
+// LINUX: ret i32 (%struct.S2*, i32)* @_ZN2S23fooEi.arch_ivybridge
+// LINUX: ret i32 (%struct.S2*, i32)* @_ZN2S23fooEi.sse4.2
+// LINUX: ret i32 (%struct.S2*, i32)* @_ZN2S23fooEi
+
+// WINDOWS: define dso_local i32 @"?foo@S2@@QEAAHH@Z.resolver"(%struct.S2*, i32)
+// WINDOWS: call i32 @"?foo@S2@@QEAAHH@Z.arch_sandybridge"
+// WINDOWS: call i32 @"?foo@S2@@QEAAHH@Z.arch_ivybridge"
+// WINDOWS: call i32 @"?foo@S2@@QEAAHH@Z.sse4.2"
+// WINDOWS: call i32 @"?foo@S2@@QEAAHH@Z"
+
+// LINUX: define i32 @_ZN2S23fooEi.sse4.2(%struct.S2* %this, i32)
+// LINUX: define i32 @_ZN2S23fooEi.arch_ivybridge(%struct.S2* %this, i32)
+// LINUX: define i32 @_ZN2S23fooEi(%struct.S2* %this, i32)
+
+// WINDOWS: define dso_local i32 @"?foo@S2@@QEAAHH@Z.sse4.2"(%struct.S2* %this, i32)
+// WINDOWS: define dso_local i32 @"?foo@S2@@QEAAHH@Z.arch_ivybridge"(%struct.S2* %this, i32)
+// WINDOWS: define dso_local i32 @"?foo@S2@@QEAAHH@Z"(%struct.S2* %this, i32)
+
+// LINUX: define i32 @_Z9templ_usev()
+// LINUX: call i32 @_ZN5templIiE3fooEi.ifunc
+// LINUX: call i32 @_ZN5templIdE3fooEi.ifunc
+
+// WINDOWS: define dso_local i32 @"?templ_use@@YAHXZ"()
+// WINDOWS: call i32 @"?foo@?$templ@H@@QEAAHH@Z.resolver"
+// WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z.resolver"
+
+// LINUX: define i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.resolver() comdat
+// LINUX: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.arch_sandybridge
+// LINUX: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.arch_ivybridge
+// LINUX: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.sse4.2
+// LINUX: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi
+
+// WINDOWS: define dso_local i32 @"?foo@?$templ@H@@QEAAHH@Z.resolver"(%struct.templ*, i32)
+// WINDOWS: call i32 @"?foo@?$templ@H@@QEAAHH@Z.arch_sandybridge"
+// WINDOWS: call i32 @"?foo@?$templ@H@@QEAAHH@Z.arch_ivybridge"
+// WINDOWS: call i32 @"?foo@?$templ@H@@QEAAHH@Z.sse4.2"
+// WINDOWS: call i32 @"?foo@?$templ@H@@QEAAHH@Z"
+
+// LINUX: define i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.resolver() comdat
+// LINUX: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.arch_sandybridge
+// LINUX: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.arch_ivybridge
+// LINUX: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.sse4.2
+// LINUX: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi
+
+// WINDOWS: define dso_local i32 @"?foo@?$templ@N@@QEAAHH@Z.resolver"(%struct.templ.0*, i32) comdat
+// WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z.arch_sandybridge"
+// WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z.arch_ivybridge"
+// WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z.sse4.2"
+// WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z"
+
+// LINUX: define linkonce_odr i32 @_ZN1S3fooEi.sse4.2(%struct.S* %this, i32)
+// LINUX: ret i32 0
+
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@S@@QEAAHH@Z.sse4.2"(%struct.S* %this, i32)
+// WINDOWS: ret i32 0
+
+// LINUX: declare i32 @_ZN1S3fooEi.arch_sandybridge(%struct.S*, i32)
+
+// WINDOWS: declare dso_local i32 @"?foo@S@@QEAAHH@Z.arch_sandybridge"(%struct.S*, i32)
+
+// LINUX: define linkonce_odr i32 @_ZN1S3fooEi.arch_ivybridge(%struct.S* %this, i32)
+// LINUX: ret i32 1
+
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@S@@QEAAHH@Z.arch_ivybridge"(%struct.S* %this, i32)
+// WINDOWS: ret i32 1
+
+// LINUX: define linkonce_odr i32 @_ZN1S3fooEi(%struct.S* %this, i32)
+// LINUX: ret i32 2
+
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@S@@QEAAHH@Z"(%struct.S* %this, i32)
+// WINDOWS: ret i32 2
+
+// LINUX: define linkonce_odr i32 @_ZN5templIiE3fooEi.sse4.2
+// LINUX: declare i32 @_ZN5templIiE3fooEi.arch_sandybridge
+// LINUX: define linkonce_odr i32 @_ZN5templIiE3fooEi.arch_ivybridge
+// LINUX: define linkonce_odr i32 @_ZN5templIiE3fooEi
+
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@?$templ@H@@QEAAHH@Z.sse4.2"
+// WINDOWS: declare dso_local i32 @"?foo@?$templ@H@@QEAAHH@Z.arch_sandybridge"
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@?$templ@H@@QEAAHH@Z.arch_ivybridge"
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@?$templ@H@@QEAAHH@Z"
+
+// LINUX: define linkonce_odr i32 @_ZN5templIdE3fooEi.sse4.2
+// LINUX: declare i32 @_ZN5templIdE3fooEi.arch_sandybridge
+// LINUX: define linkonce_odr i32 @_ZN5templIdE3fooEi.arch_ivybridge
+// LINUX: define linkonce_odr i32 @_ZN5templIdE3fooEi
+
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@?$templ@N@@QEAAHH@Z.sse4.2"
+// WINDOWS: declare dso_local i32 @"?foo@?$templ@N@@QEAAHH@Z.arch_sandybridge"
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@?$templ@N@@QEAAHH@Z.arch_ivybridge"
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@?$templ@N@@QEAAHH@Z"
diff --git a/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp b/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp
index 63353c12d29a..1c051b385384 100644
--- a/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp
+++ b/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS
struct S {
int __attribute__((target("sse4.2"))) foo(int);
int __attribute__((target("arch=sandybridge"))) foo(int);
@@ -15,25 +16,46 @@ int bar() {
return s.foo(0);
}
-// CHECK: @_ZN1S3fooEi.ifunc = ifunc i32 (%struct.S*, i32), i32 (%struct.S*, i32)* ()* @_ZN1S3fooEi.resolver
+// LINUX: @_ZN1S3fooEi.ifunc = ifunc i32 (%struct.S*, i32), i32 (%struct.S*, i32)* ()* @_ZN1S3fooEi.resolver
-// CHECK: define i32 @_ZN1S3fooEi(%struct.S* %this, i32)
-// CHECK: ret i32 2
+// LINUX: define i32 @_ZN1S3fooEi(%struct.S* %this, i32)
+// LINUX: ret i32 2
-// CHECK: define i32 @_ZN1S3fooEi.sse4.2(%struct.S* %this, i32)
-// CHECK: ret i32 0
+// WINDOWS: define dso_local i32 @"?foo@S@@QEAAHH@Z"(%struct.S* %this, i32)
+// WINDOWS: ret i32 2
-// CHECK: define i32 @_ZN1S3fooEi.arch_ivybridge(%struct.S* %this, i32)
-// CHECK: ret i32 1
+// LINUX: define i32 @_ZN1S3fooEi.sse4.2(%struct.S* %this, i32)
+// LINUX: ret i32 0
-// CHECK: define i32 @_Z3barv()
-// CHECK: %s = alloca %struct.S, align 1
-// CHECK: %call = call i32 @_ZN1S3fooEi.ifunc(%struct.S* %s, i32 0)
+// WINDOWS: define dso_local i32 @"?foo@S@@QEAAHH@Z.sse4.2"(%struct.S* %this, i32)
+// WINDOWS: ret i32 0
-// CHECK: define i32 (%struct.S*, i32)* @_ZN1S3fooEi.resolver() comdat
-// CHECK: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.arch_sandybridge
-// CHECK: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.arch_ivybridge
-// CHECK: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.sse4.2
-// CHECK: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi
+// LINUX: define i32 @_ZN1S3fooEi.arch_ivybridge(%struct.S* %this, i32)
+// LINUX: ret i32 1
-// CHECK: declare i32 @_ZN1S3fooEi.arch_sandybridge(%struct.S*, i32)
+// WINDOWS: define dso_local i32 @"?foo@S@@QEAAHH@Z.arch_ivybridge"(%struct.S* %this, i32)
+// WINDOWS: ret i32 1
+
+// LINUX: define i32 @_Z3barv()
+// LINUX: %s = alloca %struct.S, align 1
+// LINUX: %call = call i32 @_ZN1S3fooEi.ifunc(%struct.S* %s, i32 0)
+
+// WINDOWS: define dso_local i32 @"?bar@@YAHXZ"()
+// WINDOWS: %s = alloca %struct.S, align 1
+// WINDOWS: %call = call i32 @"?foo@S@@QEAAHH@Z.resolver"(%struct.S* %s, i32 0)
+
+// LINUX: define i32 (%struct.S*, i32)* @_ZN1S3fooEi.resolver() comdat
+// LINUX: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.arch_sandybridge
+// LINUX: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.arch_ivybridge
+// LINUX: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.sse4.2
+// LINUX: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi
+
+// WINDOWS: define dso_local i32 @"?foo@S@@QEAAHH@Z.resolver"(%struct.S*, i32) comdat
+// WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.arch_sandybridge"(%struct.S* %0, i32 %1)
+// WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.arch_ivybridge"(%struct.S* %0, i32 %1)
+// WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.sse4.2"(%struct.S* %0, i32 %1)
+// WINDOWS: call i32 @"?foo@S@@QEAAHH@Z"(%struct.S* %0, i32 %1)
+
+// LINUX: declare i32 @_ZN1S3fooEi.arch_sandybridge(%struct.S*, i32)
+
+// WINDOWS: declare dso_local i32 @"?foo@S@@QEAAHH@Z.arch_sandybridge"(%struct.S*, i32)
diff --git a/test/CodeGenCXX/attr-target-mv-overloads.cpp b/test/CodeGenCXX/attr-target-mv-overloads.cpp
index c72ea77fa46f..a213d247cb1f 100644
--- a/test/CodeGenCXX/attr-target-mv-overloads.cpp
+++ b/test/CodeGenCXX/attr-target-mv-overloads.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS
int __attribute__((target("sse4.2"))) foo_overload(int) { return 0; }
int __attribute__((target("arch=sandybridge"))) foo_overload(int);
@@ -13,38 +14,69 @@ int bar2() {
return foo_overload() + foo_overload(1);
}
-// CHECK: @_Z12foo_overloadv.ifunc = ifunc i32 (), i32 ()* ()* @_Z12foo_overloadv.resolver
-// CHECK: @_Z12foo_overloadi.ifunc = ifunc i32 (i32), i32 (i32)* ()* @_Z12foo_overloadi.resolver
-
-
-// CHECK: define i32 @_Z12foo_overloadi.sse4.2(i32)
-// CHECK: ret i32 0
-// CHECK: define i32 @_Z12foo_overloadi.arch_ivybridge(i32)
-// CHECK: ret i32 1
-// CHECK: define i32 @_Z12foo_overloadi(i32)
-// CHECK: ret i32 2
-// CHECK: define i32 @_Z12foo_overloadv.sse4.2()
-// CHECK: ret i32 0
-// CHECK: define i32 @_Z12foo_overloadv.arch_ivybridge()
-// CHECK: ret i32 1
-// CHECK: define i32 @_Z12foo_overloadv()
-// CHECK: ret i32 2
-
-// CHECK: define i32 @_Z4bar2v()
-// CHECK: call i32 @_Z12foo_overloadv.ifunc()
-// CHECK: call i32 @_Z12foo_overloadi.ifunc(i32 1)
-
-// CHECK: define i32 ()* @_Z12foo_overloadv.resolver() comdat
-// CHECK: ret i32 ()* @_Z12foo_overloadv.arch_sandybridge
-// CHECK: ret i32 ()* @_Z12foo_overloadv.arch_ivybridge
-// CHECK: ret i32 ()* @_Z12foo_overloadv.sse4.2
-// CHECK: ret i32 ()* @_Z12foo_overloadv
-
-// CHECK: define i32 (i32)* @_Z12foo_overloadi.resolver() comdat
-// CHECK: ret i32 (i32)* @_Z12foo_overloadi.arch_sandybridge
-// CHECK: ret i32 (i32)* @_Z12foo_overloadi.arch_ivybridge
-// CHECK: ret i32 (i32)* @_Z12foo_overloadi.sse4.2
-// CHECK: ret i32 (i32)* @_Z12foo_overloadi
-
-// CHECK: declare i32 @_Z12foo_overloadv.arch_sandybridge()
-// CHECK: declare i32 @_Z12foo_overloadi.arch_sandybridge(i32)
+// LINUX: @_Z12foo_overloadv.ifunc = ifunc i32 (), i32 ()* ()* @_Z12foo_overloadv.resolver
+// LINUX: @_Z12foo_overloadi.ifunc = ifunc i32 (i32), i32 (i32)* ()* @_Z12foo_overloadi.resolver
+
+// LINUX: define i32 @_Z12foo_overloadi.sse4.2(i32)
+// LINUX: ret i32 0
+// LINUX: define i32 @_Z12foo_overloadi.arch_ivybridge(i32)
+// LINUX: ret i32 1
+// LINUX: define i32 @_Z12foo_overloadi(i32)
+// LINUX: ret i32 2
+// LINUX: define i32 @_Z12foo_overloadv.sse4.2()
+// LINUX: ret i32 0
+// LINUX: define i32 @_Z12foo_overloadv.arch_ivybridge()
+// LINUX: ret i32 1
+// LINUX: define i32 @_Z12foo_overloadv()
+// LINUX: ret i32 2
+
+// WINDOWS: define dso_local i32 @"?foo_overload@@YAHH@Z.sse4.2"(i32)
+// WINDOWS: ret i32 0
+// WINDOWS: define dso_local i32 @"?foo_overload@@YAHH@Z.arch_ivybridge"(i32)
+// WINDOWS: ret i32 1
+// WINDOWS: define dso_local i32 @"?foo_overload@@YAHH@Z"(i32)
+// WINDOWS: ret i32 2
+// WINDOWS: define dso_local i32 @"?foo_overload@@YAHXZ.sse4.2"()
+// WINDOWS: ret i32 0
+// WINDOWS: define dso_local i32 @"?foo_overload@@YAHXZ.arch_ivybridge"()
+// WINDOWS: ret i32 1
+// WINDOWS: define dso_local i32 @"?foo_overload@@YAHXZ"()
+// WINDOWS: ret i32 2
+
+// LINUX: define i32 @_Z4bar2v()
+// LINUX: call i32 @_Z12foo_overloadv.ifunc()
+// LINUX: call i32 @_Z12foo_overloadi.ifunc(i32 1)
+
+// WINDOWS: define dso_local i32 @"?bar2@@YAHXZ"()
+// WINDOWS: call i32 @"?foo_overload@@YAHXZ.resolver"()
+// WINDOWS: call i32 @"?foo_overload@@YAHH@Z.resolver"(i32 1)
+
+// LINUX: define i32 ()* @_Z12foo_overloadv.resolver() comdat
+// LINUX: ret i32 ()* @_Z12foo_overloadv.arch_sandybridge
+// LINUX: ret i32 ()* @_Z12foo_overloadv.arch_ivybridge
+// LINUX: ret i32 ()* @_Z12foo_overloadv.sse4.2
+// LINUX: ret i32 ()* @_Z12foo_overloadv
+
+// WINDOWS: define dso_local i32 @"?foo_overload@@YAHXZ.resolver"() comdat
+// WINDOWS: call i32 @"?foo_overload@@YAHXZ.arch_sandybridge"
+// WINDOWS: call i32 @"?foo_overload@@YAHXZ.arch_ivybridge"
+// WINDOWS: call i32 @"?foo_overload@@YAHXZ.sse4.2"
+// WINDOWS: call i32 @"?foo_overload@@YAHXZ"
+
+// LINUX: define i32 (i32)* @_Z12foo_overloadi.resolver() comdat
+// LINUX: ret i32 (i32)* @_Z12foo_overloadi.arch_sandybridge
+// LINUX: ret i32 (i32)* @_Z12foo_overloadi.arch_ivybridge
+// LINUX: ret i32 (i32)* @_Z12foo_overloadi.sse4.2
+// LINUX: ret i32 (i32)* @_Z12foo_overloadi
+
+// WINDOWS: define dso_local i32 @"?foo_overload@@YAHH@Z.resolver"(i32) comdat
+// WINDOWS: call i32 @"?foo_overload@@YAHH@Z.arch_sandybridge"
+// WINDOWS: call i32 @"?foo_overload@@YAHH@Z.arch_ivybridge"
+// WINDOWS: call i32 @"?foo_overload@@YAHH@Z.sse4.2"
+// WINDOWS: call i32 @"?foo_overload@@YAHH@Z"
+
+// LINUX: declare i32 @_Z12foo_overloadv.arch_sandybridge()
+// LINUX: declare i32 @_Z12foo_overloadi.arch_sandybridge(i32)
+
+// WINDOWS: declare dso_local i32 @"?foo_overload@@YAHXZ.arch_sandybridge"()
+// WINDOWS: declare dso_local i32 @"?foo_overload@@YAHH@Z.arch_sandybridge"(i32)
diff --git a/test/CodeGenCXX/auto-var-init.cpp b/test/CodeGenCXX/auto-var-init.cpp
new file mode 100644
index 000000000000..0d13c0af4e8f
--- /dev/null
+++ b/test/CodeGenCXX/auto-var-init.cpp
@@ -0,0 +1,1350 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s -check-prefix=PATTERN
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s -check-prefix=ZERO
+
+template<typename T> void used(T &) noexcept;
+
+#define TEST_UNINIT(NAME, TYPE) \
+ using type_##NAME = TYPE; \
+ void test_##NAME##_uninit() { \
+ type_##NAME uninit; \
+ used(uninit); \
+ }
+
+// Value initialization on scalars, aggregate initialization on aggregates.
+#define TEST_BRACES(NAME, TYPE) \
+ using type_##NAME = TYPE; \
+ void test_##NAME##_braces() { \
+ type_##NAME braces = {}; \
+ used(braces); \
+ }
+
+#define TEST_CUSTOM(NAME, TYPE, ...) \
+ using type_##NAME = TYPE; \
+ void test_##NAME##_custom() { \
+ type_##NAME custom __VA_ARGS__; \
+ used(custom); \
+ }
+
+// None of the synthesized globals should contain `undef`.
+// PATTERN-NOT: undef
+// ZERO-NOT: undef
+
+// PATTERN: @__const.test_empty_uninit.uninit = private unnamed_addr constant %struct.empty { i8 -86 }, align 1
+struct empty {};
+// PATTERN: @__const.test_small_uninit.uninit = private unnamed_addr constant %struct.small { i8 -86 }, align 1
+// PATTERN: @__const.test_small_custom.custom = private unnamed_addr constant %struct.small { i8 42 }, align 1
+// ZERO: @__const.test_small_custom.custom = private unnamed_addr constant %struct.small { i8 42 }, align 1
+struct small { char c; };
+// PATTERN: @__const.test_smallinit_uninit.uninit = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
+// PATTERN: @__const.test_smallinit_braces.braces = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
+// PATTERN: @__const.test_smallinit_custom.custom = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
+struct smallinit { char c = 42; };
+// PATTERN: @__const.test_smallpartinit_uninit.uninit = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
+// PATTERN: @__const.test_smallpartinit_braces.braces = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
+// PATTERN: @__const.test_smallpartinit_custom.custom = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
+struct smallpartinit { char c = 42, d; };
+// PATTERN: @__const.test_nullinit_uninit.uninit = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
+// PATTERN: @__const.test_nullinit_braces.braces = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
+// PATTERN: @__const.test_nullinit_custom.custom = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
+struct nullinit { char* null = nullptr; };
+// PATTERN: @__const.test_padded_uninit.uninit = private unnamed_addr constant %struct.padded { i8 -86, i32 -1431655766 }, align 4
+// PATTERN: @__const.test_padded_custom.custom = private unnamed_addr constant %struct.padded { i8 42, i32 13371337 }, align 4
+// ZERO: @__const.test_padded_custom.custom = private unnamed_addr constant %struct.padded { i8 42, i32 13371337 }, align 4
+struct padded { char c; int i; };
+// PATTERN: @__const.test_paddednullinit_uninit.uninit = private unnamed_addr constant %struct.paddednullinit { i8 -86, i32 -1431655766 }, align 4
+// PATTERN: @__const.test_paddednullinit_braces.braces = private unnamed_addr constant %struct.paddednullinit { i8 -86, i32 -1431655766 }, align 4
+// PATTERN: @__const.test_paddednullinit_custom.custom = private unnamed_addr constant %struct.paddednullinit { i8 -86, i32 -1431655766 }, align 4
+struct paddednullinit { char c = 0; int i = 0; };
+// PATTERN: @__const.test_bitfield_uninit.uninit = private unnamed_addr constant %struct.bitfield { i8 -86, [3 x i8] c"\AA\AA\AA" }, align 4
+// PATTERN: @__const.test_bitfield_custom.custom = private unnamed_addr constant %struct.bitfield { i8 20, [3 x i8] zeroinitializer }, align 4
+// ZERO: @__const.test_bitfield_custom.custom = private unnamed_addr constant %struct.bitfield { i8 20, [3 x i8] zeroinitializer }, align 4
+struct bitfield { int i : 4; int j : 2; };
+// PATTERN: @__const.test_bitfieldaligned_uninit.uninit = private unnamed_addr constant %struct.bitfieldaligned { i8 -86, [3 x i8] c"\AA\AA\AA", i8 -86, [3 x i8] c"\AA\AA\AA" }, align 4
+// PATTERN: @__const.test_bitfieldaligned_custom.custom = private unnamed_addr constant %struct.bitfieldaligned { i8 4, [3 x i8] zeroinitializer, i8 1, [3 x i8] zeroinitializer }, align 4
+// ZERO: @__const.test_bitfieldaligned_custom.custom = private unnamed_addr constant %struct.bitfieldaligned { i8 4, [3 x i8] zeroinitializer, i8 1, [3 x i8] zeroinitializer }, align 4
+struct bitfieldaligned { int i : 4; int : 0; int j : 2; };
+struct big { unsigned a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z; };
+// PATTERN: @__const.test_arraytail_uninit.uninit = private unnamed_addr constant %struct.arraytail { i32 -1431655766, [0 x i32] zeroinitializer }, align 4
+// PATTERN: @__const.test_arraytail_custom.custom = private unnamed_addr constant %struct.arraytail { i32 57005, [0 x i32] zeroinitializer }, align 4
+// ZERO: @__const.test_arraytail_custom.custom = private unnamed_addr constant %struct.arraytail { i32 57005, [0 x i32] zeroinitializer }, align 4
+struct arraytail { int i; int arr[]; };
+// PATTERN: @__const.test_int1_uninit.uninit = private unnamed_addr constant [1 x i32] [i32 -1431655766], align 4
+// PATTERN: @__const.test_int1_custom.custom = private unnamed_addr constant [1 x i32] [i32 858993459], align 4
+// ZERO: @__const.test_int1_custom.custom = private unnamed_addr constant [1 x i32] [i32 858993459], align 4
+// PATTERN: @__const.test_bool4_uninit.uninit = private unnamed_addr constant [4 x i8] c"\AA\AA\AA\AA", align 1
+// PATTERN: @__const.test_bool4_custom.custom = private unnamed_addr constant [4 x i8] c"\01\01\01\01", align 1
+// ZERO: @__const.test_bool4_custom.custom = private unnamed_addr constant [4 x i8] c"\01\01\01\01", align 1
+// PATTERN: @__const.test_intptr4_uninit.uninit = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*)], align 16
+// PATTERN: @__const.test_intptr4_custom.custom = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*)], align 16
+// ZERO: @__const.test_intptr4_custom.custom = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*)], align 16
+// PATTERN: @__const.test_tailpad4_uninit.uninit = private unnamed_addr constant [4 x %struct.tailpad] [%struct.tailpad { i16 -21846, i8 -86 }, %struct.tailpad { i16 -21846, i8 -86 }, %struct.tailpad { i16 -21846, i8 -86 }, %struct.tailpad { i16 -21846, i8 -86 }], align 16
+// PATTERN: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x %struct.tailpad] [%struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }], align 16
+// ZERO: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x %struct.tailpad] [%struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }], align 16
+struct tailpad { short s; char c; };
+// PATTERN: @__const.test_atomicnotlockfree_uninit.uninit = private unnamed_addr constant %struct.notlockfree { [4 x i64] [i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206] }, align 8
+struct notlockfree { long long a[4]; };
+// PATTERN: @__const.test_atomicpadded_uninit.uninit = private unnamed_addr constant %struct.padded { i8 -86, i32 -1431655766 }, align 8
+// PATTERN: @__const.test_atomictailpad_uninit.uninit = private unnamed_addr constant %struct.tailpad { i16 -21846, i8 -86 }, align 4
+// PATTERN: @__const.test_complexfloat_uninit.uninit = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
+// PATTERN: @__const.test_complexfloat_braces.braces = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
+// PATTERN: @__const.test_complexfloat_custom.custom = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
+// PATTERN: @__const.test_complexdouble_uninit.uninit = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
+// PATTERN: @__const.test_complexdouble_braces.braces = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
+// PATTERN: @__const.test_complexdouble_custom.custom = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
+// PATTERN: @__const.test_semivolatile_uninit.uninit = private unnamed_addr constant %struct.semivolatile { i32 -1431655766, i32 -1431655766 }, align 4
+// PATTERN: @__const.test_semivolatile_custom.custom = private unnamed_addr constant %struct.semivolatile { i32 1145324612, i32 1145324612 }, align 4
+struct semivolatile { int i; volatile int vi; };
+// PATTERN: @__const.test_semivolatileinit_uninit.uninit = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
+// PATTERN: @__const.test_semivolatileinit_braces.braces = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
+// PATTERN: @__const.test_semivolatileinit_custom.custom = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
+// ZERO: @__const.test_semivolatile_custom.custom = private unnamed_addr constant %struct.semivolatile { i32 1145324612, i32 1145324612 }, align 4
+struct semivolatileinit { int i = 0x11111111; volatile int vi = 0x11111111; };
+// PATTERN: @__const.test_base_uninit.uninit = private unnamed_addr constant %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, align 8
+// PATTERN: @__const.test_base_braces.braces = private unnamed_addr constant %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, align 8
+struct base { virtual ~base(); };
+// PATTERN: @__const.test_derived_uninit.uninit = private unnamed_addr constant %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } }, align 8
+// PATTERN: @__const.test_derived_braces.braces = private unnamed_addr constant %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } }, align 8
+struct derived : public base {};
+// PATTERN: @__const.test_virtualderived_uninit.uninit = private unnamed_addr constant %struct.virtualderived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } } }, align 8
+// PATTERN: @__const.test_virtualderived_braces.braces = private unnamed_addr constant %struct.virtualderived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } } }, align 8
+struct virtualderived : public virtual base, public virtual derived {};
+// PATTERN: @__const.test_matching_uninit.uninit = private unnamed_addr constant %union.matching { i32 -1431655766 }, align 4
+// PATTERN: @__const.test_matching_custom.custom = private unnamed_addr constant { float } { float 6.145500e+04 }, align 4
+union matching { int i; float f; };
+// PATTERN: @__const.test_matchingreverse_uninit.uninit = private unnamed_addr constant %union.matchingreverse { float 0xFFFFFFFFE0000000 }, align 4
+// PATTERN: @__const.test_matchingreverse_custom.custom = private unnamed_addr constant { i32 } { i32 61455 }, align 4
+// ZERO: @__const.test_matching_custom.custom = private unnamed_addr constant { float } { float 6.145500e+04 }, align 4
+union matchingreverse { float f; int i; };
+// PATTERN: @__const.test_unmatched_uninit.uninit = private unnamed_addr constant %union.unmatched { i32 -1431655766 }, align 4
+// PATTERN: @__const.test_unmatched_custom.custom = private unnamed_addr constant %union.unmatched { i32 1001242351 }, align 4
+// ZERO: @__const.test_matchingreverse_custom.custom = private unnamed_addr constant { i32 } { i32 61455 }, align 4
+union unmatched { char c; int i; };
+// PATTERN: @__const.test_unmatchedreverse_uninit.uninit = private unnamed_addr constant %union.unmatchedreverse { i32 -1431655766 }, align 4
+// PATTERN: @__const.test_unmatchedreverse_custom.custom = private unnamed_addr constant { i8, [3 x i8] } { i8 42, [3 x i8] zeroinitializer }, align 4
+// ZERO: @__const.test_unmatched_custom.custom = private unnamed_addr constant %union.unmatched { i32 1001242351 }, align 4
+union unmatchedreverse { int i; char c; };
+// PATTERN: @__const.test_unmatchedfp_uninit.uninit = private unnamed_addr constant %union.unmatchedfp { double 0xFFFFFFFFFFFFFFFF }, align 8
+// PATTERN: @__const.test_unmatchedfp_custom.custom = private unnamed_addr constant %union.unmatchedfp { double 0x400921FB54442D18 }, align 8
+// ZERO: @__const.test_unmatchedreverse_custom.custom = private unnamed_addr constant { i8, [3 x i8] } { i8 42, [3 x i8] zeroinitializer }, align 4
+// ZERO: @__const.test_unmatchedfp_custom.custom = private unnamed_addr constant %union.unmatchedfp { double 0x400921FB54442D18 }, align 8
+union unmatchedfp { float f; double d; };
+enum emptyenum {};
+enum smallenum { VALUE };
+
+extern "C" {
+
+TEST_UNINIT(char, char);
+// CHECK-LABEL: @test_char_uninit()
+// CHECK: %uninit = alloca i8, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_char_uninit()
+// PATTERN: store i8 -86, i8* %uninit, align 1
+// ZERO-LABEL: @test_char_uninit()
+// ZERO: store i8 0, i8* %uninit, align 1
+
+TEST_BRACES(char, char);
+// CHECK-LABEL: @test_char_braces()
+// CHECK: %braces = alloca i8, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i8 0, i8* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(uchar, unsigned char);
+// CHECK-LABEL: @test_uchar_uninit()
+// CHECK: %uninit = alloca i8, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_uchar_uninit()
+// PATTERN: store i8 -86, i8* %uninit, align 1
+// ZERO-LABEL: @test_uchar_uninit()
+// ZERO: store i8 0, i8* %uninit, align 1
+
+TEST_BRACES(uchar, unsigned char);
+// CHECK-LABEL: @test_uchar_braces()
+// CHECK: %braces = alloca i8, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i8 0, i8* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(schar, signed char);
+// CHECK-LABEL: @test_schar_uninit()
+// CHECK: %uninit = alloca i8, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_schar_uninit()
+// PATTERN: store i8 -86, i8* %uninit, align 1
+// ZERO-LABEL: @test_schar_uninit()
+// ZERO: store i8 0, i8* %uninit, align 1
+
+TEST_BRACES(schar, signed char);
+// CHECK-LABEL: @test_schar_braces()
+// CHECK: %braces = alloca i8, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i8 0, i8* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(wchar_t, wchar_t);
+// CHECK-LABEL: @test_wchar_t_uninit()
+// CHECK: %uninit = alloca i32, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_wchar_t_uninit()
+// PATTERN: store i32 -1431655766, i32* %uninit, align
+// ZERO-LABEL: @test_wchar_t_uninit()
+// ZERO: store i32 0, i32* %uninit, align
+
+TEST_BRACES(wchar_t, wchar_t);
+// CHECK-LABEL: @test_wchar_t_braces()
+// CHECK: %braces = alloca i32, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i32 0, i32* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(short, short);
+// CHECK-LABEL: @test_short_uninit()
+// CHECK: %uninit = alloca i16, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_short_uninit()
+// PATTERN: store i16 -21846, i16* %uninit, align
+// ZERO-LABEL: @test_short_uninit()
+// ZERO: store i16 0, i16* %uninit, align
+
+TEST_BRACES(short, short);
+// CHECK-LABEL: @test_short_braces()
+// CHECK: %braces = alloca i16, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i16 0, i16* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(ushort, unsigned short);
+// CHECK-LABEL: @test_ushort_uninit()
+// CHECK: %uninit = alloca i16, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_ushort_uninit()
+// PATTERN: store i16 -21846, i16* %uninit, align
+// ZERO-LABEL: @test_ushort_uninit()
+// ZERO: store i16 0, i16* %uninit, align
+
+TEST_BRACES(ushort, unsigned short);
+// CHECK-LABEL: @test_ushort_braces()
+// CHECK: %braces = alloca i16, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i16 0, i16* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(int, int);
+// CHECK-LABEL: @test_int_uninit()
+// CHECK: %uninit = alloca i32, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_int_uninit()
+// PATTERN: store i32 -1431655766, i32* %uninit, align
+// ZERO-LABEL: @test_int_uninit()
+// ZERO: store i32 0, i32* %uninit, align
+
+TEST_BRACES(int, int);
+// CHECK-LABEL: @test_int_braces()
+// CHECK: %braces = alloca i32, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i32 0, i32* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(unsigned, unsigned);
+// CHECK-LABEL: @test_unsigned_uninit()
+// CHECK: %uninit = alloca i32, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_unsigned_uninit()
+// PATTERN: store i32 -1431655766, i32* %uninit, align
+// ZERO-LABEL: @test_unsigned_uninit()
+// ZERO: store i32 0, i32* %uninit, align
+
+TEST_BRACES(unsigned, unsigned);
+// CHECK-LABEL: @test_unsigned_braces()
+// CHECK: %braces = alloca i32, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i32 0, i32* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(long, long);
+// CHECK-LABEL: @test_long_uninit()
+// CHECK: %uninit = alloca i64, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_long_uninit()
+// PATTERN: store i64 -6148914691236517206, i64* %uninit, align
+// ZERO-LABEL: @test_long_uninit()
+// ZERO: store i64 0, i64* %uninit, align
+
+TEST_BRACES(long, long);
+// CHECK-LABEL: @test_long_braces()
+// CHECK: %braces = alloca i64, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i64 0, i64* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(ulong, unsigned long);
+// CHECK-LABEL: @test_ulong_uninit()
+// CHECK: %uninit = alloca i64, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_ulong_uninit()
+// PATTERN: store i64 -6148914691236517206, i64* %uninit, align
+// ZERO-LABEL: @test_ulong_uninit()
+// ZERO: store i64 0, i64* %uninit, align
+
+TEST_BRACES(ulong, unsigned long);
+// CHECK-LABEL: @test_ulong_braces()
+// CHECK: %braces = alloca i64, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i64 0, i64* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(longlong, long long);
+// CHECK-LABEL: @test_longlong_uninit()
+// CHECK: %uninit = alloca i64, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_longlong_uninit()
+// PATTERN: store i64 -6148914691236517206, i64* %uninit, align
+// ZERO-LABEL: @test_longlong_uninit()
+// ZERO: store i64 0, i64* %uninit, align
+
+TEST_BRACES(longlong, long long);
+// CHECK-LABEL: @test_longlong_braces()
+// CHECK: %braces = alloca i64, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i64 0, i64* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(ulonglong, unsigned long long);
+// CHECK-LABEL: @test_ulonglong_uninit()
+// CHECK: %uninit = alloca i64, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_ulonglong_uninit()
+// PATTERN: store i64 -6148914691236517206, i64* %uninit, align
+// ZERO-LABEL: @test_ulonglong_uninit()
+// ZERO: store i64 0, i64* %uninit, align
+
+TEST_BRACES(ulonglong, unsigned long long);
+// CHECK-LABEL: @test_ulonglong_braces()
+// CHECK: %braces = alloca i64, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i64 0, i64* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(int128, __int128);
+// CHECK-LABEL: @test_int128_uninit()
+// CHECK: %uninit = alloca i128, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_int128_uninit()
+// PATTERN: store i128 -113427455640312821154458202477256070486, i128* %uninit, align
+// ZERO-LABEL: @test_int128_uninit()
+// ZERO: store i128 0, i128* %uninit, align
+
+TEST_BRACES(int128, __int128);
+// CHECK-LABEL: @test_int128_braces()
+// CHECK: %braces = alloca i128, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i128 0, i128* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(uint128, unsigned __int128);
+// CHECK-LABEL: @test_uint128_uninit()
+// CHECK: %uninit = alloca i128, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_uint128_uninit()
+// PATTERN: store i128 -113427455640312821154458202477256070486, i128* %uninit, align
+// ZERO-LABEL: @test_uint128_uninit()
+// ZERO: store i128 0, i128* %uninit, align
+
+TEST_BRACES(uint128, unsigned __int128);
+// CHECK-LABEL: @test_uint128_braces()
+// CHECK: %braces = alloca i128, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i128 0, i128* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+
+TEST_UNINIT(fp16, __fp16);
+// CHECK-LABEL: @test_fp16_uninit()
+// CHECK: %uninit = alloca half, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_fp16_uninit()
+// PATTERN: store half 0xHFFFF, half* %uninit, align
+// ZERO-LABEL: @test_fp16_uninit()
+// ZERO: store half 0xH0000, half* %uninit, align
+
+TEST_BRACES(fp16, __fp16);
+// CHECK-LABEL: @test_fp16_braces()
+// CHECK: %braces = alloca half, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store half 0xH0000, half* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(float, float);
+// CHECK-LABEL: @test_float_uninit()
+// CHECK: %uninit = alloca float, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_float_uninit()
+// PATTERN: store float 0xFFFFFFFFE0000000, float* %uninit, align
+// ZERO-LABEL: @test_float_uninit()
+// ZERO: store float 0.000000e+00, float* %uninit, align
+
+TEST_BRACES(float, float);
+// CHECK-LABEL: @test_float_braces()
+// CHECK: %braces = alloca float, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store float 0.000000e+00, float* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(double, double);
+// CHECK-LABEL: @test_double_uninit()
+// CHECK: %uninit = alloca double, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_double_uninit()
+// PATTERN: store double 0xFFFFFFFFFFFFFFFF, double* %uninit, align
+// ZERO-LABEL: @test_double_uninit()
+// ZERO: store double 0.000000e+00, double* %uninit, align
+
+TEST_BRACES(double, double);
+// CHECK-LABEL: @test_double_braces()
+// CHECK: %braces = alloca double, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store double 0.000000e+00, double* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(longdouble, long double);
+// CHECK-LABEL: @test_longdouble_uninit()
+// CHECK: %uninit = alloca x86_fp80, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_longdouble_uninit()
+// PATTERN: store x86_fp80 0xKFFFFFFFFFFFFFFFFFFFF, x86_fp80* %uninit, align
+// ZERO-LABEL: @test_longdouble_uninit()
+// ZERO: store x86_fp80 0xK00000000000000000000, x86_fp80* %uninit, align
+
+TEST_BRACES(longdouble, long double);
+// CHECK-LABEL: @test_longdouble_braces()
+// CHECK: %braces = alloca x86_fp80, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store x86_fp80 0xK00000000000000000000, x86_fp80* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+
+TEST_UNINIT(intptr, int*);
+// CHECK-LABEL: @test_intptr_uninit()
+// CHECK: %uninit = alloca i32*, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_intptr_uninit()
+// PATTERN: store i32* inttoptr (i64 -6148914691236517206 to i32*), i32** %uninit, align
+// ZERO-LABEL: @test_intptr_uninit()
+// ZERO: store i32* null, i32** %uninit, align
+
+TEST_BRACES(intptr, int*);
+// CHECK-LABEL: @test_intptr_braces()
+// CHECK: %braces = alloca i32*, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i32* null, i32** %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(intptrptr, int**);
+// CHECK-LABEL: @test_intptrptr_uninit()
+// CHECK: %uninit = alloca i32**, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_intptrptr_uninit()
+// PATTERN: store i32** inttoptr (i64 -6148914691236517206 to i32**), i32*** %uninit, align
+// ZERO-LABEL: @test_intptrptr_uninit()
+// ZERO: store i32** null, i32*** %uninit, align
+
+TEST_BRACES(intptrptr, int**);
+// CHECK-LABEL: @test_intptrptr_braces()
+// CHECK: %braces = alloca i32**, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i32** null, i32*** %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(function, void(*)());
+// CHECK-LABEL: @test_function_uninit()
+// CHECK: %uninit = alloca void ()*, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_function_uninit()
+// PATTERN: store void ()* inttoptr (i64 -6148914691236517206 to void ()*), void ()** %uninit, align
+// ZERO-LABEL: @test_function_uninit()
+// ZERO: store void ()* null, void ()** %uninit, align
+
+TEST_BRACES(function, void(*)());
+// CHECK-LABEL: @test_function_braces()
+// CHECK: %braces = alloca void ()*, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store void ()* null, void ()** %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(bool, bool);
+// CHECK-LABEL: @test_bool_uninit()
+// CHECK: %uninit = alloca i8, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_bool_uninit()
+// PATTERN: store i8 -86, i8* %uninit, align 1
+// ZERO-LABEL: @test_bool_uninit()
+// ZERO: store i8 0, i8* %uninit, align 1
+
+TEST_BRACES(bool, bool);
+// CHECK-LABEL: @test_bool_braces()
+// CHECK: %braces = alloca i8, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i8 0, i8* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+
+TEST_UNINIT(empty, empty);
+// CHECK-LABEL: @test_empty_uninit()
+// CHECK: %uninit = alloca %struct.empty, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_empty_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_empty_uninit.uninit
+// ZERO-LABEL: @test_empty_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(empty, empty);
+// CHECK-LABEL: @test_empty_braces()
+// CHECK: %braces = alloca %struct.empty, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(small, small);
+// CHECK-LABEL: @test_small_uninit()
+// CHECK: %uninit = alloca %struct.small, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_small_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_small_uninit.uninit
+// ZERO-LABEL: @test_small_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(small, small);
+// CHECK-LABEL: @test_small_braces()
+// CHECK: %braces = alloca %struct.small, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 1, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(small, small, { 42 });
+// CHECK-LABEL: @test_small_custom()
+// CHECK: %custom = alloca %struct.small, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(smallinit, smallinit);
+// CHECK-LABEL: @test_smallinit_uninit()
+// CHECK: %uninit = alloca %struct.smallinit, align
+// CHECK-NEXT: call void @{{.*}}smallinit{{.*}}%uninit)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+
+TEST_BRACES(smallinit, smallinit);
+// CHECK-LABEL: @test_smallinit_braces()
+// CHECK: %braces = alloca %struct.smallinit, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[C:[^ ]*]] = getelementptr inbounds %struct.smallinit, %struct.smallinit* %braces, i32 0, i32 0
+// CHECK-NEXT: store i8 42, i8* %[[C]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(smallinit, smallinit, { 100 });
+// CHECK-LABEL: @test_smallinit_custom()
+// CHECK: %custom = alloca %struct.smallinit, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[C:[^ ]*]] = getelementptr inbounds %struct.smallinit, %struct.smallinit* %custom, i32 0, i32 0
+// CHECK-NEXT: store i8 100, i8* %[[C]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(smallpartinit, smallpartinit);
+// CHECK-LABEL: @test_smallpartinit_uninit()
+// CHECK: %uninit = alloca %struct.smallpartinit, align
+// CHECK-NEXT: call void @{{.*}}smallpartinit{{.*}}%uninit)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_smallpartinit_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_smallpartinit_uninit.uninit
+// ZERO-LABEL: @test_smallpartinit_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(smallpartinit, smallpartinit);
+// CHECK-LABEL: @test_smallpartinit_braces()
+// CHECK: %braces = alloca %struct.smallpartinit, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[C:[^ ]*]] = getelementptr inbounds %struct.smallpartinit, %struct.smallpartinit* %braces, i32 0, i32 0
+// CHECK-NEXT: store i8 42, i8* %[[C]], align [[ALIGN]]
+// CHECK-NEXT: %[[D:[^ ]*]] = getelementptr inbounds %struct.smallpartinit, %struct.smallpartinit* %braces, i32 0, i32 1
+// CHECK-NEXT: store i8 0, i8* %[[D]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(smallpartinit, smallpartinit, { 100, 42 });
+// CHECK-LABEL: @test_smallpartinit_custom()
+// CHECK: %custom = alloca %struct.smallpartinit, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[C:[^ ]*]] = getelementptr inbounds %struct.smallpartinit, %struct.smallpartinit* %custom, i32 0, i32 0
+// CHECK-NEXT: store i8 100, i8* %[[C]], align [[ALIGN]]
+// CHECK-NEXT: %[[D:[^ ]*]] = getelementptr inbounds %struct.smallpartinit, %struct.smallpartinit* %custom, i32 0, i32 1
+// CHECK-NEXT: store i8 42, i8* %[[D]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(nullinit, nullinit);
+// CHECK-LABEL: @test_nullinit_uninit()
+// CHECK: %uninit = alloca %struct.nullinit, align
+// CHECK-NEXT: call void @{{.*}}nullinit{{.*}}%uninit)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+
+TEST_BRACES(nullinit, nullinit);
+// CHECK-LABEL: @test_nullinit_braces()
+// CHECK: %braces = alloca %struct.nullinit, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[N:[^ ]*]] = getelementptr inbounds %struct.nullinit, %struct.nullinit* %braces, i32 0, i32 0
+// CHECK-NEXT: store i8* null, i8** %[[N]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(nullinit, nullinit, { (char*)"derp" });
+// CHECK-LABEL: @test_nullinit_custom()
+// CHECK: %custom = alloca %struct.nullinit, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[N:[^ ]*]] = getelementptr inbounds %struct.nullinit, %struct.nullinit* %custom, i32 0, i32 0
+// CHECK-NEXT: store i8* getelementptr inbounds {{.*}}, i8** %[[N]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(padded, padded);
+// CHECK-LABEL: @test_padded_uninit()
+// CHECK: %uninit = alloca %struct.padded, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_padded_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_padded_uninit.uninit
+// ZERO-LABEL: @test_padded_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(padded, padded);
+// CHECK-LABEL: @test_padded_braces()
+// CHECK: %braces = alloca %struct.padded, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 8, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(padded, padded, { 42, 13371337 });
+// CHECK-LABEL: @test_padded_custom()
+// CHECK: %custom = alloca %struct.padded, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(paddednullinit, paddednullinit);
+// CHECK-LABEL: @test_paddednullinit_uninit()
+// CHECK: %uninit = alloca %struct.paddednullinit, align
+// CHECK-NEXT: call void @{{.*}}paddednullinit{{.*}}%uninit)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_paddednullinit_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_paddednullinit_uninit.uninit
+// ZERO-LABEL: @test_paddednullinit_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(paddednullinit, paddednullinit);
+// CHECK-LABEL: @test_paddednullinit_braces()
+// CHECK: %braces = alloca %struct.paddednullinit, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[C:[^ ]*]] = getelementptr inbounds %struct.paddednullinit, %struct.paddednullinit* %braces, i32 0, i32 0
+// CHECK-NEXT: store i8 0, i8* %[[C]], align [[ALIGN]]
+// CHECK-NEXT: %[[I:[^ ]*]] = getelementptr inbounds %struct.paddednullinit, %struct.paddednullinit* %braces, i32 0, i32 1
+// CHECK-NEXT: store i32 0, i32* %[[I]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(paddednullinit, paddednullinit, { 42, 13371337 });
+// CHECK-LABEL: @test_paddednullinit_custom()
+// CHECK: %custom = alloca %struct.paddednullinit, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[C:[^ ]*]] = getelementptr inbounds %struct.paddednullinit, %struct.paddednullinit* %custom, i32 0, i32 0
+// CHECK-NEXT: store i8 42, i8* %[[C]], align [[ALIGN]]
+// CHECK-NEXT: %[[I:[^ ]*]] = getelementptr inbounds %struct.paddednullinit, %struct.paddednullinit* %custom, i32 0, i32 1
+// CHECK-NEXT: store i32 13371337, i32* %[[I]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(bitfield, bitfield);
+// CHECK-LABEL: @test_bitfield_uninit()
+// CHECK: %uninit = alloca %struct.bitfield, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_bitfield_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_bitfield_uninit.uninit
+// ZERO-LABEL: @test_bitfield_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(bitfield, bitfield);
+// CHECK-LABEL: @test_bitfield_braces()
+// CHECK: %braces = alloca %struct.bitfield, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(bitfield, bitfield, { 4, 1 });
+// CHECK-LABEL: @test_bitfield_custom()
+// CHECK: %custom = alloca %struct.bitfield, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(bitfieldaligned, bitfieldaligned);
+// CHECK-LABEL: @test_bitfieldaligned_uninit()
+// CHECK: %uninit = alloca %struct.bitfieldaligned, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_bitfieldaligned_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_bitfieldaligned_uninit.uninit
+// ZERO-LABEL: @test_bitfieldaligned_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(bitfieldaligned, bitfieldaligned);
+// CHECK-LABEL: @test_bitfieldaligned_braces()
+// CHECK: %braces = alloca %struct.bitfieldaligned, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(bitfieldaligned, bitfieldaligned, { 4, 1 });
+// CHECK-LABEL: @test_bitfieldaligned_custom()
+// CHECK: %custom = alloca %struct.bitfieldaligned, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(big, big);
+// CHECK-LABEL: @test_big_uninit()
+// CHECK: %uninit = alloca %struct.big, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_big_uninit()
+// PATTERN: call void @llvm.memset{{.*}}, i8 -86,
+// ZERO-LABEL: @test_big_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(big, big);
+// CHECK-LABEL: @test_big_braces()
+// CHECK: %braces = alloca %struct.big, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 104, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(big, big, { 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA });
+// CHECK-LABEL: @test_big_custom()
+// CHECK: %custom = alloca %struct.big, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 -86, i64 104, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(arraytail, arraytail);
+// CHECK-LABEL: @test_arraytail_uninit()
+// CHECK: %uninit = alloca %struct.arraytail, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_arraytail_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_arraytail_uninit.uninit
+// ZERO-LABEL: @test_arraytail_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(arraytail, arraytail);
+// CHECK-LABEL: @test_arraytail_braces()
+// CHECK: %braces = alloca %struct.arraytail, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 4, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(arraytail, arraytail, { 0xdead });
+// CHECK-LABEL: @test_arraytail_custom()
+// CHECK: %custom = alloca %struct.arraytail, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+
+TEST_UNINIT(int0, int[0]);
+// CHECK-LABEL: @test_int0_uninit()
+// CHECK: %uninit = alloca [0 x i32], align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_int0_uninit()
+// PATTERN: %uninit = alloca [0 x i32], align
+// PATTERN-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// ZERO-LABEL: @test_int0_uninit()
+// ZERO: %uninit = alloca [0 x i32], align
+// ZERO-NEXT: call void @{{.*}}used{{.*}}%uninit)
+
+TEST_BRACES(int0, int[0]);
+// CHECK-LABEL: @test_int0_braces()
+// CHECK: %braces = alloca [0 x i32], align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 0, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(int1, int[1]);
+// CHECK-LABEL: @test_int1_uninit()
+// CHECK: %uninit = alloca [1 x i32], align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_int1_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_int1_uninit.uninit
+// ZERO-LABEL: @test_int1_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(int1, int[1]);
+// CHECK-LABEL: @test_int1_braces()
+// CHECK: %braces = alloca [1 x i32], align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 4, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(int1, int[1], { 0x33333333 });
+// CHECK-LABEL: @test_int1_custom()
+// CHECK: %custom = alloca [1 x i32], align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(int64, int[64]);
+// CHECK-LABEL: @test_int64_uninit()
+// CHECK: %uninit = alloca [64 x i32], align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_int64_uninit()
+// PATTERN: call void @llvm.memset{{.*}}, i8 -86,
+// ZERO-LABEL: @test_int64_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(int64, int[64]);
+// CHECK-LABEL: @test_int64_braces()
+// CHECK: %braces = alloca [64 x i32], align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 256, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(int64, int[64], = { 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111 });
+// CHECK-LABEL: @test_int64_custom()
+// CHECK: %custom = alloca [64 x i32], align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 17, i64 256, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(bool4, bool[4]);
+// CHECK-LABEL: @test_bool4_uninit()
+// CHECK: %uninit = alloca [4 x i8], align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_bool4_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_bool4_uninit.uninit
+// ZERO-LABEL: @test_bool4_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(bool4, bool[4]);
+// CHECK-LABEL: @test_bool4_braces()
+// CHECK: %braces = alloca [4 x i8], align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 4, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(bool4, bool[4], { true, true, true, true });
+// CHECK-LABEL: @test_bool4_custom()
+// CHECK: %custom = alloca [4 x i8], align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(intptr4, int*[4]);
+// CHECK-LABEL: @test_intptr4_uninit()
+// CHECK: %uninit = alloca [4 x i32*], align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_intptr4_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_intptr4_uninit.uninit
+// ZERO-LABEL: @test_intptr4_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(intptr4, int*[4]);
+// CHECK-LABEL: @test_intptr4_braces()
+// CHECK: %braces = alloca [4 x i32*], align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 32, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+ TEST_CUSTOM(intptr4, int*[4], = { (int*)0x22222222, (int*)0x22222222, (int*)0x22222222, (int*)0x22222222 });
+// CHECK-LABEL: @test_intptr4_custom()
+// CHECK: %custom = alloca [4 x i32*], align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(tailpad4, tailpad[4]);
+// CHECK-LABEL: @test_tailpad4_uninit()
+// CHECK: %uninit = alloca [4 x %struct.tailpad], align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_tailpad4_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_tailpad4_uninit.uninit
+// ZERO-LABEL: @test_tailpad4_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(tailpad4, tailpad[4]);
+// CHECK-LABEL: @test_tailpad4_braces()
+// CHECK: %braces = alloca [4 x %struct.tailpad], align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 16, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(tailpad4, tailpad[4], { {257, 1}, {257, 1}, {257, 1}, {257, 1} });
+// CHECK-LABEL: @test_tailpad4_custom()
+// CHECK: %custom = alloca [4 x %struct.tailpad], align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(tailpad9, tailpad[9]);
+// CHECK-LABEL: @test_tailpad9_uninit()
+// CHECK: %uninit = alloca [9 x %struct.tailpad], align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_tailpad9_uninit()
+// PATTERN: call void @llvm.memset{{.*}}, i8 -86,
+// ZERO-LABEL: @test_tailpad9_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(tailpad9, tailpad[9]);
+// CHECK-LABEL: @test_tailpad9_braces()
+// CHECK: %braces = alloca [9 x %struct.tailpad], align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 36, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(tailpad9, tailpad[9], { {257, 1}, {257, 1}, {257, 1}, {257, 1}, {257, 1}, {257, 1}, {257, 1}, {257, 1}, {257, 1} });
+// CHECK-LABEL: @test_tailpad9_custom()
+// CHECK: %custom = alloca [9 x %struct.tailpad], align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 1, i64 36, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+
+TEST_UNINIT(atomicbool, _Atomic(bool));
+// CHECK-LABEL: @test_atomicbool_uninit()
+// CHECK: %uninit = alloca i8, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_atomicbool_uninit()
+// PATTERN: store i8 -86, i8* %uninit, align 1
+// ZERO-LABEL: @test_atomicbool_uninit()
+// ZERO: store i8 0, i8* %uninit, align 1
+
+TEST_UNINIT(atomicint, _Atomic(int));
+// CHECK-LABEL: @test_atomicint_uninit()
+// CHECK: %uninit = alloca i32, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_atomicint_uninit()
+// PATTERN: store i32 -1431655766, i32* %uninit, align 4
+// ZERO-LABEL: @test_atomicint_uninit()
+// ZERO: store i32 0, i32* %uninit, align 4
+
+TEST_UNINIT(atomicdouble, _Atomic(double));
+// CHECK-LABEL: @test_atomicdouble_uninit()
+// CHECK: %uninit = alloca double, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_atomicdouble_uninit()
+// PATTERN: store double 0xFFFFFFFFFFFFFFFF, double* %uninit, align 8
+// ZERO-LABEL: @test_atomicdouble_uninit()
+// ZERO: store double 0.000000e+00, double* %uninit, align 8
+
+TEST_UNINIT(atomicnotlockfree, _Atomic(notlockfree));
+// CHECK-LABEL: @test_atomicnotlockfree_uninit()
+// CHECK: %uninit = alloca %struct.notlockfree, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_atomicnotlockfree_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_atomicnotlockfree_uninit.uninit
+// ZERO-LABEL: @test_atomicnotlockfree_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_UNINIT(atomicpadded, _Atomic(padded));
+// CHECK-LABEL: @test_atomicpadded_uninit()
+// CHECK: %uninit = alloca %struct.padded, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_atomicpadded_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_atomicpadded_uninit.uninit
+// ZERO-LABEL: @test_atomicpadded_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_UNINIT(atomictailpad, _Atomic(tailpad));
+// CHECK-LABEL: @test_atomictailpad_uninit()
+// CHECK: %uninit = alloca %struct.tailpad, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_atomictailpad_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_atomictailpad_uninit.uninit
+// ZERO-LABEL: @test_atomictailpad_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+
+TEST_UNINIT(complexfloat, _Complex float);
+// CHECK-LABEL: @test_complexfloat_uninit()
+// CHECK: %uninit = alloca { float, float }, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_complexfloat_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_complexfloat_uninit.uninit
+// ZERO-LABEL: @test_complexfloat_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(complexfloat, _Complex float);
+// CHECK-LABEL: @test_complexfloat_braces()
+// CHECK: %braces = alloca { float, float }, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[R:[^ ]*]] = getelementptr inbounds { float, float }, { float, float }* %braces, i32 0, i32 0
+// CHECK-NEXT: %[[I:[^ ]*]] = getelementptr inbounds { float, float }, { float, float }* %braces, i32 0, i32 1
+// CHECK-NEXT: store float 0.000000e+00, float* %[[R]], align [[ALIGN]]
+// CHECK-NEXT: store float 0.000000e+00, float* %[[I]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(complexfloat, _Complex float, { 3.1415926535897932384626433, 3.1415926535897932384626433 });
+// CHECK-LABEL: @test_complexfloat_custom()
+// CHECK: %custom = alloca { float, float }, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[R:[^ ]*]] = getelementptr inbounds { float, float }, { float, float }* %custom, i32 0, i32 0
+// CHECK-NEXT: %[[I:[^ ]*]] = getelementptr inbounds { float, float }, { float, float }* %custom, i32 0, i32 1
+// CHECK-NEXT: store float 0x400921FB60000000, float* %[[R]], align [[ALIGN]]
+// CHECK-NEXT: store float 0x400921FB60000000, float* %[[I]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(complexdouble, _Complex double);
+// CHECK-LABEL: @test_complexdouble_uninit()
+// CHECK: %uninit = alloca { double, double }, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_complexdouble_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_complexdouble_uninit.uninit
+// ZERO-LABEL: @test_complexdouble_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(complexdouble, _Complex double);
+// CHECK-LABEL: @test_complexdouble_braces()
+// CHECK: %braces = alloca { double, double }, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[R:[^ ]*]] = getelementptr inbounds { double, double }, { double, double }* %braces, i32 0, i32 0
+// CHECK-NEXT: %[[I:[^ ]*]] = getelementptr inbounds { double, double }, { double, double }* %braces, i32 0, i32 1
+// CHECK-NEXT: store double 0.000000e+00, double* %[[R]], align [[ALIGN]]
+// CHECK-NEXT: store double 0.000000e+00, double* %[[I]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(complexdouble, _Complex double, { 3.1415926535897932384626433, 3.1415926535897932384626433 });
+// CHECK-LABEL: @test_complexdouble_custom()
+// CHECK: %custom = alloca { double, double }, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[R:[^ ]*]] = getelementptr inbounds { double, double }, { double, double }* %custom, i32 0, i32 0
+// CHECK-NEXT: %[[I:[^ ]*]] = getelementptr inbounds { double, double }, { double, double }* %custom, i32 0, i32 1
+// CHECK-NEXT: store double 0x400921FB54442D18, double* %[[R]], align [[ALIGN]]
+// CHECK-NEXT: store double 0x400921FB54442D18, double* %[[I]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+
+TEST_UNINIT(volatileint, volatile int);
+// CHECK-LABEL: @test_volatileint_uninit()
+// CHECK: %uninit = alloca i32, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_volatileint_uninit()
+// PATTERN: store volatile i32 -1431655766, i32* %uninit, align 4
+// ZERO-LABEL: @test_volatileint_uninit()
+// ZERO: store volatile i32 0, i32* %uninit, align 4
+
+TEST_BRACES(volatileint, volatile int);
+// CHECK-LABEL: @test_volatileint_braces()
+// CHECK: %braces = alloca i32, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store volatile i32 0, i32* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(semivolatile, semivolatile);
+// CHECK-LABEL: @test_semivolatile_uninit()
+// CHECK: %uninit = alloca %struct.semivolatile, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_semivolatile_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_semivolatile_uninit.uninit
+// ZERO-LABEL: @test_semivolatile_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(semivolatile, semivolatile);
+// CHECK-LABEL: @test_semivolatile_braces()
+// CHECK: %braces = alloca %struct.semivolatile, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 8, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(semivolatile, semivolatile, { 0x44444444, 0x44444444 });
+// CHECK-LABEL: @test_semivolatile_custom()
+// CHECK: %custom = alloca %struct.semivolatile, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(semivolatileinit, semivolatileinit);
+// CHECK-LABEL: @test_semivolatileinit_uninit()
+// CHECK: %uninit = alloca %struct.semivolatileinit, align
+// CHECK-NEXT: call void @{{.*}}semivolatileinit{{.*}}%uninit)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+
+TEST_BRACES(semivolatileinit, semivolatileinit);
+// CHECK-LABEL: @test_semivolatileinit_braces()
+// CHECK: %braces = alloca %struct.semivolatileinit, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[I:[^ ]*]] = getelementptr inbounds %struct.semivolatileinit, %struct.semivolatileinit* %braces, i32 0, i32 0
+// CHECK-NEXT: store i32 286331153, i32* %[[I]], align [[ALIGN]]
+// CHECK-NEXT: %[[VI:[^ ]*]] = getelementptr inbounds %struct.semivolatileinit, %struct.semivolatileinit* %braces, i32 0, i32 1
+// CHECK-NEXT: store volatile i32 286331153, i32* %[[VI]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(semivolatileinit, semivolatileinit, { 0x44444444, 0x44444444 });
+// CHECK-LABEL: @test_semivolatileinit_custom()
+// CHECK: %custom = alloca %struct.semivolatileinit, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[I:[^ ]*]] = getelementptr inbounds %struct.semivolatileinit, %struct.semivolatileinit* %custom, i32 0, i32 0
+// CHECK-NEXT: store i32 1145324612, i32* %[[I]], align [[ALIGN]]
+// CHECK-NEXT: %[[VI:[^ ]*]] = getelementptr inbounds %struct.semivolatileinit, %struct.semivolatileinit* %custom, i32 0, i32 1
+// CHECK-NEXT: store volatile i32 1145324612, i32* %[[VI]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+
+TEST_UNINIT(base, base);
+// CHECK-LABEL: @test_base_uninit()
+// CHECK: %uninit = alloca %struct.base, align
+// CHECK-NEXT: call void @{{.*}}base{{.*}}%uninit)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_base_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_base_uninit.uninit
+// ZERO-LABEL: @test_base_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(base, base);
+// CHECK-LABEL: @test_base_braces()
+// CHECK: %braces = alloca %struct.base, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 8, i1 false)
+// CHECK-NEXT: call void @{{.*}}base{{.*}}%braces)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(derived, derived);
+// CHECK-LABEL: @test_derived_uninit()
+// CHECK: %uninit = alloca %struct.derived, align
+// CHECK-NEXT: call void @{{.*}}derived{{.*}}%uninit)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_derived_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_derived_uninit.uninit
+// ZERO-LABEL: @test_derived_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(derived, derived);
+// CHECK-LABEL: @test_derived_braces()
+// CHECK: %braces = alloca %struct.derived, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 8, i1 false)
+// CHECK-NEXT: call void @{{.*}}derived{{.*}}%braces)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(virtualderived, virtualderived);
+// CHECK-LABEL: @test_virtualderived_uninit()
+// CHECK: %uninit = alloca %struct.virtualderived, align
+// CHECK-NEXT: call void @{{.*}}virtualderived{{.*}}%uninit)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_virtualderived_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_virtualderived_uninit.uninit
+// ZERO-LABEL: @test_virtualderived_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(virtualderived, virtualderived);
+// CHECK-LABEL: @test_virtualderived_braces()
+// CHECK: %braces = alloca %struct.virtualderived, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 16, i1 false)
+// CHECK-NEXT: call void @{{.*}}virtualderived{{.*}}%braces)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+
+TEST_UNINIT(matching, matching);
+// CHECK-LABEL: @test_matching_uninit()
+// CHECK: %uninit = alloca %union.matching, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_matching_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_matching_uninit.uninit
+// ZERO-LABEL: @test_matching_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(matching, matching);
+// CHECK-LABEL: @test_matching_braces()
+// CHECK: %braces = alloca %union.matching, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 4, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(matching, matching, { .f = 0xf00f });
+// CHECK-LABEL: @test_matching_custom()
+// CHECK: %custom = alloca %union.matching, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(matchingreverse, matchingreverse);
+// CHECK-LABEL: @test_matchingreverse_uninit()
+// CHECK: %uninit = alloca %union.matchingreverse, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_matchingreverse_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_matchingreverse_uninit.uninit
+// ZERO-LABEL: @test_matchingreverse_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(matchingreverse, matchingreverse);
+// CHECK-LABEL: @test_matchingreverse_braces()
+// CHECK: %braces = alloca %union.matchingreverse, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 4, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(matchingreverse, matchingreverse, { .i = 0xf00f });
+// CHECK-LABEL: @test_matchingreverse_custom()
+// CHECK: %custom = alloca %union.matchingreverse, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(unmatched, unmatched);
+// CHECK-LABEL: @test_unmatched_uninit()
+// CHECK: %uninit = alloca %union.unmatched, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_unmatched_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_unmatched_uninit.uninit
+// ZERO-LABEL: @test_unmatched_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(unmatched, unmatched);
+// CHECK-LABEL: @test_unmatched_braces()
+// CHECK: %braces = alloca %union.unmatched, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(unmatched, unmatched, { .i = 0x3badbeef });
+// CHECK-LABEL: @test_unmatched_custom()
+// CHECK: %custom = alloca %union.unmatched, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(unmatchedreverse, unmatchedreverse);
+// CHECK-LABEL: @test_unmatchedreverse_uninit()
+// CHECK: %uninit = alloca %union.unmatchedreverse, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_unmatchedreverse_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_unmatchedreverse_uninit.uninit
+// ZERO-LABEL: @test_unmatchedreverse_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(unmatchedreverse, unmatchedreverse);
+// CHECK-LABEL: @test_unmatchedreverse_braces()
+// CHECK: %braces = alloca %union.unmatchedreverse, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 4, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(unmatchedreverse, unmatchedreverse, { .c = 42 });
+// CHECK-LABEL: @test_unmatchedreverse_custom()
+// CHECK: %custom = alloca %union.unmatchedreverse, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(unmatchedfp, unmatchedfp);
+// CHECK-LABEL: @test_unmatchedfp_uninit()
+// CHECK: %uninit = alloca %union.unmatchedfp, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_unmatchedfp_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_unmatchedfp_uninit.uninit
+// ZERO-LABEL: @test_unmatchedfp_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(unmatchedfp, unmatchedfp);
+// CHECK-LABEL: @test_unmatchedfp_braces()
+// CHECK: %braces = alloca %union.unmatchedfp, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(unmatchedfp, unmatchedfp, { .d = 3.1415926535897932384626433 });
+// CHECK-LABEL: @test_unmatchedfp_custom()
+// CHECK: %custom = alloca %union.unmatchedfp, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+
+TEST_UNINIT(emptyenum, emptyenum);
+// CHECK-LABEL: @test_emptyenum_uninit()
+// CHECK: %uninit = alloca i32, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_emptyenum_uninit()
+// PATTERN: store i32 -1431655766, i32* %braces, align 4
+// ZERO-LABEL: @test_emptyenum_uninit()
+// ZERO: store i32 0, i32* %braces, align 4
+
+TEST_BRACES(emptyenum, emptyenum);
+// CHECK-LABEL: @test_emptyenum_braces()
+// CHECK: %braces = alloca i32, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i32 0, i32* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(emptyenum, emptyenum, { (emptyenum)42 });
+// CHECK-LABEL: @test_emptyenum_custom()
+// CHECK: %custom = alloca i32, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i32 42, i32* %custom, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(smallenum, smallenum);
+// CHECK-LABEL: @test_smallenum_uninit()
+// CHECK: %uninit = alloca i32, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_smallenum_uninit()
+// PATTERN: store i32 -1431655766, i32* %braces, align 4
+// ZERO-LABEL: @test_smallenum_uninit()
+// ZERO: store i32 0, i32* %braces, align 4
+
+TEST_BRACES(smallenum, smallenum);
+// CHECK-LABEL: @test_smallenum_braces()
+// CHECK: %braces = alloca i32, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i32 0, i32* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(smallenum, smallenum, { (smallenum)42 });
+// CHECK-LABEL: @test_smallenum_custom()
+// CHECK: %custom = alloca i32, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i32 42, i32* %custom, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+
+TEST_UNINIT(intvec16, int __attribute__((vector_size(16))));
+// CHECK-LABEL: @test_intvec16_uninit()
+// CHECK: %uninit = alloca <4 x i32>, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_intvec16_uninit()
+// PATTERN: store <4 x i32> <i32 -1431655766, i32 -1431655766, i32 -1431655766, i32 -1431655766>, <4 x i32>* %uninit, align 16
+// ZERO-LABEL: @test_intvec16_uninit()
+// ZERO: store <4 x i32> zeroinitializer, <4 x i32>* %uninit, align 16
+
+TEST_BRACES(intvec16, int __attribute__((vector_size(16))));
+// CHECK-LABEL: @test_intvec16_braces()
+// CHECK: %braces = alloca <4 x i32>, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store <4 x i32> zeroinitializer, <4 x i32>* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(intvec16, int __attribute__((vector_size(16))), { 0x44444444, 0x44444444, 0x44444444, 0x44444444 });
+// CHECK-LABEL: @test_intvec16_custom()
+// CHECK: %custom = alloca <4 x i32>, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store <4 x i32> <i32 1145324612, i32 1145324612, i32 1145324612, i32 1145324612>, <4 x i32>* %custom, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(longlongvec32, long long __attribute__((vector_size(32))));
+// CHECK-LABEL: @test_longlongvec32_uninit()
+// CHECK: %uninit = alloca <4 x i64>, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_longlongvec32_uninit()
+// PATTERN: store <4 x i64> <i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206>, <4 x i64>* %uninit, align 32
+// ZERO-LABEL: @test_longlongvec32_uninit()
+// ZERO: store <4 x i64> zeroinitializer, <4 x i64>* %uninit, align 32
+
+TEST_BRACES(longlongvec32, long long __attribute__((vector_size(32))));
+// CHECK-LABEL: @test_longlongvec32_braces()
+// CHECK: %braces = alloca <4 x i64>, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store <4 x i64> zeroinitializer, <4 x i64>* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(longlongvec32, long long __attribute__((vector_size(32))), { 0x3333333333333333, 0x3333333333333333, 0x3333333333333333, 0x3333333333333333 });
+// CHECK-LABEL: @test_longlongvec32_custom()
+// CHECK: %custom = alloca <4 x i64>, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store <4 x i64> <i64 3689348814741910323, i64 3689348814741910323, i64 3689348814741910323, i64 3689348814741910323>, <4 x i64>* %custom, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(floatvec16, float __attribute__((vector_size(16))));
+// CHECK-LABEL: @test_floatvec16_uninit()
+// CHECK: %uninit = alloca <4 x float>, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_floatvec16_uninit()
+// PATTERN: store <4 x float> <float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000>, <4 x float>* %uninit, align 16
+// ZERO-LABEL: @test_floatvec16_uninit()
+// ZERO: store <4 x float> zeroinitializer, <4 x float>* %uninit, align 16
+
+TEST_BRACES(floatvec16, float __attribute__((vector_size(16))));
+// CHECK-LABEL: @test_floatvec16_braces()
+// CHECK: %braces = alloca <4 x float>, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store <4 x float> zeroinitializer, <4 x float>* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(floatvec16, float __attribute__((vector_size(16))), { 3.1415926535897932384626433, 3.1415926535897932384626433, 3.1415926535897932384626433, 3.1415926535897932384626433 });
+// CHECK-LABEL: @test_floatvec16_custom()
+// CHECK: %custom = alloca <4 x float>, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store <4 x float> <float 0x400921FB60000000, float 0x400921FB60000000, float 0x400921FB60000000, float 0x400921FB60000000>, <4 x float>* %custom, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(doublevec32, double __attribute__((vector_size(32))));
+// CHECK-LABEL: @test_doublevec32_uninit()
+// CHECK: %uninit = alloca <4 x double>, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_doublevec32_uninit()
+// PATTERN: store <4 x double> <double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF>, <4 x double>* %uninit, align 32
+// ZERO-LABEL: @test_doublevec32_uninit()
+// ZERO: store <4 x double> zeroinitializer, <4 x double>* %uninit, align 32
+
+TEST_BRACES(doublevec32, double __attribute__((vector_size(32))));
+// CHECK-LABEL: @test_doublevec32_braces()
+// CHECK: %braces = alloca <4 x double>, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store <4 x double> zeroinitializer, <4 x double>* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(doublevec32, double __attribute__((vector_size(32))), { 3.1415926535897932384626433, 3.1415926535897932384626433, 3.1415926535897932384626433, 3.1415926535897932384626433 });
+// CHECK-LABEL: @test_doublevec32_custom()
+// CHECK: %custom = alloca <4 x double>, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store <4 x double> <double 0x400921FB54442D18, double 0x400921FB54442D18, double 0x400921FB54442D18, double 0x400921FB54442D18>, <4 x double>* %custom, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+
+} // extern "C"
diff --git a/test/CodeGenCXX/block-byref-cxx-objc.cpp b/test/CodeGenCXX/block-byref-cxx-objc.cpp
index ce1ebd615ef8..6aca809c2c72 100644
--- a/test/CodeGenCXX/block-byref-cxx-objc.cpp
+++ b/test/CodeGenCXX/block-byref-cxx-objc.cpp
@@ -1,17 +1,23 @@
-// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - -fblocks | FileCheck %s
+// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -triple %itanium_abi_triple -o - -fblocks -fexceptions | FileCheck %s
// rdar://8594790
struct A {
int x;
A(const A &);
A();
- ~A();
+ ~A() noexcept(false);
};
-int main()
-{
- __block A BYREF_VAR;
- ^{ BYREF_VAR.x = 1234; };
+struct B {
+ int x;
+ B(const B &);
+ B();
+ ~B();
+};
+
+int testA() {
+ __block A a0, a1;
+ ^{ a0.x = 1234; a1.x = 5678; };
return 0;
}
@@ -19,10 +25,32 @@ int main()
// CHECK: call {{.*}} @_ZN1AC1ERKS_
// CHECK-LABEL: define internal void @__Block_byref_object_dispose_
// CHECK: call {{.*}} @_ZN1AD1Ev
-// CHECK-LABEL: define internal void @__copy_helper_block_
-// CHECK: call {{.*}}void @_Block_object_assign
-// CHECK-LABEL: define internal void @__destroy_helper_block_
-// CHECK: call {{.*}}void @_Block_object_dispose
+
+// CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block_e{{4|8}}_{{20|32}}rc{{24|40}}rc(
+// CHECK: call void @_Block_object_assign(
+// CHECK: invoke void @_Block_object_assign(
+// CHECK: call void @_Block_object_dispose({{.*}}) #[[NOUNWIND_ATTR:[0-9]+]]
+
+// CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block_e{{4|8}}_{{20|32}}rd{{24|40}}rd(
+// CHECK: invoke void @_Block_object_dispose(
+// CHECK: call void @_Block_object_dispose(
+// CHECK: invoke void @_Block_object_dispose(
+
+int testB() {
+ __block B b0, b1;
+ ^{ b0.x = 1234; b1.x = 5678; };
+ return 0;
+}
+
+// CHECK-LABEL: define internal void @__Block_byref_object_copy_
+// CHECK: call {{.*}} @_ZN1BC1ERKS_
+// CHECK-LABEL: define internal void @__Block_byref_object_dispose_
+// CHECK: call {{.*}} @_ZN1BD1Ev
+
+// CHECK-NOT: define{{.*}}@__copy_helper_block
+// CHECK: define linkonce_odr hidden void @__destroy_helper_block_e{{4|8}}_{{20|32}}r{{24|40}}r(
+
+// CHECK: attributes #[[NOUNWIND_ATTR]] = {{{.*}}nounwind{{.*}}}
// rdar://problem/11135650
namespace test1 {
diff --git a/test/CodeGenCXX/block-byref.cpp b/test/CodeGenCXX/block-byref.cpp
new file mode 100644
index 000000000000..1cb86a547573
--- /dev/null
+++ b/test/CodeGenCXX/block-byref.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - | FileCheck %s
+// REQUIRES: x86-registered-target
+
+// CHECK: @b = global i32 0,
+
+// CHECK: define {{.*}}void @{{.*}}test{{.*}}_block_invoke(
+// CHECK: store i32 2, i32* @b,
+// CHECK: ret void
+
+int b;
+
+void test() {
+ int &a = b;
+ ^{ a = 2; };
+}
diff --git a/test/CodeGenCXX/block-capture.cpp b/test/CodeGenCXX/block-capture.cpp
index 623838357a38..515d64d35dad 100644
--- a/test/CodeGenCXX/block-capture.cpp
+++ b/test/CodeGenCXX/block-capture.cpp
@@ -4,10 +4,12 @@
// CHECK: [[baz:%[0-9a-z_]*]] = alloca %struct.__block_byref_baz
// CHECK: [[bazref:%[0-9a-z_\.]*]] = getelementptr inbounds %struct.__block_byref_baz, %struct.__block_byref_baz* [[baz]], i32 0, i32 1
// CHECK: store %struct.__block_byref_baz* [[baz]], %struct.__block_byref_baz** [[bazref]]
+// CHECK: bitcast %struct.__block_byref_baz* [[baz]] to i8*
// CHECK: [[disposable:%[0-9a-z_]*]] = bitcast %struct.__block_byref_baz* [[baz]] to i8*
// CHECK: call void @_Block_object_dispose(i8* [[disposable]]
int main() {
__block int baz = [&]() { return 0; }();
+ ^{ (void)baz; };
return 0;
}
diff --git a/test/CodeGenCXX/blocks.cpp b/test/CodeGenCXX/blocks.cpp
index 37219d3f7abd..3b3363dc4175 100644
--- a/test/CodeGenCXX/blocks.cpp
+++ b/test/CodeGenCXX/blocks.cpp
@@ -1,5 +1,8 @@
// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
+// CHECK: %[[STRUCT_BLOCK_DESCRIPTOR:.*]] = type { i64, i64 }
+// CHECK: @[[BLOCK_DESCRIPTOR22:.*]] = internal constant { i64, i64, i8*, i8*, i8*, i8* } { i64 0, i64 36, i8* bitcast (void (i8*, i8*)* @__copy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE to i8*), i8* bitcast (void (i8*)* @__destroy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE to i8*), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @{{.*}}, i32 0, i32 0), i8* null }, align 8
+
namespace test0 {
// CHECK-LABEL: define void @_ZN5test04testEi(
// CHECK: define internal void @___ZN5test04testEi_block_invoke{{.*}}(
@@ -73,6 +76,7 @@ namespace test2 {
void test() {
__block A a;
__block B b;
+ ^{ (void)a; (void)b; };
}
// CHECK-LABEL: define internal void @__Block_byref_object_copy
@@ -122,7 +126,7 @@ 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: bitcast i8* [[BLOCKDESC]] to <{ i8*, i32, i32, i8*, %struct.__block_descriptor* }>*
+ // 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]])
// CHECK-NEXT: call void @_ZN5test41AD1Ev([[A]]* [[TMP]])
@@ -252,3 +256,54 @@ namespace test9 {
});
}
}
+
+namespace test10 {
+ // Check that 'v' is included in the copy helper function name to indicate
+ // the constructor taking a volatile parameter is called to copy the captured
+ // object.
+
+ // CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block_8_32c16_ZTSVN6test101BE(
+ // CHECK: call void @_ZN6test101BC1ERVKS0_(
+ // CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block_8_32c16_ZTSVN6test101BE(
+ // CHECK: call void @_ZN6test101BD1Ev(
+
+ struct B {
+ int a;
+ B();
+ B(const B &);
+ B(const volatile B &);
+ ~B();
+ };
+
+ void test() {
+ volatile B x;
+ ^{ (void)x; };
+ }
+}
+
+// Copy/dispose helper functions and block descriptors of blocks that capture
+// objects that are non-external and non-trivial have internal linkage.
+
+// CHECK-LABEL: define internal void @_ZN12_GLOBAL__N_14testEv(
+// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i8* }* @[[BLOCK_DESCRIPTOR22]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %{{.*}}, align 8
+
+// CHECK-LABEL: define internal void @__copy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE(
+// CHECK-LABEL: define internal void @__destroy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE(
+
+namespace {
+ struct B {
+ int a;
+ B();
+ B(const B &);
+ ~B();
+ };
+
+ void test() {
+ B x;
+ ^{ (void)x; };
+ }
+}
+
+void callTest() {
+ test();
+}
diff --git a/test/CodeGenCXX/builtin-constant-p.cpp b/test/CodeGenCXX/builtin-constant-p.cpp
new file mode 100644
index 000000000000..6d853e8a6828
--- /dev/null
+++ b/test/CodeGenCXX/builtin-constant-p.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -o - %s
+
+// Don't crash if the argument to __builtin_constant_p isn't scalar.
+template <typename T>
+constexpr bool is_constant(const T v) {
+ return __builtin_constant_p(v);
+}
+
+template <typename T>
+class numeric {
+ public:
+ using type = T;
+
+ template <typename S>
+ constexpr numeric(S value)
+ : value_(static_cast<T>(value)) {}
+
+ private:
+ const T value_;
+};
+
+bool bcp() {
+ return is_constant(numeric<int>(1));
+}
diff --git a/test/CodeGenCXX/builtin-launder.cpp b/test/CodeGenCXX/builtin-launder.cpp
new file mode 100644
index 000000000000..b3d849c8aec9
--- /dev/null
+++ b/test/CodeGenCXX/builtin-launder.cpp
@@ -0,0 +1,321 @@
+// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -fstrict-vtable-pointers -o - %s \
+// RUN: | FileCheck --check-prefixes=CHECK,CHECK-STRICT %s
+// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -o - %s \
+// RUN: | FileCheck --check-prefixes=CHECK,CHECK-NONSTRICT %s
+
+//===----------------------------------------------------------------------===//
+// Positive Cases
+//===----------------------------------------------------------------------===//
+
+struct TestVirtualFn {
+ virtual void foo() {}
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_virtual_fn
+extern "C" void test_builtin_launder_virtual_fn(TestVirtualFn *p) {
+ // CHECK: store [[TYPE:%[^ ]+]] %p, [[TYPE]]* %p.addr
+ // CHECK-NEXT: [[TMP0:%.*]] = load [[TYPE]], [[TYPE]]* %p.addr
+
+ // CHECK-NONSTRICT-NEXT: store [[TYPE]] [[TMP0]], [[TYPE]]* %d
+
+ // CHECK-STRICT-NEXT: [[TMP1:%.*]] = bitcast [[TYPE]] [[TMP0]] to i8*
+ // CHECK-STRICT-NEXT: [[TMP2:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* [[TMP1]])
+ // CHECK-STRICT-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [[TYPE]]
+ // CHECK-STRICT-NEXT: store [[TYPE]] [[TMP3]], [[TYPE]]* %d
+
+ // CHECK-NEXT: ret void
+ TestVirtualFn *d = __builtin_launder(p);
+}
+
+struct TestPolyBase : TestVirtualFn {
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_poly_base
+extern "C" void test_builtin_launder_poly_base(TestPolyBase *p) {
+ // CHECK-STRICT-NOT: ret void
+ // CHECK-STRICT: @llvm.launder.invariant.group
+
+ // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group
+
+ // CHECK: ret void
+ TestPolyBase *d = __builtin_launder(p);
+}
+
+struct TestBase {};
+struct TestVirtualBase : virtual TestBase {};
+
+// CHECK-LABEL: define void @test_builtin_launder_virtual_base
+extern "C" void test_builtin_launder_virtual_base(TestVirtualBase *p) {
+ // CHECK-STRICT-NOT: ret void
+ // CHECK-STRICT: @llvm.launder.invariant.group
+
+ // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group
+
+ // CHECK: ret void
+ TestVirtualBase *d = __builtin_launder(p);
+}
+
+//===----------------------------------------------------------------------===//
+// Negative Cases
+//===----------------------------------------------------------------------===//
+
+// CHECK-LABEL: define void @test_builtin_launder_ommitted_one
+extern "C" void test_builtin_launder_ommitted_one(int *p) {
+ // CHECK: entry
+ // CHECK-NEXT: %p.addr = alloca i32*
+ // CHECK-NEXT: %d = alloca i32*
+ // CHECK-NEXT: store i32* %p, i32** %p.addr, align 8
+ // CHECK-NEXT: [[TMP:%.*]] = load i32*, i32** %p.addr
+ // CHECK-NEXT: store i32* [[TMP]], i32** %d
+ // CHECK-NEXT: ret void
+ int *d = __builtin_launder(p);
+}
+
+struct TestNoInvariant {
+ int x;
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_ommitted_two
+extern "C" void test_builtin_launder_ommitted_two(TestNoInvariant *p) {
+ // CHECK: entry
+ // CHECK-NOT: llvm.launder.invariant.group
+ // CHECK-NEXT: %p.addr = alloca [[TYPE:%.*]], align 8
+ // CHECK-NEXT: %d = alloca [[TYPE]]
+ // CHECK-NEXT: store [[TYPE]] %p, [[TYPE]]* %p.addr
+ // CHECK-NEXT: [[TMP:%.*]] = load [[TYPE]], [[TYPE]]* %p.addr
+ // CHECK-NEXT: store [[TYPE]] [[TMP]], [[TYPE]]* %d
+ // CHECK-NEXT: ret void
+ TestNoInvariant *d = __builtin_launder(p);
+}
+
+struct TestVirtualMember {
+ TestVirtualFn member;
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_virtual_member
+extern "C" void test_builtin_launder_virtual_member(TestVirtualMember *p) {
+ // CHECK: entry
+ // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group
+ // CHECK-STRICT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestVirtualMember *d = __builtin_launder(p);
+}
+
+struct TestVirtualMemberDepth2 {
+ TestVirtualMember member;
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_virtual_member_depth_2
+extern "C" void test_builtin_launder_virtual_member_depth_2(TestVirtualMemberDepth2 *p) {
+ // CHECK: entry
+ // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group
+ // CHECK-STRICT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestVirtualMemberDepth2 *d = __builtin_launder(p);
+}
+
+struct TestVirtualReferenceMember {
+ TestVirtualFn &member;
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_virtual_reference_member
+extern "C" void test_builtin_launder_virtual_reference_member(TestVirtualReferenceMember *p) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestVirtualReferenceMember *d = __builtin_launder(p);
+}
+
+struct TestRecursiveMember {
+ TestRecursiveMember() : member(*this) {}
+ TestRecursiveMember &member;
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_recursive_member
+extern "C" void test_builtin_launder_recursive_member(TestRecursiveMember *p) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestRecursiveMember *d = __builtin_launder(p);
+}
+
+struct TestVirtualRecursiveMember {
+ TestVirtualRecursiveMember() : member(*this) {}
+ TestVirtualRecursiveMember &member;
+ virtual void foo();
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_virtual_recursive_member
+extern "C" void test_builtin_launder_virtual_recursive_member(TestVirtualRecursiveMember *p) {
+ // CHECK: entry
+ // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group
+ // CHECK-STRICT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestVirtualRecursiveMember *d = __builtin_launder(p);
+}
+
+// CHECK-LABEL: define void @test_builtin_launder_array(
+extern "C" void test_builtin_launder_array(TestVirtualFn (&Arr)[5]) {
+ // CHECK: entry
+ // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group
+ // CHECK-STRICT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestVirtualFn *d = __builtin_launder(Arr);
+}
+
+// CHECK-LABEL: define void @test_builtin_launder_array_nested(
+extern "C" void test_builtin_launder_array_nested(TestVirtualFn (&Arr)[5][2]) {
+ // CHECK: entry
+ // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group
+ // CHECK-STRICT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ using RetTy = TestVirtualFn(*)[2];
+ RetTy d = __builtin_launder(Arr);
+}
+
+// CHECK-LABEL: define void @test_builtin_launder_array_no_invariant(
+extern "C" void test_builtin_launder_array_no_invariant(TestNoInvariant (&Arr)[5]) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestNoInvariant *d = __builtin_launder(Arr);
+}
+
+// CHECK-LABEL: define void @test_builtin_launder_array_nested_no_invariant(
+extern "C" void test_builtin_launder_array_nested_no_invariant(TestNoInvariant (&Arr)[5][2]) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ using RetTy = TestNoInvariant(*)[2];
+ RetTy d = __builtin_launder(Arr);
+}
+
+template <class Member>
+struct WithMember {
+ Member mem;
+};
+
+template struct WithMember<TestVirtualFn[5]>;
+
+// CHECK-LABEL: define void @test_builtin_launder_member_array(
+extern "C" void test_builtin_launder_member_array(WithMember<TestVirtualFn[5]> *p) {
+ // CHECK: entry
+ // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group
+ // CHECK-STRICT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ auto *d = __builtin_launder(p);
+}
+
+template struct WithMember<TestVirtualFn[5][2]>;
+
+// CHECK-LABEL: define void @test_builtin_launder_member_array_nested(
+extern "C" void test_builtin_launder_member_array_nested(WithMember<TestVirtualFn[5][2]> *p) {
+ // CHECK: entry
+ // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group
+ // CHECK-STRICT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ auto *d = __builtin_launder(p);
+}
+
+template struct WithMember<TestNoInvariant[5]>;
+
+// CHECK-LABEL: define void @test_builtin_launder_member_array_no_invariant(
+extern "C" void test_builtin_launder_member_array_no_invariant(WithMember<TestNoInvariant[5]> *p) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ auto *d = __builtin_launder(p);
+}
+
+template struct WithMember<TestNoInvariant[5][2]>;
+
+// CHECK-LABEL: define void @test_builtin_launder_member_array_nested_no_invariant(
+extern "C" void test_builtin_launder_member_array_nested_no_invariant(WithMember<TestNoInvariant[5][2]> *p) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ auto *d = __builtin_launder(p);
+}
+
+template <class T>
+struct WithBase : T {};
+
+template struct WithBase<TestNoInvariant>;
+
+// CHECK-LABEL: define void @test_builtin_launder_base_no_invariant(
+extern "C" void test_builtin_launder_base_no_invariant(WithBase<TestNoInvariant> *p) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ auto *d = __builtin_launder(p);
+}
+
+template struct WithBase<TestVirtualFn>;
+
+// CHECK-LABEL: define void @test_builtin_launder_base(
+extern "C" void test_builtin_launder_base(WithBase<TestVirtualFn> *p) {
+ // CHECK: entry
+ // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group
+ // CHECK-STRICT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ auto *d = __builtin_launder(p);
+}
+
+/// The test cases in this namespace technically need to be laundered according
+/// to the language in the standard (ie they have const or reference subobjects)
+/// but LLVM doesn't currently optimize on these cases -- so Clang emits
+/// __builtin_launder as a nop.
+///
+/// NOTE: Adding optimizations for these cases later is an LTO ABI break. That's
+/// probably OK for now -- but is something to keep in mind.
+namespace pessimizing_cases {
+
+struct TestConstMember {
+ const int x;
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_const_member
+extern "C" void test_builtin_launder_const_member(TestConstMember *p) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestConstMember *d = __builtin_launder(p);
+}
+
+struct TestConstSubobject {
+ TestConstMember x;
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_const_subobject
+extern "C" void test_builtin_launder_const_subobject(TestConstSubobject *p) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestConstSubobject *d = __builtin_launder(p);
+}
+
+struct TestConstObject {
+ const struct TestConstMember x;
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_const_object
+extern "C" void test_builtin_launder_const_object(TestConstObject *p) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestConstObject *d = __builtin_launder(p);
+}
+
+struct TestReferenceMember {
+ int &x;
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_reference_member
+extern "C" void test_builtin_launder_reference_member(TestReferenceMember *p) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestReferenceMember *d = __builtin_launder(p);
+}
+
+} // namespace pessimizing_cases
diff --git a/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp b/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp
index d5c1f603ff3f..61272b1ceea2 100644
--- a/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp
+++ b/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp
@@ -1,8 +1,12 @@
-// RUN: %clang_cc1 %s -emit-llvm -o -
+// RUN: %clang_cc1 %s -emit-llvm-only -o -
// https://bugs.llvm.org/show_bug.cgi?id=38356
// We only check that we do not crash.
+// ASAN increases stack usage, so we are hitting stack overflow before reaching
+// recursive template instantiation limit.
+// XFAIL: darwin && asan
+
template <typename a, a b(unsigned), int c, unsigned...>
struct d : d<a, b, c - 1> {};
template <typename a, a b(unsigned), unsigned... e>
diff --git a/test/CodeGenCXX/catch-implicit-integer-sign-changes-true-negatives.cpp b/test/CodeGenCXX/catch-implicit-integer-sign-changes-true-negatives.cpp
new file mode 100644
index 000000000000..95349387b3b4
--- /dev/null
+++ b/test/CodeGenCXX/catch-implicit-integer-sign-changes-true-negatives.cpp
@@ -0,0 +1,149 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -fsanitize=implicit-integer-sign-change -fno-sanitize-recover=implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER
+// RUN: %clang_cc1 -fsanitize=implicit-integer-sign-change -fsanitize-recover=implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER
+// RUN: %clang_cc1 -fsanitize=implicit-integer-sign-change -fsanitize-trap=implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP
+
+extern "C" { // Disable name mangling.
+
+// ========================================================================== //
+// The expected true-negatives.
+// ========================================================================== //
+
+// Sanitization is explicitly disabled.
+// ========================================================================== //
+
+// CHECK-LABEL: @blacklist_0
+__attribute__((no_sanitize("undefined"))) unsigned int blacklist_0(signed int src) {
+ // We are not in "undefined" group, so that doesn't work.
+ // CHECK-SANITIZE: call
+ // CHECK: }
+ return src;
+}
+
+// CHECK-LABEL: @blacklist_1
+__attribute__((no_sanitize("integer"))) unsigned int blacklist_1(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return src;
+}
+
+// CHECK-LABEL: @blacklist_2
+__attribute__((no_sanitize("implicit-conversion"))) unsigned int blacklist_2(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return src;
+}
+
+// CHECK-LABEL: @blacklist_3
+__attribute__((no_sanitize("implicit-integer-sign-change"))) unsigned int blacklist_3(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return src;
+}
+
+// Explicit sign-changing conversions.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_signed_int_to_unsigned_int
+unsigned int explicit_signed_int_to_unsigned_int(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned int)src;
+}
+
+// CHECK-LABEL: @explicit_unsigned_int_to_signed_int
+signed int explicit_unsigned_int_to_signed_int(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (signed int)src;
+}
+
+// Explicit NOP conversions.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_unsigned_int_to_unsigned_int
+unsigned int explicit_unsigned_int_to_unsigned_int(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned int)src;
+}
+
+// CHECK-LABEL: @explicit_signed_int_to_signed_int
+signed int explicit_signed_int_to_signed_int(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (signed int)src;
+}
+
+// Explicit functional sign-changing casts.
+// ========================================================================== //
+
+using UnsignedInt = unsigned int;
+using SignedInt = signed int;
+
+// CHECK-LABEL: explicit_functional_unsigned_int_to_signed_int
+signed int explicit_functional_unsigned_int_to_signed_int(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return SignedInt(src);
+}
+
+// CHECK-LABEL: @explicit_functional_signed_int_to_unsigned_int
+unsigned int explicit_functional_signed_int_to_unsigned_int(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return UnsignedInt(src);
+}
+
+// Explicit functional NOP casts.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_functional_unsigned_int_to_unsigned_int
+unsigned int explicit_functional_unsigned_int_to_unsigned_int(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return UnsignedInt(src);
+}
+
+// CHECK-LABEL: @explicit_functional_signed_int_to_signed_int
+signed int explicit_functional_signed_int_to_signed_int(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return SignedInt(src);
+}
+
+// Explicit C++-style sign-changing casts.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_cppstyle_unsigned_int_to_signed_int
+signed int explicit_cppstyle_unsigned_int_to_signed_int(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<signed int>(src);
+}
+
+// CHECK-LABEL: @explicit_cppstyle_signed_int_to_unsigned_int
+unsigned int explicit_cppstyle_signed_int_to_unsigned_int(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<unsigned int>(src);
+}
+
+// Explicit C++-style casts NOP casts.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_cppstyle_unsigned_int_to_unsigned_int
+unsigned int explicit_cppstyle_unsigned_int_to_unsigned_int(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<unsigned int>(src);
+}
+
+// CHECK-LABEL: @explicit_cppstyle_signed_int_to_signed_int
+signed int explicit_cppstyle_signed_int_to_signed_int(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<signed int>(src);
+}
+
+} // extern "C"
diff --git a/test/CodeGenCXX/catch-implicit-integer-truncations.cpp b/test/CodeGenCXX/catch-implicit-integer-truncations.cpp
index ba7676a3504a..2902fe1e884d 100644
--- a/test/CodeGenCXX/catch-implicit-integer-truncations.cpp
+++ b/test/CodeGenCXX/catch-implicit-integer-truncations.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK
-// RUN: %clang_cc1 -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER
-// RUN: %clang_cc1 -fsanitize=implicit-integer-truncation -fsanitize-recover=implicit-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER
-// RUN: %clang_cc1 -fsanitize=implicit-integer-truncation -fsanitize-trap=implicit-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP
+// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fno-sanitize-recover=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER
+// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fsanitize-recover=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER
+// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fsanitize-trap=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP
extern "C" { // Disable name mangling.
diff --git a/test/CodeGenCXX/catch-undef-behavior.cpp b/test/CodeGenCXX/catch-undef-behavior.cpp
index 4513936e49a3..0e8d4fa51a0c 100644
--- a/test/CodeGenCXX/catch-undef-behavior.cpp
+++ b/test/CodeGenCXX/catch-undef-behavior.cpp
@@ -72,7 +72,7 @@ void member_access(S *p) {
// The two hash values are for 64- and 32-bit Clang binaries, respectively.
// FIXME: We should produce a 64-bit value either way.
//
- // CHECK-NEXT: xor i64 {{-4030275160588942838|2562089159}}, %[[VPTR]]
+ // CHECK-NEXT: xor i64 {{-4030275160588942838|1107558922}}, %[[VPTR]]
// CHECK-NEXT: mul i64 {{.*}}, -7070675565921424023
// CHECK-NEXT: lshr i64 {{.*}}, 47
// CHECK-NEXT: xor i64
@@ -121,7 +121,7 @@ void member_access(S *p) {
// (3b) Check that 'p' actually points to an 'S'
// CHECK: load i64, i64*
- // CHECK-NEXT: xor i64 {{-4030275160588942838|2562089159}},
+ // CHECK-NEXT: xor i64 {{-4030275160588942838|1107558922}},
// [...]
// CHECK: getelementptr inbounds [128 x i64], [128 x i64]* @__ubsan_vptr_type_cache, i32 0, i64 %
// CHECK: br i1
@@ -520,6 +520,49 @@ void upcast_to_vbase() {
}
}
+struct nothrow {};
+void *operator new[](__SIZE_TYPE__, nothrow) noexcept;
+
+namespace NothrowNew {
+ struct X { X(); };
+
+ // CHECK-LABEL: define{{.*}}nothrow_new_trivial
+ void *nothrow_new_trivial() {
+ // CHECK: %[[is_null:.*]] = icmp eq i8*{{.*}}, null
+ // CHECK: br i1 %[[is_null]], label %[[null:.*]], label %[[nonnull:.*]]
+
+ // CHECK: [[nonnull]]:
+ // CHECK: llvm.objectsize
+ // CHECK: br i1
+ //
+ // CHECK: call {{.*}}__ubsan_handle_type_mismatch
+ //
+ // CHECK: [[null]]:
+ // CHECK-NOT: {{ }}br{{ }}
+ // CHECK: ret
+ return new (nothrow{}) char[123456];
+ }
+
+ // CHECK-LABEL: define{{.*}}nothrow_new_nontrivial
+ void *nothrow_new_nontrivial() {
+ // CHECK: %[[is_null:.*]] = icmp eq i8*{{.*}}, null
+ // CHECK: br i1 %[[is_null]], label %[[null:.*]], label %[[nonnull:.*]]
+
+ // CHECK: [[nonnull]]:
+ // CHECK: llvm.objectsize
+ // CHECK: br i1
+ //
+ // CHECK: call {{.*}}__ubsan_handle_type_mismatch
+ //
+ // CHECK: call {{.*}}_ZN10NothrowNew1XC1Ev
+ //
+ // CHECK: [[null]]:
+ // CHECK-NOT: {{ }}br{{ }}
+ // CHECK: ret
+ return new (nothrow{}) X[123456];
+ }
+}
+
struct ThisAlign {
void this_align_lambda();
void this_align_lambda_2();
diff --git a/test/CodeGenCXX/cfi-cross-dso.cpp b/test/CodeGenCXX/cfi-cross-dso.cpp
index 6d5e0591191c..4b7b3d70f098 100644
--- a/test/CodeGenCXX/cfi-cross-dso.cpp
+++ b/test/CodeGenCXX/cfi-cross-dso.cpp
@@ -26,7 +26,7 @@ void g() {
b.f();
}
-// MS: @[[B_VTABLE:.*]] = private unnamed_addr constant { [2 x i8*] } {{.*}}@"??_R4B@?A@@6B@"{{.*}}@"?f@B@?A@@UEAAXXZ"
+// MS: @[[B_VTABLE:.*]] = private unnamed_addr constant { [2 x i8*] } {{.*}}@"??_R4B@?A0x{{[^@]*}}@@6B@"{{.*}}@"?f@B@?A0x{{[^@]*}}@@UEAAXXZ"
// CHECK: %[[VT:.*]] = load void (%struct.A*)**, void (%struct.A*)***
// CHECK: %[[VT2:.*]] = bitcast {{.*}}%[[VT]] to i8*, !nosanitize
diff --git a/test/CodeGenCXX/cfi-icall.cpp b/test/CodeGenCXX/cfi-icall.cpp
index e53aeefd8a9b..00c9f59700ac 100644
--- a/test/CodeGenCXX/cfi-icall.cpp
+++ b/test/CodeGenCXX/cfi-icall.cpp
@@ -21,7 +21,7 @@ void g() {
}
// ITANIUM: define internal void @_ZN12_GLOBAL__N_11fENS_1SE({{.*}} !type [[TS1:![0-9]+]] !type [[TS2:![0-9]+]]
-// MS: define internal void @"?f@?A@@YAXUS@?A@@@Z"({{.*}} !type [[TS1:![0-9]+]] !type [[TS2:![0-9]+]]
+// MS: define internal void @"?f@?A0x{{[^@]*}}@@YAXUS@?A0x{{[^@]*}}@@@Z"({{.*}} !type [[TS1:![0-9]+]] !type [[TS2:![0-9]+]]
// CHECK: [[VOIDS1]] = distinct !{}
// CHECK: [[TS1]] = !{i64 0, [[VOIDS1]]}
diff --git a/test/CodeGenCXX/conditional-temporaries.cpp b/test/CodeGenCXX/conditional-temporaries.cpp
index e08de61f9d41..48c911788265 100644
--- a/test/CodeGenCXX/conditional-temporaries.cpp
+++ b/test/CodeGenCXX/conditional-temporaries.cpp
@@ -1,6 +1,7 @@
// REQUIRES: amdgpu-registered-target
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -O3 | FileCheck %s
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=amdgcn-amd-amdhsa -O3 | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -O2 -disable-llvm-passes | FileCheck %s --check-prefixes=CHECK,CHECK-NOOPT
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -O2 | FileCheck %s --check-prefixes=CHECK,CHECK-OPT
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=amdgcn-amd-amdhsa -O2 | FileCheck %s --check-prefixes=CHECK,CHECK-OPT
namespace {
@@ -38,20 +39,167 @@ Checker c;
}
-// CHECK-LABEL: define i32 @_Z12getCtorCallsv()
+// CHECK-OPT-LABEL: define i32 @_Z12getCtorCallsv()
int getCtorCalls() {
- // CHECK: ret i32 5
+ // CHECK-OPT: ret i32 5
return ctorcalls;
}
-// CHECK-LABEL: define i32 @_Z12getDtorCallsv()
+// CHECK-OPT-LABEL: define i32 @_Z12getDtorCallsv()
int getDtorCalls() {
- // CHECK: ret i32 5
+ // CHECK-OPT: ret i32 5
return dtorcalls;
}
-// CHECK-LABEL: define zeroext i1 @_Z7successv()
+// CHECK-OPT-LABEL: define zeroext i1 @_Z7successv()
bool success() {
- // CHECK: ret i1 true
+ // CHECK-OPT: ret i1 true
return ctorcalls == dtorcalls;
}
+
+struct X { ~X(); int f(); };
+int g(int, int, int);
+// CHECK-LABEL: @_Z16lifetime_nontriv
+int lifetime_nontriv(bool cond) {
+ // CHECK-NOOPT: store i1 false,
+ // CHECK-NOOPT: store i1 false,
+ // CHECK-NOOPT: store i1 false,
+ // CHECK-NOOPT: store i1 false,
+ // CHECK-NOOPT: store i1 false,
+ // CHECK-NOOPT: store i1 false,
+ // CHECK-NOOPT: br i1
+ //
+ // CHECK-NOOPT: call void @llvm.lifetime.start
+ // CHECK-NOOPT: store i1 true,
+ // CHECK-NOOPT: store i1 true,
+ // CHECK-NOOPT: call i32 @_ZN1X1fEv(
+ // CHECK-NOOPT: call void @llvm.lifetime.start
+ // CHECK-NOOPT: store i1 true,
+ // CHECK-NOOPT: store i1 true,
+ // CHECK-NOOPT: call i32 @_ZN1X1fEv(
+ // CHECK-NOOPT: call void @llvm.lifetime.start
+ // CHECK-NOOPT: store i1 true,
+ // CHECK-NOOPT: store i1 true,
+ // CHECK-NOOPT: call i32 @_ZN1X1fEv(
+ // CHECK-NOOPT: call i32 @_Z1giii(
+ // CHECK-NOOPT: br label
+ //
+ // CHECK-NOOPT: call i32 @_Z1giii(i32 1, i32 2, i32 3)
+ // CHECK-NOOPT: br label
+ //
+ // CHECK-NOOPT: load i1,
+ // CHECK-NOOPT: br i1
+ // CHECK-NOOPT: call void @_ZN1XD1Ev(
+ // CHECK-NOOPT: br label
+ //
+ // CHECK-NOOPT: load i1,
+ // CHECK-NOOPT: br i1
+ // CHECK-NOOPT: call void @llvm.lifetime.end
+ // CHECK-NOOPT: br label
+ //
+ // CHECK-NOOPT: load i1,
+ // CHECK-NOOPT: br i1
+ // CHECK-NOOPT: call void @_ZN1XD1Ev(
+ // CHECK-NOOPT: br label
+ //
+ // CHECK-NOOPT: load i1,
+ // CHECK-NOOPT: br i1
+ // CHECK-NOOPT: call void @llvm.lifetime.end
+ // CHECK-NOOPT: br label
+ //
+ // CHECK-NOOPT: load i1,
+ // CHECK-NOOPT: br i1
+ // CHECK-NOOPT: call void @_ZN1XD1Ev(
+ // CHECK-NOOPT: br label
+ //
+ // CHECK-NOOPT: load i1,
+ // CHECK-NOOPT: br i1
+ // CHECK-NOOPT: call void @llvm.lifetime.end
+ // CHECK-NOOPT: br label
+ //
+ // CHECK-NOOPT: ret
+
+ // CHECK-OPT: br i1
+ //
+ // CHECK-OPT: call void @llvm.lifetime.start
+ // CHECK-OPT: call i32 @_ZN1X1fEv(
+ // CHECK-OPT: call void @llvm.lifetime.start
+ // CHECK-OPT: call i32 @_ZN1X1fEv(
+ // CHECK-OPT: call void @llvm.lifetime.start
+ // CHECK-OPT: call i32 @_ZN1X1fEv(
+ // CHECK-OPT: call i32 @_Z1giii(
+ // CHECK-OPT: call void @_ZN1XD1Ev(
+ // CHECK-OPT: call void @llvm.lifetime.end
+ // CHECK-OPT: call void @_ZN1XD1Ev(
+ // CHECK-OPT: call void @llvm.lifetime.end
+ // CHECK-OPT: call void @_ZN1XD1Ev(
+ // CHECK-OPT: call void @llvm.lifetime.end
+ // CHECK-OPT: br label
+ return cond ? g(X().f(), X().f(), X().f()) : g(1, 2, 3);
+}
+
+struct Y { int f(); };
+int g(int, int, int);
+// CHECK-LABEL: @_Z13lifetime_triv
+int lifetime_triv(bool cond) {
+ // CHECK-NOOPT: call void @llvm.lifetime.start
+ // CHECK-NOOPT: call void @llvm.lifetime.start
+ // CHECK-NOOPT: call void @llvm.lifetime.start
+ // CHECK-NOOPT: br i1
+ //
+ // CHECK-NOOPT: call i32 @_ZN1Y1fEv(
+ // CHECK-NOOPT: call i32 @_ZN1Y1fEv(
+ // CHECK-NOOPT: call i32 @_ZN1Y1fEv(
+ // CHECK-NOOPT: call i32 @_Z1giii(
+ // CHECK-NOOPT: br label
+ //
+ // CHECK-NOOPT: call i32 @_Z1giii(i32 1, i32 2, i32 3)
+ // CHECK-NOOPT: br label
+ //
+ // CHECK-NOOPT: call void @llvm.lifetime.end
+ // CHECK-NOOPT-NOT: br
+ // CHECK-NOOPT: call void @llvm.lifetime.end
+ // CHECK-NOOPT-NOT: br
+ // CHECK-NOOPT: call void @llvm.lifetime.end
+ //
+ // CHECK-NOOPT: ret
+
+ // FIXME: LLVM isn't smart enough to remove the lifetime markers from the
+ // g(1, 2, 3) path here.
+
+ // CHECK-OPT: call void @llvm.lifetime.start
+ // CHECK-OPT: call void @llvm.lifetime.start
+ // CHECK-OPT: call void @llvm.lifetime.start
+ // CHECK-OPT: br i1
+ //
+ // CHECK-OPT: call i32 @_ZN1Y1fEv(
+ // CHECK-OPT: call i32 @_ZN1Y1fEv(
+ // CHECK-OPT: call i32 @_ZN1Y1fEv(
+ // CHECK-OPT: call i32 @_Z1giii(
+ // CHECK-OPT: br label
+ //
+ // CHECK-OPT: call void @llvm.lifetime.end
+ // CHECK-OPT: call void @llvm.lifetime.end
+ // CHECK-OPT: call void @llvm.lifetime.end
+ return cond ? g(Y().f(), Y().f(), Y().f()) : g(1, 2, 3);
+}
+
+struct Z { ~Z() {} int f(); };
+int g(int, int, int);
+// CHECK-LABEL: @_Z22lifetime_nontriv_empty
+int lifetime_nontriv_empty(bool cond) {
+ // CHECK-OPT: br i1
+ //
+ // CHECK-OPT: call void @llvm.lifetime.start
+ // CHECK-OPT: call i32 @_ZN1Z1fEv(
+ // CHECK-OPT: call void @llvm.lifetime.start
+ // CHECK-OPT: call i32 @_ZN1Z1fEv(
+ // CHECK-OPT: call void @llvm.lifetime.start
+ // CHECK-OPT: call i32 @_ZN1Z1fEv(
+ // CHECK-OPT: call i32 @_Z1giii(
+ // CHECK-OPT: call void @llvm.lifetime.end
+ // CHECK-OPT: call void @llvm.lifetime.end
+ // CHECK-OPT: call void @llvm.lifetime.end
+ // CHECK-OPT: br label
+ return cond ? g(Z().f(), Z().f(), Z().f()) : g(1, 2, 3);
+}
diff --git a/test/CodeGenCXX/const-init-cxx11.cpp b/test/CodeGenCXX/const-init-cxx11.cpp
index 801d7b1e19cc..9fb4ba5fe178 100644
--- a/test/CodeGenCXX/const-init-cxx11.cpp
+++ b/test/CodeGenCXX/const-init-cxx11.cpp
@@ -402,7 +402,7 @@ namespace UnemittedTemporaryDecl {
// CHECK: @_ZZN12LocalVarInit3aggEvE1a = internal constant {{.*}} i32 101
// CHECK: @_ZZN12LocalVarInit4ctorEvE1a = internal constant {{.*}} i32 102
-// CHECK: @_ZZN12LocalVarInit8mutable_EvE1a = private unnamed_addr constant {{.*}} i32 103
+// CHECK: @__const._ZN12LocalVarInit8mutable_Ev.a = private unnamed_addr constant {{.*}} i32 103
// CHECK: @_ZGRN33ClassTemplateWithStaticDataMember1SIvE1aE_ = linkonce_odr constant i32 5, comdat
// CHECK: @_ZN33ClassTemplateWithStaticDataMember3useE = constant i32* @_ZGRN33ClassTemplateWithStaticDataMember1SIvE1aE_
// CHECK: @_ZGRN39ClassTemplateWithHiddenStaticDataMember1SIvE1aE_ = linkonce_odr hidden constant i32 5, comdat
@@ -461,7 +461,7 @@ namespace LocalVarInit {
// CHECK: define {{.*}} @_ZN12LocalVarInit8mutable_Ev
// CHECK-NOT: call
- // CHECK: call {{.*}}memcpy{{.*}} @_ZZN12LocalVarInit8mutable_EvE1a
+ // CHECK: call {{.*}}memcpy{{.*}} @__const._ZN12LocalVarInit8mutable_Ev.a
// CHECK-NOT: call
// Can't fold return value due to 'mutable'.
// CHECK-NOT: ret i32 103
diff --git a/test/CodeGenCXX/crash.cpp b/test/CodeGenCXX/crash.cpp
index d12c021a6dcc..63bca484b5dd 100644
--- a/test/CodeGenCXX/crash.cpp
+++ b/test/CodeGenCXX/crash.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 %s -std=c++11 -emit-llvm-only
// RUN: %clang_cc1 -emit-obj -o %t -debug-info-kind=line-tables-only -std=c++11 %s
+// RUN: %clang_cc1 -emit-obj -o %t -debug-info-kind=line-directives-only -std=c++11 %s
// CHECK that we don't crash.
// PR11676's example is ill-formed:
diff --git a/test/CodeGenCXX/cxx-block-objects.cpp b/test/CodeGenCXX/cxx-block-objects.cpp
index ff868fcdd06f..d28bcb670fd2 100644
--- a/test/CodeGenCXX/cxx-block-objects.cpp
+++ b/test/CodeGenCXX/cxx-block-objects.cpp
@@ -25,9 +25,9 @@ main()
return 0;
}
-// CHECK-LABEL: define internal void @__copy_helper_block_
+// CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block_
// CHECK: call void @_ZN1AC1ERKS_
-// CHECK-LABEL:define internal void @__destroy_helper_block_
+// CHECK-LABEL:define linkonce_odr hidden void @__destroy_helper_block_
// CHECK: call void @_ZN1AD1Ev
diff --git a/test/CodeGenCXX/cxx11-thread-local.cpp b/test/CodeGenCXX/cxx11-thread-local.cpp
index 70f5a47fd3b8..156c4f591908 100644
--- a/test/CodeGenCXX/cxx11-thread-local.cpp
+++ b/test/CodeGenCXX/cxx11-thread-local.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck --check-prefix=CHECK --check-prefix=LINUX %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -O2 -disable-llvm-passes -o - -triple x86_64-linux-gnu | FileCheck --check-prefix=CHECK --check-prefix=LINUX --check-prefix=CHECK-OPT %s
// RUN: %clang_cc1 -std=c++11 -femulated-tls -emit-llvm %s -o - \
// RUN: -triple x86_64-linux-gnu 2>&1 | FileCheck --check-prefix=CHECK --check-prefix=LINUX %s
// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-apple-darwin12 | FileCheck --check-prefix=CHECK --check-prefix=DARWIN %s
@@ -307,6 +308,7 @@ void set_anon_i() {
// CHECK: br i1 %[[NEED_TLS_INIT]],
// init:
// CHECK: store i8 1, i8* @__tls_guard
+// CHECK-OPT: call {}* @llvm.invariant.start.p0i8(i64 1, i8* @__tls_guard)
// CHECK-NOT: call void @[[V_M_INIT]]()
// CHECK: call void @[[A_INIT]]()
// CHECK-NOT: call void @[[V_M_INIT]]()
diff --git a/test/CodeGenCXX/cxx1y-init-captures.cpp b/test/CodeGenCXX/cxx1y-init-captures.cpp
index dcfe4d47292d..c76180c5bf43 100644
--- a/test/CodeGenCXX/cxx1y-init-captures.cpp
+++ b/test/CodeGenCXX/cxx1y-init-captures.cpp
@@ -38,6 +38,19 @@ void g() {
// CHECK: add nsw i32
+// CHECK-LABEL: define void @_Z18init_capture_dtorsv
+void init_capture_dtors() {
+ // Ensure that init-captures are not treated as separate full-expressions.
+ struct HasDtor { ~HasDtor() {} };
+ void some_function_call();
+ void other_function_call();
+ // CHECK: call {{.*}}some_function_call
+ // CHECK: call {{.*}}HasDtorD
+ ([x = (HasDtor(), 0)]{}, some_function_call());
+ // CHECK: call {{.*}}other_function_call
+ other_function_call();
+}
+
int h(int a) {
// CHECK-LABEL: define i32 @_Z1hi(
// CHECK: %[[A_ADDR:.*]] = alloca i32,
diff --git a/test/CodeGenCXX/cxx2a-init-statement.cpp b/test/CodeGenCXX/cxx2a-init-statement.cpp
new file mode 100644
index 000000000000..2d45c8554451
--- /dev/null
+++ b/test/CodeGenCXX/cxx2a-init-statement.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -std=c++2a -triple x86_64-apple-macosx10.7.0 -emit-llvm -o - %s -w | FileCheck %s
+
+// CHECK: @__const._Z1fv.arr = private unnamed_addr constant [3 x i32] [i32 1, i32 2, i32 3], align 4
+
+void f() {
+ // CHECK: %[[ARR:.*]] = alloca [3 x i32], align 4
+ // CHECK: call void @llvm.memcpy{{.*}}({{.*}} @__const._Z1fv.arr
+ for (int arr[3] = {1, 2, 3}; int a : arr)
+ ;
+}
diff --git a/test/CodeGenCXX/dbg-info-all-calls-described.cpp b/test/CodeGenCXX/dbg-info-all-calls-described.cpp
new file mode 100644
index 000000000000..547c2707226d
--- /dev/null
+++ b/test/CodeGenCXX/dbg-info-all-calls-described.cpp
@@ -0,0 +1,61 @@
+// Test that call site debug info is (un)supported in various configurations.
+
+// Supported: DWARF5, -O1, standalone DI
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - \
+// RUN: -O1 -disable-llvm-passes \
+// RUN: -debug-info-kind=standalone -dwarf-version=5 \
+// RUN: | FileCheck %s -check-prefix=HAS-ATTR \
+// RUN: -implicit-check-not=DISubprogram -implicit-check-not=DIFlagAllCallsDescribed
+
+// Supported: DWARF4 + LLDB tuning, -O1, limited DI
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - \
+// RUN: -O1 -disable-llvm-passes \
+// RUN: -debugger-tuning=lldb \
+// RUN: -debug-info-kind=standalone -dwarf-version=4 \
+// RUN: | FileCheck %s -check-prefix=HAS-ATTR \
+// RUN: -implicit-check-not=DISubprogram -implicit-check-not=DIFlagAllCallsDescribed
+
+// Supported: DWARF4 + LLDB tuning, -O1, line-tables only DI
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - \
+// RUN: -O1 -disable-llvm-passes \
+// RUN: -debugger-tuning=lldb \
+// RUN: -debug-info-kind=line-tables-only -dwarf-version=4 \
+// RUN: | FileCheck %s -check-prefix=LINE-TABLES-ONLY
+
+// Unsupported: -O0
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - \
+// RUN: -O0 \
+// RUN: -debug-info-kind=standalone -dwarf-version=5 \
+// RUN: | FileCheck %s -check-prefix=NO-ATTR
+
+// Unsupported: DWARF4
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - \
+// RUN: -O1 -disable-llvm-passes \
+// RUN: -debug-info-kind=standalone -dwarf-version=4 \
+// RUN: | FileCheck %s -check-prefix=NO-ATTR
+
+// NO-ATTR-NOT: FlagAllCallsDescribed
+
+// HAS-ATTR-DAG: DISubprogram(name: "declaration2", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition
+// HAS-ATTR-DAG: DISubprogram(name: "struct1", {{.*}}, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized)
+// HAS-ATTR-DAG: DISubprogram(name: "struct1", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition
+// HAS-ATTR-DAG: DISubprogram(name: "method1", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition
+// HAS-ATTR-DAG: DISubprogram(name: "force_irgen", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition
+
+// LINE-TABLES-ONLY: DISubprogram(name: "force_irgen", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition
+
+void declaration1();
+
+void declaration2();
+
+void declaration2() {}
+
+struct struct1 {
+ struct1() {}
+ void method1() {}
+};
+
+void __attribute__((optnone)) force_irgen() {
+ declaration1();
+ struct1().method1();
+}
diff --git a/test/CodeGenCXX/debug-info-access.cpp b/test/CodeGenCXX/debug-info-access.cpp
index 44d6b4da17a3..0759ee1d13bd 100644
--- a/test/CodeGenCXX/debug-info-access.cpp
+++ b/test/CodeGenCXX/debug-info-access.cpp
@@ -35,8 +35,8 @@ private:
// CHECK: !DISubprogram(name: "free",
-// CHECK-SAME: isDefinition: true
// CHECK-SAME: flags: DIFlagPrototyped,
+// CHECK-SAME: spFlags: DISPFlagDefinition
void free() {}
U u;
diff --git a/test/CodeGenCXX/debug-info-blocks.cpp b/test/CodeGenCXX/debug-info-blocks.cpp
index ed0d659eeae1..7eea3ce09649 100644
--- a/test/CodeGenCXX/debug-info-blocks.cpp
+++ b/test/CodeGenCXX/debug-info-blocks.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 %s -debug-info-kind=line-tables-only -fblocks -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -debug-info-kind=line-directives-only -fblocks -S -emit-llvm -o - | FileCheck %s
struct A {
A();
@@ -8,11 +9,12 @@ struct A {
void test() {
__block A a;
+ ^{ (void)a; };
}
// CHECK: !DISubprogram(name: "__Block_byref_object_copy_",
-// CHECK-SAME: line: 10,
-// CHECK-SAME: isLocal: true, isDefinition: true
+// CHECK-SAME: line: 11,
+// CHECK-SAME: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK: !DISubprogram(name: "__Block_byref_object_dispose_",
-// CHECK-SAME: line: 10,
-// CHECK-SAME: isLocal: true, isDefinition: true
+// CHECK-SAME: line: 11,
+// CHECK-SAME: DISPFlagLocalToUnit | DISPFlagDefinition
diff --git a/test/CodeGenCXX/debug-info-byval.cpp b/test/CodeGenCXX/debug-info-byval.cpp
index 5b0850b9643c..38f803d6d9bb 100644
--- a/test/CodeGenCXX/debug-info-byval.cpp
+++ b/test/CodeGenCXX/debug-info-byval.cpp
@@ -1,5 +1,5 @@
// FIXME: Check IR rather than asm, then triple is not needed.
-// RUN: %clang -Xclang -triple=%itanium_abi_triple -g -S %s -o - | FileCheck %s
+// RUN: %clang --target=%itanium_abi_triple -g -S %s -o - | FileCheck %s
// Test to check presence of debug info for byval parameter.
// Radar 8350436.
class DAG {
diff --git a/test/CodeGenCXX/debug-info-class-limited-plugin.test b/test/CodeGenCXX/debug-info-class-limited-plugin.test
index 533c2f6b16c5..17248d5743da 100644
--- a/test/CodeGenCXX/debug-info-class-limited-plugin.test
+++ b/test/CodeGenCXX/debug-info-class-limited-plugin.test
@@ -1,2 +1,2 @@
-RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -o - -load %llvmshlibdir/PrintFunctionNames%pluginext -add-plugin print-function-names %S/Inputs/debug-info-class-limited.cpp 2>&1 | FileCheck %S/Inputs/debug-info-class-limited.cpp
+RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -o - -load %llvmshlibdir/PrintFunctionNames%pluginext -add-plugin print-fns %S/Inputs/debug-info-class-limited.cpp 2>&1 | FileCheck %S/Inputs/debug-info-class-limited.cpp
REQUIRES: plugins, examples
diff --git a/test/CodeGenCXX/debug-info-ctor2.cpp b/test/CodeGenCXX/debug-info-ctor2.cpp
index 3bc931e98448..95b0608dadc8 100644
--- a/test/CodeGenCXX/debug-info-ctor2.cpp
+++ b/test/CodeGenCXX/debug-info-ctor2.cpp
@@ -1,5 +1,5 @@
// FIXME: Check IR rather than asm, then triple is not needed.
-// RUN: %clang -Xclang -triple=%itanium_abi_triple -fverbose-asm -g -S %s -o - | grep AT_explicit
+// RUN: %clang --target=%itanium_abi_triple -fverbose-asm -g -S %s -o - | grep AT_explicit
class MyClass
diff --git a/test/CodeGenCXX/debug-info-cxx1y.cpp b/test/CodeGenCXX/debug-info-cxx1y.cpp
index 403424e2d6a8..f1298b1d858c 100644
--- a/test/CodeGenCXX/debug-info-cxx1y.cpp
+++ b/test/CodeGenCXX/debug-info-cxx1y.cpp
@@ -18,12 +18,12 @@
// FIXME: The context of this definition should be the CU/file scope, not the class.
// CHECK: !DISubprogram(name: "func", {{.*}} scope: [[FOO]]
// CHECK-SAME: type: [[SUBROUTINE_TYPE]]
-// CHECK-SAME: isDefinition: true
+// CHECK-SAME: DISPFlagDefinition
// CHECK-SAME: declaration: [[FUNC_DECL:![0-9]*]]
// CHECK: [[FUNC_DECL]] = !DISubprogram(name: "func",
// CHECK-SAME: scope: [[FOO]]
// CHECK-SAME: type: [[SUBROUTINE_TYPE]]
-// CHECK-SAME: isDefinition: false
+// CHECK-SAME: spFlags: 0
struct foo {
static auto func();
diff --git a/test/CodeGenCXX/debug-info-decl-nested.cpp b/test/CodeGenCXX/debug-info-decl-nested.cpp
index feab1d709094..5345ff2dff94 100644
--- a/test/CodeGenCXX/debug-info-decl-nested.cpp
+++ b/test/CodeGenCXX/debug-info-decl-nested.cpp
@@ -19,13 +19,13 @@ class OuterClass
} theInnerClass;
// CHECK0: ![[DECL:[0-9]+]] = !DISubprogram(name: "OuterClass"
// CHECK0-SAME: line: [[@LINE+2]]
-// CHECK0-SAME: isDefinition: false
+// CHECK0-SAME: spFlags: 0
OuterClass(const Foo *); // line 10
};
OuterClass::InnerClass OuterClass::theInnerClass; // This toplevel decl causes InnerClass to be generated.
// CHECK0: !DISubprogram(name: "OuterClass"
// CHECK0-SAME: line: [[@LINE+3]]
-// CHECK0-SAME: isDefinition: true
+// CHECK0-SAME: DISPFlagDefinition
// CHECK0-SAME: declaration: ![[DECL]]
OuterClass::OuterClass(const Foo *meta) { } // line 13
@@ -43,13 +43,13 @@ class OuterClass1
} theInnerClass1;
// CHECK1: ![[DECL:[0-9]+]] = !DISubprogram(name: "Bar"
// CHECK1-SAME: line: [[@LINE+2]]
-// CHECK1-SAME: isDefinition: false
+// CHECK1-SAME: spFlags: 0
void Bar(const Foo1 *);
};
OuterClass1::InnerClass1 OuterClass1::theInnerClass1;
// CHECK1: !DISubprogram(name: "Bar"
// CHECK1-SAME: line: [[@LINE+3]]
-// CHECK1-SAME: isDefinition: true
+// CHECK1-SAME: DISPFlagDefinition
// CHECK1-SAME: declaration: ![[DECL]]
void OuterClass1::Bar(const Foo1 *meta) { }
@@ -66,12 +66,12 @@ class OuterClass2
} theInnerClass2;
// CHECK2: ![[DECL:[0-9]+]] = !DISubprogram(name: "~OuterClass2"
// CHECK2-SAME: line: [[@LINE+2]]
-// CHECK2-SAME: isDefinition: false
+// CHECK2-SAME: spFlags: 0
~OuterClass2(); // line 10
};
OuterClass2::InnerClass2 OuterClass2::theInnerClass2;
// CHECK4: !DISubprogram(name: "~OuterClass2"
// CHECK4-SAME: line: [[@LINE+3]]
-// CHECK4-SAME: isDefinition: true
+// CHECK4-SAME: DISPFlagDefinition
// CHECK4-SAME: declaration: ![[DECL]]
OuterClass2::~OuterClass2() { }
diff --git a/test/CodeGenCXX/debug-info-enum-class.cpp b/test/CodeGenCXX/debug-info-enum-class.cpp
index e857bb195913..3664c67bf360 100644
--- a/test/CodeGenCXX/debug-info-enum-class.cpp
+++ b/test/CodeGenCXX/debug-info-enum-class.cpp
@@ -15,7 +15,7 @@ D d;
// CHECK-SAME: baseType: ![[INT:[0-9]+]]
// CHECK-SAME: size: 32
// CHECK-NOT: offset:
-// CHECK-SAME: flags: DIFlagFixedEnum
+// CHECK-SAME: flags: DIFlagEnumClass
// CHECK-SAME: ){{$}}
// CHECK: ![[INT]] = !DIBasicType(name: "int"
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "B"
@@ -23,7 +23,7 @@ D d;
// CHECK-SAME: baseType: ![[ULONG:[0-9]+]]
// CHECK-SAME: size: 64
// CHECK-NOT: offset:
-// CHECK-SAME: flags: DIFlagFixedEnum
+// CHECK-SAME: flags: DIFlagEnumClass
// CHECK-SAME: ){{$}}
// CHECK: ![[ULONG]] = !DIBasicType(name: "long unsigned int"
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "C"
@@ -52,6 +52,7 @@ namespace test2 {
// FIXME: this should just be a declaration under -fno-standalone-debug
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E"
// CHECK-SAME: scope: [[TEST2:![0-9]+]]
+// CHECK-NOT: DIFlagEnumClass
// CHECK-SAME: elements: [[TEST_ENUMS:![0-9]+]]
// CHECK-SAME: identifier: "_ZTSN5test21EE"
// CHECK: [[TEST2]] = !DINamespace(name: "test2"
@@ -67,6 +68,7 @@ namespace test3 {
// FIXME: this should just be a declaration under -fno-standalone-debug
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E"
// CHECK-SAME: scope: [[TEST3:![0-9]+]]
+// CHECK-NOT: DIFlagEnumClass
// CHECK-SAME: elements: [[TEST_ENUMS]]
// CHECK-SAME: identifier: "_ZTSN5test31EE"
// CHECK: [[TEST3]] = !DINamespace(name: "test3"
@@ -78,6 +80,7 @@ void func(E *) {
namespace test4 {
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E"
// CHECK-SAME: scope: [[TEST4:![0-9]+]]
+// CHECK-NOT: DIFlagEnumClass
// CHECK-SAME: elements: [[TEST_ENUMS]]
// CHECK-SAME: identifier: "_ZTSN5test41EE"
// CHECK: [[TEST4]] = !DINamespace(name: "test4"
diff --git a/test/CodeGenCXX/debug-info-function-context.cpp b/test/CodeGenCXX/debug-info-function-context.cpp
index 1db62d96d5b6..40a6643e71f9 100644
--- a/test/CodeGenCXX/debug-info-function-context.cpp
+++ b/test/CodeGenCXX/debug-info-function-context.cpp
@@ -28,10 +28,10 @@ int global_namespace_variable = 1;
// CHECK: ![[FILE:[0-9]+]] = !DIFile(filename: "{{.*}}context.cpp",
// CHECK: ![[C:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "C",
// CHECK: ![[NS:.*]] = !DINamespace(name: "ns"
-// CHECK: !DISubprogram(name: "member_function",{{.*}} scope: ![[C]],{{.*}} isDefinition: true
+// CHECK: !DISubprogram(name: "member_function",{{.*}} scope: ![[C]],{{.*}} DISPFlagDefinition
-// CHECK: !DISubprogram(name: "static_member_function",{{.*}} scope: ![[C]],{{.*}} isDefinition: true
+// CHECK: !DISubprogram(name: "static_member_function",{{.*}} scope: ![[C]],{{.*}} DISPFlagDefinition
-// CHECK: !DISubprogram(name: "global_function",{{.*}} scope: ![[FILE]],{{.*}} isDefinition: true
+// CHECK: !DISubprogram(name: "global_function",{{.*}} scope: ![[FILE]],{{.*}} DISPFlagDefinition
-// CHECK: !DISubprogram(name: "global_namespace_function",{{.*}} scope: ![[NS]],{{.*}} isDefinition: true
+// CHECK: !DISubprogram(name: "global_namespace_function",{{.*}} scope: ![[NS]],{{.*}} DISPFlagDefinition
diff --git a/test/CodeGenCXX/debug-info-gline-tables-only.cpp b/test/CodeGenCXX/debug-info-gline-tables-only.cpp
index d98b27872d62..ceb7856addc6 100644
--- a/test/CodeGenCXX/debug-info-gline-tables-only.cpp
+++ b/test/CodeGenCXX/debug-info-gline-tables-only.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 %s -fno-rtti -debug-info-kind=line-tables-only -S -emit-llvm -o - | FileCheck %s
-// Checks that clang with "-gline-tables-only" doesn't emit debug info
+// RUN: %clang_cc1 %s -fno-rtti -debug-info-kind=line-directives-only -S -emit-llvm -o - | FileCheck %s
+// Checks that clang with "-gline-tables-only" or "-gline-directives-only" doesn't emit debug info
// for variables and types.
// CHECK-NOT: DW_TAG_namespace
diff --git a/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp b/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp
index 7b57c08a1097..0ede3c6e48b7 100644
--- a/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp
+++ b/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp
@@ -16,12 +16,12 @@ void foo() {
static A stat;
}
-// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_var_init",{{.*}} line: 12,{{.*}} isLocal: true, isDefinition: true
-// CHECK-NOKEXT: !DISubprogram(name: "__dtor_glob",{{.*}} line: 12,{{.*}} isLocal: true, isDefinition: true
-// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_var_init.1",{{.*}} line: 13,{{.*}} isLocal: true, isDefinition: true
-// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_array_dtor",{{.*}} line: 13,{{.*}} isLocal: true, isDefinition: true
-// CHECK-NOKEXT: !DISubprogram(name: "__dtor_array",{{.*}} line: 13,{{.*}} isLocal: true, isDefinition: true
-// CHECK-NOKEXT: !DISubprogram(name: "__dtor__ZZ3foovE4stat",{{.*}} line: 16,{{.*}} isLocal: true, isDefinition: true
-// CHECK-NOKEXT: !DISubprogram({{.*}} isLocal: true, isDefinition: true
+// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_var_init",{{.*}} line: 12,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram(name: "__dtor_glob",{{.*}} line: 12,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_var_init.1",{{.*}} line: 13,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_array_dtor",{{.*}} line: 13,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram(name: "__dtor_array",{{.*}} line: 13,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram(name: "__dtor__ZZ3foovE4stat",{{.*}} line: 16,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram({{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
-// CHECK-KEXT: !DISubprogram({{.*}} isLocal: true, isDefinition: true
+// CHECK-KEXT: !DISubprogram({{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
diff --git a/test/CodeGenCXX/debug-info-inlined.cpp b/test/CodeGenCXX/debug-info-inlined.cpp
index 53e2cc9289c2..d36715bcfcb6 100644
--- a/test/CodeGenCXX/debug-info-inlined.cpp
+++ b/test/CodeGenCXX/debug-info-inlined.cpp
@@ -26,4 +26,4 @@ B::B() : Forward(WithDtor()) {}
// CHECK-SAME: !dbg ![[INL:[0-9]+]]
// CHECK: ![[INL]] = !DILocation(line: 10, scope: ![[SP:[0-9]+]], inlinedAt:
-// CHECK: ![[SP]] = distinct !DISubprogram(name: "Base", {{.*}}isDefinition: true
+// CHECK: ![[SP]] = distinct !DISubprogram(name: "Base", {{.*}} DISPFlagDefinition
diff --git a/test/CodeGenCXX/debug-info-lambda.cpp b/test/CodeGenCXX/debug-info-lambda.cpp
new file mode 100644
index 000000000000..a10765de3777
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-lambda.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm \
+// RUN: -debug-info-kind=line-tables-only -dwarf-column-info -std=c++11 %s -o - | FileCheck %s
+
+// CHECK-LABEL: define{{.*}}lambda_in_func
+void lambda_in_func(int &ref) {
+ // CHECK: [[ref_slot:%.*]] = getelementptr inbounds %class.anon, %class.anon* {{.*}}, i32 0, i32 0, !dbg [[lambda_decl_loc:![0-9]+]]
+ // CHECK-NEXT: %1 = load i32*, i32** %ref.addr, align {{.*}}, !dbg [[capture_init_loc:![0-9]+]]
+ // CHECK-NEXT: store i32* %1, i32** %0, align {{.*}}, !dbg [[lambda_decl_loc]]
+ // CHECK-NEXT: call {{.*}}void {{.*}}, !dbg [[lambda_call_loc:![0-9]+]]
+
+ auto helper = [ // CHECK: [[lambda_decl_loc]] = !DILocation(line: [[@LINE]], column: 17
+ &]() { // CHECK: [[capture_init_loc]] = !DILocation(line: [[@LINE]], column: 18
+ ++ref;
+ };
+ helper(); // CHECK: [[lambda_call_loc]] = !DILocation(line: [[@LINE]]
+}
diff --git a/test/CodeGenCXX/debug-info-line.cpp b/test/CodeGenCXX/debug-info-line.cpp
index a1c4ef9eea25..100cfa6e5e9a 100644
--- a/test/CodeGenCXX/debug-info-line.cpp
+++ b/test/CodeGenCXX/debug-info-line.cpp
@@ -1,5 +1,7 @@
// RUN: %clang_cc1 -w -debug-info-kind=line-tables-only -std=c++11 -fexceptions -fcxx-exceptions -S -mllvm -no-discriminators -emit-llvm %s -o - -triple %itanium_abi_triple | FileCheck %s
// RUN: %clang_cc1 -w -debug-info-kind=line-tables-only -std=c++11 -fexceptions -fcxx-exceptions -S -mllvm -no-discriminators -emit-llvm %s -o - -triple i686-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 -w -debug-info-kind=line-directives-only -std=c++11 -fexceptions -fcxx-exceptions -S -mllvm -no-discriminators -emit-llvm %s -o - -triple %itanium_abi_triple | FileCheck %s
+// RUN: %clang_cc1 -w -debug-info-kind=line-directives-only -std=c++11 -fexceptions -fcxx-exceptions -S -mllvm -no-discriminators -emit-llvm %s -o - -triple i686-linux-gnu | FileCheck %s
int &src();
int *sink();
diff --git a/test/CodeGenCXX/debug-info-member.cpp b/test/CodeGenCXX/debug-info-member.cpp
index 7ba97b5b54e7..68d02526131b 100644
--- a/test/CodeGenCXX/debug-info-member.cpp
+++ b/test/CodeGenCXX/debug-info-member.cpp
@@ -1,5 +1,5 @@
// FIXME: Check IR rather than asm, then triple is not needed.
-// RUN: %clang -Xclang -triple=%itanium_abi_triple -fverbose-asm -g -S %s -o - | grep DW_ACCESS_public
+// RUN: %clang --target=%itanium_abi_triple -fverbose-asm -g -S %s -o - | grep DW_ACCESS_public
class A {
public:
int x;
diff --git a/test/CodeGenCXX/debug-info-method-spec.cpp b/test/CodeGenCXX/debug-info-method-spec.cpp
index c00da004f456..0c803fdf6bf5 100644
--- a/test/CodeGenCXX/debug-info-method-spec.cpp
+++ b/test/CodeGenCXX/debug-info-method-spec.cpp
@@ -1,5 +1,5 @@
// FIXME: Check IR rather than asm, then triple is not needed.
-// RUN: %clang -Xclang -triple=%itanium_abi_triple -fverbose-asm -g -S %s -o - | grep DW_AT_specification
+// RUN: %clang --target=%itanium_abi_triple -fverbose-asm -g -S %s -o - | grep DW_AT_specification
// Radar 9254491
class A {
public:
diff --git a/test/CodeGenCXX/debug-info-ms-abi.cpp b/test/CodeGenCXX/debug-info-ms-abi.cpp
index e83d7e94230d..0ce13a02e319 100644
--- a/test/CodeGenCXX/debug-info-ms-abi.cpp
+++ b/test/CodeGenCXX/debug-info-ms-abi.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -debug-info-kind=limited -gcodeview -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -debug-info-kind=limited -gcodeview -gcodeview-ghash -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,GHASH
// Tests that certain miscellaneous features work in the MS ABI.
@@ -29,19 +30,25 @@ Foo::Nested n;
// CHECK: ![[vptr_ty]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[vshape]], size: 32
// CHECK: ![[f]] = !DISubprogram(name: "f",
-// CHECK-SAME: containingType: ![[Foo]], virtuality: DW_VIRTUALITY_virtual, virtualIndex: 0,
+// CHECK-SAME: containingType: ![[Foo]], virtualIndex: 0,
// CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual,
+// CHECK-SAME: spFlags: DISPFlagVirtual
// CHECK: ![[g]] = !DISubprogram(name: "g",
-// CHECK-SAME: containingType: ![[Foo]], virtuality: DW_VIRTUALITY_virtual, virtualIndex: 1,
+// CHECK-SAME: containingType: ![[Foo]], virtualIndex: 1,
// CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual,
+// CHECK-SAME: spFlags: DISPFlagVirtual
// CHECK: ![[h]] = !DISubprogram(name: "h",
-// CHECK-SAME: containingType: ![[Foo]], virtuality: DW_VIRTUALITY_virtual, virtualIndex: 2,
+// CHECK-SAME: containingType: ![[Foo]], virtualIndex: 2,
// CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual,
+// CHECK-SAME: spFlags: DISPFlagVirtual
// 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)
+
+// CHECK: !{{[0-9]+}} = !{i32 2, !"CodeView", i32 1}
+// GHASH: !{{[0-9]+}} = !{i32 2, !"CodeViewGHash", i32 1}
diff --git a/test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp b/test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp
index d6fdee62d677..88449c8d6b75 100644
--- a/test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp
+++ b/test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -triple i686--windows -emit-llvm -debug-info-kind=line-tables-only -x c++ %s -fms-extensions -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i686--windows -emit-llvm -debug-info-kind=line-directives-only -x c++ %s -fms-extensions -o - | FileCheck %s
struct __declspec(dllexport) S { virtual ~S(); };
struct __declspec(dllexport) T { virtual ~T(); };
diff --git a/test/CodeGenCXX/debug-info-namespace.cpp b/test/CodeGenCXX/debug-info-namespace.cpp
index 296c99efc8eb..be88feda1112 100644
--- a/test/CodeGenCXX/debug-info-namespace.cpp
+++ b/test/CodeGenCXX/debug-info-namespace.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -std=c++11 -debug-info-kind=limited -S -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -std=c++11 -debug-info-kind=line-tables-only -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-GMLT %s
+// RUN: %clang_cc1 -std=c++11 -debug-info-kind=line-directives-only -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-GMLI %s
// RUN: %clang_cc1 -std=c++11 -debug-info-kind=standalone -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-NOLIMIT %s
namespace A {
@@ -89,7 +90,7 @@ void C::c() {}
// CHECK: [[LEX2]] = distinct !DILexicalBlock(scope: [[LEX1:![0-9]+]], file: [[FOOCPP]],
// CHECK: [[LEX1]] = distinct !DILexicalBlock(scope: [[FUNC:![0-9]+]], file: [[FOOCPP]],
-// CHECK: [[FUNC:![0-9]+]] = distinct !DISubprogram(name: "func",{{.*}} isDefinition: true
+// CHECK: [[FUNC:![0-9]+]] = distinct !DISubprogram(name: "func",{{.*}} DISPFlagDefinition
// CHECK: [[M5]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[FUNC]], entity: [[CTXT:![0-9]+]],
// CHECK: [[M6]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[FOO:![0-9]+]], file: [[FOOCPP]], line: 27)
// CHECK: [[FOO]] = !DICompositeType(tag: DW_TAG_structure_type, name: "foo",
@@ -102,7 +103,7 @@ void C::c() {}
// CHECK: [[M8]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[F1:![0-9]+]]
// CHECK: [[F1:![0-9]+]] = distinct !DISubprogram(name: "f1",{{.*}} line: 4
-// CHECK-SAME: isDefinition: true
+// CHECK-SAME: DISPFlagDefinition
// CHECK: [[M9]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[I]]
// CHECK: [[M10]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[BAZ:![0-9]+]]
// CHECK: [[BAZ]] = !DIDerivedType(tag: DW_TAG_typedef, name: "baz", scope: [[NS]], file: [[FOOCPP]],
@@ -116,15 +117,19 @@ void C::c() {}
// CHECK-SAME: scope: [[NS]], file: [[FOOCPP]], line: 9
// CHECK: [[M15]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[VAR_FWD:![0-9]+]]
// CHECK: [[M16]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[FUNC_FWD:![0-9]+]]
-// CHECK: [[FUNC_FWD]] = distinct !DISubprogram(name: "func_fwd",{{.*}} line: 53,{{.*}} isDefinition: true
+// CHECK: [[FUNC_FWD]] = distinct !DISubprogram(name: "func_fwd",{{.*}} line: 53,{{.*}} DISPFlagDefinition
// CHECK: [[M17]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[CTXT]], entity: [[I]]
-// CHECK: distinct !DISubprogram(name: "c",{{.*}}, scope: ![[C:[0-9]+]],{{.*}}, line: 60,{{.*}} isDefinition: true
+// CHECK: distinct !DISubprogram(name: "c",{{.*}}, scope: ![[C:[0-9]+]],{{.*}}, line: 60,{{.*}} DISPFlagDefinition
// CHECK: ![[C]] = !DINamespace(name: "C",
// CHECK-GMLT: [[CU:![0-9]+]] = distinct !DICompileUnit(
// CHECK-GMLT-SAME: emissionKind: LineTablesOnly,
// CHECK-GMLT-NOT: imports:
+// CHECK-GMLI: [[CU:![0-9]+]] = distinct !DICompileUnit(
+// CHECK-GMLI-SAME: emissionKind: DebugDirectivesOnly,
+// CHECK-GMLI-NOT: imports:
+
// CHECK-NOLIMIT: !DICompositeType(tag: DW_TAG_structure_type, name: "bar",{{.*}} line: 6,
// CHECK-NOLIMIT-NOT: DIFlagFwdDecl
// CHECK-NOLIMIT-SAME: ){{$}}
diff --git a/test/CodeGenCXX/debug-info-static-fns.cpp b/test/CodeGenCXX/debug-info-static-fns.cpp
index 59c7471f7ca6..2c8ed8f26c56 100644
--- a/test/CodeGenCXX/debug-info-static-fns.cpp
+++ b/test/CodeGenCXX/debug-info-static-fns.cpp
@@ -10,4 +10,4 @@ namespace A {
// CHECK: define internal i32 @_ZN1AL1aEi({{.*}} !dbg [[DBG:![0-9]+]]
// CHECK: [[DBG]] = distinct !DISubprogram(name: "a", linkageName: "_ZN1AL1aEi",
// CHECK-SAME: line: 4
-// CHECK-SAME: isDefinition: true
+// CHECK-SAME: DISPFlagDefinition
diff --git a/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp b/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp
index c8d8a1de855d..cd51b522505d 100644
--- a/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp
+++ b/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp
@@ -1,8 +1,9 @@
// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -debug-info-kind=limited %s -o - | FileCheck %s
-// Run again with -gline-tables-only and verify we don't crash. We won't output
+// Run again with -gline-tables-only or -gline-directives-only and verify we don't crash. We won't output
// type info at all.
// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -debug-info-kind=line-tables-only %s -o - | FileCheck %s -check-prefix LINES-ONLY
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -debug-info-kind=line-directives-only %s -o - | FileCheck %s -check-prefix LINES-ONLY
// LINES-ONLY-NOT: !DICompositeType(tag: DW_TAG_structure_type
diff --git a/test/CodeGenCXX/debug-info-template-member.cpp b/test/CodeGenCXX/debug-info-template-member.cpp
index a6aa1a05a256..db6006cab820 100644
--- a/test/CodeGenCXX/debug-info-template-member.cpp
+++ b/test/CodeGenCXX/debug-info-template-member.cpp
@@ -22,6 +22,19 @@ inline int add3(int x) {
// CHECK: [[X]] = !DIGlobalVariableExpression(var: [[XV:.*]], expr: !DIExpression())
// CHECK: [[XV]] = distinct !DIGlobalVariable(name: "x",
// CHECK-SAME: type: ![[OUTER_FOO_INNER_ID:[0-9]+]]
+//
+// CHECK: {{![0-9]+}} = distinct !DIGlobalVariable(
+// CHECK-SAME: name: "var"
+// CHECK-SAME: templateParams: {{![0-9]+}}
+// CHECK: !DITemplateTypeParameter(name: "T", type: [[TY:![0-9]+]])
+// CHECK: {{![0-9]+}} = distinct !DIGlobalVariable(
+// CHECK-SAME: name: "var"
+// CHECK-SAME: templateParams: {{![0-9]+}}
+// CHECK: !DITemplateTypeParameter(name: "P", type: {{![0-9]+}})
+// CHECK: {{![0-9]+}} = distinct !DIGlobalVariable(
+// CHECK-SAME: name: "varray"
+// CHECK-SAME: templateParams: {{![0-9]+}}
+// CHECK: !DITemplateValueParameter(name: "N", type: [[TY]], value: i32 1)
// CHECK: ![[OUTER_FOO_INNER_ID:[0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "inner"{{.*}}, identifier:
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo"
@@ -103,3 +116,15 @@ void f2() {
// declaration/reference in the compile unit.
// CHECK: !DISubprogram(name: "MyClass"
// CHECK-SAME: scope: [[C]]
+
+template <typename T>
+T var = T();
+template <typename P>
+P var<P *> = P();
+template <typename T, int N>
+T varray[N];
+void f3() {
+ var<int> = 1;
+ var<int *> = 1;
+ varray<int, 1>[0] = 1;
+}
diff --git a/test/CodeGenCXX/debug-info-thunk-msabi.cpp b/test/CodeGenCXX/debug-info-thunk-msabi.cpp
index 565992ad2a3d..3dbabafdd87d 100644
--- a/test/CodeGenCXX/debug-info-thunk-msabi.cpp
+++ b/test/CodeGenCXX/debug-info-thunk-msabi.cpp
@@ -12,8 +12,8 @@ class __declspec(dllexport) A {
//
// CHECK: ![[SP]] = distinct !DISubprogram(
// CHECK-SAME: line: 4
-// CHECK-SAME: isDefinition: true
// CHECK-SAME: DIFlagArtificial
+// CHECK-SAME: DISPFlagDefinition
// CHECK-SAME: ){{$}}
//
// CHECK: ![[DBG]] = !DILocation(line: 0
diff --git a/test/CodeGenCXX/debug-info-thunk.cpp b/test/CodeGenCXX/debug-info-thunk.cpp
index 56dec93f6b39..f6130cc28ced 100644
--- a/test/CodeGenCXX/debug-info-thunk.cpp
+++ b/test/CodeGenCXX/debug-info-thunk.cpp
@@ -86,7 +86,7 @@ namespace Test4 {
};
}
void C::c() {}
-// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@?A@Test4@@W7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk
+// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@?A0x{{[^@]*}}@Test4@@W7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk
void C::f() {}
// Force C::f to be used.
@@ -268,9 +268,9 @@ namespace Test12 {
//
// ITANIUM: ![[SP]] = distinct !DISubprogram(linkageName: "_ZThn{{[48]}}_N6Test121C1fEv"
// ITANIUM-SAME: line: 261
- // ITANIUM-SAME: isDefinition: true
// ITANIUM-SAME: DIFlagArtificial
// ITANIUM-SAME: DIFlagThunk
+ // ITANIUM-SAME: DISPFlagDefinition
// ITANIUM-SAME: ){{$}}
//
// ITANIUM: ![[DBG]] = !DILocation(line: 0
diff --git a/test/CodeGenCXX/debug-info-vla.cpp b/test/CodeGenCXX/debug-info-vla.cpp
index 6c35f301f968..73bdaf0abc53 100644
--- a/test/CodeGenCXX/debug-info-vla.cpp
+++ b/test/CodeGenCXX/debug-info-vla.cpp
@@ -13,7 +13,7 @@ int (*fp)(int[][*]) = nullptr;
// CHECK: [[ELEM_TYPE]] = !{[[NOCOUNT:.*]]}
// CHECK: [[NOCOUNT]] = !DISubrange(count: -1)
//
-// CHECK: [[VAR:![0-9]+]] = !DILocalVariable(name: "__vla_expr", {{.*}}flags: DIFlagArtificial
+// CHECK: [[VAR:![0-9]+]] = !DILocalVariable(name: "__vla_expr0", {{.*}}flags: DIFlagArtificial
// CHECK: !DICompositeType(tag: DW_TAG_array_type,
// CHECK-NOT: size:
// CHECK-SAME: elements: [[ELEM_TYPE:![0-9]+]]
diff --git a/test/CodeGenCXX/debug-info-windows-dtor.cpp b/test/CodeGenCXX/debug-info-windows-dtor.cpp
index 0b3d7e17e3fa..beea56ce7368 100644
--- a/test/CodeGenCXX/debug-info-windows-dtor.cpp
+++ b/test/CodeGenCXX/debug-info-windows-dtor.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -triple i386-unknown-windows-msvc -std=c++11 -emit-llvm -debug-info-kind=line-tables-only %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i386-unknown-windows-msvc -std=c++11 -emit-llvm -debug-info-kind=line-directives-only %s -o - | FileCheck %s
struct A {
virtual ~A() {}
diff --git a/test/CodeGenCXX/debug-info.cpp b/test/CodeGenCXX/debug-info.cpp
index 6d6d0c7d19cf..8ac4016493c5 100644
--- a/test/CodeGenCXX/debug-info.cpp
+++ b/test/CodeGenCXX/debug-info.cpp
@@ -103,7 +103,7 @@ Cls obj;
// CHECK: [[FUNC:[0-9]+]] = distinct !DISubprogram(name: "func", linkageName: "_ZN7pr147634funcENS_3fooE"
// CHECK-SAME: type: {{![0-9]+}}
-// CHECK-SAME: isDefinition: true
+// CHECK-SAME: DISPFlagDefinition
// CHECK: [[PR14763:![0-9]+]] = !DINamespace(name: "pr14763"
namespace pr14763 {
diff --git a/test/CodeGenCXX/debug-lambda-expressions.cpp b/test/CodeGenCXX/debug-lambda-expressions.cpp
index 1717fc468656..324c0926fb9f 100644
--- a/test/CodeGenCXX/debug-lambda-expressions.cpp
+++ b/test/CodeGenCXX/debug-lambda-expressions.cpp
@@ -40,7 +40,7 @@ int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
// CHECK: ![[INT:[0-9]+]] = !DIBasicType(name: "int"
// A: 10
-// CHECK: ![[A_FUNC:.*]] = distinct !DISubprogram(name: "a"{{.*}}, line: [[A_LINE:[0-9]+]]{{.*}}, isDefinition: true
+// CHECK: ![[A_FUNC:.*]] = distinct !DISubprogram(name: "a"{{.*}}, line: [[A_LINE:[0-9]+]]{{.*}} DISPFlagDefinition
// Back to A. -- 78
// CHECK: ![[LAM_A:.*]] = distinct !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[A_FUNC]]{{.*}}, line: [[A_LINE]],
@@ -52,7 +52,7 @@ int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
// CHECK-SAME: DIFlagPublic
// B: 14
-// CHECK: ![[B_FUNC:.*]] = distinct !DISubprogram(name: "b"{{.*}}, line: [[B_LINE:[0-9]+]]{{.*}}, isDefinition: true
+// CHECK: ![[B_FUNC:.*]] = distinct !DISubprogram(name: "b"{{.*}}, line: [[B_LINE:[0-9]+]]{{.*}} DISPFlagDefinition
// Back to B. -- 67
// CHECK: ![[LAM_B:.*]] = distinct !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[B_FUNC]]{{.*}}, line: [[B_LINE]],
@@ -68,7 +68,7 @@ int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
// CHECK-SAME: DIFlagPublic
// C: 17
-// CHECK: ![[C_FUNC:.*]] = distinct !DISubprogram(name: "c"{{.*}}, line: [[C_LINE:[0-9]+]]{{.*}}, isDefinition: true
+// CHECK: ![[C_FUNC:.*]] = distinct !DISubprogram(name: "c"{{.*}}, line: [[C_LINE:[0-9]+]]{{.*}} DISPFlagDefinition
// Back to C. -- 55
// CHECK: ![[LAM_C:.*]] = distinct !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[C_FUNC]]{{.*}}, line: [[C_LINE]],
@@ -85,7 +85,7 @@ int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
// CHECK-SAME: DIFlagPublic
// D: 18
-// CHECK: ![[D_FUNC:.*]] = distinct !DISubprogram(name: "d"{{.*}}, line: [[D_LINE:[0-9]+]]{{.*}}, isDefinition: true
+// CHECK: ![[D_FUNC:.*]] = distinct !DISubprogram(name: "d"{{.*}}, line: [[D_LINE:[0-9]+]]{{.*}} DISPFlagDefinition
// Back to D. -- 24
// CHECK: ![[LAM_D:.*]] = distinct !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[D_FUNC]]{{.*}}, line: [[D_LINE]],
diff --git a/test/CodeGenCXX/debug-prefix-map-lambda.cpp b/test/CodeGenCXX/debug-prefix-map-lambda.cpp
new file mode 100644
index 000000000000..f0fb1a312c8b
--- /dev/null
+++ b/test/CodeGenCXX/debug-prefix-map-lambda.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -debug-info-kind=limited -triple %itanium_abi_triple \
+// RUN: -fdebug-prefix-map=%S=/SOURCE_ROOT %s -emit-llvm -o - | FileCheck %s
+
+template <typename T> void b(T) {}
+void c() {
+ // CHECK: !DISubprogram(name: "b<(lambda at
+ // CHECK-SAME: SOURCE_ROOT
+ // CHECK-SAME: [[@LINE+1]]:{{[0-9]+}})>"
+ b([]{});
+}
diff --git a/test/CodeGenCXX/dllexport-missing-key.cpp b/test/CodeGenCXX/dllexport-missing-key.cpp
new file mode 100644
index 000000000000..90e736f6fad3
--- /dev/null
+++ b/test/CodeGenCXX/dllexport-missing-key.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -std=c++11 -o - %s | FileCheck --check-prefix=GNU %s
+
+class __declspec(dllexport) QAbstractLayoutStyleInfo {
+public:
+ QAbstractLayoutStyleInfo() : m_isWindow(false) {}
+ virtual ~QAbstractLayoutStyleInfo() {}
+
+ virtual bool hasChangedCore() const { return false; }
+
+ virtual void invalidate() {}
+
+ virtual double windowMargin(bool orientation) const = 0;
+
+ bool isWindow() const { return m_isWindow; }
+
+protected:
+ bool m_isWindow;
+};
+
+// GNU-DAG: @_ZTV24QAbstractLayoutStyleInfo = weak_odr dso_local dllexport
+// GNU-DAG: @_ZTS24QAbstractLayoutStyleInfo = linkonce_odr
+// GNU-DAG: @_ZTI24QAbstractLayoutStyleInfo = linkonce_odr
diff --git a/test/CodeGenCXX/dllexport-no-dllexport-inlines.cpp b/test/CodeGenCXX/dllexport-no-dllexport-inlines.cpp
new file mode 100644
index 000000000000..3866731a3cd9
--- /dev/null
+++ b/test/CodeGenCXX/dllexport-no-dllexport-inlines.cpp
@@ -0,0 +1,133 @@
+// RUN: %clang_cc1 %s -fms-extensions -triple x86_64-windows-msvc \
+// RUN: -disable-llvm-passes \
+// RUN: -fno-dllexport-inlines -emit-llvm -O1 -o - | \
+// RUN: FileCheck --check-prefix=CHECK --check-prefix=NOEXPORTINLINE %s
+
+// RUN: %clang_cc1 %s -fms-extensions -triple x86_64-windows-msvc \
+// RUN: -disable-llvm-passes \
+// RUN: -emit-llvm -O1 -o - | \
+// RUN: FileCheck --check-prefix=CHECK --check-prefix=EXPORTINLINE %s
+
+
+struct __declspec(dllexport) ExportedClass {
+
+ // NOEXPORTINLINE-DAG: define linkonce_odr dso_local void @"?InclassDefFunc@ExportedClass@@
+ // EXPORTINLINE-DAG: define weak_odr dso_local dllexport void @"?InclassDefFunc@ExportedClass@@
+ void InclassDefFunc() {}
+
+ // CHECK-DAG: define weak_odr dso_local dllexport i32 @"?InclassDefFuncWithStaticVariable@ExportedClass@@QEAAHXZ"
+ int InclassDefFuncWithStaticVariable() {
+ // CHECK-DAG: @"?static_variable@?1??InclassDefFuncWithStaticVariable@ExportedClass@@QEAAHXZ@4HA" = weak_odr dso_local dllexport global i32 0, comdat, align 4
+ static int static_variable = 0;
+ ++static_variable;
+ return static_variable;
+ }
+
+ // CHECK-DAG: define weak_odr dso_local dllexport i32 @"?InclassDefFunctWithLambdaStaticVariable@ExportedClass@@QEAAHXZ"
+ int InclassDefFunctWithLambdaStaticVariable() {
+ // CHECK-DAG: @"?static_x@?2???R<lambda_1>@?0??InclassDefFunctWithLambdaStaticVariable@ExportedClass@@QEAAHXZ@QEBA?A?<auto>@@XZ@4HA" = weak_odr dso_local dllexport global i32 0, comdat, align 4
+ return ([]() { static int static_x; return ++static_x; })();
+ }
+
+ // NOEXPORTINLINE-DAG: define linkonce_odr dso_local void @"?InlineOutclassDefFunc@ExportedClass@@QEAAXXZ
+ // EXPORTINLINE-DAG: define weak_odr dso_local dllexport void @"?InlineOutclassDefFunc@ExportedClass@@QEAAXXZ
+ inline void InlineOutclassDefFunc();
+
+ // CHECK-DAG: define weak_odr dso_local dllexport i32 @"?InlineOutclassDefFuncWithStaticVariable@ExportedClass@@QEAAHXZ"
+ inline int InlineOutclassDefFuncWithStaticVariable();
+
+ // CHECK-DAG: define dso_local dllexport void @"?OutoflineDefFunc@ExportedClass@@QEAAXXZ"
+ void OutoflineDefFunc();
+};
+
+void ExportedClass::OutoflineDefFunc() {}
+
+inline void ExportedClass::InlineOutclassDefFunc() {}
+
+inline int ExportedClass::InlineOutclassDefFuncWithStaticVariable() {
+ static int static_variable = 0;
+ return ++static_variable;
+}
+
+void ExportedClassUser() {
+ ExportedClass a;
+ a.InclassDefFunc();
+ a.InlineOutclassDefFunc();
+}
+
+template<typename T>
+struct __declspec(dllexport) TemplateExportedClass {
+ void InclassDefFunc() {}
+
+ int InclassDefFuncWithStaticVariable() {
+ static int static_x = 0;
+ return ++static_x;
+ }
+};
+
+class A11{};
+class B22{};
+
+// CHECK-DAG: define weak_odr dso_local dllexport void @"?InclassDefFunc@?$TemplateExportedClass@VA11@@@@QEAAXXZ"
+// CHECK-DAG: define weak_odr dso_local dllexport i32 @"?InclassDefFuncWithStaticVariable@?$TemplateExportedClass@VA11@@@@QEAAHXZ"
+// CHECK-DAG: @"?static_x@?2??InclassDefFuncWithStaticVariable@?$TemplateExportedClass@VA11@@@@QEAAHXZ@4HA" = weak_odr dso_local dllexport global i32 0, comdat, align 4
+template class TemplateExportedClass<A11>;
+
+// NOEXPORTINLINE-DAG: define linkonce_odr dso_local void @"?InclassDefFunc@?$TemplateExportedClass@VB22@@@@QEAAXXZ"
+// EXPORTINLINE-DAG: define weak_odr dso_local dllexport void @"?InclassDefFunc@?$TemplateExportedClass@VB22@@@@QEAAXXZ
+// CHECK-DAG: define weak_odr dso_local dllexport i32 @"?InclassDefFuncWithStaticVariable@?$TemplateExportedClass@VB22@@@@QEAAHXZ"
+// CHECK-DAG: @"?static_x@?2??InclassDefFuncWithStaticVariable@?$TemplateExportedClass@VB22@@@@QEAAHXZ@4HA" = weak_odr dso_local dllexport global i32 0, comdat, align 4
+TemplateExportedClass<B22> b22;
+
+void TemplateExportedClassUser() {
+ b22.InclassDefFunc();
+ b22.InclassDefFuncWithStaticVariable();
+}
+
+
+template<typename T>
+struct TemplateNoAttributeClass {
+ void InclassDefFunc() {}
+ int InclassDefFuncWithStaticLocal() {
+ static int static_x;
+ return ++static_x;
+ }
+};
+
+// CHECK-DAG: define weak_odr dso_local dllexport void @"?InclassDefFunc@?$TemplateNoAttributeClass@VA11@@@@QEAAXXZ"
+// CHECK-DAG: define weak_odr dso_local dllexport i32 @"?InclassDefFuncWithStaticLocal@?$TemplateNoAttributeClass@VA11
+// CHECK-DAG: @"?static_x@?2??InclassDefFuncWithStaticLocal@?$TemplateNoAttributeClass@VA11@@@@QEAAHXZ@4HA" = weak_odr dso_local dllexport global i32 0, comdat, align 4
+template class __declspec(dllexport) TemplateNoAttributeClass<A11>;
+
+// CHECK-DAG: define available_externally dllimport void @"?InclassDefFunc@?$TemplateNoAttributeClass@VB22@@@@QEAAXXZ"
+// CHECK-DAG: define available_externally dllimport i32 @"?InclassDefFuncWithStaticLocal@?$TemplateNoAttributeClass@VB22@@@@QEAAHXZ"
+// CHECK-DAG: @"?static_x@?2??InclassDefFuncWithStaticLocal@?$TemplateNoAttributeClass@VB22@@@@QEAAHXZ@4HA" = available_externally dllimport global i32 0, align 4
+extern template class __declspec(dllimport) TemplateNoAttributeClass<B22>;
+
+void TemplateNoAttributeClassUser() {
+ TemplateNoAttributeClass<B22> b22;
+ b22.InclassDefFunc();
+ b22.InclassDefFuncWithStaticLocal();
+}
+
+struct __declspec(dllimport) ImportedClass {
+ // NOEXPORTINLINE-DAG: define linkonce_odr dso_local void @"?InClassDefFunc@ImportedClass@@QEAAXXZ"
+ // EXPORTINLINE-DAG: define available_externally dllimport void @"?InClassDefFunc@ImportedClass@@QEAAXXZ"
+ void InClassDefFunc() {}
+
+ // EXPORTINLINE-DAG: define available_externally dllimport i32 @"?InClassDefFuncWithStaticVariable@ImportedClass@@QEAAHXZ"
+ // NOEXPORTINLINE-DAG: define linkonce_odr dso_local i32 @"?InClassDefFuncWithStaticVariable@ImportedClass@@QEAAHXZ"
+ int InClassDefFuncWithStaticVariable() {
+ // CHECK-DAG: @"?static_variable@?1??InClassDefFuncWithStaticVariable@ImportedClass@@QEAAHXZ@4HA" = available_externally dllimport global i32 0, align 4
+ static int static_variable = 0;
+ ++static_variable;
+ return static_variable;
+ }
+};
+
+int InClassDefFuncUser() {
+ // This is necessary for declare statement of ImportedClass::InClassDefFunc().
+ ImportedClass c;
+ c.InClassDefFunc();
+ return c.InClassDefFuncWithStaticVariable();
+}
diff --git a/test/CodeGenCXX/dllexport.cpp b/test/CodeGenCXX/dllexport.cpp
index a7b6aad357e5..16cfb8465845 100644
--- a/test/CodeGenCXX/dllexport.cpp
+++ b/test/CodeGenCXX/dllexport.cpp
@@ -43,7 +43,7 @@ __declspec(dllexport) extern int ExternGlobalDecl;
// M64-DAG: @__ImageBase = external dso_local constant i8
-// GNU-DAG: @_ZTVN10__cxxabiv117__class_type_infoE = external dso_local global
+// GNU-DAG: @_ZTVN10__cxxabiv117__class_type_infoE = external global
// dllexport implies a definition.
// MSC-DAG: @"?GlobalDef@@3HA" = dso_local dllexport global i32 0, align 4
@@ -137,7 +137,7 @@ class __declspec(dllexport) i : h<> {};
// Declarations are not exported.
// MSC-DAG: @"??$VarTmplImplicitDef@UImplicitInst_Exported@@@@3HA" = external dso_local global
-// GNU-DAG: @_Z18VarTmplImplicitDefI21ImplicitInst_ExportedE = external dso_local global
+// GNU-DAG: @_Z18VarTmplImplicitDefI21ImplicitInst_ExportedE = external global
template<typename T> __declspec(dllexport) extern int VarTmplImplicitDef;
USEVAR(VarTmplImplicitDef<ImplicitInst_Exported>)
@@ -797,7 +797,7 @@ struct __declspec(dllexport) PR23308 {
};
void PR23308::f(InternalLinkageType*) {}
long use(PR23308* p) { p->f(nullptr); }
-// M32-DAG: define internal x86_thiscallcc void @"?f@PR23308@@QAEXPAUInternalLinkageType@?A@@@Z"
+// M32-DAG: define internal x86_thiscallcc void @"?f@PR23308@@QAEXPAUInternalLinkageType@?A0x{{[^@]*}}@@@Z"
template <typename T> struct PR23770BaseTemplate { void f() {} };
template <typename T> struct PR23770DerivedTemplate : PR23770BaseTemplate<int> {};
@@ -1012,6 +1012,18 @@ struct __declspec(dllexport) LayerTreeImpl {
// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %"struct.LayerTreeImpl::ElementLayers"* @"??0ElementLayers@LayerTreeImpl@@QAE@XZ"
// M64-DAG: define weak_odr dso_local dllexport %"struct.LayerTreeImpl::ElementLayers"* @"??0ElementLayers@LayerTreeImpl@@QEAA@XZ"
+namespace pr39496 {
+// Make sure dll attribute are inherited by static locals also in template
+// specializations.
+template <typename> struct __declspec(dllexport) S { int foo() { static int x; return x++; } };
+int foo() { S<int> s; return s.foo(); }
+// MSC-DAG: @"?x@?{{1|2}}??foo@?$S@H@pr39496@@Q{{[A-Z]*}}HXZ@4HA" = weak_odr dso_local dllexport global i32 0, comdat, align 4
+
+template <typename> struct T { int foo() { static int x; return x++; } };
+template struct __declspec(dllexport) T<int>;
+// MSC-DAG: @"?x@?{{1|2}}??foo@?$T@H@pr39496@@Q{{[A-Z]*}}HXZ@4HA" = weak_odr dso_local dllexport global i32 0, comdat, align 4
+}
+
class __declspec(dllexport) ACE_Shared_Object {
public:
virtual ~ACE_Shared_Object();
diff --git a/test/CodeGenCXX/dllimport-members.cpp b/test/CodeGenCXX/dllimport-members.cpp
index 7a7519f66831..f8034cfb47c1 100644
--- a/test/CodeGenCXX/dllimport-members.cpp
+++ b/test/CodeGenCXX/dllimport-members.cpp
@@ -854,7 +854,7 @@ USEMV(MemVarTmpl, ImportedStaticVar<ExplicitSpec_Imported>)
// Not importing specialization of a member variable template without explicit
// dllimport.
// MSC-DAG: @"??$ImportedStaticVar@UExplicitSpec_NotImported@@@MemVarTmpl@@2HB" = external dso_local constant i32
-// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI24ExplicitSpec_NotImportedEE = external dso_local constant i32
+// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI24ExplicitSpec_NotImportedEE = external constant i32
template<> const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_NotImported>;
USEMV(MemVarTmpl, ImportedStaticVar<ExplicitSpec_NotImported>)
diff --git a/test/CodeGenCXX/dllimport.cpp b/test/CodeGenCXX/dllimport.cpp
index 74f58cc3b171..e9f0e4795f79 100644
--- a/test/CodeGenCXX/dllimport.cpp
+++ b/test/CodeGenCXX/dllimport.cpp
@@ -78,7 +78,7 @@ USEVAR(GlobalRedecl2c)
// NB: MSC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
// and drop the dllimport with a warning.
// MSC-DAG: @"?GlobalRedecl3@@3HA" = external dso_local global i32
-// GNU-DAG: @GlobalRedecl3 = external dso_local global i32
+// GNU-DAG: @GlobalRedecl3 = external global i32
__declspec(dllimport) extern int GlobalRedecl3;
extern int GlobalRedecl3; // dllimport ignored
USEVAR(GlobalRedecl3)
@@ -137,7 +137,7 @@ template<typename T> __declspec(dllimport) int VarTmplRedecl2;
USEVAR(VarTmplRedecl2<ImplicitInst_Imported>)
// MSC-DAG: @"??$VarTmplRedecl3@UImplicitInst_Imported@@@@3HA" = external dso_local global i32
-// GNU-DAG: @_Z14VarTmplRedecl3I21ImplicitInst_ImportedE = external dso_local global i32
+// GNU-DAG: @_Z14VarTmplRedecl3I21ImplicitInst_ImportedE = external global i32
template<typename T> __declspec(dllimport) extern int VarTmplRedecl3;
template<typename T> extern int VarTmplRedecl3; // dllimport ignored
USEVAR(VarTmplRedecl3<ImplicitInst_Imported>)
@@ -996,3 +996,26 @@ template struct __declspec(dllexport) ExplicitInstantiationDeclTemplateBase2<int
USEMEMFUNC(ExplicitInstantiationDeclTemplateBase2<int>, func)
// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitInstantiationDeclTemplateBase2@H@@QAEXXZ"
// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN38ExplicitInstantiationDeclTemplateBase2IiE4funcEv
+
+namespace pr39496 {
+// Make sure dll attribute are inherited by static locals also in template
+// specializations.
+template <typename> struct __declspec(dllimport) S { int foo() { static int x; return x++; } };
+int foo() { S<int> s; return s.foo(); }
+// MO1-DAG: @"?x@?{{1|2}}??foo@?$S@H@pr39496@@Q{{[A-Z]*}}HXZ@4HA" = available_externally dllimport global i32 0, align 4
+
+template <typename> struct T { int foo() { static int x; return x++; } };
+extern template struct __declspec(dllimport) T<int>;
+int bar() { T<int> t; return t.foo(); }
+// MO1-DAG: @"?x@?{{1|2}}??foo@?$T@H@pr39496@@Q{{[A-Z]*}}HXZ@4HA" = available_externally dllimport global i32 0, align 4
+
+template <typename T> struct __declspec(dllimport) U {
+ void foo() {
+ // Don't inherit dllimport to src before attaching the initializer.
+ static constexpr char src[] = {"hello"};
+ T arr[sizeof(src)];
+ }
+};
+void baz() { U<int> u; u.foo(); } // No diagnostic.
+
+}
diff --git a/test/CodeGenCXX/dso-local-executable.cpp b/test/CodeGenCXX/dso-local-executable.cpp
index cc8d50f09c9e..ceb649e074a3 100644
--- a/test/CodeGenCXX/dso-local-executable.cpp
+++ b/test/CodeGenCXX/dso-local-executable.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -triple x86_64-pc-linux -mrelocation-model static -O1 -emit-llvm %s -o - | FileCheck --check-prefix=STATIC %s
// RUN: %clang_cc1 -triple x86_64-pc-linux -mrelocation-model static -fno-plt -O1 -emit-llvm %s -o - | FileCheck --check-prefix=NOPLT %s
+// RUN: %clang_cc1 -triple x86_64-w64-mingw32 -O1 -emit-llvm %s -o - | FileCheck --check-prefix=MINGW %s
// STATIC-DAG: @_ZTV1C = linkonce_odr dso_local unnamed_addr constant
// STATIC-DAG: @_ZTS1C = linkonce_odr dso_local constant
@@ -19,6 +20,15 @@
// NOPLT-DAG: define dso_local void @_ZN1CC1Ev(
// NOPLT-DAG: define linkonce_odr dso_local void @_ZN1C3fooEv(
+// MINGW-DAG: @_ZTV1C = linkonce_odr dso_local unnamed_addr constant
+// MINGW-DAG: @_ZTS1C = linkonce_odr dso_local constant
+// MINGW-DAG: @_ZTI1C = linkonce_odr dso_local constant
+// MINGW-DAG: @_ZZ14useStaticLocalvE3obj = linkonce_odr dso_local global
+// MINGW-DAG: @_ZGVZN5guard1gEvE1a = linkonce_odr dso_local global
+// MINGW-DAG: define dso_local void @_ZN1CC2Ev(
+// MINGW-DAG: define dso_local void @_ZN1CC1Ev(
+// MINGW-DAG: define linkonce_odr dso_local void @_ZN1C3fooEv(
+
struct C {
C();
virtual void foo() {}
@@ -48,15 +58,23 @@ int h() {
} // namespace guard
+// STATIC-DAG: @_ZN5test23barIiE1xE = available_externally dso_local constant i32
// STATIC-DAG: define available_externally dso_local void @_ZN5test23barIcEC1Ev(
+// NOPLT-DAG: @_ZN5test23barIiE1xE = available_externally dso_local constant i32
// NOPLT-DAG: define available_externally void @_ZN5test23barIcEC1Ev(
+// MINGW-DAG: @_ZN5test23barIiE1xE = available_externally constant i32
+// MINGW-DAG: define available_externally dso_local void @_ZN5test23barIcEC1Ev(
namespace test2 {
void foo();
template <typename T>
struct bar {
virtual void zed();
+ static const int x = 42;
bar() { foo(); }
};
extern template class bar<char>;
bar<char> abc;
+const int *getX() {
+ return &bar<int>::x;
+}
} // namespace test2
diff --git a/test/CodeGenCXX/empty-struct-init-list.cpp b/test/CodeGenCXX/empty-struct-init-list.cpp
new file mode 100644
index 000000000000..33f52ba7032d
--- /dev/null
+++ b/test/CodeGenCXX/empty-struct-init-list.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++14 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++17 -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: struct.a
+typedef struct { } a;
+typedef struct {
+ a b[];
+} c;
+
+// CHECK: {{(dso_local )?}}global %struct.c{{.*}}zeroinitializer
+c d{ };
diff --git a/test/CodeGenCXX/exceptions-seh-filter-captures.cpp b/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
index 0e9766220828..79fba7537146 100644
--- a/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
+++ b/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
@@ -21,7 +21,7 @@ extern "C" void test_freefunc(int p1) {
// CHECK: invoke void @might_crash()
// CHECK-LABEL: define internal i32 @"?filt$0@0@test_freefunc@@"(i8* %exception_pointers, i8* %frame_pointer)
-// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %frame_pointer)
+// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.eh.recoverfp(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %frame_pointer)
// CHECK: %[[p1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %[[fp]], i32 0)
// CHECK: %[[p1_ptr:[^ ]*]] = bitcast i8* %[[p1_i8]] to i32*
// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %[[fp]], i32 1)
@@ -51,7 +51,7 @@ void S::test_method() {
// CHECK: invoke void @might_crash()
// CHECK-LABEL: define internal i32 @"?filt$0@0@test_method@S@@"(i8* %exception_pointers, i8* %frame_pointer)
-// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (void (%struct.S*)* @"?test_method@S@@QEAAXXZ" to i8*), i8* %frame_pointer)
+// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.eh.recoverfp(i8* bitcast (void (%struct.S*)* @"?test_method@S@@QEAAXXZ" to i8*), i8* %frame_pointer)
// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%struct.S*)* @"?test_method@S@@QEAAXXZ" to i8*), i8* %[[fp]], i32 0)
// CHECK: %[[l1_ptr:[^ ]*]] = bitcast i8* %[[l1_i8]] to i32*
// CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ptr]]
@@ -76,7 +76,7 @@ void test_lambda() {
// CHECK: invoke void @might_crash()
// CHECK-LABEL: define internal i32 @"?filt$0@0@?R<lambda_0>@?0??test_lambda@@YAXXZ@"(i8* %exception_pointers, i8* %frame_pointer)
-// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (void (%class.anon*)* @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ" to i8*), i8* %frame_pointer)
+// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.eh.recoverfp(i8* bitcast (void (%class.anon*)* @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ" to i8*), i8* %frame_pointer)
// CHECK: %[[l2_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%class.anon*)* @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ" to i8*), i8* %[[fp]], i32 0)
// CHECK: %[[l2_ptr:[^ ]*]] = bitcast i8* %[[l2_i8]] to i32*
// CHECK: %[[l2:[^ ]*]] = load i32, i32* %[[l2_ptr]]
diff --git a/test/CodeGenCXX/float128-declarations.cpp b/test/CodeGenCXX/float128-declarations.cpp
index 07e73b281728..18a25d9faba8 100644
--- a/test/CodeGenCXX/float128-declarations.cpp
+++ b/test/CodeGenCXX/float128-declarations.cpp
@@ -6,8 +6,6 @@
// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86
// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-linux-gnu -std=c++11 \
// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86
-// RUN: %clang_cc1 -emit-llvm -triple systemz-unknown-linux-gnu -std=c++11 \
-// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-SYSZ
// RUN: %clang_cc1 -emit-llvm -triple i686-pc-openbsd -std=c++11 \
// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86
// RUN: %clang_cc1 -emit-llvm -triple amd64-pc-openbsd -std=c++11 \
@@ -16,10 +14,13 @@
// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86
// RUN: %clang_cc1 -emit-llvm -triple x86_64-pc-solaris2.11 -std=c++11 \
// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86
+// RUN: %clang_cc1 -emit-llvm -triple i586-pc-haiku -std=c++11 \
+// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-haiku -std=c++11 \
+// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86
//
/* Various contexts where type __float128 can appear. The different check
- prefixes are due to different mangling on X86 and different calling
- convention on SystemZ. */
+ prefixes are due to different mangling on X86. */
/* Namespace */
namespace {
@@ -92,7 +93,7 @@ int main(void) {
// CHECK-DAG: define linkonce_odr void @_ZN2C1C2EU10__float128(%class.C1* %this, fp128 %arg)
// CHECK-DAG: define linkonce_odr fp128 @_ZN2C16func2cEU10__float128(fp128 %arg)
// CHECK-DAG: define linkonce_odr fp128 @_Z6func1tIU10__float128ET_S0_(fp128 %arg)
-// CHECK-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { fp128 0xL00000000000000004006080000000000 }
+// CHECK-DAG: @__const.main.s1 = private unnamed_addr constant %struct.S1 { fp128 0xL00000000000000004006080000000000 }
// CHECK-DAG: store fp128 0xLF0AFD0EBFF292DCE42E0B38CDD83F26F, fp128* %f1l, align 16
// CHECK-DAG: store fp128 0xL00000000000000008000000000000000, fp128* %f2l, align 16
// CHECK-DAG: store fp128 0xLFFFFFFFFFFFFFFFF7FFEFFFFFFFFFFFF, fp128* %f3l, align 16
@@ -114,7 +115,7 @@ int main(void) {
// CHECK-X86-DAG: define linkonce_odr void @_ZN2C1C2Eg(%class.C1* %this, fp128 %arg)
// CHECK-X86-DAG: define linkonce_odr fp128 @_ZN2C16func2cEg(fp128 %arg)
// CHECK-X86-DAG: define linkonce_odr fp128 @_Z6func1tIgET_S0_(fp128 %arg)
-// CHECK-X86-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { fp128 0xL00000000000000004006080000000000 }
+// CHECK-X86-DAG: @__const.main.s1 = private unnamed_addr constant %struct.S1 { fp128 0xL00000000000000004006080000000000 }
// CHECK-X86-DAG: store fp128 0xLF0AFD0EBFF292DCE42E0B38CDD83F26F, fp128* %f1l, align 16
// CHECK-X86-DAG: store fp128 0xL00000000000000008000000000000000, fp128* %f2l, align 16
// CHECK-X86-DAG: store fp128 0xLFFFFFFFFFFFFFFFF7FFEFFFFFFFFFFFF, fp128* %f3l, align 16
@@ -122,25 +123,3 @@ int main(void) {
// CHECK-X86-DAG: [[F4L:%[a-z0-9]+]] = load fp128, fp128* %f4l
// CHECK-X86-DAG: [[INC:%[a-z0-9]+]] = fadd fp128 [[F4L]], 0xL00000000000000003FFF000000000000
// CHECK-X86-DAG: store fp128 [[INC]], fp128* %f4l
-
-// CHECK-SYSZ-DAG: @_ZN12_GLOBAL__N_13f1nE = internal global fp128 0xL00000000000000000000000000000000
-// CHECK-SYSZ-DAG: @_ZN12_GLOBAL__N_13f2nE = internal global fp128 0xL00000000000000004004080000000000
-// CHECK-SYSZ-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x fp128]
-// CHECK-SYSZ-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x fp128] [fp128 0xL33333333333333333FFF333333333333, fp128 0xL00000000000000004000800000000000, fp128 0xL00000000000000004025176592E00000]
-// CHECK-SYSZ-DAG: define internal void @_ZN12_GLOBAL__N_16func1nERKU10__float128(fp128*
-// CHECK-SYSZ-DAG: @f1f = global fp128 0xL00000000000000000000000000000000
-// CHECK-SYSZ-DAG: @f2f = global fp128 0xL33333333333333334004033333333333
-// CHECK-SYSZ-DAG: @arr1f = global [10 x fp128]
-// CHECK-SYSZ-DAG: @arr2f = global [3 x fp128] [fp128 0xL3333333333333333BFFF333333333333, fp128 0xL0000000000000000C000800000000000, fp128 0xL0000000000000000C025176592E00000]
-// CHECK-SYSZ-DAG: declare void @_Z6func1fU10__float128(fp128*
-// CHECK-SYSZ-DAG: define linkonce_odr void @_ZN2C1C2EU10__float128(%class.C1* %this, fp128*
-// CHECK-SYSZ-DAG: define linkonce_odr void @_ZN2C16func2cEU10__float128(fp128*
-// CHECK-SYSZ-DAG: define linkonce_odr void @_Z6func1tIU10__float128ET_S0_(fp128*
-// CHECK-SYSZ-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { fp128 0xL00000000000000004006080000000000 }
-// CHECK-SYSZ-DAG: store fp128 0xLF0AFD0EBFF292DCE42E0B38CDD83F26F, fp128* %f1l, align 16
-// CHECK-SYSZ-DAG: store fp128 0xL00000000000000008000000000000000, fp128* %f2l, align 16
-// CHECK-SYSZ-DAG: store fp128 0xLFFFFFFFFFFFFFFFF7FFEFFFFFFFFFFFF, fp128* %f3l, align 16
-// CHECK-SYSZ-DAG: store fp128 0xL0000000000000000BFFF000000000000, fp128* %f5l, align 16
-// CHECK-SYSZ-DAG: [[F4L:%[a-z0-9]+]] = load fp128, fp128* %f4l
-// CHECK-SYSZ-DAG: [[INC:%[a-z0-9]+]] = fadd fp128 [[F4L]], 0xL00000000000000003FFF000000000000
-// CHECK-SYSZ-DAG: store fp128 [[INC]], fp128* %f4l
diff --git a/test/CodeGenCXX/float16-declarations.cpp b/test/CodeGenCXX/float16-declarations.cpp
index e82c05ec8c81..7e1c1e8db93c 100644
--- a/test/CodeGenCXX/float16-declarations.cpp
+++ b/test/CodeGenCXX/float16-declarations.cpp
@@ -106,9 +106,9 @@ int main(void) {
// 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: @__const.main.s1 = 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* align 2 [[S1]], i8* align 2 bitcast (%struct.S1* @_ZZ4mainE2s1 to i8*), i64 2, i1 false)
+// CHECK-DAG: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 2 [[S1]], i8* align 2 bitcast (%struct.S1* @__const.main.s1 to i8*), i64 2, i1 false)
_Float16 f4l = func1n(f1l) + func1f(f2l) + c1.func1c(f3l) + c1.func2c(f1l) +
func1t(f1l) + s1.mem2 - f1n + f2n;
@@ -123,7 +123,7 @@ int main(void) {
// 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
+// CHECK-DAG: @__const.main.arr1l = 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
diff --git a/test/CodeGenCXX/globalinit-loc.cpp b/test/CodeGenCXX/globalinit-loc.cpp
index 203eb2142667..e9715a651f40 100644
--- a/test/CodeGenCXX/globalinit-loc.cpp
+++ b/test/CodeGenCXX/globalinit-loc.cpp
@@ -8,8 +8,8 @@
// CHECK: !dbg ![[DBG:.*]]
// CHECK: !DISubprogram(linkageName: "_GLOBAL__sub_I_globalinit_loc.cpp"
// CHECK-NOT: line:
-// CHECK-SAME: isLocal: true
-// CHECK-SAME: isDefinition: true
+// CHECK-SAME: DISPFlagLocalToUnit
+// CHECK-SAME: DISPFlagDefinition
// CHECK: ![[DBG]] = !DILocation(line: 0,
# 99 "someheader.h"
class A {
diff --git a/test/CodeGenCXX/inalloca-lambda.cpp b/test/CodeGenCXX/inalloca-lambda.cpp
new file mode 100644
index 000000000000..ac85ee175268
--- /dev/null
+++ b/test/CodeGenCXX/inalloca-lambda.cpp
@@ -0,0 +1,11 @@
+// RUN: not %clang_cc1 -triple i686-windows-msvc -emit-llvm -o /dev/null %s 2>&1 | FileCheck %s
+
+// PR28299
+// CHECK: error: cannot compile this forwarded non-trivially copyable parameter yet
+
+class A {
+ A(const A &);
+};
+typedef void (*fptr_t)(A);
+fptr_t fn1() { return [](A) {}; }
+
diff --git a/test/CodeGenCXX/inheriting-constructor-cleanup.cpp b/test/CodeGenCXX/inheriting-constructor-cleanup.cpp
new file mode 100644
index 000000000000..3aac9ac9f78e
--- /dev/null
+++ b/test/CodeGenCXX/inheriting-constructor-cleanup.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -triple x86_64-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-darwin -std=c++11 -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s --check-prefix=EXCEPTIONS
+
+// PR36748
+// rdar://problem/45805151
+
+// Classes to verify order of destroying function parameters.
+struct S1 {
+ ~S1();
+};
+struct S2 {
+ ~S2();
+};
+
+struct Base {
+ // Use variadic args to cause inlining the inherited constructor.
+ Base(const S1&, const S2&, const char *fmt, ...) {}
+};
+
+struct NonTrivialDtor {
+ ~NonTrivialDtor() {}
+};
+struct Inheritor : public NonTrivialDtor, public Base {
+ using Base::Base;
+};
+
+void f() {
+ Inheritor(S1(), S2(), "foo");
+ // CHECK-LABEL: define void @_Z1fv
+ // CHECK: %[[TMP1:.*]] = alloca %struct.S1
+ // CHECK: %[[TMP2:.*]] = alloca %struct.S2
+ // CHECK: call void (%struct.Base*, %struct.S1*, %struct.S2*, i8*, ...) @_ZN4BaseC2ERK2S1RK2S2PKcz(%struct.Base* {{.*}}, %struct.S1* dereferenceable(1) %[[TMP1]], %struct.S2* dereferenceable(1) %[[TMP2]], i8* {{.*}})
+ // CHECK-NEXT: call void @_ZN9InheritorD1Ev(%struct.Inheritor* {{.*}})
+ // CHECK-NEXT: call void @_ZN2S2D1Ev(%struct.S2* %[[TMP2]])
+ // CHECK-NEXT: call void @_ZN2S1D1Ev(%struct.S1* %[[TMP1]])
+
+ // EXCEPTIONS-LABEL: define void @_Z1fv
+ // EXCEPTIONS: %[[TMP1:.*]] = alloca %struct.S1
+ // EXCEPTIONS: %[[TMP2:.*]] = alloca %struct.S2
+ // EXCEPTIONS: invoke void (%struct.Base*, %struct.S1*, %struct.S2*, i8*, ...) @_ZN4BaseC2ERK2S1RK2S2PKcz(%struct.Base* {{.*}}, %struct.S1* dereferenceable(1) %[[TMP1]], %struct.S2* dereferenceable(1) %[[TMP2]], i8* {{.*}})
+ // EXCEPTIONS-NEXT: to label %[[CONT:.*]] unwind label %[[LPAD:.*]]
+
+ // EXCEPTIONS: [[CONT]]:
+ // EXCEPTIONS-NEXT: call void @_ZN9InheritorD1Ev(%struct.Inheritor* {{.*}})
+ // EXCEPTIONS-NEXT: call void @_ZN2S2D1Ev(%struct.S2* %[[TMP2]])
+ // EXCEPTIONS-NEXT: call void @_ZN2S1D1Ev(%struct.S1* %[[TMP1]])
+
+ // EXCEPTIONS: [[LPAD]]:
+ // EXCEPTIONS: call void @_ZN14NonTrivialDtorD2Ev(%struct.NonTrivialDtor* {{.*}})
+ // EXCEPTIONS-NEXT: call void @_ZN2S2D1Ev(%struct.S2* %[[TMP2]])
+ // EXCEPTIONS-NEXT: call void @_ZN2S1D1Ev(%struct.S1* %[[TMP1]])
+}
diff --git a/test/CodeGenCXX/inline-template-hint.cpp b/test/CodeGenCXX/inline-template-hint.cpp
new file mode 100644
index 000000000000..3e64b1f74932
--- /dev/null
+++ b/test/CodeGenCXX/inline-template-hint.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 \
+// RUN: -finline-functions -emit-llvm -disable-llvm-passes -o - \
+// RUN: | FileCheck -allow-deprecated-dag-overlap %s \
+// RUN: --check-prefix=CHECK --check-prefix=SUITABLE
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 \
+// RUN: -finline-hint-functions -emit-llvm -disable-llvm-passes -o - \
+// RUN: | FileCheck -allow-deprecated-dag-overlap %s \
+// RUN: --check-prefix=CHECK --check-prefix=HINTED
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 \
+// RUN: -fno-inline -emit-llvm -disable-llvm-passes -o - \
+// RUN: | FileCheck -allow-deprecated-dag-overlap %s \
+// RUN: --check-prefix=CHECK --check-prefix=NOINLINE
+
+struct A {
+ inline void int_run(int);
+
+ template <class T>
+ inline void template_run(T);
+};
+
+// CHECK: @_ZN1A7int_runEi({{.*}}) [[ATTR:#[0-9]+]]
+void A::int_run(int) {}
+// CHECK: @_ZN1A12template_runIiEEvT_({{.*}}) [[ATTR]]
+template <typename T>
+void A::template_run(T) {}
+
+void bar() {
+ A().int_run(1);
+ A().template_run(1);
+}
+
+// SUITABLE: attributes [[ATTR]] = { {{.*}}inlinehint{{.*}} }
+// HINTED: attributes [[ATTR]] = { {{.*}}inlinehint{{.*}} }
+// NOINLINE: attributes [[ATTR]] = { {{.*}}noinline{{.*}} }
diff --git a/test/CodeGenCXX/lifetime-asan.cpp b/test/CodeGenCXX/lifetime-asan.cpp
new file mode 100644
index 000000000000..9ccb28c876a1
--- /dev/null
+++ b/test/CodeGenCXX/lifetime-asan.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - -fno-exceptions -O0 %s | FileCheck %s -check-prefixes=CHECK,CHECK-O0 --implicit-check-not=llvm.lifetime
+// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - -fno-exceptions -O0 \
+// RUN: -fsanitize=address -fsanitize-address-use-after-scope %s | \
+// RUN: FileCheck %s -check-prefixes=CHECK,CHECK-ASAN-USE-AFTER-SCOPE
+
+extern int bar(char *A, int n);
+
+struct X { X(); ~X(); int *p; };
+struct Y { Y(); int *p; };
+
+extern "C" void a(), b(), c(), d();
+
+// CHECK-LABEL: @_Z3foo
+void foo(int n) {
+ // CHECK: call void @a()
+ a();
+
+ // CHECK: call void @b()
+ // CHECK-ASAN-USE-AFTER-SCOPE: store i1 false
+ // CHECK-ASAN-USE-AFTER-SCOPE: store i1 false
+ // CHECK: br i1
+ //
+ // CHECK-ASAN-USE-AFTER-SCOPE: @llvm.lifetime.start
+ // CHECK-ASAN-USE-AFTER-SCOPE: store i1 true
+ // CHECK: call void @_ZN1XC
+ // CHECK: br label
+ //
+ // CHECK-ASAN-USE-AFTER-SCOPE: @llvm.lifetime.start
+ // CHECK-ASAN-USE-AFTER-SCOPE: store i1 true
+ // CHECK: call void @_ZN1YC
+ // CHECK: br label
+ //
+ // CHECK: call void @c()
+ // CHECK-ASAN-USE-AFTER-SCOPE: br i1
+ // CHECK-ASAN-USE-AFTER-SCOPE: @llvm.lifetime.end
+ // CHECK-ASAN-USE-AFTER-SCOPE: br i1
+ // CHECK-ASAN-USE-AFTER-SCOPE: @llvm.lifetime.end
+ b(), (n ? X().p : Y().p), c();
+
+ // CHECK: call void @d()
+ d();
+}
diff --git a/test/CodeGenCXX/linetable-fnbegin.cpp b/test/CodeGenCXX/linetable-fnbegin.cpp
index f4cf53b0c5f5..3b93d70bd705 100644
--- a/test/CodeGenCXX/linetable-fnbegin.cpp
+++ b/test/CodeGenCXX/linetable-fnbegin.cpp
@@ -7,7 +7,7 @@
// CHECK: [[HPP:.*]] = !DIFile(filename: "./template.hpp",
// CHECK: [[SP:.*]] = distinct !DISubprogram(name: "bar",
// CHECK-SAME: file: [[HPP]], line: 22
-// CHECK-SAME: isDefinition: true
+// CHECK-SAME: DISPFlagDefinition
// We shouldn't need a lexical block for this function.
// CHECK: [[DBG]] = !DILocation(line: 23, scope: [[SP]])
diff --git a/test/CodeGenCXX/linetable-virtual-variadic.cpp b/test/CodeGenCXX/linetable-virtual-variadic.cpp
index cd746cdfdfe2..60dee5fe61b4 100644
--- a/test/CodeGenCXX/linetable-virtual-variadic.cpp
+++ b/test/CodeGenCXX/linetable-virtual-variadic.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -debug-info-kind=line-tables-only %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -debug-info-kind=line-directives-only %s -o - | FileCheck %s
// Crasher for PR22929.
class Base {
virtual void VariadicFunction(...);
diff --git a/test/CodeGenCXX/mangle-address-space.cpp b/test/CodeGenCXX/mangle-address-space.cpp
index cd10384594ea..549ae54dfbe4 100644
--- a/test/CodeGenCXX/mangle-address-space.cpp
+++ b/test/CodeGenCXX/mangle-address-space.cpp
@@ -1,15 +1,64 @@
-// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s --check-prefixes=CHECK,CHECKNOOCL
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-windows-msvc -o - %s | FileCheck %s --check-prefixes=WIN,WINNOOCL
+// RUN: %clang_cc1 -cl-std=c++ -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s --check-prefixes=CHECK,CHECKOCL
+// RUN: %clang_cc1 -cl-std=c++ -emit-llvm -triple x86_64-windows-msvc -o - %s | FileCheck %s --check-prefixes=WIN,WINOCL
-// CHECK-LABEL: define {{.*}}void @_Z2f0Pc
+// CHECKNOOCL-LABEL: define {{.*}}void @_Z2f0Pc
+// WINNOOCL-LABEL: define {{.*}}void @"?f0@@YAXPEAD@Z"
+// CHECKOCL-LABEL: define {{.*}}void @_Z2f0PU9CLgenericc
+// WINOCL-LABEL: define {{.*}}void @"?f0@@YAXPEAU?$_ASCLgeneric@$$CAD@__clang@@@Z"
void f0(char *p) { }
// CHECK-LABEL: define {{.*}}void @_Z2f0PU3AS1c
+// WIN-LABEL: define {{.*}}void @"?f0@@YAXPEAU?$_AS@$00$$CAD@__clang@@@Z"
void f0(char __attribute__((address_space(1))) *p) { }
struct OpaqueType;
typedef OpaqueType __attribute__((address_space(100))) * OpaqueTypePtr;
// CHECK-LABEL: define {{.*}}void @_Z2f0PU5AS10010OpaqueType
+// WIN-LABEL: define {{.*}}void @"?f0@@YAXPEAU?$_AS@$0GE@$$CAUOpaqueType@@@__clang@@@Z"
void f0(OpaqueTypePtr) { }
// CHECK-LABEL: define {{.*}}void @_Z2f1PU3AS1Kc
-void f1(char __attribute__((address_space(1))) const *p) {} \ No newline at end of file
+// WIN-LABEL: define {{.*}}void @"?f1@@YAXPEAU?$_AS@$00$$CBD@__clang@@@Z"
+void f1(char __attribute__((address_space(1))) const *p) {}
+
+// Ensure we can do return values, which change in MS mode.
+// CHECK-LABEL: define {{.*}}float addrspace(1)* @_Z2f1PU3AS2Kc
+// WIN-LABEL: define {{.*}}float addrspace(1)* @"?f1@@YAPEAU?$_AS@$00$$CAM@__clang@@PEAU?$_AS@$01$$CBD@2@@Z"
+__attribute__((address_space(1))) float *f1(char __attribute__((address_space(2))) const *p) { return 0;}
+
+#if !defined(__OPENCL_CPP_VERSION__)
+// Return value of address space without a pointer is invalid in opencl.
+// Ensure we skip return values, since non-pointers aren't supposed to have an AS.
+// CHECKNOOCL-LABEL: define {{.*}}float @_Z2f2PU3AS2Kc
+// WINNOOCL-LABEL: define {{.*}}float @"?f2@@YA?AMQEAU?$_AS@$01$$CBD@__clang@@@Z"
+__attribute__((address_space(1))) float f2(char __attribute__((address_space(2))) const * const p) { return 0;}
+#endif
+
+#ifdef __OPENCL_CPP_VERSION__
+// CHECKOCL-LABEL: define {{.*}}void @_Z6ocl_f0PU9CLprivatec
+// WINOCL-LABEL: define {{.*}}void @"?ocl_f0@@YAXPEAU?$_ASCLprivate@$$CAD@__clang@@@Z"
+void ocl_f0(char __private *p) { }
+
+struct ocl_OpaqueType;
+typedef ocl_OpaqueType __global * ocl_OpaqueTypePtr;
+
+// CHECKOCL-LABEL: define {{.*}}void @_Z6ocl_f0PU8CLglobal14ocl_OpaqueType
+// WINOCL-LABEL: define {{.*}}void @"?ocl_f0@@YAXPEAU?$_ASCLglobal@$$CAUocl_OpaqueType@@@__clang@@@Z"
+void ocl_f0(ocl_OpaqueTypePtr) { }
+
+// CHECKOCL-LABEL: define {{.*}}void @_Z6ocl_f1PU10CLconstantKc
+// WINOCL-LABEL: define {{.*}}void @"?ocl_f1@@YAXPEAU?$_ASCLconstant@$$CBD@__clang@@@Z"
+void ocl_f1(char __constant const *p) {}
+
+// Ensure we can do return values, which change in MS mode.
+// CHECKOCL-LABEL: define {{.*}}float* @_Z6ocl_f1PU9CLgenericKc
+// WINOCL-LABEL: define {{.*}}float* @"?ocl_f1@@YAPEAU?$_ASCLconstant@$$CAM@__clang@@PEAU?$_ASCLgeneric@$$CBD@2@@Z"
+__constant float *ocl_f1(char __generic const *p) { return 0;}
+
+// Ensure we skip return values, since non-pointers aren't supposed to have an AS.
+// CHECKOCL-LABEL: define {{.*}}float* @_Z6ocl_f2PU9CLgenericKc
+// WINOCL-LABEL: define {{.*}}float* @"?ocl_f2@@YAPEAU?$_ASCLgeneric@$$CAM@__clang@@QEAU?$_ASCLgeneric@$$CBD@2@@Z"
+__generic float *ocl_f2(__generic char const * const p) { return 0;}
+#endif
diff --git a/test/CodeGenCXX/mangle-long-double.cpp b/test/CodeGenCXX/mangle-long-double.cpp
index e248c474a2e7..177982b8f1aa 100644
--- a/test/CodeGenCXX/mangle-long-double.cpp
+++ b/test/CodeGenCXX/mangle-long-double.cpp
@@ -1,12 +1,8 @@
// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s --check-prefix=POWER64-LINUX
// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s --check-prefix=POWER-LINUX
-// RUN: %clang_cc1 -triple powerpc64-apple-darwin9 %s -emit-llvm -o - | FileCheck %s --check-prefix=POWER64-DARWIN
-// RUN: %clang_cc1 -triple powerpc-apple-darwin9 %s -emit-llvm -o - | FileCheck %s --check-prefix=POWER-DARWIN
// RUN: %clang_cc1 -triple s390x-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s --check-prefix=S390X-LINUX
void f(long double) {}
// POWER64-LINUX: _Z1fg
// POWER-LINUX: _Z1fg
-// POWER64-DARWIN: _Z1fe
-// POWER-DARWIN: _Z1fe
// S390X-LINUX: _Z1fg
diff --git a/test/CodeGenCXX/mangle-ms-exception-spec.cpp b/test/CodeGenCXX/mangle-ms-exception-spec.cpp
new file mode 100644
index 000000000000..1aaf2486ea14
--- /dev/null
+++ b/test/CodeGenCXX/mangle-ms-exception-spec.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -std=c++11 -fms-extensions -emit-llvm %s -o - -triple=x86_64-pc-win32 -Wno-noexcept-type -fms-compatibility-version=19.12 | FileCheck %s --check-prefix=CHECK --check-prefix=CXX11
+// RUN: %clang_cc1 -std=c++17 -fms-extensions -emit-llvm %s -o - -triple=x86_64-pc-win32 | FileCheck %s --check-prefix=CHECK --check-prefix=NOCOMPAT
+// RUN: %clang_cc1 -std=c++17 -fms-extensions -emit-llvm %s -o - -triple=x86_64-pc-win32 -fms-compatibility-version=19.12 | FileCheck %s --check-prefix=CHECK --check-prefix=CXX17
+
+// Prove that mangling only changed for noexcept types under /std:C++17, not all noexcept functions
+// CHECK-DAG: @"?nochange@@YAXXZ"
+void nochange() noexcept {}
+
+// CXX11-DAG: @"?a@@YAXP6AHXZ@Z"
+// NOCOMPAT-DAG: @"?a@@YAXP6AHXZ@Z"
+// CXX17-DAG: @"?a@@YAXP6AHX_E@Z"
+void a(int() noexcept) {}
+// CHECK-DAG: @"?b@@YAXP6AHXZ@Z"
+void b(int() noexcept(false)) {}
+// CXX11-DAG: @"?c@@YAXP6AHXZ@Z"
+// NOCOMPAT-DAG: @"?c@@YAXP6AHXZ@Z"
+// CXX17-DAG: @"?c@@YAXP6AHX_E@Z"
+void c(int() noexcept(true)) {}
+// CHECK-DAG: @"?d@@YAXP6AHXZ@Z"
+void d(int()) {}
+
+template <typename T>
+class e;
+template <typename T, typename... U>
+class e<T(U...) noexcept> {
+ // CXX11-DAG: @"?ee@?$e@$$A6AXXZ@@EEAAXXZ"
+ // NOCOMPAT-DAG: @"?ee@?$e@$$A6AXXZ@@EEAAXXZ"
+ // CXX17-DAG: @"?ee@?$e@$$A6AXX_E@@EEAAXXZ"
+ virtual T ee(U &&...) noexcept {};
+};
+
+e<void() noexcept> e1;
+
+template <typename T>
+class f;
+template <typename T, typename... U>
+class f<T(U...)> {
+ // CHECK-DAG: @"?ff@?$f@$$A6AXXZ@@EEAAXXZ"
+ virtual T ff(U &&...) noexcept {};
+};
+
+f<void()> f1;
diff --git a/test/CodeGenCXX/mangle-ms-templates.cpp b/test/CodeGenCXX/mangle-ms-templates.cpp
index 8c6062b6d5ee..469a23afc8e1 100644
--- a/test/CodeGenCXX/mangle-ms-templates.cpp
+++ b/test/CodeGenCXX/mangle-ms-templates.cpp
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=i386-pc-win32 | FileCheck %s
-// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility-version=19 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility-version=19 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
+// RUN: %clang_cc1 -std=c++17 -fms-compatibility-version=19 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -std=c++17 -fms-compatibility-version=19 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
template<typename T>
class Class {
@@ -185,13 +187,35 @@ void spam() {
// Unlike Itanium, there is no character code to indicate an argument pack.
// Tested with MSVC 2013, the first version which supports variadic templates.
-template <typename ...Ts> void variadic_fn_template(const Ts &...args) { }
+template <typename ...Ts> void variadic_fn_template(const Ts &...args);
+template <typename... Ts, typename... Us>
+void multi_variadic_fn(Ts... ts, Us... us);
+template <typename... Ts, typename C, typename... Us>
+void multi_variadic_mixed(Ts... ts, C c, Us... us);
void variadic_fn_instantiate() {
variadic_fn_template(0, 1, 3, 4);
variadic_fn_template(0, 1, 'a', "b");
+
+ // Directlly consecutive packs are separated by $$Z...
+ multi_variadic_fn<int, int>(1, 2, 3, 4, 5);
+ multi_variadic_fn<int, int, int>(1, 2, 3, 4, 5);
+
+ // ...but not if another template parameter is between them.
+ multi_variadic_mixed<int, int>(1, 2, 3);
+ multi_variadic_mixed<int, int>(1, 2, 3, 4);
}
// CHECK: "??$variadic_fn_template@HHHH@@YAXABH000@Z"
+// X64: "??$variadic_fn_template@HHHH@@YAXAEBH000@Z"
// CHECK: "??$variadic_fn_template@HHD$$BY01D@@YAXABH0ABDAAY01$$CBD@Z"
+// X64: "??$variadic_fn_template@HHD$$BY01D@@YAXAEBH0AEBDAEAY01$$CBD@Z"
+// CHECK: "??$multi_variadic_fn@HH$$ZHHH@@YAXHHHHH@Z"
+// X64: "??$multi_variadic_fn@HH$$ZHHH@@YAXHHHHH@Z"
+// CHECK: "??$multi_variadic_fn@HHH$$ZHH@@YAXHHHHH@Z"
+// X64: "??$multi_variadic_fn@HHH$$ZHH@@YAXHHHHH@Z"
+// CHECK: "??$multi_variadic_mixed@HHH$$V@@YAXHHH@Z"
+// X64: "??$multi_variadic_mixed@HHH$$V@@YAXHHH@Z"
+// CHECK: "??$multi_variadic_mixed@HHHH@@YAXHHHH@Z"
+// X64: "??$multi_variadic_mixed@HHHH@@YAXHHHH@Z"
template <typename ...Ts>
struct VariadicClass {
diff --git a/test/CodeGenCXX/mangle-ms-thunks-covariant.cpp b/test/CodeGenCXX/mangle-ms-thunks-covariant.cpp
new file mode 100644
index 000000000000..47b1a38ffe18
--- /dev/null
+++ b/test/CodeGenCXX/mangle-ms-thunks-covariant.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fno-rtti-data -std=c++11 -fms-extensions -emit-llvm %s -o - -triple=x86_64-pc-win32 -fms-compatibility-version=19.00 | FileCheck %s --check-prefix=CHECK
+
+namespace t1 {
+struct A {
+public:
+ virtual ~A();
+ virtual A *f();
+};
+struct B {
+public:
+ virtual ~B();
+
+private:
+ virtual B *f();
+};
+struct C : A, B {
+ virtual ~C();
+
+protected:
+ virtual C *f();
+};
+C c;
+}
+// Main external C::f impl:
+// CHECK-DAG: "?f@C@t1@@MEAAPEAU12@XZ"
+// New slot in C's vftable for B, returns C* directly:
+// CHECK-DAG: "?f@C@t1@@O7EAAPEAU12@XZ"
+// Return-adjusting thunk in C's vftable for B:
+// CHECK-DAG: "?f@C@t1@@W7EAAPEAUB@2@XZ"
diff --git a/test/CodeGenCXX/mangle-ms-vector-types.cpp b/test/CodeGenCXX/mangle-ms-vector-types.cpp
index f55713e6c0c8..c2461a30700f 100644
--- a/test/CodeGenCXX/mangle-ms-vector-types.cpp
+++ b/test/CodeGenCXX/mangle-ms-vector-types.cpp
@@ -94,5 +94,9 @@ typedef __attribute__((ext_vector_type(4))) int vi4b;
void foovi4b(vi4b) {}
// CHECK: define dso_local void @"?foovi4b@@YAXT?$__vector@H$03@__clang@@@Z"
+typedef float __attribute__((__ext_vector_type__(3))) vf3;
+void foovf3(vf3) {}
+// CHECK: define dso_local void @"?foovf3@@YAXT?$__vector@M$02@__clang@@@Z"
+
// Clang does not support vectors of complex types, so we can't test the
// mangling of them.
diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp
index 3cc1b1645e9c..e128c9443153 100644
--- a/test/CodeGenCXX/mangle-ms.cpp
+++ b/test/CodeGenCXX/mangle-ms.cpp
@@ -15,7 +15,7 @@ namespace N {
namespace {
int anonymous;
-// CHECK-DAG: @"?anonymous@?A@N@@3HA"
+// CHECK-DAG: @"?anonymous@?A0x{{[^@]*}}@N@@3HA"
}
}
diff --git a/test/CodeGenCXX/mangle-win-ccs.cpp b/test/CodeGenCXX/mangle-win-ccs.cpp
new file mode 100644
index 000000000000..f5ddf974cf8f
--- /dev/null
+++ b/test/CodeGenCXX/mangle-win-ccs.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple i686-windows-gnu -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple i686-windows-itanium -o - | FileCheck %s
+
+// GCC 5.1 began mangling these Windows calling conventions into function
+// types, since they can be used for overloading. They've always been mangled
+// in the MS ABI, but they are new to the Itanium mangler. Note that the main
+// function definition does not use a calling convention. Only function types
+// that appear later use it.
+
+template <typename Fn> static int func_as_ptr(Fn fn) { return int(fn); }
+
+void f_cdecl(int, int);
+void __attribute__((stdcall)) f_stdcall(int, int);
+void __attribute__((fastcall)) f_fastcall(int, int);
+void __attribute__((thiscall)) f_thiscall(int, int);
+
+int as_cdecl() { return func_as_ptr(f_cdecl); }
+int as_stdcall() { return func_as_ptr(f_stdcall); }
+int as_fastcall() { return func_as_ptr(f_fastcall); }
+
+// CHECK: define dso_local i32 @_Z8as_cdeclv()
+// CHECK: call i32 @_ZL11func_as_ptrIPFviiEEiT_(void (i32, i32)* @_Z7f_cdeclii)
+
+// CHECK: define dso_local i32 @_Z10as_stdcallv()
+// CHECK: call i32 @_ZL11func_as_ptrIPU7stdcallFviiEEiT_(void (i32, i32)* @"\01__Z9f_stdcallii@8")
+
+// CHECK: define dso_local i32 @_Z11as_fastcallv()
+// CHECK: call i32 @_ZL11func_as_ptrIPU8fastcallFviiEEiT_(void (i32, i32)* @"\01@_Z10f_fastcallii@8")
+
+// PR40107: We should mangle thiscall here but we don't because we can't
+// disambiguate it from the member pointer case below where it shouldn't be
+// mangled.
+//int as_thiscall() { return func_as_ptr(f_thiscall); }
+// CHECKX: define dso_local i32 @_Z11as_thiscallv()
+// CHECKX: call i32 @_ZL11func_as_ptrIPU8thiscallFviiEEiT_(void (i32, i32)* @_Z10f_thiscallii)
+
+// CHECK: define dso_local void @_Z11funcRefTypeRU8fastcallFviiE(void (i32, i32)* %fr)
+void funcRefType(void(__attribute__((fastcall)) & fr)(int, int)) {
+ fr(1, 2);
+}
+
+struct Foo { void bar(int, int); };
+
+// PR40107: In this case, the member function pointer uses the thiscall
+// convention, but GCC doesn't mangle it, so we don't either.
+// CHECK: define dso_local void @_Z15memptr_thiscallP3FooMS_FvvE(%struct.Foo* {{.*}})
+void memptr_thiscall(Foo *o, void (Foo::*mp)()) { (o->*mp)(); }
+
+// CHECK: define dso_local void @_Z12memptrCCTypeR3FooMS_U8fastcallFviiE(%struct.Foo* {{.*}}, { i32, i32 }* byval{{.*}})
+void memptrCCType(Foo &o, void (__attribute__((fastcall)) Foo::*mp)(int, int)) {
+ (o.*mp)(1, 2);
+}
+
+// CHECK: define dso_local i32 @_Z17useTemplateFnTypev()
+// CHECK: call i32 @_ZL14templateFnTypeIU8fastcallFviiEElPT_(void (i32, i32)* @"\01@_Z10f_fastcallii@8")
+template <typename Fn> static long templateFnType(Fn *fn) { return long(fn); }
+long useTemplateFnType() { return templateFnType(f_fastcall); }
+
+// CHECK: define weak_odr dso_local x86_fastcallcc void @"\01@_Z10fnTemplateIsEvv@0"()
+// CHECK: define dso_local x86_fastcallcc void @"\01@_Z10fnTemplateIiEvv@0"()
+template <typename T> void __attribute__((fastcall)) fnTemplate() {}
+template void __attribute__((fastcall)) fnTemplate<short>();
+template <> void __attribute__((fastcall)) fnTemplate<int>() {}
+
+// CHECK: define weak_odr dso_local x86_fastcallcc void (i32, i32)* @"\01@_Z12fnTempReturnIsEPU8fastcallFviiEv@0"()
+// CHECK: define dso_local x86_fastcallcc void (i32, i32)* @"\01@_Z12fnTempReturnIiEPU8fastcallFviiEv@0"()
+typedef void (__attribute__((fastcall)) *fp_cc_t)(int, int);
+template <typename T> fp_cc_t __attribute__((fastcall)) fnTempReturn() { return nullptr; }
+template fp_cc_t __attribute__((fastcall)) fnTempReturn<short>();
+template <> fp_cc_t __attribute__((fastcall)) fnTempReturn<int>() { return nullptr; }
diff --git a/test/CodeGenCXX/mangle-win64-ccs.cpp b/test/CodeGenCXX/mangle-win64-ccs.cpp
new file mode 100644
index 000000000000..10c0430117c5
--- /dev/null
+++ b/test/CodeGenCXX/mangle-win64-ccs.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -o - -emit-llvm %s | FileCheck %s -check-prefix CHECK-WIN
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -o - -emit-llvm %s | FileCheck %s -check-prefix CHECK-LIN
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+template <typename FTy> ptrdiff_t func_as_int(FTy *fp) { return ptrdiff_t(fp); }
+
+int f_plain(int);
+int __attribute__((sysv_abi)) f_sysvabi(int);
+int __attribute__((ms_abi)) f_msabi(int);
+ptrdiff_t useThem() {
+ ptrdiff_t rv = 0;
+ rv += func_as_int(f_plain);
+ rv += func_as_int(f_sysvabi);
+ rv += func_as_int(f_msabi);
+ return rv;
+}
+
+// CHECK-WIN: define dso_local i64 @_Z7useThemv()
+// CHECK-WIN: call i64 @_Z11func_as_intIFiiEExPT_(i32 (i32)* @_Z7f_plaini)
+// CHECK-WIN: call i64 @_Z11func_as_intIU8sysv_abiFiiEExPT_(i32 (i32)* @_Z9f_sysvabii)
+// CHECK-WIN: call i64 @_Z11func_as_intIFiiEExPT_(i32 (i32)* @_Z7f_msabii)
+
+// CHECK-LIN: define i64 @_Z7useThemv()
+// CHECK-LIN: call i64 @_Z11func_as_intIFiiEElPT_(i32 (i32)* @_Z7f_plaini)
+// CHECK-LIN: call i64 @_Z11func_as_intIFiiEElPT_(i32 (i32)* @_Z9f_sysvabii)
+// CHECK-LIN: call i64 @_Z11func_as_intIU6ms_abiFiiEElPT_(i32 (i32)* @_Z7f_msabii)
diff --git a/test/CodeGenCXX/merge-functions.cpp b/test/CodeGenCXX/merge-functions.cpp
index 2137f19c409c..20a286e02203 100644
--- a/test/CodeGenCXX/merge-functions.cpp
+++ b/test/CodeGenCXX/merge-functions.cpp
@@ -1,5 +1,5 @@
// REQUIRES: x86-registered-target
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -O1 -fmerge-functions -emit-llvm -o - -x c++ < %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -O1 -fmerge-functions -emit-llvm -o - -x c++ < %s | FileCheck %s -implicit-check-not=_ZN1A1gEiPi
// Basic functionality test. Function merging doesn't kick in on functions that
// are too simple.
@@ -9,6 +9,4 @@ struct A {
virtual int g(int x, int *p) { return x ? *p : 1; }
} a;
-// CHECK: define {{.*}} @_ZN1A1gEiPi
-// CHECK-NEXT: tail call i32 @_ZN1A1fEiPi
-// CHECK-NEXT: ret
+// CHECK: define {{.*}} @_ZN1A1fEiPi
diff --git a/test/CodeGenCXX/microsoft-abi-static-initializers.cpp b/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
index db9526633ff1..e6a0891cfc65 100644
--- a/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
+++ b/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
@@ -3,8 +3,8 @@
// CHECK: @llvm.global_ctors = appending global [5 x { i32, void ()*, i8* }] [
// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"??__Eselectany1@@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"?selectany1@@3US@@A", i32 0, i32 0) },
// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"??__Eselectany2@@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"?selectany2@@3US@@A", i32 0, i32 0) },
-// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"??__Es@?$ExportedTemplate@H@@2US@@A@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"?s@?$ExportedTemplate@H@@2US@@A", i32 0, i32 0) },
-// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"??__Efoo@?$B@H@@2VA@@A@YAXXZ", i8* bitcast (%class.A* @"?foo@?$B@H@@2VA@@A" to i8*) },
+// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"??__E?s@?$ExportedTemplate@H@@2US@@A@@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"?s@?$ExportedTemplate@H@@2US@@A", i32 0, i32 0) },
+// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"??__E?foo@?$B@H@@2VA@@A@@YAXXZ", i8* bitcast (%class.A* @"?foo@?$B@H@@2VA@@A" to i8*) },
// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_microsoft_abi_static_initializers.cpp, i8* null }
// CHECK: ]
@@ -231,18 +231,18 @@ void force_usage() {
DynamicDLLImportInitVSMangling::switch_test3();
}
-// CHECK: define linkonce_odr dso_local void @"??__Efoo@?$B@H@@2VA@@A@YAXXZ"() {{.*}} comdat
+// CHECK: define linkonce_odr dso_local void @"??__E?foo@?$B@H@@2VA@@A@@YAXXZ"() {{.*}} comdat
// CHECK-NOT: and
// CHECK-NOT: ?_Bfoo@
// CHECK: call x86_thiscallcc %class.A* @"??0A@@QAE@XZ"
-// CHECK: call i32 @atexit(void ()* @"??__Ffoo@?$B@H@@2VA@@A@YAXXZ")
+// CHECK: call i32 @atexit(void ()* @"??__F?foo@?$B@H@@2VA@@A@@YAXXZ")
// CHECK: ret void
// CHECK: define linkonce_odr dso_local x86_thiscallcc %class.A* @"??0A@@QAE@XZ"({{.*}}) {{.*}} comdat
// CHECK: define linkonce_odr dso_local x86_thiscallcc void @"??1A@@QAE@XZ"({{.*}}) {{.*}} comdat
-// CHECK: define internal void @"??__Ffoo@?$B@H@@2VA@@A@YAXXZ"
+// CHECK: define internal void @"??__F?foo@?$B@H@@2VA@@A@@YAXXZ"
// CHECK: call x86_thiscallcc void @"??1A@@QAE@XZ"{{.*}}foo
// CHECK: ret void
diff --git a/test/CodeGenCXX/microsoft-abi-structors.cpp b/test/CodeGenCXX/microsoft-abi-structors.cpp
index 97b90ce6b9eb..b0d2b5654030 100644
--- a/test/CodeGenCXX/microsoft-abi-structors.cpp
+++ b/test/CodeGenCXX/microsoft-abi-structors.cpp
@@ -467,9 +467,9 @@ struct A {
void *getA() {
return (void*)new A();
}
-// CHECK: define internal x86_thiscallcc i8* @"??_GA@?A@@UAEPAXI@Z"
+// CHECK: define internal x86_thiscallcc i8* @"??_GA@?A0x{{[^@]*}}@@UAEPAXI@Z"
// CHECK: (%"struct.(anonymous namespace)::A"* %this, i32 %should_call_delete)
-// CHECK: define internal x86_thiscallcc void @"??1A@?A@@UAE@XZ"
+// CHECK: define internal x86_thiscallcc void @"??1A@?A0x{{[^@]*}}@@UAE@XZ"
// CHECK: (%"struct.(anonymous namespace)::A"* %this)
// Check that we correctly transform __stdcall to __thiscall for ctors and
diff --git a/test/CodeGenCXX/microsoft-abi-throw.cpp b/test/CodeGenCXX/microsoft-abi-throw.cpp
index cbbce2daaad8..f55b94acf1d7 100644
--- a/test/CodeGenCXX/microsoft-abi-throw.cpp
+++ b/test/CodeGenCXX/microsoft-abi-throw.cpp
@@ -22,7 +22,7 @@
// CHECK-DAG: @_TI1P6AXXZ = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.1* @_CTA1P6AXXZ to i8*) }, section ".xdata", comdat
// CHECK-DAG: @_TIU2PAPFAH = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 4, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.2* @_CTA2PAPFAH to i8*) }, section ".xdata", comdat
// CHECK-DAG: @_CTA2PAPFAH = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.2 { i32 2, [2 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0PAPFAH@84", %eh.CatchableType* @"_CT??_R0PAX@84"] }, section ".xdata", comdat
-// CHECK-DAG: @"_TI1?AUFoo@?A@@" = internal unnamed_addr constant %eh.ThrowInfo { i32 0, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.1* @"_CTA1?AUFoo@?A@@" to i8*) }, section ".xdata"
+// CHECK-DAG: @"_TI1?AUFoo@?A0x{{[^@]*}}@@" = internal unnamed_addr constant %eh.ThrowInfo { i32 0, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.1* @"_CTA1?AUFoo@?A0x{{[^@]*}}@@" to i8*) }, section ".xdata"
struct N { ~N(); };
@@ -135,6 +135,6 @@ namespace { struct Foo { } foo_exc; }
void *GetExceptionInfo_test2() {
// CHECK-LABEL: @"?GetExceptionInfo_test2@@YAPAXXZ"
-// CHECK: ret i8* bitcast (%eh.ThrowInfo* @"_TI1?AUFoo@?A@@" to i8*)
+// CHECK: ret i8* bitcast (%eh.ThrowInfo* @"_TI1?AUFoo@?A0x{{[^@]*}}@@" to i8*)
return __GetExceptionInfo(foo_exc);
}
diff --git a/test/CodeGenCXX/microsoft-abi-thunks.cpp b/test/CodeGenCXX/microsoft-abi-thunks.cpp
index c2f64f38417c..2b0231ffe74e 100644
--- a/test/CodeGenCXX/microsoft-abi-thunks.cpp
+++ b/test/CodeGenCXX/microsoft-abi-thunks.cpp
@@ -160,5 +160,5 @@ struct E : D {
E::E() {}
E e;
// Class with internal linkage has internal linkage thunks.
-// CODEGEN: define internal x86_thiscallcc %struct.C* @"?goo@E@?A@@QAEPAUB@@XZ"
+// CODEGEN: define internal x86_thiscallcc %struct.C* @"?goo@E@?A0x{{[^@]*}}@@QAEPAUB@@XZ"
}
diff --git a/test/CodeGenCXX/microsoft-abi-vbtables.cpp b/test/CodeGenCXX/microsoft-abi-vbtables.cpp
index 46e159c628f0..ae6602053b8c 100644
--- a/test/CodeGenCXX/microsoft-abi-vbtables.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vbtables.cpp
@@ -19,7 +19,7 @@ D d; // Force vbtable emission.
// C: vbptr C
// int c
-// CHECK-DAG: @"??_8D@Test1@@7B01@@" = linkonce_odr unnamed_addr constant [4 x i32] [i32 0, i32 8, i32 12, i32 20]
+// CHECK-DAG: @"??_8D@Test1@@7B01@@" = linkonce_odr unnamed_addr constant [4 x i32] [i32 0, i32 8, i32 12, i32 20], comdat, align 4
// CHECK-DAG: @"??_8D@Test1@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 -4]
// CHECK-DAG: @"??_8D@Test1@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 -12]
// CHECK-DAG: @"??_8C@Test1@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
diff --git a/test/CodeGenCXX/microsoft-abi-vftables.cpp b/test/CodeGenCXX/microsoft-abi-vftables.cpp
index 65370ab1ece5..f8d26f14f91d 100644
--- a/test/CodeGenCXX/microsoft-abi-vftables.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vftables.cpp
@@ -36,10 +36,10 @@ struct W {
virtual ~W() {}
} w;
}
-// RTTI-DAG: [[VTABLE_W:@.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast ({{.*}} @"??_R4W@?A@@6B@" to i8*), i8* bitcast ({{.*}} @"??_GW@?A@@UAEPAXI@Z" to i8*)] }
-// RTTI-DAG: @"??_7W@?A@@6B@" = internal unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[VTABLE_W]], i32 0, i32 0, i32 1)
+// RTTI-DAG: [[VTABLE_W:@.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast ({{.*}} @"??_R4W@?A0x{{[^@]*}}@@6B@" to i8*), i8* bitcast ({{.*}} @"??_GW@?A0x{{[^@]*}}@@UAEPAXI@Z" to i8*)] }
+// RTTI-DAG: @"??_7W@?A0x{{[^@]*}}@@6B@" = internal unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[VTABLE_W]], i32 0, i32 0, i32 1)
-// NO-RTTI-DAG: @"??_7W@?A@@6B@" = internal unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast ({{.*}} @"??_GW@?A@@UAEPAXI@Z" to i8*)] }
+// NO-RTTI-DAG: @"??_7W@?A0x{{[^@]*}}@@6B@" = internal unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast ({{.*}} @"??_GW@?A0x{{[^@]*}}@@UAEPAXI@Z" to i8*)] }
struct X {};
template <class> struct Y : virtual X {
diff --git a/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp b/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp
index ef8a5e486825..5ebe612e00ac 100644
--- a/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp
+++ b/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp
@@ -57,14 +57,14 @@ void f() {
// CHECK32: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$BA@AE" to i8*), i8** %ptr
// CHECK32: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$B3AE" to i8*), i8** %ptr2
// CHECK32: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$B7AE" to i8*), i8** %ptr3
-// CHECK32: store i8* bitcast (void (%"struct.(anonymous namespace)::D"*, ...)* @"??_9D@?A@@$BA@AE" to i8*), i8** %ptr4
+// CHECK32: store i8* bitcast (void (%"struct.(anonymous namespace)::D"*, ...)* @"??_9D@?A0x{{[^@]*}}@@$BA@AE" to i8*), i8** %ptr4
// CHECK32: }
//
// CHECK64-LABEL: define dso_local void @"?f@@YAXXZ"()
// CHECK64: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$BA@AA" to i8*), i8** %ptr
// CHECK64: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$B7AA" to i8*), i8** %ptr2
// CHECK64: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$BBA@AA" to i8*), i8** %ptr3
-// CHECK64: store i8* bitcast (void (%"struct.(anonymous namespace)::D"*, ...)* @"??_9D@?A@@$BA@AA" to i8*), i8** %ptr
+// CHECK64: store i8* bitcast (void (%"struct.(anonymous namespace)::D"*, ...)* @"??_9D@?A0x{{[^@]*}}@@$BA@AA" to i8*), i8** %ptr
// CHECK64: }
}
@@ -125,7 +125,7 @@ void f() {
// CHECK64: }
// Thunk for calling the virtual function in internal class D.
-// CHECK32-LABEL: define internal x86_thiscallcc void @"??_9D@?A@@$BA@AE"(%"struct.(anonymous namespace)::D"* %this, ...)
+// CHECK32-LABEL: define internal x86_thiscallcc void @"??_9D@?A0x{{[^@]*}}@@$BA@AE"(%"struct.(anonymous namespace)::D"* %this, ...)
// CHECK32: #[[ATTR]]
// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** %{{.*}}, i64 0
// CHECK32: [[CALLEE:%.*]] = load void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** [[VPTR]]
@@ -133,7 +133,7 @@ void f() {
// CHECK32-NEXT: ret void
// CHECK32: }
//
-// CHECK64-LABEL: define internal void @"??_9D@?A@@$BA@AA"(%"struct.(anonymous namespace)::D"* %this, ...)
+// CHECK64-LABEL: define internal void @"??_9D@?A0x{{[^@]*}}@@$BA@AA"(%"struct.(anonymous namespace)::D"* %this, ...)
// CHECK64: #[[ATTR]]
// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** %{{.*}}, i64 0
// CHECK64: [[CALLEE:%.*]] = load void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** [[VPTR]]
diff --git a/test/CodeGenCXX/msabi-swiftcall-cc.cpp b/test/CodeGenCXX/msabi-swiftcall-cc.cpp
index d8205ed192a5..3cc90a83fbd1 100644
--- a/test/CodeGenCXX/msabi-swiftcall-cc.cpp
+++ b/test/CodeGenCXX/msabi-swiftcall-cc.cpp
@@ -12,8 +12,8 @@ void (__attribute__((__swiftcall__)) *p)();
namespace {
void __attribute__((__swiftcall__)) __attribute__((__used__)) f() { }
}
-// CHECK-DAG: @"?f@?A@@YSXXZ"
-// CHECK-64-DAG: @"?f@?A@@YSXXZ"
+// CHECK-DAG: @"?f@?A0x{{[^@]*}}@@YSXXZ"
+// CHECK-64-DAG: @"?f@?A0x{{[^@]*}}@@YSXXZ"
namespace n {
void __attribute__((__swiftcall__)) f() {}
@@ -44,8 +44,8 @@ void (__attribute__((__preserve_most__)) *q)();
namespace {
void __attribute__((__preserve_most__)) __attribute__((__used__)) g() {}
}
-// CHECK-DAG: @"?g@?A@@YUXXZ"
-// CHECK-64-DAG: @"?g@?A@@YUXXZ"
+// CHECK-DAG: @"?g@?A0x{{[^@]*}}@@YUXXZ"
+// CHECK-64-DAG: @"?g@?A0x{{[^@]*}}@@YUXXZ"
namespace n {
void __attribute__((__preserve_most__)) g() {}
diff --git a/test/CodeGenCXX/no-lto-unit.cpp b/test/CodeGenCXX/no-lto-unit.cpp
index 24b8fd01546a..3797f0742efb 100644
--- a/test/CodeGenCXX/no-lto-unit.cpp
+++ b/test/CodeGenCXX/no-lto-unit.cpp
@@ -2,6 +2,8 @@
// RUN: llvm-dis -o - %t | FileCheck %s
// RUN: %clang_cc1 -flto=thin -flto-unit -fno-lto-unit -triple x86_64-unknown-linux -fvisibility hidden -emit-llvm-bc -o %t %s
// RUN: llvm-dis -o - %t | FileCheck %s
+// RUN: llvm-bcanalyzer -dump %t | FileCheck %s --check-prefix=NOLTOUNIT
+// NOLTOUNIT: <FLAGS op0=0/>
// CHECK-NOT: !type
class A {
diff --git a/test/CodeGenCXX/no_destroy.cpp b/test/CodeGenCXX/no_destroy.cpp
new file mode 100644
index 000000000000..93e6ce17bb69
--- /dev/null
+++ b/test/CodeGenCXX/no_destroy.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-apple-macosx10.13.0 -o - | FileCheck %s
+
+struct NonTrivial {
+ ~NonTrivial();
+};
+
+// CHECK-NOT: __cxa_atexit{{.*}}_ZN10NonTrivialD1Ev
+[[clang::no_destroy]] NonTrivial nt1;
+// CHECK-NOT: _tlv_atexit{{.*}}_ZN10NonTrivialD1Ev
+[[clang::no_destroy]] thread_local NonTrivial nt2;
+
+struct NonTrivial2 {
+ ~NonTrivial2();
+};
+
+// CHECK: __cxa_atexit{{.*}}_ZN11NonTrivial2D1Ev
+NonTrivial2 nt21;
+// CHECK: _tlv_atexit{{.*}}_ZN11NonTrivial2D1Ev
+thread_local NonTrivial2 nt22;
+
+void f() {
+ // CHECK: __cxa_atexit{{.*}}_ZN11NonTrivial2D1Ev
+ static NonTrivial2 nt21;
+ // CHECK: _tlv_atexit{{.*}}_ZN11NonTrivial2D1Ev
+ thread_local NonTrivial2 nt22;
+}
+
+// CHECK: __cxa_atexit{{.*}}_ZN10NonTrivialD1Ev
+[[clang::always_destroy]] NonTrivial nt3;
+// CHECK: _tlv_atexit{{.*}}_ZN10NonTrivialD1Ev
+[[clang::always_destroy]] thread_local NonTrivial nt4;
diff --git a/test/CodeGenCXX/noescape.cpp b/test/CodeGenCXX/noescape.cpp
index 90d24de3da29..40bc839788ac 100644
--- a/test/CodeGenCXX/noescape.cpp
+++ b/test/CodeGenCXX/noescape.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -fblocks -o - %s | FileCheck %s
struct S {
int a[4];
@@ -65,3 +65,32 @@ typedef void (*NoEscapeFunc)(__attribute__((noescape)) int *);
void test3(NoEscapeFunc f, int *p) {
f(p);
}
+
+namespace TestByref {
+
+struct S {
+ S();
+ ~S();
+ S(const S &);
+ int a;
+};
+
+typedef void (^BlockTy)(void);
+S &getS();
+void noescapefunc(__attribute__((noescape)) BlockTy);
+
+// Check that __block variables with reference types are handled correctly.
+
+// CHECK: define void @_ZN9TestByref4testEv(
+// CHECK: %[[X:.*]] = alloca %[[STRUCT_TESTBYREF:.*]]*, align 8
+// CHECK: %[[BLOCK:.*]] = alloca <{ i8*, i32, i32, i8*, %{{.*}}*, %[[STRUCT_TESTBYREF]]* }>, align 8
+// CHECK: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %{{.*}}*, %[[STRUCT_TESTBYREF]]* }>, <{ i8*, i32, i32, i8*, %{{.*}}*, %[[STRUCT_TESTBYREF]]* }>* %[[BLOCK]], i32 0, i32 5
+// CHECK: %[[V0:.*]] = load %[[STRUCT_TESTBYREF]]*, %[[STRUCT_TESTBYREF]]** %[[X]], align 8
+// CHECK: store %[[STRUCT_TESTBYREF]]* %[[V0]], %[[STRUCT_TESTBYREF]]** %[[BLOCK_CAPTURED]], align 8
+
+void test() {
+ __block S &x = getS();
+ noescapefunc(^{ (void)x; });
+}
+
+}
diff --git a/test/CodeGenCXX/override-layout-packed-base.cpp b/test/CodeGenCXX/override-layout-packed-base.cpp
index 26ed4b5d815a..03255f2f6ebf 100644
--- a/test/CodeGenCXX/override-layout-packed-base.cpp
+++ b/test/CodeGenCXX/override-layout-packed-base.cpp
@@ -1,26 +1,40 @@
-// RUN: %clang_cc1 -w -fdump-record-layouts-simple -foverride-record-layout=%S/Inputs/override-layout-packed-base.layout %s | FileCheck %s
+// RUN: %clang_cc1 -triple i686-windows-msvc -w -fdump-record-layouts-simple -foverride-record-layout=%S/Inputs/override-layout-packed-base.layout %s | FileCheck %s
+
+//#pragma pack(push, 1)
// CHECK: Type: class B<0>
+// CHECK: Size:40
// CHECK: FieldOffsets: [0, 32]
// CHECK: Type: class B<1>
+// CHECK: Size:40
// CHECK: FieldOffsets: [0, 32]
-//#pragma pack(push, 1)
template<int I>
class B {
int _b1;
char _b2;
};
-//#pragma pack(pop)
// CHECK: Type: class C
+// CHECK: Size:88
// CHECK: FieldOffsets: [80]
class C : B<0>, B<1> {
char _c;
};
+// CHECK: Type: class D
+// CHECK: Size:120
+// CHECK: FieldOffsets: [32]
+
+class D : virtual B<0>, virtual B<1> {
+ char _d;
+};
+
+//#pragma pack(pop)
+
void use_structs() {
C cs[sizeof(C)];
+ D ds[sizeof(D)];
}
diff --git a/test/CodeGenCXX/pragma-init_seg.cpp b/test/CodeGenCXX/pragma-init_seg.cpp
index 8b33b854fd21..f0b15598c472 100644
--- a/test/CodeGenCXX/pragma-init_seg.cpp
+++ b/test/CodeGenCXX/pragma-init_seg.cpp
@@ -28,8 +28,8 @@ int z = f();
namespace internal_init {
namespace {
int x = f();
-// CHECK: @"?x@?A@internal_init@@3HA" = internal global i32 0, align 4
-// CHECK: @__cxx_init_fn_ptr.2 = private constant void ()* @"??__Ex@?A@internal_init@@YAXXZ", section ".asdf"
+// CHECK: @"?x@?A0x{{[^@]*}}@internal_init@@3HA" = internal global i32 0, align 4
+// CHECK: @__cxx_init_fn_ptr.2 = private constant void ()* @"??__Ex@?A0x{{[^@]*}}@internal_init@@YAXXZ", section ".asdf"
}
}
@@ -44,7 +44,7 @@ template <typename T> struct A { static const int x; };
template <typename T> const int A<T>::x = f();
template struct A<int>;
// CHECK: @"?x@?$A@H@explicit_template_instantiation@@2HB" = weak_odr dso_local global i32 0, comdat, align 4
-// CHECK: @__cxx_init_fn_ptr.4 = private constant void ()* @"??__Ex@?$A@H@explicit_template_instantiation@@2HB@YAXXZ", section ".asdf", comdat($"?x@?$A@H@explicit_template_instantiation@@2HB")
+// CHECK: @__cxx_init_fn_ptr.4 = private constant void ()* @"??__E?x@?$A@H@explicit_template_instantiation@@2HB@@YAXXZ", section ".asdf", comdat($"?x@?$A@H@explicit_template_instantiation@@2HB")
}
namespace implicit_template_instantiation {
@@ -52,7 +52,7 @@ template <typename T> struct A { static const int x; };
template <typename T> const int A<T>::x = f();
int g() { return A<int>::x; }
// CHECK: @"?x@?$A@H@implicit_template_instantiation@@2HB" = linkonce_odr dso_local global i32 0, comdat, align 4
-// CHECK: @__cxx_init_fn_ptr.5 = private constant void ()* @"??__Ex@?$A@H@implicit_template_instantiation@@2HB@YAXXZ", section ".asdf", comdat($"?x@?$A@H@implicit_template_instantiation@@2HB")
+// CHECK: @__cxx_init_fn_ptr.5 = private constant void ()* @"??__E?x@?$A@H@implicit_template_instantiation@@2HB@@YAXXZ", section ".asdf", comdat($"?x@?$A@H@implicit_template_instantiation@@2HB")
}
// ... and here's where we emitted user level ctors.
diff --git a/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp b/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp
new file mode 100644
index 000000000000..da060f7902ef
--- /dev/null
+++ b/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+// Verify that the outer loop has the llvm.access.group property for the
+// accesses outside and inside the inner loop, even when the inner loop
+// is not perfectly nested.
+void vectorize_imperfectly_nested_test(int *List, int Length) {
+#pragma clang loop vectorize(assume_safety) interleave(disable) unroll(disable)
+ for (int i = 0; i < Length; ++i) {
+ List[i * Length] = 42;
+#pragma clang loop vectorize(assume_safety) interleave(disable) unroll(disable)
+ for (int j = 1; j < Length - 1; ++j)
+ List[i * Length + j] = (i + j) * 2;
+ List[(i + 1) * Length - 1] = 21;
+ }
+}
+
+
+// CHECK: load i32, i32* %Length.addr, align 4, !llvm.access.group ![[ACCESS_GROUP_2:[0-9]+]]
+
+// CHECK: %[[MUL:.+]] = mul nsw i32 %add, 2
+// CHECK: store i32 %[[MUL]], i32* %{{.+}}, !llvm.access.group ![[ACCESS_GROUP_3:[0-9]+]]
+// CHECK: br label %{{.+}}, !llvm.loop ![[INNER_LOOPID:[0-9]+]]
+// CHECK: store i32 21, i32* %{{.+}}, !llvm.access.group ![[ACCESS_GROUP_2]]
+// CHECK: br label %{{.+}}, !llvm.loop ![[OUTER_LOOPID:[0-9]+]]
+
+// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
+// CHECK: ![[ACCESS_GROUP_LIST_3:[0-9]+]] = !{![[ACCESS_GROUP_2]], ![[ACCESS_GROUP_4:[0-9]+]]}
+// CHECK: ![[ACCESS_GROUP_4]] = distinct !{}
+// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_8:[0-9]+]]}
+// CHECK: ![[PARALLEL_ACCESSES_8]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_4]]}
+// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_10:[0-9]+]]}
+// CHECK: ![[PARALLEL_ACCESSES_10]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
diff --git a/test/CodeGenCXX/pragma-loop-safety-nested.cpp b/test/CodeGenCXX/pragma-loop-safety-nested.cpp
new file mode 100644
index 000000000000..deec06bbc827
--- /dev/null
+++ b/test/CodeGenCXX/pragma-loop-safety-nested.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+// Verify that the outer loop has the llvm.access.group property for the
+// accesses outside and inside the inner loop.
+void vectorize_nested_test(int *List, int Length) {
+#pragma clang loop vectorize(assume_safety) interleave(disable) unroll(disable)
+ for (int i = 0; i < Length; ++i) {
+#pragma clang loop vectorize(assume_safety) interleave(disable) unroll(disable)
+ for (int j = 0; j < Length; ++j)
+ List[i * Length + j] = (i + j) * 2;
+ }
+}
+
+
+// CHECK: load i32, i32* %Length.addr, align 4, !llvm.access.group ![[ACCESS_GROUP_2:[0-9]+]]
+// CHECK: %[[MUL:.+]] = mul
+// CHECK: store i32 %[[MUL]], i32* %{{.+}}, !llvm.access.group ![[ACCESS_GROUP_LIST_3:[0-9]+]]
+// CHECK: br label %{{.+}}, !llvm.loop ![[INNER_LOOPID:[0-9]+]]
+// CHECK: br label %{{.+}}, !llvm.loop ![[OUTER_LOOPID:[0-9]+]]
+
+// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
+// CHECK: ![[ACCESS_GROUP_LIST_3]] = !{![[ACCESS_GROUP_2]], ![[ACCESS_GROUP_4:[0-9]+]]}
+// CHECK: ![[ACCESS_GROUP_4]] = distinct !{}
+// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_8:[0-9]+]]}
+// CHECK: ![[PARALLEL_ACCESSES_8]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_4]]}
+// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_10:[0-9]+]]}
+// CHECK: ![[PARALLEL_ACCESSES_10]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
diff --git a/test/CodeGenCXX/pragma-loop-safety-outer.cpp b/test/CodeGenCXX/pragma-loop-safety-outer.cpp
new file mode 100644
index 000000000000..d99b86ffe23a
--- /dev/null
+++ b/test/CodeGenCXX/pragma-loop-safety-outer.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+// Verify that the outer loop has the inner loop's access in its
+// llvm.loop.parallel_accesses property.
+void vectorize_outer_test(int *List, int Length) {
+#pragma clang loop vectorize(assume_safety) interleave(disable) unroll(disable)
+ for (int i = 0; i < Length; i += 2) {
+#pragma clang loop unroll(full)
+ for (int j = 0; j < 2; j += 1)
+ List[i + j] = (i + j) * 2;
+ }
+}
+
+// CHECK: %[[MUL:.+]] = mul
+// CHECK: store i32 %[[MUL]], i32* %{{.+}}, !llvm.access.group ![[ACCESS_GROUP_2:[0-9]+]]
+// CHECK: br label %{{.+}}, !llvm.loop ![[INNER_LOOPID:[0-9]+]]
+// CHECK: br label %{{.+}}, !llvm.loop ![[OUTER_LOOPID:[0-9]+]]
+
+// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
+// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]],
+// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_9:[0-9]+]]}
+// CHECK: ![[PARALLEL_ACCESSES_9]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
diff --git a/test/CodeGenCXX/pragma-loop-safety.cpp b/test/CodeGenCXX/pragma-loop-safety.cpp
index c6ce82737d0b..c0b10b0a6bd1 100644
--- a/test/CodeGenCXX/pragma-loop-safety.cpp
+++ b/test/CodeGenCXX/pragma-loop-safety.cpp
@@ -3,19 +3,19 @@
// Verify assume_safety vectorization is recognized.
void vectorize_test(int *List, int Length) {
// CHECK: define {{.*}} @_Z14vectorize_test
-// CHECK: [[LOAD1_IV:.+]] = load i32, i32* [[IV1:[^,]+]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID:[0-9]+]]
-// CHECK-NEXT: [[LOAD1_LEN:.+]] = load i32, i32* [[LEN1:.+]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
+// CHECK: [[LOAD1_IV:.+]] = load i32, i32* [[IV1:[^,]+]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_2:[0-9]+]]
+// CHECK-NEXT: [[LOAD1_LEN:.+]] = load i32, i32* [[LEN1:.+]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_2]]
// CHECK-NEXT: [[CMP1:.+]] = icmp slt i32[[LOAD1_IV]],[[LOAD1_LEN]]
// CHECK-NEXT: br i1[[CMP1]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]]
#pragma clang loop vectorize(assume_safety) interleave(disable) unroll(disable)
for (int i = 0; i < Length; i++) {
- // CHECK: [[RHIV1:.+]] = load i32, i32* [[IV1]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
+ // CHECK: [[RHIV1:.+]] = load i32, i32* [[IV1]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_2]]
// CHECK-DAG: [[CALC1:.+]] = mul nsw i32[[RHIV1]], 2
- // CHECK-DAG: [[SIV1:.+]] = load i32, i32* [[IV1]]{{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
+ // CHECK-DAG: [[SIV1:.+]] = load i32, i32* [[IV1]]{{.*}}!llvm.access.group ![[ACCESS_GROUP_2]]
// CHECK-DAG: [[INDEX1:.+]] = sext i32[[SIV1]] to i64
- // CHECK-DAG: [[ARRAY1:.+]] = load i32*, i32** [[LIST1:.*]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
+ // CHECK-DAG: [[ARRAY1:.+]] = load i32*, i32** [[LIST1:.*]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_2]]
// CHECK-DAG: [[PTR1:.+]] = getelementptr inbounds i32, i32*[[ARRAY1]], i64[[INDEX1]]
- // CHECK: store i32[[CALC1]], i32*[[PTR1]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
+ // CHECK: store i32[[CALC1]], i32*[[PTR1]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_2]]
// CHECK-NEXT: br label [[LOOP1_INC:[^,]+]]
List[i] = i * 2;
@@ -26,19 +26,19 @@ void vectorize_test(int *List, int Length) {
// Verify assume_safety interleaving is recognized.
void interleave_test(int *List, int Length) {
// CHECK: define {{.*}} @_Z15interleave_test
-// CHECK: [[LOAD2_IV:.+]] = load i32, i32* [[IV2:[^,]+]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID:[0-9]+]]
-// CHECK-NEXT: [[LOAD2_LEN:.+]] = load i32, i32* [[LEN2:.+]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
+// CHECK: [[LOAD2_IV:.+]] = load i32, i32* [[IV2:[^,]+]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_8:[0-9]+]]
+// CHECK-NEXT: [[LOAD2_LEN:.+]] = load i32, i32* [[LEN2:.+]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_8]]
// CHECK-NEXT: [[CMP2:.+]] = icmp slt i32[[LOAD2_IV]],[[LOAD2_LEN]]
// CHECK-NEXT: br i1[[CMP2]], label %[[LOOP2_BODY:[^,]+]], label %[[LOOP2_END:[^,]+]]
#pragma clang loop interleave(assume_safety) vectorize(disable) unroll(disable)
for (int i = 0; i < Length; i++) {
- // CHECK: [[RHIV2:.+]] = load i32, i32* [[IV2]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
+ // CHECK: [[RHIV2:.+]] = load i32, i32* [[IV2]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_8]]
// CHECK-DAG: [[CALC2:.+]] = mul nsw i32[[RHIV2]], 2
- // CHECK-DAG: [[SIV2:.+]] = load i32, i32* [[IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
+ // CHECK-DAG: [[SIV2:.+]] = load i32, i32* [[IV2]]{{.*}}!llvm.access.group ![[ACCESS_GROUP_8]]
// CHECK-DAG: [[INDEX2:.+]] = sext i32[[SIV2]] to i64
- // CHECK-DAG: [[ARRAY2:.+]] = load i32*, i32** [[LIST2:.*]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
+ // CHECK-DAG: [[ARRAY2:.+]] = load i32*, i32** [[LIST2:.*]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_8]]
// CHECK-DAG: [[PTR2:.+]] = getelementptr inbounds i32, i32*[[ARRAY2]], i64[[INDEX2]]
- // CHECK: store i32[[CALC2]], i32*[[PTR2]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
+ // CHECK: store i32[[CALC2]], i32*[[PTR2]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_8]]
// CHECK-NEXT: br label [[LOOP2_INC:[^,]+]]
List[i] = i * 2;
@@ -46,9 +46,13 @@ void interleave_test(int *List, int Length) {
}
}
-// CHECK: ![[LOOP1_HINTS]] = distinct !{![[LOOP1_HINTS]], ![[INTERLEAVE_1:[0-9]+]], ![[INTENABLE_1:[0-9]+]], ![[UNROLL_DISABLE:[0-9]+]]}
+// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
+// CHECK: ![[LOOP1_HINTS]] = distinct !{![[LOOP1_HINTS]], ![[INTERLEAVE_1:[0-9]+]], ![[INTENABLE_1:[0-9]+]], ![[UNROLL_DISABLE:[0-9]+]], ![[PARALLEL_ACCESSES_7:[0-9]+]]}
// CHECK: ![[INTERLEAVE_1]] = !{!"llvm.loop.interleave.count", i32 1}
// CHCCK: ![[INTENABLE_1]] = !{!"llvm.loop.vectorize.enable", i1 true}
// CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
-// CHECK: ![[LOOP2_HINTS]] = distinct !{![[LOOP2_HINTS]], ![[WIDTH_1:[0-9]+]], ![[INTENABLE_1]], ![[UNROLL_DISABLE]]}
+// CHECK: ![[PARALLEL_ACCESSES_7]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
+// CHECK: ![[ACCESS_GROUP_8]] = distinct !{}
+// CHECK: ![[LOOP2_HINTS]] = distinct !{![[LOOP2_HINTS]], ![[WIDTH_1:[0-9]+]], ![[INTENABLE_1]], ![[UNROLL_DISABLE]], ![[PARALLEL_ACCESSES_11:[0-9]+]]}
// CHECK: ![[WIDTH_1]] = !{!"llvm.loop.vectorize.width", i32 1}
+// CHECK: ![[PARALLEL_ACCESSES_11]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_8]]}
diff --git a/test/CodeGenCXX/pragma-pipeline.cpp b/test/CodeGenCXX/pragma-pipeline.cpp
new file mode 100644
index 000000000000..6846f1544365
--- /dev/null
+++ b/test/CodeGenCXX/pragma-pipeline.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -triple hexagon -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+void pipeline_disabled(int *List, int Length, int Value) {
+// CHECK-LABEL: define {{.*}} @_Z17pipeline_disabled
+#pragma clang loop pipeline(disable)
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
+ List[i] = Value;
+ }
+}
+
+void pipeline_not_disabled(int *List, int Length, int Value) {
+ // CHECK-LABEL: define {{.*}} @_Z21pipeline_not_disabled
+ for (int i = 0; i < Length; i++) {
+ List[i] = Value;
+ }
+}
+
+void pipeline_initiation_interval(int *List, int Length, int Value) {
+// CHECK-LABEL: define {{.*}} @_Z28pipeline_initiation_interval
+#pragma clang loop pipeline_initiation_interval(10)
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_3:.*]]
+ List[i] = Value;
+ }
+}
+
+void pipeline_disabled_on_nested_loop(int *List, int Length, int Value) {
+ // CHECK-LABEL: define {{.*}} @_Z32pipeline_disabled_on_nested_loop
+ for (int i = 0; i < Length; i++) {
+#pragma clang loop pipeline(disable)
+ for (int j = 0; j < Length; j++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_4:.*]]
+ List[i * Length + j] = Value;
+ }
+ }
+}
+
+// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[PIPELINE_DISABLE:.*]]}
+// CHECK: ![[PIPELINE_DISABLE]] = !{!"llvm.loop.pipeline.disable", i1 true}
+
+// CHECK-NOT:llvm.loop.pipeline
+
+// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[PIPELINE_II_10:.*]]}
+// CHECK: ![[PIPELINE_II_10]] = !{!"llvm.loop.pipeline.initiationinterval", i32 10}
+
+// CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], ![[PIPELINE_DISABLE]]}
diff --git a/test/CodeGenCXX/pragma-unroll-and-jam.cpp b/test/CodeGenCXX/pragma-unroll-and-jam.cpp
new file mode 100644
index 000000000000..984212603450
--- /dev/null
+++ b/test/CodeGenCXX/pragma-unroll-and-jam.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -triple arm-none-eabi -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+void unroll_and_jam(int *List, int Length, int Value) {
+ // CHECK-LABEL: define {{.*}} @_Z14unroll_and_jam
+#pragma unroll_and_jam
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
+ List[i * Length + j] = Value;
+ }
+ }
+}
+
+void unroll_and_jam_count(int *List, int Length, int Value) {
+ // CHECK-LABEL: define {{.*}} @_Z20unroll_and_jam_count
+#pragma unroll_and_jam(4)
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_2:.*]]
+ List[i * Length + j] = Value;
+ }
+ }
+}
+
+void nounroll_and_jam(int *List, int Length, int Value) {
+ // CHECK-LABEL: define {{.*}} @_Z16nounroll_and_jam
+#pragma nounroll_and_jam
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_3:.*]]
+ List[i * Length + j] = Value;
+ }
+ }
+}
+
+void clang_unroll_plus_nounroll_and_jam(int *List, int Length, int Value) {
+ // CHECK-LABEL: define {{.*}} @_Z34clang_unroll_plus_nounroll_and_jam
+#pragma nounroll_and_jam
+#pragma unroll(4)
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_7:.*]]
+ List[i * Length + j] = Value;
+ }
+ }
+}
+
+// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[UNJ_ENABLE:.*]]}
+// CHECK: ![[UNJ_ENABLE]] = !{!"llvm.loop.unroll_and_jam.enable"}
+// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2]], ![[UNJ_4:.*]]}
+// CHECK: ![[UNJ_4]] = !{!"llvm.loop.unroll_and_jam.count", i32 4}
+// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[UNJ_DISABLE:.*]]}
+// CHECK: ![[UNJ_DISABLE]] = !{!"llvm.loop.unroll_and_jam.disable"}
+// CHECK: ![[LOOP_7]] = distinct !{![[LOOP_7]], ![[UNROLL_4:.*]], ![[UNJ_DISABLE:.*]]}
+// CHECK: ![[UNROLL_4]] = !{!"llvm.loop.unroll.count", i32 4}
diff --git a/test/CodeGenCXX/profile-remap.cpp b/test/CodeGenCXX/profile-remap.cpp
new file mode 100644
index 000000000000..0fc7c7b40033
--- /dev/null
+++ b/test/CodeGenCXX/profile-remap.cpp
@@ -0,0 +1,29 @@
+// REQUIRES: x86-registered-target
+//
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fprofile-sample-use=%S/Inputs/profile-remap.samples -fprofile-remapping-file=%S/Inputs/profile-remap.map -fexperimental-new-pass-manager -O2 %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SAMPLES
+// RUN: llvm-profdata merge -output %T.profdata %S/Inputs/profile-remap.proftext
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fprofile-instrument-use-path=%T.profdata -fprofile-remapping-file=%S/Inputs/profile-remap.map -fexperimental-new-pass-manager -O2 %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-INSTR
+
+namespace Foo {
+ struct X {};
+ bool cond();
+ void bar();
+ void baz();
+ void function(X x) {
+ if (cond())
+ bar();
+ else
+ baz();
+ }
+}
+
+// CHECK: define {{.*}} @_ZN3Foo8functionENS_1XE() {{.*}} !prof [[FUNC_ENTRY:![0-9]*]]
+// CHECK: br i1 {{.*}} !prof [[BR_WEIGHTS:![0-9]*]]
+//
+// FIXME: Laplace's rule of succession is applied to sample profiles...
+// CHECK-SAMPLES-DAG: [[FUNC_ENTRY]] = !{!"function_entry_count", i64 1}
+// CHECK-SAMPLES-DAG: [[BR_WEIGHTS]] = !{!"branch_weights", i32 11, i32 91}
+//
+// ... but not to instruction profiles.
+// CHECK-INSTR-DAG: [[FUNC_ENTRY]] = !{!"function_entry_count", i64 100}
+// CHECK-INSTR-DAG: [[BR_WEIGHTS]] = !{!"branch_weights", i32 10, i32 90}
diff --git a/test/CodeGenCXX/speculative-vtt.cpp b/test/CodeGenCXX/speculative-vtt.cpp
new file mode 100644
index 000000000000..120d95d4d482
--- /dev/null
+++ b/test/CodeGenCXX/speculative-vtt.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu %s -O2 -disable-llvm-passes -emit-llvm -o - | FileCheck %s
+struct A { virtual ~A(); };
+template<typename T> struct B : virtual A {
+ ~B() override {}
+};
+struct C : B<int>, B<float> { C(); ~C() override; };
+struct D : C { ~D() override; };
+
+// We must not create a reference to B<int>::~B() here, because we're not going to emit it.
+// CHECK-NOT: @_ZN1BIiED1Ev
+// CHECK-NOT: @_ZTC1D0_1BIiE =
+// CHECK-NOT: @_ZTT1D = available_externally
+D *p = new D;
diff --git a/test/CodeGenCXX/static-init-wasm.cpp b/test/CodeGenCXX/static-init-wasm.cpp
index 68d139157e2d..579818ce5a20 100644
--- a/test/CodeGenCXX/static-init-wasm.cpp
+++ b/test/CodeGenCXX/static-init-wasm.cpp
@@ -38,7 +38,7 @@ void g() {
// Test various aspects of static constructor calls.
struct A {
- A();
+ A();
};
A theA;
diff --git a/test/CodeGenCXX/thunk-returning-memptr.cpp b/test/CodeGenCXX/thunk-returning-memptr.cpp
new file mode 100644
index 000000000000..0b7870c6d658
--- /dev/null
+++ b/test/CodeGenCXX/thunk-returning-memptr.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple=i686 -emit-llvm -o - %s | FileCheck %s
+
+
+struct X;
+typedef void (X::*memptr)();
+
+struct A {
+ virtual memptr f();
+};
+
+struct B {
+ virtual memptr f();
+};
+
+struct C : A, B {
+ C();
+ memptr f() override __attribute__((noinline)) { return nullptr; };
+};
+
+C::C() {}
+
+// Make sure the member pointer is returned from the thunk via the return slot.
+// Because of the tail call, the return value cannot be copied into a local
+// alloca. (PR39901)
+
+// CHECK-LABEL: define linkonce_odr void @_ZThn4_N1C1fEv({ i32, i32 }* noalias sret %agg.result, %struct.C* %this)
+// CHECK: tail call void @_ZN1C1fEv({ i32, i32 }* sret %agg.result
diff --git a/test/CodeGenCXX/trivial-auto-var-init-attribute.cpp b/test/CodeGenCXX/trivial-auto-var-init-attribute.cpp
new file mode 100644
index 000000000000..e7c9e9ac2a5a
--- /dev/null
+++ b/test/CodeGenCXX/trivial-auto-var-init-attribute.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks %s -emit-llvm -o - | FileCheck %s -check-prefix=UNINIT
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s -check-prefix=PATTERN
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s -check-prefix=ZERO
+
+template<typename T> void used(T &) noexcept;
+
+extern "C" {
+
+// UNINIT-LABEL: test_attribute_uninitialized(
+// UNINIT: alloca
+// UNINIT-NEXT: call void
+// ZERO-LABEL: test_attribute_uninitialized(
+// ZERO: alloca
+// ZERO-NEXT: call void
+// PATTERN-LABEL: test_attribute_uninitialized(
+// PATTERN: alloca
+// PATTERN-NEXT: call void
+void test_attribute_uninitialized() {
+ [[clang::uninitialized]] int i;
+ used(i);
+}
+
+} // extern "C"
diff --git a/test/CodeGenCXX/trivial-auto-var-init.cpp b/test/CodeGenCXX/trivial-auto-var-init.cpp
new file mode 100644
index 000000000000..b795c0755bd4
--- /dev/null
+++ b/test/CodeGenCXX/trivial-auto-var-init.cpp
@@ -0,0 +1,216 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks %s -emit-llvm -o - | FileCheck %s -check-prefix=UNINIT
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s -check-prefix=PATTERN
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s -check-prefix=ZERO
+
+// None of the synthesized globals should contain `undef`.
+// PATTERN-NOT: undef
+// ZERO-NOT: undef
+
+template<typename T> void used(T &) noexcept;
+
+extern "C" {
+
+// UNINIT-LABEL: test_selfinit(
+// ZERO-LABEL: test_selfinit(
+// ZERO: store i32 0, i32* %self, align 4
+// PATTERN-LABEL: test_selfinit(
+// PATTERN: store i32 -1431655766, i32* %self, align 4
+void test_selfinit() {
+ int self = self + 1;
+ used(self);
+}
+
+// UNINIT-LABEL: test_block(
+// ZERO-LABEL: test_block(
+// ZERO: store i32 0, i32* %block
+// PATTERN-LABEL: test_block(
+// PATTERN: store i32 -1431655766, i32* %block
+void test_block() {
+ __block int block;
+ used(block);
+}
+
+// This type of code is currently not handled by zero / pattern initialization.
+// The test will break when that is fixed.
+// UNINIT-LABEL: test_goto_unreachable_value(
+// ZERO-LABEL: test_goto_unreachable_value(
+// ZERO-NOT: store {{.*}}%oops
+// PATTERN-LABEL: test_goto_unreachable_value(
+// PATTERN-NOT: store {{.*}}%oops
+void test_goto_unreachable_value() {
+ goto jump;
+ int oops;
+ jump:
+ used(oops);
+}
+
+// This type of code is currently not handled by zero / pattern initialization.
+// The test will break when that is fixed.
+// UNINIT-LABEL: test_goto(
+// ZERO-LABEL: test_goto(
+// ZERO: if.then:
+// ZERO: br label %jump
+// ZERO: store i32 0, i32* %oops, align 4
+// ZERO: br label %jump
+// ZERO: jump:
+// PATTERN-LABEL: test_goto(
+// PATTERN: if.then:
+// PATTERN: br label %jump
+// PATTERN: store i32 -1431655766, i32* %oops, align 4
+// PATTERN: br label %jump
+// PATTERN: jump:
+void test_goto(int i) {
+ if (i)
+ goto jump;
+ int oops;
+ jump:
+ used(oops);
+}
+
+// This type of code is currently not handled by zero / pattern initialization.
+// The test will break when that is fixed.
+// UNINIT-LABEL: test_switch(
+// ZERO-LABEL: test_switch(
+// ZERO: sw.bb:
+// ZERO-NEXT: store i32 0, i32* %oops, align 4
+// ZERO: sw.bb1:
+// ZERO-NEXT: call void @{{.*}}used
+// PATTERN-LABEL: test_switch(
+// PATTERN: sw.bb:
+// PATTERN-NEXT: store i32 -1431655766, i32* %oops, align 4
+// PATTERN: sw.bb1:
+// PATTERN-NEXT: call void @{{.*}}used
+void test_switch(int i) {
+ switch (i) {
+ case 0:
+ int oops;
+ break;
+ case 1:
+ used(oops);
+ }
+}
+
+// UNINIT-LABEL: test_vla(
+// ZERO-LABEL: test_vla(
+// ZERO: %[[SIZE:[0-9]+]] = mul nuw i64 %{{.*}}, 4
+// ZERO: call void @llvm.memset{{.*}}(i8* align 16 %{{.*}}, i8 0, i64 %[[SIZE]], i1 false)
+// PATTERN-LABEL: test_vla(
+// PATTERN: %vla.iszerosized = icmp eq i64 %{{.*}}, 0
+// PATTERN: br i1 %vla.iszerosized, label %vla-init.cont, label %vla-setup.loop
+// PATTERN: vla-setup.loop:
+// PATTERN: %[[SIZE:[0-9]+]] = mul nuw i64 %{{.*}}, 4
+// PATTERN: %vla.begin = bitcast i32* %vla to i8*
+// PATTERN: %vla.end = getelementptr inbounds i8, i8* %vla.begin, i64 %[[SIZE]]
+// PATTERN: br label %vla-init.loop
+// PATTERN: vla-init.loop:
+// PATTERN: %vla.cur = phi i8* [ %vla.begin, %vla-setup.loop ], [ %vla.next, %vla-init.loop ]
+// PATTERN: call void @llvm.memcpy{{.*}} %vla.cur, {{.*}}@__const.test_vla.vla
+// PATTERN: %vla.next = getelementptr inbounds i8, i8* %vla.cur, i64 4
+// PATTERN: %vla-init.isdone = icmp eq i8* %vla.next, %vla.end
+// PATTERN: br i1 %vla-init.isdone, label %vla-init.cont, label %vla-init.loop
+// PATTERN: vla-init.cont:
+// PATTERN: call void @{{.*}}used
+void test_vla(int size) {
+ // Variable-length arrays can't have a zero size according to C11 6.7.6.2/5.
+ // Neither can they be negative-sized.
+ //
+ // We don't use the former fact because some code creates zero-sized VLAs and
+ // doesn't use them. clang makes these share locations with other stack
+ // values, which leads to initialization of the wrong values.
+ //
+ // We rely on the later fact because it generates better code.
+ //
+ // Both cases are caught by UBSan.
+ int vla[size];
+ int *ptr = vla;
+ used(ptr);
+}
+
+// UNINIT-LABEL: test_struct_vla(
+// ZERO-LABEL: test_struct_vla(
+// ZERO: %[[SIZE:[0-9]+]] = mul nuw i64 %{{.*}}, 16
+// ZERO: call void @llvm.memset{{.*}}(i8* align 16 %{{.*}}, i8 0, i64 %[[SIZE]], i1 false)
+// PATTERN-LABEL: test_struct_vla(
+// PATTERN: %vla.iszerosized = icmp eq i64 %{{.*}}, 0
+// PATTERN: br i1 %vla.iszerosized, label %vla-init.cont, label %vla-setup.loop
+// PATTERN: vla-setup.loop:
+// PATTERN: %[[SIZE:[0-9]+]] = mul nuw i64 %{{.*}}, 16
+// PATTERN: %vla.begin = bitcast %struct.anon* %vla to i8*
+// PATTERN: %vla.end = getelementptr inbounds i8, i8* %vla.begin, i64 %[[SIZE]]
+// PATTERN: br label %vla-init.loop
+// PATTERN: vla-init.loop:
+// PATTERN: %vla.cur = phi i8* [ %vla.begin, %vla-setup.loop ], [ %vla.next, %vla-init.loop ]
+// PATTERN: call void @llvm.memcpy{{.*}} %vla.cur, {{.*}}@__const.test_struct_vla.vla
+// PATTERN: %vla.next = getelementptr inbounds i8, i8* %vla.cur, i64 16
+// PATTERN: %vla-init.isdone = icmp eq i8* %vla.next, %vla.end
+// PATTERN: br i1 %vla-init.isdone, label %vla-init.cont, label %vla-init.loop
+// PATTERN: vla-init.cont:
+// PATTERN: call void @{{.*}}used
+void test_struct_vla(int size) {
+ // Same as above, but with a struct that doesn't just memcpy.
+ struct {
+ float f;
+ char c;
+ void *ptr;
+ } vla[size];
+ void *ptr = static_cast<void*>(vla);
+ used(ptr);
+}
+
+// UNINIT-LABEL: test_zsa(
+// ZERO-LABEL: test_zsa(
+// ZERO: %zsa = alloca [0 x i32], align 4
+// ZERO-NOT: %zsa
+// ZERO: call void @{{.*}}used
+// PATTERN-LABEL: test_zsa(
+// PATTERN: %zsa = alloca [0 x i32], align 4
+// PATTERN-NOT: %zsa
+// PATTERN: call void @{{.*}}used
+void test_zsa(int size) {
+ // Technically not valid, but as long as clang accepts them we should do
+ // something sensible (i.e. not store to the zero-size array).
+ int zsa[0];
+ used(zsa);
+}
+
+// UNINIT-LABEL: test_huge_uninit(
+// ZERO-LABEL: test_huge_uninit(
+// ZERO: call void @llvm.memset{{.*}}, i8 0, i64 65536,
+// PATTERN-LABEL: test_huge_uninit(
+// PATTERN: call void @llvm.memset{{.*}}, i8 -86, i64 65536,
+void test_huge_uninit() {
+ // We can't emit this as an inline constant to a store instruction because
+ // SDNode hits an internal size limit.
+ char big[65536];
+ used(big);
+}
+
+// UNINIT-LABEL: test_huge_small_init(
+// ZERO-LABEL: test_huge_small_init(
+// ZERO: call void @llvm.memset{{.*}}, i8 0, i64 65536,
+// ZERO: store i8 97,
+// ZERO: store i8 98,
+// ZERO: store i8 99,
+// ZERO: store i8 100,
+// PATTERN-LABEL: test_huge_small_init(
+// PATTERN: call void @llvm.memset{{.*}}, i8 0, i64 65536,
+// PATTERN: store i8 97,
+// PATTERN: store i8 98,
+// PATTERN: store i8 99,
+// PATTERN: store i8 100,
+void test_huge_small_init() {
+ char big[65536] = { 'a', 'b', 'c', 'd' };
+ used(big);
+}
+
+// UNINIT-LABEL: test_huge_larger_init(
+// ZERO-LABEL: test_huge_larger_init(
+// ZERO: call void @llvm.memcpy{{.*}} @__const.test_huge_larger_init.big, {{.*}}, i64 65536,
+// PATTERN-LABEL: test_huge_larger_init(
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_huge_larger_init.big, {{.*}}, i64 65536,
+void test_huge_larger_init() {
+ char big[65536] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
+ used(big);
+}
+
+} // extern "C"
diff --git a/test/CodeGenCXX/trivial_abi.cpp b/test/CodeGenCXX/trivial_abi.cpp
index 2cf07b22581a..e37c8ff615a2 100644
--- a/test/CodeGenCXX/trivial_abi.cpp
+++ b/test/CodeGenCXX/trivial_abi.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fcxx-exceptions -fexceptions -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++17 -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++17 -fcxx-exceptions -fexceptions -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s
// CHECK: %[[STRUCT_SMALL:.*]] = type { i32* }
// CHECK: %[[STRUCT_LARGE:.*]] = type { i32*, [128 x i32] }
@@ -43,6 +43,13 @@ struct HasNonTrivial {
NonTrivial m;
};
+struct __attribute__((trivial_abi)) CopyMoveDeleted {
+ CopyMoveDeleted(int);
+ CopyMoveDeleted(const CopyMoveDeleted &) = delete;
+ CopyMoveDeleted(CopyMoveDeleted &&) = delete;
+ int a;
+};
+
// CHECK: define void @_Z14testParamSmall5Small(i64 %[[A_COERCE:.*]])
// CHECK: %[[A:.*]] = alloca %[[STRUCT_SMALL]], align 8
// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_SMALL]], %[[STRUCT_SMALL]]* %[[A]], i32 0, i32 0
@@ -237,3 +244,11 @@ void calleeExceptionLarge(Large, Large);
void testExceptionLarge() {
calleeExceptionLarge(Large(), Large());
}
+
+// A class with deleted copy and move constructors can still be passed or
+// returned in registers if the class is annotated with trivial_abi.
+
+// CHECK: define i64 @_Z19testCopyMoveDeletedi(i32 %
+CopyMoveDeleted testCopyMoveDeleted(int a) {
+ return a;
+}
diff --git a/test/CodeGenCXX/type-metadata-thinlto.cpp b/test/CodeGenCXX/type-metadata-thinlto.cpp
index 2a586fc4c37c..8bf39f129c40 100644
--- a/test/CodeGenCXX/type-metadata-thinlto.cpp
+++ b/test/CodeGenCXX/type-metadata-thinlto.cpp
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 -flto=thin -flto-unit -triple x86_64-unknown-linux -fvisibility hidden -emit-llvm-bc -o %t %s
+// RUN: %clang_cc1 -flto=thin -flto-unit -fsplit-lto-unit -triple x86_64-unknown-linux -fvisibility hidden -emit-llvm-bc -o %t %s
// RUN: llvm-modextract -o - -n 1 %t | llvm-dis | FileCheck %s
+// RUN: llvm-modextract -b -o - -n 1 %t | llvm-bcanalyzer -dump | FileCheck %s --check-prefix=LTOUNIT
+// LTOUNIT: <FLAGS op0=8/>
// CHECK: @_ZTV1A = linkonce_odr
class A {
diff --git a/test/CodeGenCXX/type-metadata.cpp b/test/CodeGenCXX/type-metadata.cpp
index 8e3e4bd182fe..a7a34673cdfc 100644
--- a/test/CodeGenCXX/type-metadata.cpp
+++ b/test/CodeGenCXX/type-metadata.cpp
@@ -82,8 +82,8 @@
// MS: comdat($"??_7B@@6B0@@"), !type [[B8:![0-9]+]]
// MS: comdat($"??_7B@@6BA@@@"), !type [[A8]]
// MS: comdat($"??_7C@@6B@"), !type [[A8]]
-// MS: comdat($"??_7D@?A@@6BB@@@"), !type [[B8]], !type [[D8:![0-9]+]]
-// MS: comdat($"??_7D@?A@@6BA@@@"), !type [[A8]]
+// MS: comdat($"??_7D@?A0x{{[^@]*}}@@6BB@@@"), !type [[B8]], !type [[D8:![0-9]+]]
+// MS: comdat($"??_7D@?A0x{{[^@]*}}@@6BA@@@"), !type [[A8]]
// MS: comdat($"??_7FA@?1??foo@@YAXXZ@6B@"), !type [[A8]], !type [[FA8:![0-9]+]]
struct A {
@@ -161,7 +161,7 @@ void af(A *a) {
}
// ITANIUM: define internal void @_Z3df1PN12_GLOBAL__N_11DE
-// MS: define internal void @"?df1@@YAXPEAUD@?A@@@Z"
+// MS: define internal void @"?df1@@YAXPEAUD@?A0x{{[^@]*}}@@@Z"
void df1(D *d) {
// TT-ITANIUM: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata ![[DTYPE:[0-9]+]])
// TT-MS: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"?AUA@@")
@@ -171,7 +171,7 @@ void df1(D *d) {
}
// ITANIUM: define internal void @_Z3dg1PN12_GLOBAL__N_11DE
-// MS: define internal void @"?dg1@@YAXPEAUD@?A@@@Z"
+// MS: define internal void @"?dg1@@YAXPEAUD@?A0x{{[^@]*}}@@@Z"
void dg1(D *d) {
// TT-ITANIUM: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
// TT-MS: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"?AUB@@")
@@ -181,7 +181,7 @@ void dg1(D *d) {
}
// ITANIUM: define internal void @_Z3dh1PN12_GLOBAL__N_11DE
-// MS: define internal void @"?dh1@@YAXPEAUD@?A@@@Z"
+// MS: define internal void @"?dh1@@YAXPEAUD@?A0x{{[^@]*}}@@@Z"
void dh1(D *d) {
// TT-ITANIUM: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata ![[DTYPE]])
// TT-MS: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata ![[DTYPE:[0-9]+]])
@@ -191,7 +191,7 @@ void dh1(D *d) {
}
// ITANIUM: define internal void @_Z3df2PN12_GLOBAL__N_11DE
-// MS: define internal void @"?df2@@YAXPEAUD@?A@@@Z"
+// MS: define internal void @"?df2@@YAXPEAUD@?A0x{{[^@]*}}@@@Z"
__attribute__((no_sanitize("cfi")))
void df2(D *d) {
// CFI-NVT-NOT: call i1 @llvm.type.test
@@ -201,7 +201,7 @@ void df2(D *d) {
}
// ITANIUM: define internal void @_Z3df3PN12_GLOBAL__N_11DE
-// MS: define internal void @"?df3@@YAXPEAUD@?A@@@Z"
+// MS: define internal void @"?df3@@YAXPEAUD@?A0x{{[^@]*}}@@@Z"
__attribute__((no_sanitize("address"))) __attribute__((no_sanitize("cfi-vcall")))
void df3(D *d) {
// CFI-NVT-NOT: call i1 @llvm.type.test
diff --git a/test/CodeGenCXX/ubsan-check-debuglocs.cpp b/test/CodeGenCXX/ubsan-check-debuglocs.cpp
new file mode 100644
index 000000000000..96a697aca5eb
--- /dev/null
+++ b/test/CodeGenCXX/ubsan-check-debuglocs.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited \
+// RUN: -fsanitize=null %s -o - | FileCheck %s
+
+// Check that santizer check calls have a !dbg location.
+// CHECK: define {{.*}}acquire{{.*}} !dbg
+// CHECK-NOT: define
+// CHECK: call void {{.*}}@__ubsan_handle_type_mismatch_v1
+// CHECK-SAME: !dbg
+
+struct SourceLocation {
+ SourceLocation acquire() {};
+};
+extern "C" void __ubsan_handle_type_mismatch_v1(SourceLocation *Loc);
+static void handleTypeMismatchImpl(SourceLocation *Loc) { Loc->acquire(); }
+void __ubsan_handle_type_mismatch_v1(SourceLocation *Loc) {
+ handleTypeMismatchImpl(Loc);
+}
diff --git a/test/CodeGenCXX/visibility-inlines-hidden-staticvar.cpp b/test/CodeGenCXX/visibility-inlines-hidden-staticvar.cpp
new file mode 100644
index 000000000000..c0fa57d859c7
--- /dev/null
+++ b/test/CodeGenCXX/visibility-inlines-hidden-staticvar.cpp
@@ -0,0 +1,111 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck -check-prefixes=CHECK-NO-VIH %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -fvisibility hidden -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck %s --check-prefix=CHECK-VIS-HIDDEN
+// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -fvisibility protected -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck %s --check-prefix=CHECK-VIS-PROTECTED
+
+// When a function is hidden due to -fvisibility-inlines-hidden option, static local variables of the function should not be hidden by the option.
+
+// CHECK-DAG: @_ZZ4funcvE3var = internal global i32 0
+// CHECK-DAG: @_ZZ11hidden_funcvE3var = internal global i32 0
+// CHECK-DAG: @_ZZ12default_funcvE3var = internal global i32 0
+// CHECK-DAG: @_ZZ11inline_funcvE3var = linkonce_odr global i32 0, comdat
+// CHECK-DAG: @_ZZ18inline_hidden_funcvE3var = linkonce_odr hidden global i32 0, comdat
+// CHECK-DAG: @_ZZ19inline_default_funcvE3var = linkonce_odr global i32 0, comdat
+// CHECK-DAG: @_ZZN13ExportedClass10inl_methodEvE3var = linkonce_odr global i32 0, comdat, align 4
+// CHECK-DAG: define i32 @_Z4funcv()
+// CHECK-DAG: define hidden i32 @_Z11hidden_funcv()
+// CHECK-DAG: define i32 @_Z12default_funcv()
+// CHECK-DAG: define linkonce_odr hidden i32 @_Z11inline_funcv()
+// CHECK-DAG: define linkonce_odr hidden i32 @_Z18inline_hidden_funcv()
+// CHECK-DAG: define linkonce_odr i32 @_Z19inline_default_funcv()
+// CHECK-DAG: define linkonce_odr hidden i32 @_ZN13ExportedClass10inl_methodEv({{.*}})
+// CHECK-DAG: define i32 @_ZN13ExportedClass10ext_methodEv({{.*}})
+
+// CHECK-NO-VIH-DAG: @_ZZ4funcvE3var = internal global i32 0
+// CHECK-NO-VIH-DAG: @_ZZ11hidden_funcvE3var = internal global i32 0
+// CHECK-NO-VIH-DAG: @_ZZ12default_funcvE3var = internal global i32 0
+// CHECK-NO-VIH-DAG: @_ZZ11inline_funcvE3var = linkonce_odr global i32 0, comdat
+// CHECK-NO-VIH-DAG: @_ZZ18inline_hidden_funcvE3var = linkonce_odr hidden global i32 0, comdat
+// CHECK-NO-VIH-DAG: @_ZZ19inline_default_funcvE3var = linkonce_odr global i32 0, comdat
+// CHECK-NO-VIH-DAG: @_ZZN13ExportedClass10inl_methodEvE3var = linkonce_odr global i32 0, comdat, align 4
+// CHECK-NO-VIH-DAG: define i32 @_Z4funcv()
+// CHECK-NO-VIH-DAG: define hidden i32 @_Z11hidden_funcv()
+// CHECK-NO-VIH-DAG: define i32 @_Z12default_funcv()
+// CHECK-NO-VIH-DAG: define linkonce_odr i32 @_Z11inline_funcv()
+// CHECK-NO-VIH-DAG: define linkonce_odr hidden i32 @_Z18inline_hidden_funcv()
+// CHECK-NO-VIH-DAG: define linkonce_odr i32 @_Z19inline_default_funcv()
+// CHECK-NO-VIH-DAG: define linkonce_odr i32 @_ZN13ExportedClass10inl_methodEv({{.*}})
+// CHECK-NO-VIH-DAG: define i32 @_ZN13ExportedClass10ext_methodEv({{.*}})
+
+// CHECK-VIS-HIDDEN-DAG: @_ZZ4funcvE3var = internal global i32 0
+// CHECK-VIS-HIDDEN-DAG: @_ZZ11hidden_funcvE3var = internal global i32 0
+// CHECK-VIS-HIDDEN-DAG: @_ZZ12default_funcvE3var = internal global i32 0
+// CHECK-VIS-HIDDEN-DAG: @_ZZ11inline_funcvE3var = linkonce_odr hidden global i32 0, comdat
+// CHECK-VIS-HIDDEN-DAG: @_ZZ18inline_hidden_funcvE3var = linkonce_odr hidden global i32 0, comdat
+// CHECK-VIS-HIDDEN-DAG: @_ZZ19inline_default_funcvE3var = linkonce_odr global i32 0, comdat
+// CHECK-VIS-HIDDEN-DAG: @_ZZN13ExportedClass10inl_methodEvE3var = linkonce_odr global i32 0, comdat, align 4
+// CHECK-VIS-HIDDEN-DAG: define hidden i32 @_Z4funcv()
+// CHECK-VIS-HIDDEN-DAG: define hidden i32 @_Z11hidden_funcv()
+// CHECK-VIS-HIDDEN-DAG: define i32 @_Z12default_funcv()
+// CHECK-VIS-HIDDEN-DAG: define linkonce_odr hidden i32 @_Z11inline_funcv()
+// CHECK-VIS-HIDDEN-DAG: define linkonce_odr hidden i32 @_Z18inline_hidden_funcv()
+// CHECK-VIS-HIDDEN-DAG: define linkonce_odr i32 @_Z19inline_default_funcv()
+// CHECK-VIS-HIDDEN-DAG: define linkonce_odr hidden i32 @_ZN13ExportedClass10inl_methodEv({{.*}})
+// CHECK-VIS-HIDDEN-DAG: define i32 @_ZN13ExportedClass10ext_methodEv({{.*}})
+
+// CHECK-VIS-PROTECTED-DAG: @_ZZ4funcvE3var = internal global i32 0
+// CHECK-VIS-PROTECTED-DAG: @_ZZ11hidden_funcvE3var = internal global i32 0
+// CHECK-VIS-PROTECTED-DAG: @_ZZ12default_funcvE3var = internal global i32 0
+// CHECK-VIS-PROTECTED-DAG: @_ZZ11inline_funcvE3var = linkonce_odr protected global i32 0, comdat
+// CHECK-VIS-PROTECTED-DAG: @_ZZ18inline_hidden_funcvE3var = linkonce_odr hidden global i32 0, comdat
+// CHECK-VIS-PROTECTED-DAG: @_ZZ19inline_default_funcvE3var = linkonce_odr global i32 0, comdat
+// CHECK-VIS-PROTECTED-DAG: @_ZZN13ExportedClass10inl_methodEvE3var = linkonce_odr global i32 0, comdat, align 4
+// CHECK-VIS-PROTECTED-DAG: define protected i32 @_Z4funcv()
+// CHECK-VIS-PROTECTED-DAG: define hidden i32 @_Z11hidden_funcv()
+// CHECK-VIS-PROTECTED-DAG: define i32 @_Z12default_funcv()
+// CHECK-VIS-PROTECTED-DAG: define linkonce_odr hidden i32 @_Z11inline_funcv()
+// CHECK-VIS-PROTECTED-DAG: define linkonce_odr hidden i32 @_Z18inline_hidden_funcv()
+// CHECK-VIS-PROTECTED-DAG: define linkonce_odr i32 @_Z19inline_default_funcv()
+// CHECK-VIS-PROTECTED-DAG: define linkonce_odr hidden i32 @_ZN13ExportedClass10inl_methodEv({{.*}})
+// CHECK-VIS-PROTECTED-DAG: define i32 @_ZN13ExportedClass10ext_methodEv({{.*}})
+
+int func(void) {
+ static int var = 0;
+ return var++;
+}
+inline int inline_func(void) {
+ static int var = 0;
+ return var++;
+}
+int __attribute__((visibility("hidden"))) hidden_func(void) {
+ static int var = 0;
+ return var++;
+}
+inline int __attribute__((visibility("hidden"))) inline_hidden_func(void) {
+ static int var = 0;
+ return var++;
+}
+int __attribute__((visibility("default"))) default_func(void) {
+ static int var = 0;
+ return var++;
+}
+inline int __attribute__((visibility("default"))) inline_default_func(void) {
+ static int var = 0;
+ return var++;
+}
+struct __attribute__((visibility("default"))) ExportedClass {
+ int inl_method() {
+ static int var = 0;
+ return var++;
+ }
+ int ext_method();
+};
+int ExportedClass::ext_method() { return inl_method(); }
+void bar(void) {
+ func();
+ inline_func();
+ hidden_func();
+ inline_hidden_func();
+ default_func();
+ inline_default_func();
+}
diff --git a/test/CodeGenCXX/vtable-align.cpp b/test/CodeGenCXX/vtable-align.cpp
index 1b82cbc085c9..bd0494fe5dd5 100644
--- a/test/CodeGenCXX/vtable-align.cpp
+++ b/test/CodeGenCXX/vtable-align.cpp
@@ -10,5 +10,8 @@ struct A {
void A::f() {}
// CHECK-32: @_ZTV1A = unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1fEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1gEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1hEv to i8*)] }, align 4
-
+// CHECK-32: @_ZTS1A = constant [3 x i8] c"1A\00", align 1
+// CHECK-32: @_ZTI1A = constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv117__class_type_infoE, i32 2) to i8*), i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZTS1A, i32 0, i32 0) }, align 4
// CHECK-64: @_ZTV1A = unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1fEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1gEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1hEv to i8*)] }, align 8
+// CHECK-64: @_ZTS1A = constant [3 x i8] c"1A\00", align 1
+// CHECK-64: @_ZTI1A = constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv117__class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZTS1A, i32 0, i32 0) }, align 8
diff --git a/test/CodeGenCXX/vtable-debug-info.cpp b/test/CodeGenCXX/vtable-debug-info.cpp
index 8710c76e0bfa..0ac90b3ec1d3 100644
--- a/test/CodeGenCXX/vtable-debug-info.cpp
+++ b/test/CodeGenCXX/vtable-debug-info.cpp
@@ -1,6 +1,6 @@
// RUN: %clang -emit-llvm -S -g %s -o /dev/null
// Radar 8730409
-// XFAIL: win32
+// XFAIL: windows-msvc
// FIXME: This test crashes on *-pc-win32
// for lack of debugging support on -integrated-as (MCCOFF).
diff --git a/test/CodeGenCXX/vtable-linkage.cpp b/test/CodeGenCXX/vtable-linkage.cpp
index 0c55eb26f7f1..d4f06ce6ce03 100644
--- a/test/CodeGenCXX/vtable-linkage.cpp
+++ b/test/CodeGenCXX/vtable-linkage.cpp
@@ -98,10 +98,10 @@ void use_F() {
// C has no key function, so its vtable should have weak_odr linkage
// and hidden visibility (rdar://problem/7523229).
-// CHECK-DAG: @_ZTV1C = linkonce_odr unnamed_addr constant {{.*}}, comdat,
-// CHECK-DAG: @_ZTS1C = linkonce_odr constant {{.*}}, comdat{{$}}
-// CHECK-DAG: @_ZTI1C = linkonce_odr constant {{.*}}, comdat{{$}}
-// CHECK-DAG: @_ZTT1C = linkonce_odr unnamed_addr constant {{.*}}, comdat{{$}}
+// CHECK-DAG: @_ZTV1C = linkonce_odr unnamed_addr constant {{.*}}, comdat, align 8{{$}}
+// CHECK-DAG: @_ZTS1C = linkonce_odr constant {{.*}}, comdat, align 1{{$}}
+// CHECK-DAG: @_ZTI1C = linkonce_odr constant {{.*}}, comdat, align 8{{$}}
+// CHECK-DAG: @_ZTT1C = linkonce_odr unnamed_addr constant {{.*}}, comdat, align 8{{$}}
// D has a key function that is defined in this translation unit so its vtable is
// defined in the translation unit.
@@ -120,27 +120,27 @@ void use_F() {
// defined in this translation unit, so its vtable should have
// weak_odr linkage.
// CHECK-DAG: @_ZTV1EIsE = weak_odr unnamed_addr constant {{.*}}, comdat,
-// CHECK-DAG: @_ZTS1EIsE = weak_odr constant {{.*}}, comdat{{$}}
-// CHECK-DAG: @_ZTI1EIsE = weak_odr constant {{.*}}, comdat{{$}}
+// CHECK-DAG: @_ZTS1EIsE = weak_odr constant {{.*}}, comdat, align 1{{$}}
+// CHECK-DAG: @_ZTI1EIsE = weak_odr constant {{.*}}, comdat, align 8{{$}}
// F<short> is an explicit template instantiation without a key
// function, so its vtable should have weak_odr linkage
// CHECK-DAG: @_ZTV1FIsE = weak_odr unnamed_addr constant {{.*}}, comdat,
-// CHECK-DAG: @_ZTS1FIsE = weak_odr constant {{.*}}, comdat{{$}}
-// CHECK-DAG: @_ZTI1FIsE = weak_odr constant {{.*}}, comdat{{$}}
+// CHECK-DAG: @_ZTS1FIsE = weak_odr constant {{.*}}, comdat, align 1{{$}}
+// CHECK-DAG: @_ZTI1FIsE = weak_odr constant {{.*}}, comdat, align 8{{$}}
// E<long> is an implicit template instantiation with a key function
// defined in this translation unit, so its vtable should have
// linkonce_odr linkage.
// CHECK-DAG: @_ZTV1EIlE = linkonce_odr unnamed_addr constant {{.*}}, comdat,
-// CHECK-DAG: @_ZTS1EIlE = linkonce_odr constant {{.*}}, comdat{{$}}
-// CHECK-DAG: @_ZTI1EIlE = linkonce_odr constant {{.*}}, comdat{{$}}
+// CHECK-DAG: @_ZTS1EIlE = linkonce_odr constant {{.*}}, comdat, align 1{{$}}
+// CHECK-DAG: @_ZTI1EIlE = linkonce_odr constant {{.*}}, comdat, align 8{{$}}
// F<long> is an implicit template instantiation with no key function,
// so its vtable should have linkonce_odr linkage.
// CHECK-DAG: @_ZTV1FIlE = linkonce_odr unnamed_addr constant {{.*}}, comdat,
-// CHECK-DAG: @_ZTS1FIlE = linkonce_odr constant {{.*}}, comdat{{$}}
-// CHECK-DAG: @_ZTI1FIlE = linkonce_odr constant {{.*}}, comdat{{$}}
+// CHECK-DAG: @_ZTS1FIlE = linkonce_odr constant {{.*}}, comdat, align 1{{$}}
+// CHECK-DAG: @_ZTI1FIlE = linkonce_odr constant {{.*}}, comdat, align 8{{$}}
// F<int> is an explicit template instantiation declaration without a
// key function, so its vtable should have external linkage.
@@ -171,8 +171,8 @@ void use_F() {
// F<char> is an explicit specialization without a key function, so
// its vtable should have linkonce_odr linkage.
// CHECK-DAG: @_ZTV1FIcE = linkonce_odr unnamed_addr constant {{.*}}, comdat,
-// CHECK-DAG: @_ZTS1FIcE = linkonce_odr constant {{.*}}, comdat{{$}}
-// CHECK-DAG: @_ZTI1FIcE = linkonce_odr constant {{.*}}, comdat{{$}}
+// CHECK-DAG: @_ZTS1FIcE = linkonce_odr constant {{.*}}, comdat, align 1{{$}}
+// CHECK-DAG: @_ZTI1FIcE = linkonce_odr constant {{.*}}, comdat, align 8{{$}}
// CHECK-DAG: @_ZTV1GIiE = linkonce_odr unnamed_addr constant {{.*}}, comdat,
template <typename T>
diff --git a/test/CodeGenCXX/wasm-args-returns.cpp b/test/CodeGenCXX/wasm-args-returns.cpp
index 24adc8e08761..a7c4e1e282a1 100644
--- a/test/CodeGenCXX/wasm-args-returns.cpp
+++ b/test/CodeGenCXX/wasm-args-returns.cpp
@@ -3,16 +3,18 @@
// RUN: %clang_cc1 -O1 -triple wasm64-unknown-unknown -emit-llvm -o - %s \
// RUN: | FileCheck %s
-#define concat_(x, y) x ## y
+#define concat_(x, y) x##y
#define concat(x, y) concat_(x, y)
-#define test(T) \
+#define test(T) \
T forward(T x) { return x; } \
- void use(T x); \
- T concat(def_, T)(void); \
+ void use(T x); \
+ T concat(def_, T)(void); \
void concat(test_, T)(void) { use(concat(def_, T)()); }
-struct one_field { double d; };
+struct one_field {
+ double d;
+};
test(one_field);
// CHECK: define double @_Z7forward9one_field(double returned %{{.*}})
//
@@ -24,7 +26,9 @@ test(one_field);
// CHECK: declare void @_Z3use9one_field(double)
// CHECK: declare double @_Z13def_one_fieldv()
-struct two_fields { double d, e; };
+struct two_fields {
+ double d, e;
+};
test(two_fields);
// CHECK: define void @_Z7forward10two_fields(%struct.two_fields* noalias nocapture sret %{{.*}}, %struct.two_fields* byval nocapture readonly align 8 %{{.*}})
//
@@ -38,8 +42,8 @@ test(two_fields);
// CHECK: declare void @_Z14def_two_fieldsv(%struct.two_fields* sret)
struct copy_ctor {
- double d;
- copy_ctor(copy_ctor const&);
+ double d;
+ copy_ctor(copy_ctor const &);
};
test(copy_ctor);
// CHECK: define void @_Z7forward9copy_ctor(%struct.copy_ctor* noalias sret %{{.*}}, %struct.copy_ctor* %{{.*}})
@@ -56,8 +60,8 @@ test(copy_ctor);
// CHECK: declare void @_Z13def_copy_ctorv(%struct.copy_ctor* sret)
struct __attribute__((aligned(16))) aligned_copy_ctor {
- double d, e;
- aligned_copy_ctor(aligned_copy_ctor const&);
+ double d, e;
+ aligned_copy_ctor(aligned_copy_ctor const &);
};
test(aligned_copy_ctor);
// CHECK: define void @_Z7forward17aligned_copy_ctor(%struct.aligned_copy_ctor* noalias sret %{{.*}}, %struct.aligned_copy_ctor* %{{.*}})
@@ -86,7 +90,7 @@ test(empty);
// CHECK: declare void @_Z9def_emptyv()
struct one_bitfield {
- int d:3;
+ int d : 3;
};
test(one_bitfield);
// CHECK: define i32 @_Z7forward12one_bitfield(i32 returned %{{.*}})