From bab175ec4b075c8076ba14c762900392533f6ee4 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Mon, 2 Jan 2017 19:18:08 +0000 Subject: Vendor import of clang trunk r290819: https://llvm.org/svn/llvm-project/cfe/trunk@290819 --- test/CodeGenCXX/PR26569.cpp | 16 +- test/CodeGenCXX/alias-available-externally.cpp | 20 ++ test/CodeGenCXX/alloc-size.cpp | 72 ++++++ test/CodeGenCXX/apple-kext-indirect-call-2.cpp | 16 +- test/CodeGenCXX/apple-kext-indirect-call.cpp | 6 +- .../apple-kext-indirect-virtual-dtor-call.cpp | 8 +- test/CodeGenCXX/arm-swiftcall.cpp | 2 +- test/CodeGenCXX/arm64.cpp | 36 +++ test/CodeGenCXX/atomicinit.cpp | 4 +- test/CodeGenCXX/attr.cpp | 2 +- test/CodeGenCXX/block-in-ctor-dtor.cpp | 2 - test/CodeGenCXX/builtins-arm-exclusive.cpp | 24 ++ test/CodeGenCXX/catch-undef-behavior.cpp | 8 +- test/CodeGenCXX/cfi-cross-dso.cpp | 2 +- test/CodeGenCXX/compound-literals.cpp | 40 ++- test/CodeGenCXX/const-init-cxx11.cpp | 6 +- .../constructor-destructor-return-this.cpp | 2 +- test/CodeGenCXX/constructor-init.cpp | 17 +- test/CodeGenCXX/copy-constructor-elim-2.cpp | 20 ++ test/CodeGenCXX/copy-constructor-synthesis-2.cpp | 2 +- test/CodeGenCXX/copy-constructor-synthesis.cpp | 2 +- test/CodeGenCXX/ctor-dtor-alias.cpp | 6 +- test/CodeGenCXX/cxx11-exception-spec.cpp | 2 +- test/CodeGenCXX/cxx11-noreturn.cpp | 2 +- test/CodeGenCXX/cxx1y-initializer-aggregate.cpp | 2 +- .../CodeGenCXX/cxx1y-variable-template-linkage.cpp | 4 +- test/CodeGenCXX/cxx1z-aligned-allocation.cpp | 206 ++++++++++++++++ test/CodeGenCXX/cxx1z-constexpr-if.cpp | 13 + test/CodeGenCXX/cxx1z-copy-omission.cpp | 81 ++++++ test/CodeGenCXX/cxx1z-decomposition.cpp | 118 +++++++++ test/CodeGenCXX/cxx1z-eval-order.cpp | 271 +++++++++++++++++++++ test/CodeGenCXX/cxx1z-noexcept-function-type.cpp | 9 + test/CodeGenCXX/debug-info-access.cpp | 2 +- test/CodeGenCXX/debug-info-alias.cpp | 5 +- test/CodeGenCXX/debug-info-anon-namespace.cpp | 3 +- test/CodeGenCXX/debug-info-anon-union-vars.cpp | 2 +- test/CodeGenCXX/debug-info-calling-conventions.cpp | 2 +- test/CodeGenCXX/debug-info-class-nolimit.cpp | 24 +- test/CodeGenCXX/debug-info-class.cpp | 1 + .../debug-info-codeview-injected-class.cpp | 21 ++ test/CodeGenCXX/debug-info-cxx1y.cpp | 6 +- .../CodeGenCXX/debug-info-dllimport-base-class.cpp | 53 ++++ test/CodeGenCXX/debug-info-dup-fwd-decl.cpp | 2 +- test/CodeGenCXX/debug-info-enum-class.cpp | 8 +- test/CodeGenCXX/debug-info-flex-member.cpp | 9 - test/CodeGenCXX/debug-info-global.cpp | 5 +- test/CodeGenCXX/debug-info-indirect-field-decl.cpp | 4 +- test/CodeGenCXX/debug-info-line-if.cpp | 20 +- test/CodeGenCXX/debug-info-line.cpp | 4 +- test/CodeGenCXX/debug-info-loops.cpp | 49 ++++ test/CodeGenCXX/debug-info-method.cpp | 2 +- test/CodeGenCXX/debug-info-ms-abi.cpp | 24 +- test/CodeGenCXX/debug-info-ms-anonymous-tag.cpp | 3 +- test/CodeGenCXX/debug-info-ms-bitfields.cpp | 2 +- test/CodeGenCXX/debug-info-ms-ptr-to-member.cpp | 7 +- test/CodeGenCXX/debug-info-ms-vbase.cpp | 68 ++++++ test/CodeGenCXX/debug-info-namespace.cpp | 17 +- test/CodeGenCXX/debug-info-rvalue-ref.cpp | 2 +- test/CodeGenCXX/debug-info-static-member.cpp | 32 ++- ...debug-info-template-explicit-specialization.cpp | 7 +- test/CodeGenCXX/debug-info-template-member.cpp | 10 +- test/CodeGenCXX/debug-info-template-quals.cpp | 4 +- test/CodeGenCXX/debug-info-template.cpp | 30 ++- test/CodeGenCXX/debug-info-thunk-msabi.cpp | 19 ++ test/CodeGenCXX/debug-info-thunk.cpp | 13 +- test/CodeGenCXX/debug-info-union.cpp | 2 +- test/CodeGenCXX/debug-info-uuid.cpp | 29 ++- test/CodeGenCXX/debug-info-vla.cpp | 20 ++ test/CodeGenCXX/debug-info-windows-dtor.cpp | 2 +- test/CodeGenCXX/debug-info-zero-length-arrays.cpp | 1 - test/CodeGenCXX/debug-info.cpp | 12 +- test/CodeGenCXX/debug-lambda-expressions.cpp | 10 +- test/CodeGenCXX/debug-lambda-this.cpp | 4 +- test/CodeGenCXX/default-arg-temps.cpp | 9 +- test/CodeGenCXX/derived-to-base.cpp | 2 +- test/CodeGenCXX/destructors.cpp | 128 ++++++---- .../devirtualize-virtual-function-calls-final.cpp | 16 ++ .../devirtualize-virtual-function-calls.cpp | 97 +++++++- test/CodeGenCXX/dllexport.cpp | 17 +- test/CodeGenCXX/dllimport-members.cpp | 2 +- test/CodeGenCXX/dllimport-rtti.cpp | 8 +- test/CodeGenCXX/dllimport.cpp | 27 +- test/CodeGenCXX/empty-classes.cpp | 21 ++ test/CodeGenCXX/enable_if.cpp | 2 +- test/CodeGenCXX/exceptions-seh.cpp | 2 +- test/CodeGenCXX/explicit-instantiation.cpp | 2 +- test/CodeGenCXX/global-dtor-no-atexit.cpp | 2 +- test/CodeGenCXX/global-init.cpp | 9 +- test/CodeGenCXX/implicit-copy-constructor.cpp | 8 +- test/CodeGenCXX/init-invariant.cpp | 14 +- test/CodeGenCXX/inline-dllexport-member.cpp | 8 +- test/CodeGenCXX/inline-hint.cpp | 6 +- test/CodeGenCXX/invariant.group-for-vptrs.cpp | 6 +- test/CodeGenCXX/key-function-vtable.cpp | 10 +- test/CodeGenCXX/lambda-expressions.cpp | 78 +++++- test/CodeGenCXX/linkage.cpp | 2 +- test/CodeGenCXX/main-norecurse.cpp | 2 +- test/CodeGenCXX/mangle-abi-tag.cpp | 29 +++ test/CodeGenCXX/mangle-exception-spec.cpp | 49 ++++ test/CodeGenCXX/mangle-lambdas.cpp | 10 + test/CodeGenCXX/mangle-ms-cxx11.cpp | 29 +++ test/CodeGenCXX/mangle-unnamed.cpp | 3 +- test/CodeGenCXX/mangle.cpp | 14 ++ test/CodeGenCXX/microsoft-abi-array-cookies.cpp | 2 +- .../microsoft-abi-constexpr-vs-inheritance.cpp | 4 +- test/CodeGenCXX/microsoft-abi-eh-catch.cpp | 2 +- test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp | 37 ++- test/CodeGenCXX/microsoft-abi-extern-template.cpp | 6 +- ...crosoft-abi-multiple-nonvirtual-inheritance.cpp | 12 +- test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp | 48 +++- test/CodeGenCXX/microsoft-abi-structors-alias.cpp | 2 +- test/CodeGenCXX/microsoft-abi-structors.cpp | 4 +- test/CodeGenCXX/microsoft-abi-vftables.cpp | 34 +-- .../microsoft-abi-virtual-inheritance.cpp | 16 +- ...iple-nonvirtual-inheritance-this-adjustment.cpp | 23 ++ .../microsoft-abi-vtables-return-thunks.cpp | 16 +- .../microsoft-abi-vtables-single-inheritance.cpp | 10 +- .../microsoft-abi-vtables-virtual-inheritance.cpp | 16 +- test/CodeGenCXX/microsoft-interface.cpp | 6 +- test/CodeGenCXX/microsoft-no-rtti-data.cpp | 2 +- test/CodeGenCXX/microsoft-uuidof.cpp | 8 + test/CodeGenCXX/modules-ts.cppm | 20 ++ test/CodeGenCXX/ms-inline-asm-return.cpp | 10 +- test/CodeGenCXX/ms-thread_local.cpp | 5 + test/CodeGenCXX/naked.cpp | 13 + test/CodeGenCXX/new-array-init.cpp | 84 ++++++- test/CodeGenCXX/no-exceptions.cpp | 2 +- test/CodeGenCXX/nrvo.cpp | 28 ++- test/CodeGenCXX/optnone-class-members.cpp | 2 +- test/CodeGenCXX/optnone-def-decl.cpp | 2 +- test/CodeGenCXX/partial-destruction.cpp | 39 +-- test/CodeGenCXX/pr24097.cpp | 2 +- test/CodeGenCXX/pr30731.cpp | 21 ++ test/CodeGenCXX/pragma-loop-distribute.cpp | 23 ++ test/CodeGenCXX/pragma-loop-safety.cpp | 24 +- test/CodeGenCXX/predefined-expr-cxx14.cpp | 4 +- test/CodeGenCXX/reference-cast.cpp | 2 +- test/CodeGenCXX/regcall.cpp | 97 ++++++++ test/CodeGenCXX/rtti-mingw64.cpp | 13 + test/CodeGenCXX/rtti-qualfn.cpp | 23 ++ test/CodeGenCXX/runtime-dllstorage.cpp | 158 ++++++++++++ test/CodeGenCXX/sanitize-dtor-bit-field.cpp | 4 +- test/CodeGenCXX/sanitize-dtor-derived-class.cpp | 4 +- test/CodeGenCXX/sanitize-dtor-tail-call.cpp | 4 +- test/CodeGenCXX/sanitize-dtor-trivial.cpp | 4 +- test/CodeGenCXX/sanitize-dtor-vtable.cpp | 4 +- .../skip-vtable-pointer-initialization.cpp | 16 +- test/CodeGenCXX/stack-reuse-miscompile.cpp | 2 +- test/CodeGenCXX/stack-reuse.cpp | 2 +- test/CodeGenCXX/strict-vtable-pointers.cpp | 36 +-- test/CodeGenCXX/template-instantiation.cpp | 2 +- test/CodeGenCXX/temporaries.cpp | 30 +++ test/CodeGenCXX/threadsafe-statics.cpp | 4 +- test/CodeGenCXX/thunks.cpp | 11 +- test/CodeGenCXX/ubsan-devirtualized-calls.cpp | 81 ++++++ test/CodeGenCXX/ubsan-vtable-checks.cpp | 40 +++ test/CodeGenCXX/uncopyable-args.cpp | 74 ++++++ test/CodeGenCXX/value-init.cpp | 10 +- test/CodeGenCXX/virtual-base-cast.cpp | 2 +- test/CodeGenCXX/virtual-destructor-calls.cpp | 2 +- test/CodeGenCXX/virtual-function-calls.cpp | 7 +- test/CodeGenCXX/visibility-inlines-hidden.cpp | 2 +- test/CodeGenCXX/vla-lambda-capturing.cpp | 4 +- test/CodeGenCXX/vtable-align.cpp | 4 +- test/CodeGenCXX/vtable-assume-load.cpp | 42 ++-- test/CodeGenCXX/vtable-available-externally.cpp | 2 +- test/CodeGenCXX/vtable-layout.cpp | 2 + test/CodeGenCXX/vtable-linkage.cpp | 11 +- test/CodeGenCXX/vtable-pointer-initialization.cpp | 8 +- test/CodeGenCXX/vtt-layout.cpp | 13 +- test/CodeGenCXX/wasm-args-returns.cpp | 4 +- ...-implicit-dllexport-template-specialization.cpp | 18 ++ test/CodeGenCXX/windows-itanium-dllexport.cpp | 30 +++ test/CodeGenCXX/windows-itanium-type-info.cpp | 40 +++ 174 files changed, 2996 insertions(+), 516 deletions(-) create mode 100644 test/CodeGenCXX/alias-available-externally.cpp create mode 100644 test/CodeGenCXX/alloc-size.cpp create mode 100644 test/CodeGenCXX/builtins-arm-exclusive.cpp create mode 100644 test/CodeGenCXX/cxx1z-aligned-allocation.cpp create mode 100644 test/CodeGenCXX/cxx1z-copy-omission.cpp create mode 100644 test/CodeGenCXX/cxx1z-decomposition.cpp create mode 100644 test/CodeGenCXX/cxx1z-eval-order.cpp create mode 100644 test/CodeGenCXX/cxx1z-noexcept-function-type.cpp create mode 100644 test/CodeGenCXX/debug-info-codeview-injected-class.cpp create mode 100644 test/CodeGenCXX/debug-info-dllimport-base-class.cpp delete mode 100644 test/CodeGenCXX/debug-info-flex-member.cpp create mode 100644 test/CodeGenCXX/debug-info-loops.cpp create mode 100644 test/CodeGenCXX/debug-info-ms-vbase.cpp create mode 100644 test/CodeGenCXX/debug-info-thunk-msabi.cpp create mode 100644 test/CodeGenCXX/debug-info-vla.cpp create mode 100644 test/CodeGenCXX/mangle-exception-spec.cpp create mode 100644 test/CodeGenCXX/modules-ts.cppm create mode 100644 test/CodeGenCXX/naked.cpp create mode 100644 test/CodeGenCXX/pr30731.cpp create mode 100644 test/CodeGenCXX/pragma-loop-distribute.cpp create mode 100644 test/CodeGenCXX/regcall.cpp create mode 100644 test/CodeGenCXX/rtti-mingw64.cpp create mode 100644 test/CodeGenCXX/rtti-qualfn.cpp create mode 100644 test/CodeGenCXX/runtime-dllstorage.cpp create mode 100644 test/CodeGenCXX/ubsan-devirtualized-calls.cpp create mode 100644 test/CodeGenCXX/ubsan-vtable-checks.cpp create mode 100644 test/CodeGenCXX/windows-implicit-dllexport-template-specialization.cpp create mode 100644 test/CodeGenCXX/windows-itanium-dllexport.cpp create mode 100644 test/CodeGenCXX/windows-itanium-type-info.cpp (limited to 'test/CodeGenCXX') diff --git a/test/CodeGenCXX/PR26569.cpp b/test/CodeGenCXX/PR26569.cpp index 3e2d2ffeba14..859b6e26f0c4 100644 --- a/test/CodeGenCXX/PR26569.cpp +++ b/test/CodeGenCXX/PR26569.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -emit-llvm -O1 -disable-llvm-optzns %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -emit-llvm -O1 -disable-llvm-passes %s -o - | FileCheck %s -class A { +class __declspec(dllimport) A { virtual void m_fn1(); }; template @@ -9,12 +9,12 @@ class B : virtual A {}; extern template class __declspec(dllimport) B; class __declspec(dllexport) C : B {}; -// CHECK-DAG: @[[VTABLE_C:.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4C@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1@A@@EAEXXZ" to i8*)] -// CHECK-DAG: @[[VTABLE_B:.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4?$B@H@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1@A@@EAEXXZ" to i8*)], comdat($"\01??_S?$B@H@@6B@") -// CHECK-DAG: @[[VTABLE_A:.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4A@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1@A@@EAEXXZ" to i8*)], comdat($"\01??_7A@@6B@") +// CHECK-DAG: @[[VTABLE_C:.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4C@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1@A@@EAEXXZ" to i8*)] } +// CHECK-DAG: @[[VTABLE_B:.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4?$B@H@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1@A@@EAEXXZ" to i8*)] }, comdat($"\01??_S?$B@H@@6B@") +// CHECK-DAG: @[[VTABLE_A:.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4A@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1@A@@EAEXXZ" to i8*)] }, comdat($"\01??_SA@@6B@") -// CHECK-DAG: @"\01??_7C@@6B@" = dllexport unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* @[[VTABLE_C]], i32 0, i32 1) -// CHECK-DAG: @"\01??_S?$B@H@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* @[[VTABLE_B]], i32 0, i32 1) -// CHECK-DAG: @"\01??_7A@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* @[[VTABLE_A]], i32 0, i32 1) +// CHECK-DAG: @"\01??_7C@@6B@" = dllexport unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* @[[VTABLE_C]], i32 0, i32 0, i32 1) +// CHECK-DAG: @"\01??_S?$B@H@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* @[[VTABLE_B]], i32 0, i32 0, i32 1) +// CHECK-DAG: @"\01??_SA@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* @[[VTABLE_A]], i32 0, i32 0, i32 1) // CHECK-DAG: @"\01??_8?$B@H@@7B@" = available_externally dllimport unnamed_addr constant [2 x i32] [i32 0, i32 4] diff --git a/test/CodeGenCXX/alias-available-externally.cpp b/test/CodeGenCXX/alias-available-externally.cpp new file mode 100644 index 000000000000..473e93be0a75 --- /dev/null +++ b/test/CodeGenCXX/alias-available-externally.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -O1 -std=c++11 -emit-llvm -triple %itanium_abi_triple -disable-llvm-passes -o - %s | FileCheck %s +// Clang should not generate alias to available_externally definitions. +// Check that the destructor of Foo is defined. +// The destructors have different return type for different targets. +// CHECK: define linkonce_odr {{.*}} @_ZN3FooD2Ev +template +struct String { + String() {} + ~String(); +}; + +template +inline __attribute__((visibility("hidden"), always_inline)) +String::~String() {} + +extern template struct String; + +struct Foo : public String { Foo() { String s; } }; + +Foo f; diff --git a/test/CodeGenCXX/alloc-size.cpp b/test/CodeGenCXX/alloc-size.cpp new file mode 100644 index 000000000000..e93e231b70e8 --- /dev/null +++ b/test/CodeGenCXX/alloc-size.cpp @@ -0,0 +1,72 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -O0 %s -o - 2>&1 -std=c++11 | FileCheck %s + +namespace templates { +void *my_malloc(int N) __attribute__((alloc_size(1))); +void *my_calloc(int N, int M) __attribute__((alloc_size(1, 2))); + +struct MyType { + int arr[4]; +}; + +template int callMalloc(); + +template int callCalloc(); + +// CHECK-LABEL: define i32 @_ZN9templates6testItEv() +int testIt() { + // CHECK: call i32 @_ZN9templates10callMallocINS_6MyTypeEEEiv + // CHECK: call i32 @_ZN9templates10callCallocINS_6MyTypeELi4EEEiv + return callMalloc() + callCalloc(); +} + +// CHECK-LABEL: define linkonce_odr i32 +// @_ZN9templates10callMallocINS_6MyTypeEEEiv +template int callMalloc() { + static_assert(sizeof(T) == 16, ""); + // CHECK: ret i32 16 + return __builtin_object_size(my_malloc(sizeof(T)), 0); +} + +// CHECK-LABEL: define linkonce_odr i32 +// @_ZN9templates10callCallocINS_6MyTypeELi4EEEiv +template int callCalloc() { + static_assert(sizeof(T) * N == 64, ""); + // CHECK: ret i32 64 + return __builtin_object_size(my_malloc(sizeof(T) * N), 0); +} +} + +namespace templated_alloc_size { +using size_t = unsigned long; + +// We don't need bodies for any of these, because they're only used in +// __builtin_object_size, and that shouldn't need anything but a function +// decl with alloc_size on it. +template +T *my_malloc(size_t N = sizeof(T)) __attribute__((alloc_size(1))); + +template +T *my_calloc(size_t M, size_t N = sizeof(T)) __attribute__((alloc_size(2, 1))); + +template +void *dependent_malloc(size_t NT = N) __attribute__((alloc_size(1))); + +template +void *dependent_calloc(size_t NT = N, size_t MT = M) + __attribute__((alloc_size(1, 2))); + +template +void *dependent_calloc2(size_t NT = sizeof(T), size_t MT = M) + __attribute__((alloc_size(1, 2))); + +// CHECK-LABEL: define i32 @_ZN20templated_alloc_size6testItEv +int testIt() { + // 122 = 4 + 5*4 + 6 + 7*8 + 4*9 + // CHECK: ret i32 122 + return __builtin_object_size(my_malloc(), 0) + + __builtin_object_size(my_calloc(5), 0) + + __builtin_object_size(dependent_malloc<6>(), 0) + + __builtin_object_size(dependent_calloc<7, 8>(), 0) + + __builtin_object_size(dependent_calloc2(), 0); +} +} diff --git a/test/CodeGenCXX/apple-kext-indirect-call-2.cpp b/test/CodeGenCXX/apple-kext-indirect-call-2.cpp index d441b78140e7..3b2cda8b583b 100644 --- a/test/CodeGenCXX/apple-kext-indirect-call-2.cpp +++ b/test/CodeGenCXX/apple-kext-indirect-call-2.cpp @@ -1,9 +1,9 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -emit-llvm -o - %s | FileCheck %s -// CHECK: @_ZTV1A = unnamed_addr constant [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.A*)* @_ZNK1A3abcEv to i8*), i8* null] -// CHECK: @_ZTV4Base = unnamed_addr constant [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.Base*)* @_ZNK4Base3abcEv to i8*), i8* null] -// CHECK: @_ZTV8Derived2 = unnamed_addr constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.Derived2*)* @_ZNK8Derived23efgEv to i8*), i8* null] -// CHECK: @_ZTV2D2 = unnamed_addr constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.D2*)* @_ZNK2D23abcEv to i8*), i8* null] +// CHECK: @_ZTV1A = unnamed_addr constant { [4 x i8*] } { [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.A*)* @_ZNK1A3abcEv to i8*), i8* null] } +// CHECK: @_ZTV4Base = unnamed_addr constant { [4 x i8*] } { [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.Base*)* @_ZNK4Base3abcEv to i8*), i8* null] } +// CHECK: @_ZTV8Derived2 = unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.Derived2*)* @_ZNK8Derived23efgEv to i8*), i8* null] } +// CHECK: @_ZTV2D2 = unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.D2*)* @_ZNK2D23abcEv to i8*), i8* null] } struct A { virtual const char* abc(void) const; @@ -18,7 +18,7 @@ struct B : virtual A { void B::VF() {} void FUNC(B* p) { -// CHECK: [[T1:%.*]] = load i8* (%struct.A*)*, i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)*, i8* (%struct.A*)** bitcast ([4 x i8*]* @_ZTV1A to i8* (%struct.A*)**), i64 2) +// CHECK: [[T1:%.*]] = load i8* (%struct.A*)*, i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)*, i8* (%struct.A*)** bitcast ({ [4 x i8*] }* @_ZTV1A to i8* (%struct.A*)**), i64 2) // CHECK-NEXT: [[T2:%.*]] = call i8* [[T1]] const char* c = p->A::abc(); } @@ -33,7 +33,7 @@ struct Derived : public Base { }; void FUNC1(Derived* p) { -// CHECK: [[U1:%.*]] = load i8* (%struct.Base*)*, i8* (%struct.Base*)** getelementptr inbounds (i8* (%struct.Base*)*, i8* (%struct.Base*)** bitcast ([4 x i8*]* @_ZTV4Base to i8* (%struct.Base*)**), i64 2) +// CHECK: [[U1:%.*]] = load i8* (%struct.Base*)*, i8* (%struct.Base*)** getelementptr inbounds (i8* (%struct.Base*)*, i8* (%struct.Base*)** bitcast ({ [4 x i8*] }* @_ZTV4Base to i8* (%struct.Base*)**), i64 2) // CHECK-NEXT: [[U2:%.*]] = call i8* [[U1]] char* c = p->Base::abc(); } @@ -49,7 +49,7 @@ struct Derived2 : virtual Base2 { char* Derived2::efg(void) const { return 0; } void FUNC2(Derived2* p) { -// CHECK: [[V1:%.*]] = load i8* (%struct.Derived2*)*, i8* (%struct.Derived2*)** getelementptr inbounds (i8* (%struct.Derived2*)*, i8* (%struct.Derived2*)** bitcast ([5 x i8*]* @_ZTV8Derived2 to i8* (%struct.Derived2*)**), i64 3) +// CHECK: [[V1:%.*]] = load i8* (%struct.Derived2*)*, i8* (%struct.Derived2*)** getelementptr inbounds (i8* (%struct.Derived2*)*, i8* (%struct.Derived2*)** bitcast ({ [5 x i8*] }* @_ZTV8Derived2 to i8* (%struct.Derived2*)**), i64 3) // CHECK-NEXT: [[V2:%.*]] = call i8* [[V1]] char* c = p->Derived2::efg(); } @@ -70,7 +70,7 @@ struct Sub : D1, D2 { char* D2::abc(void) const { return 0; } void FUNC3(Sub* p) { -// CHECK: [[W1:%.*]] = load i8* (%struct.D2*)*, i8* (%struct.D2*)** getelementptr inbounds (i8* (%struct.D2*)*, i8* (%struct.D2*)** bitcast ([5 x i8*]* @_ZTV2D2 to i8* (%struct.D2*)**), i64 3) +// CHECK: [[W1:%.*]] = load i8* (%struct.D2*)*, i8* (%struct.D2*)** getelementptr inbounds (i8* (%struct.D2*)*, i8* (%struct.D2*)** bitcast ({ [5 x i8*] }* @_ZTV2D2 to i8* (%struct.D2*)**), i64 3) // CHECK-NEXT: [[W2:%.*]] = call i8* [[W1]] char* c = p->D2::abc(); } diff --git a/test/CodeGenCXX/apple-kext-indirect-call.cpp b/test/CodeGenCXX/apple-kext-indirect-call.cpp index e4c03b5da50b..ac0e3f4d39c6 100644 --- a/test/CodeGenCXX/apple-kext-indirect-call.cpp +++ b/test/CodeGenCXX/apple-kext-indirect-call.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -emit-llvm -o - %s | FileCheck %s -// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI5TemplIiE to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1gEv to i8*), i8* null] +// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI5TemplIiE to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1gEv to i8*), i8* null] } struct Base { virtual void abc(void) const; @@ -12,7 +12,7 @@ void FUNC(Base* p) { p->Base::abc(); } -// CHECK: getelementptr inbounds (void (%struct.Base*)*, void (%struct.Base*)** bitcast ([4 x i8*]* @_ZTV4Base to void (%struct.Base*)**), i64 2) +// CHECK: getelementptr inbounds (void (%struct.Base*)*, void (%struct.Base*)** bitcast ({ [4 x i8*] }* @_ZTV4Base to void (%struct.Base*)**), i64 2) // CHECK-NOT: call void @_ZNK4Base3abcEv template @@ -37,6 +37,6 @@ void f(SubTempl* t) { t->Templ::f(); } -// CHECK: getelementptr inbounds (void (%struct.Templ*)*, void (%struct.Templ*)** bitcast ([5 x i8*]* @_ZTV5TemplIiE to void (%struct.Templ*)**), i64 2) +// CHECK: getelementptr inbounds (void (%struct.Templ*)*, void (%struct.Templ*)** bitcast ({ [5 x i8*] }* @_ZTV5TemplIiE to void (%struct.Templ*)**), i64 2) // CHECK: define internal void @_ZN5TemplIiE1fEv(%struct.Templ* %this) // CHECK: define internal void @_ZN5TemplIiE1gEv(%struct.Templ* %this) diff --git a/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp b/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp index 5f6bdb230fe7..4cfa88d99455 100644 --- a/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp +++ b/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -emit-llvm -o - %s | FileCheck %s -// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant [7 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiED1Ev to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiED0Ev to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1gEv to i8*), i8* null] +// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant { [7 x i8*] } { [7 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiED1Ev to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiED0Ev to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1gEv to i8*), i8* null] } struct B1 { virtual ~B1(); @@ -12,10 +12,10 @@ void DELETE(B1 *pb1) { pb1->B1::~B1(); } // CHECK-LABEL: define void @_ZN2B1D0Ev -// CHECK: [[T1:%.*]] = load void (%struct.B1*)*, void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)*, void (%struct.B1*)** bitcast ([5 x i8*]* @_ZTV2B1 to void (%struct.B1*)**), i64 2) +// CHECK: [[T1:%.*]] = load void (%struct.B1*)*, void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)*, void (%struct.B1*)** bitcast ({ [5 x i8*] }* @_ZTV2B1 to void (%struct.B1*)**), i64 2) // CHECK-NEXT: call void [[T1]](%struct.B1* [[T2:%.*]]) // CHECK-LABEL: define void @_Z6DELETEP2B1 -// CHECK: [[T3:%.*]] = load void (%struct.B1*)*, void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)*, void (%struct.B1*)** bitcast ([5 x i8*]* @_ZTV2B1 to void (%struct.B1*)**), i64 2) +// CHECK: [[T3:%.*]] = load void (%struct.B1*)*, void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)*, void (%struct.B1*)** bitcast ({ [5 x i8*] }* @_ZTV2B1 to void (%struct.B1*)**), i64 2) // CHECK-NEXT: call void [[T3]](%struct.B1* [[T4:%.*]]) template @@ -42,7 +42,7 @@ void f(SubTempl* t) { t->Templ::~Templ(); } -// CHECK: getelementptr inbounds (void (%struct.Templ*)*, void (%struct.Templ*)** bitcast ([7 x i8*]* @_ZTV5TemplIiE to void (%struct.Templ*)**), i64 2) +// CHECK: getelementptr inbounds (void (%struct.Templ*)*, void (%struct.Templ*)** bitcast ({ [7 x i8*] }* @_ZTV5TemplIiE to void (%struct.Templ*)**), i64 2) // CHECK: declare void @_ZN5TemplIiED0Ev(%struct.Templ*) // CHECK: define internal void @_ZN5TemplIiE1fEv(%struct.Templ* %this) // CHECK: define internal void @_ZN5TemplIiE1gEv(%struct.Templ* %this) diff --git a/test/CodeGenCXX/arm-swiftcall.cpp b/test/CodeGenCXX/arm-swiftcall.cpp index 535350c808d3..5c932c77b1da 100644 --- a/test/CodeGenCXX/arm-swiftcall.cpp +++ b/test/CodeGenCXX/arm-swiftcall.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -o - %s -Wno-return-type-c-linkage | FileCheck %s +// RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -o - %s -Wno-return-type-c-linkage -std=c++03 | FileCheck %s -check-prefixes=CHECK // This isn't really testing anything ARM-specific; it's just a convenient // 32-bit platform. diff --git a/test/CodeGenCXX/arm64.cpp b/test/CodeGenCXX/arm64.cpp index 19f72726e690..80438397c3f2 100644 --- a/test/CodeGenCXX/arm64.cpp +++ b/test/CodeGenCXX/arm64.cpp @@ -84,3 +84,39 @@ namespace test2 { // CHECK-GLOBALS-DAG: @_ZTIN5test21EIiEE = weak_odr constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([14 x i8]* @_ZTSN5test21EIiEE to i64), i64 -9223372036854775808) to i8*) } } + +// ARM64 reserves the top half of the vtable offset in virtual +// member pointers. +namespace test3 { + struct A { + virtual void foo(); + virtual void bar(); + }; + + // The offset half of the pointer is still initialized to zero. + // CHECK-GLOBALS-DAG: @_ZN5test34mptrE = global { i64, i64 } { i64 0, i64 1 } + void (A::*mptr)() = &A::foo; + + // CHECK-LABEL: define void @_ZN5test34testEv() + // CHECK: [[TEMP:%.*]] = alloca [[A:.*]], align 8 + // CHECK: [[MEMPTR:%.*]] = load { i64, i64 }, { i64, i64 }* @_ZN5test34mptrE, align 8 + // CHECK: [[ADJUST_AND_IS_VIRTUAL:%.*]] = extractvalue { i64, i64 } [[MEMPTR]], 1 + // CHECK: [[ADJUST:%.*]] = ashr i64 [[ADJUST_AND_IS_VIRTUAL]], 1 + // CHECK: [[T0:%.*]] = bitcast [[A]]* [[TEMP]] to i8* + // CHECK: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 [[ADJUST]] + // CHECK: [[ADJUSTED:%.*]] = bitcast i8* [[T1]] to [[A]]* + // CHECK: [[MEMBER:%.*]] = extractvalue { i64, i64 } [[MEMPTR]], 0 + // CHECK: [[T0:%.*]] = and i64 [[ADJUST_AND_IS_VIRTUAL]], 1 + // CHECK: [[IS_VIRTUAL:%.*]] = icmp ne i64 [[T0]], 0 + // CHECK: br i1 [[IS_VIRTUAL]], + // CHECK: [[T0:%.*]] = bitcast [[A]]* [[ADJUSTED]] to i8** + // CHECK: [[VPTR:%.*]] = load i8*, i8** [[T0]], align 8 + // CHECK: [[TRUNC:%.*]] = trunc i64 [[MEMBER]] to i32 + // CHECK: [[ZEXT:%.*]] = zext i32 [[TRUNC]] to i64 + // CHECK: [[T0:%.*]] = getelementptr i8, i8* [[VPTR]], i64 [[ZEXT]] + // CHECK: [[T1:%.*]] = bitcast i8* [[T0]] to void ([[A]]*)** + // CHECK: load void ([[A]]*)*, void ([[A]]*)** [[T1]], + void test() { + (A().*mptr)(); + } +} diff --git a/test/CodeGenCXX/atomicinit.cpp b/test/CodeGenCXX/atomicinit.cpp index 96f44d52f286..4c30ec35212f 100644 --- a/test/CodeGenCXX/atomicinit.cpp +++ b/test/CodeGenCXX/atomicinit.cpp @@ -51,8 +51,8 @@ struct AtomicBoolMember { }; // CHECK-LABEL: define void @_ZN16AtomicBoolMemberC2Eb -// CHECK: {{zext i1.*to i8}} -// CHECK-NEXT: store i8 +// CHECK: zext i1 {{.*}} to i8 +// CHECK: store i8 // CHECK-NEXT: ret void AtomicBoolMember::AtomicBoolMember(bool b) : ab(b) { } diff --git a/test/CodeGenCXX/attr.cpp b/test/CodeGenCXX/attr.cpp index 67993b4227a1..7f5595f6f044 100644 --- a/test/CodeGenCXX/attr.cpp +++ b/test/CodeGenCXX/attr.cpp @@ -31,4 +31,4 @@ int test1() { return 10; } // CHECK at top of file extern "C" int test2() __attribute__((alias("_Z5test1v"))); -// CHECK: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } diff --git a/test/CodeGenCXX/block-in-ctor-dtor.cpp b/test/CodeGenCXX/block-in-ctor-dtor.cpp index 0dc0ab00437f..0ec9db1db728 100644 --- a/test/CodeGenCXX/block-in-ctor-dtor.cpp +++ b/test/CodeGenCXX/block-in-ctor-dtor.cpp @@ -42,7 +42,5 @@ X::~X() { // CHECK-LABEL: define internal void @___ZN4ZoneD2Ev_block_invoke_ // CHECK-LABEL: define internal void @___ZN1XC2Ev_block_invoke // CHECK-LABEL: define internal void @___ZN1XC2Ev_block_invoke_ -// CHECK-LABEL: define internal void @___ZN1XC1Ev_block_invoke -// CHECK-LABEL: define internal void @___ZN1XC1Ev_block_invoke_ // CHECK-LABEL: define internal void @___ZN1XD2Ev_block_invoke // CHECK-LABEL: define internal void @___ZN1XD2Ev_block_invoke_ diff --git a/test/CodeGenCXX/builtins-arm-exclusive.cpp b/test/CodeGenCXX/builtins-arm-exclusive.cpp new file mode 100644 index 000000000000..06f7a023adec --- /dev/null +++ b/test/CodeGenCXX/builtins-arm-exclusive.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -Wall -Werror -triple thumbv8-linux-gnueabi -fno-signed-char -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -Wall -Werror -triple arm64-apple-ios7.0 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARM64 + +bool b; + +// CHECK-LABEL: @_Z10test_ldrexv() +// CHECK: call i32 @llvm.arm.ldrex.p0i8(i8* @b) + +// CHECK-ARM64-LABEL: @_Z10test_ldrexv() +// CHECK-ARM64: call i64 @llvm.aarch64.ldxr.p0i8(i8* @b) + +void test_ldrex() { + b = __builtin_arm_ldrex(&b); +} + +// CHECK-LABEL: @_Z10tset_strexv() +// CHECK: %{{.*}} = call i32 @llvm.arm.strex.p0i8(i32 1, i8* @b) + +// CHECK-ARM64-LABEL: @_Z10tset_strexv() +// CHECK-ARM64: %{{.*}} = call i32 @llvm.aarch64.stxr.p0i8(i64 1, i8* @b) + +void tset_strex() { + __builtin_arm_strex(true, &b); +} diff --git a/test/CodeGenCXX/catch-undef-behavior.cpp b/test/CodeGenCXX/catch-undef-behavior.cpp index 3ca7f6d65ad4..179c33412267 100644 --- a/test/CodeGenCXX/catch-undef-behavior.cpp +++ b/test/CodeGenCXX/catch-undef-behavior.cpp @@ -277,13 +277,13 @@ int array_index(const int (&a)[4], int n) { int multi_array_index(int n, int m) { int arr[4][6]; - // CHECK: %[[IDX2_OK:.*]] = icmp ult i64 %{{.*}}, 6 - // CHECK: br i1 %[[IDX2_OK]] - // CHECK: call void @__ubsan_handle_out_of_bounds( - // CHECK: %[[IDX1_OK:.*]] = icmp ult i64 %{{.*}}, 4 // CHECK: br i1 %[[IDX1_OK]] // CHECK: call void @__ubsan_handle_out_of_bounds( + + // CHECK: %[[IDX2_OK:.*]] = icmp ult i64 %{{.*}}, 6 + // CHECK: br i1 %[[IDX2_OK]] + // CHECK: call void @__ubsan_handle_out_of_bounds( return arr[n][m]; } diff --git a/test/CodeGenCXX/cfi-cross-dso.cpp b/test/CodeGenCXX/cfi-cross-dso.cpp index d67927d4d2ed..bfa0705c6f8f 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*] {{.*}}@"\01??_R4B@?A@@6B@"{{.*}}@"\01?f@B@?A@@UEAAXXZ" +// MS: @[[B_VTABLE:.*]] = private unnamed_addr constant { [2 x i8*] } {{.*}}@"\01??_R4B@?A@@6B@"{{.*}}@"\01?f@B@?A@@UEAAXXZ" // CHECK: %[[VT:.*]] = load void (%struct.A*)**, void (%struct.A*)*** // CHECK: %[[VT2:.*]] = bitcast {{.*}}%[[VT]] to i8*, !nosanitize diff --git a/test/CodeGenCXX/compound-literals.cpp b/test/CodeGenCXX/compound-literals.cpp index 69632a7de2f4..a9882bc6d241 100644 --- a/test/CodeGenCXX/compound-literals.cpp +++ b/test/CodeGenCXX/compound-literals.cpp @@ -12,6 +12,9 @@ struct Y { X x; }; +// CHECK: @.compoundliteral = internal global [5 x i32] [i32 1, i32 2, i32 3, i32 4, i32 5], align 4 +// CHECK: @q = global i32* getelementptr inbounds ([5 x i32], [5 x i32]* @.compoundliteral, i32 0, i32 0), align 4 + // CHECK-LABEL: define i32 @_Z1fv() int f() { // CHECK: [[LVALUE:%[a-z0-9.]+]] = alloca @@ -38,20 +41,45 @@ int g() { return v[0]; } +// GCC's compound-literals-in-C++ extension lifetime-extends a compound literal +// (or a C++11 list-initialized temporary!) if: +// - it is at global scope +// - it has array type +// - it has a constant initializer + struct Z { int i[3]; }; int *p = (Z){ {1, 2, 3} }.i; // CHECK: define {{.*}}__cxx_global_var_init() -// CHECK: store i32* getelementptr inbounds (%struct.Z, %struct.Z* @.compoundliteral, i32 0, i32 0, i32 0), i32** @p +// CHECK: alloca %struct.Z +// CHECK: store i32* %{{.*}}, i32** @p +int *q = (int [5]){1, 2, 3, 4, 5}; +// (constant initialization, checked above) -int *PR21912_1 = (int []){}; +extern int n; +int *r = (int [5]){1, 2, 3, 4, 5} + n; // CHECK-LABEL: define {{.*}}__cxx_global_var_init.1() -// CHECK: store i32* getelementptr inbounds ([0 x i32], [0 x i32]* @.compoundliteral.2, i32 0, i32 0), i32** @PR21912_1 +// CHECK: %[[PTR:.*]] = getelementptr inbounds i32, i32* getelementptr inbounds ([5 x i32], [5 x i32]* @.compoundliteral.2, i32 0, i32 0), i32 % +// CHECK: store i32* %[[PTR]], i32** @r + +int *PR21912_1 = (int []){} + n; +// CHECK-LABEL: define {{.*}}__cxx_global_var_init.3() +// CHECK: %[[PTR:.*]] = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @.compoundliteral.4, i32 0, i32 0), i32 % +// CHECK: store i32* %[[PTR]], i32** @PR21912_1 union PR21912Ty { long long l; double d; }; -union PR21912Ty *PR21912_2 = (union PR21912Ty[]){{.d = 2.0}, {.l = 3}}; -// CHECK-LABEL: define {{.*}}__cxx_global_var_init.3() -// CHECK: store %union.PR21912Ty* getelementptr inbounds ([2 x %union.PR21912Ty], [2 x %union.PR21912Ty]* bitcast (<{ { double }, %union.PR21912Ty }>* @.compoundliteral.4 to [2 x %union.PR21912Ty]*), i32 0, i32 0), %union.PR21912Ty** @PR21912_2 +union PR21912Ty *PR21912_2 = (union PR21912Ty[]){{.d = 2.0}, {.l = 3}} + n; +// CHECK-LABEL: define {{.*}}__cxx_global_var_init.5() +// CHECK: %[[PTR:.*]] = getelementptr inbounds %union.PR21912Ty, %union.PR21912Ty* getelementptr inbounds ([2 x %union.PR21912Ty], [2 x %union.PR21912Ty]* bitcast (<{ { double }, %union.PR21912Ty }>* @.compoundliteral.6 to [2 x %union.PR21912Ty]*), i32 0, i32 0), i32 % +// CHECK: store %union.PR21912Ty* %[[PTR]], %union.PR21912Ty** @PR21912_2, align 4 + +// This compound literal should have local scope. +int computed_with_lambda = [] { + int *array = (int[]) { 1, 3, 5, 7 }; + return array[0]; +}(); +// CHECK-LABEL: define internal i32 @{{.*}}clEv +// CHECK: alloca [4 x i32] diff --git a/test/CodeGenCXX/const-init-cxx11.cpp b/test/CodeGenCXX/const-init-cxx11.cpp index 0c2193fb07f2..c4962bc08ad6 100644 --- a/test/CodeGenCXX/const-init-cxx11.cpp +++ b/test/CodeGenCXX/const-init-cxx11.cpp @@ -343,13 +343,13 @@ namespace VirtualMembers { constexpr E() : B(3), c{'b','y','e'} {} char c[3]; }; - // CHECK: @_ZN14VirtualMembers1eE = global { i8**, double, i32, i8**, double, [5 x i8], i16, i8**, double, [5 x i8], [3 x i8] } { i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTVN14VirtualMembers1EE, i32 0, i32 2), double 1.000000e+00, i32 64, i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTVN14VirtualMembers1EE, i32 0, i32 5), double 2.000000e+00, [5 x i8] c"hello", i16 5, i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTVN14VirtualMembers1EE, i32 0, i32 9), double 3.000000e+00, [5 x i8] c"world", [3 x i8] c"bye" } + // CHECK: @_ZN14VirtualMembers1eE = global { i8**, double, i32, i8**, double, [5 x i8], i16, i8**, double, [5 x i8], [3 x i8] } { i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN14VirtualMembers1EE, i32 0, inrange i32 0, i32 2), double 1.000000e+00, i32 64, i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN14VirtualMembers1EE, i32 0, inrange i32 1, i32 2), double 2.000000e+00, [5 x i8] c"hello", i16 5, i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN14VirtualMembers1EE, i32 0, inrange i32 2, i32 2), double 3.000000e+00, [5 x i8] c"world", [3 x i8] c"bye" } E e; struct nsMemoryImpl { virtual void f(); }; - // CHECK: @_ZN14VirtualMembersL13sGlobalMemoryE = internal global { i8** } { i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN14VirtualMembers12nsMemoryImplE, i32 0, i32 2) } + // CHECK: @_ZN14VirtualMembersL13sGlobalMemoryE = internal global { i8** } { i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN14VirtualMembers12nsMemoryImplE, i32 0, inrange i32 0, i32 2) } __attribute__((used)) static nsMemoryImpl sGlobalMemory; @@ -360,7 +360,7 @@ namespace VirtualMembers { T t; }; - // CHECK: @_ZN14VirtualMembers1tE = global { i8**, i32 } { i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN14VirtualMembers13TemplateClassIiEE, i32 0, i32 2), i32 42 } + // CHECK: @_ZN14VirtualMembers1tE = global { i8**, i32 } { i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN14VirtualMembers13TemplateClassIiEE, i32 0, inrange i32 0, i32 2), i32 42 } TemplateClass t; } diff --git a/test/CodeGenCXX/constructor-destructor-return-this.cpp b/test/CodeGenCXX/constructor-destructor-return-this.cpp index 9d47d1706bbe..164fda3c1c38 100644 --- a/test/CodeGenCXX/constructor-destructor-return-this.cpp +++ b/test/CodeGenCXX/constructor-destructor-return-this.cpp @@ -111,7 +111,7 @@ D::~D() { } // CHECKIOS5-LABEL: define %class.D* @_ZN1DD1Ev(%class.D* %this) // CHECKMS-LABEL: define x86_thiscallcc %class.D* @"\01??0D@@QAE@XZ"(%class.D* returned %this, i32 %is_most_derived) -// CHECKMS-LABEL: define x86_thiscallcc void @"\01??1D@@UAE@XZ"(%class.D*) +// CHECKMS-LABEL: define x86_thiscallcc void @"\01??1D@@UAE@XZ"(%class.D* %this) class E { public: diff --git a/test/CodeGenCXX/constructor-init.cpp b/test/CodeGenCXX/constructor-init.cpp index c78534a218de..fe15ccf8fef5 100644 --- a/test/CodeGenCXX/constructor-init.cpp +++ b/test/CodeGenCXX/constructor-init.cpp @@ -95,14 +95,14 @@ namespace InitVTable { // CHECK-LABEL: define void @_ZN10InitVTable1BC2Ev(%"struct.InitVTable::B"* %this) unnamed_addr // CHECK: [[T0:%.*]] = bitcast [[B:%.*]]* [[THIS:%.*]] to i32 (...)*** - // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN10InitVTable1BE, i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]] + // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN10InitVTable1BE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]] // CHECK: [[VTBL:%.*]] = load i32 ([[B]]*)**, i32 ([[B]]*)*** {{%.*}} // CHECK-NEXT: [[FNP:%.*]] = getelementptr inbounds i32 ([[B]]*)*, i32 ([[B]]*)** [[VTBL]], i64 0 // CHECK-NEXT: [[FN:%.*]] = load i32 ([[B]]*)*, i32 ([[B]]*)** [[FNP]] // CHECK-NEXT: [[ARG:%.*]] = call i32 [[FN]]([[B]]* [[THIS]]) // CHECK-NEXT: call void @_ZN10InitVTable1AC2Ei({{.*}}* {{%.*}}, i32 [[ARG]]) // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* [[THIS]] to i32 (...)*** - // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN10InitVTable1BE, i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]] + // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN10InitVTable1BE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]] // CHECK-NEXT: ret void B::B() : A(foo()) {} @@ -110,7 +110,7 @@ namespace InitVTable { // CHECK: [[ARG:%.*]] = add nsw i32 {{%.*}}, 5 // CHECK-NEXT: call void @_ZN10InitVTable1AC2Ei({{.*}}* {{%.*}}, i32 [[ARG]]) // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* {{%.*}} to i32 (...)*** - // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN10InitVTable1BE, i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]] + // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN10InitVTable1BE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]] // CHECK-NEXT: ret void B::B(int x) : A(x + 5) {} } @@ -207,20 +207,17 @@ namespace PR10720 { // CHECK-PR10720-LABEL: define linkonce_odr void @_ZN7PR107205pair2C2ERKS0_ // CHECK-PR10720-NOT: ret - // CHECK-PR10720: load - // CHECK-PR10720: icmp ult - // CHECK-PR10720-NEXT: br i1 // CHECK-PR10720: call void @_ZN7PR107201XC1ERKS0_ - // CHECK-PR10720-NEXT: br label + // CHECK-PR10720: icmp eq + // CHECK-PR10720-NEXT: br i1 // CHECK-PR10720: ret void // CHECK-PR10720-LABEL: define linkonce_odr void @_ZN7PR107205pair2C2EOS0_ // CHECK-PR10720-NOT: ret // CHECK-PR10720: load - // CHECK-PR10720: icmp ult - // CHECK-PR10720-NEXT: br i1 // CHECK-PR10720: call void @_ZN7PR107201XC1EOS0_ - // CHECK-PR10720-NEXT: br label + // CHECK-PR10720: icmp eq + // CHECK-PR10720-NEXT: br i1 // CHECK-PR10720: ret void pair2(pair2&&) = default; diff --git a/test/CodeGenCXX/copy-constructor-elim-2.cpp b/test/CodeGenCXX/copy-constructor-elim-2.cpp index c263b7ebf952..26b6b4851f5a 100644 --- a/test/CodeGenCXX/copy-constructor-elim-2.cpp +++ b/test/CodeGenCXX/copy-constructor-elim-2.cpp @@ -74,3 +74,23 @@ namespace PR12139 { return a.value; } } + +namespace ElidableCallIsNotCopyCtor { + struct A { A(const A&); }; + struct B : A { + B(B&); + B(A); + B(int); + }; + void f() { + // Here, we construct via B(int) then B(A). The B(A) construction is + // elidable, but we don't have an AST representation for the case where we + // must elide not only a constructor call but also some argument + // conversions, so we don't elide it. + // CHECK-LABEL: define void @_ZN25ElidableCallIsNotCopyCtor1fEv( + // CHECK: call {{.*}} @_ZN25ElidableCallIsNotCopyCtor1BC1Ei( + // CHECK: call {{.*}} @_ZN25ElidableCallIsNotCopyCtor1AC1ERKS0_( + // CHECK: call {{.*}} @_ZN25ElidableCallIsNotCopyCtor1BC1ENS_1AE( + B b = 0; + } +} diff --git a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp index 9790ca882c6b..9d7e18e80f67 100644 --- a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp +++ b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp @@ -24,4 +24,4 @@ struct A { virtual void a(); }; A x(A& y) { return y; } // CHECK: define linkonce_odr {{.*}} @_ZN1AC1ERKS_(%struct.A* {{.*}}%this, %struct.A* dereferenceable({{[0-9]+}})) unnamed_addr -// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i32 0, i32 2) to i32 (...)**) +// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV1A, i32 0, inrange i32 0, i32 2) to i32 (...)**) diff --git a/test/CodeGenCXX/copy-constructor-synthesis.cpp b/test/CodeGenCXX/copy-constructor-synthesis.cpp index 4928c61488e9..5a2cc1440f74 100644 --- a/test/CodeGenCXX/copy-constructor-synthesis.cpp +++ b/test/CodeGenCXX/copy-constructor-synthesis.cpp @@ -166,7 +166,7 @@ void f(B b1) { // CHECK-LABEL: define linkonce_odr void @_ZN12rdar138169401AC2ERKS0_( // CHECK: [[THIS:%.*]] = load [[A]]*, [[A]]** // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[THIS]] to i32 (...)*** -// CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @_ZTVN12rdar138169401AE, i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]] +// CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [4 x i8*] }, { [4 x i8*] }* @_ZTVN12rdar138169401AE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]] // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 1 // CHECK-NEXT: [[OTHER:%.*]] = load [[A]]*, [[A]]** // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]], [[A]]* [[OTHER]], i32 0, i32 1 diff --git a/test/CodeGenCXX/ctor-dtor-alias.cpp b/test/CodeGenCXX/ctor-dtor-alias.cpp index 018e958aab53..6826ee5796ca 100644 --- a/test/CodeGenCXX/ctor-dtor-alias.cpp +++ b/test/CodeGenCXX/ctor-dtor-alias.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases | FileCheck --check-prefix=NOOPT %s -// RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-optzns > %t +// RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-passes > %t // RUN: FileCheck --check-prefix=CHECK1 --input-file=%t %s // RUN: FileCheck --check-prefix=CHECK2 --input-file=%t %s // RUN: FileCheck --check-prefix=CHECK3 --input-file=%t %s @@ -8,7 +8,7 @@ // RUN: FileCheck --check-prefix=CHECK5 --input-file=%t %s // RUN: FileCheck --check-prefix=CHECK6 --input-file=%t %s -// RUN: %clang_cc1 %s -triple i686-pc-windows-gnu -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-optzns | FileCheck --check-prefix=COFF %s +// RUN: %clang_cc1 %s -triple i686-pc-windows-gnu -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-passes | FileCheck --check-prefix=COFF %s namespace test1 { // Test that we produce the apropriate comdats when creating aliases to @@ -172,7 +172,7 @@ void zed() { } } -// CHECK5: @_ZTV1C = linkonce_odr unnamed_addr constant [4 x i8*] [{{[^@]*}}@_ZTI1C {{[^@]*}}@_ZN1CD2Ev {{[^@]*}}@_ZN1CD0Ev {{[^@]*}}] +// CHECK5: @_ZTV1C = linkonce_odr unnamed_addr constant { [4 x i8*] } {{[^@]*}}@_ZTI1C {{[^@]*}}@_ZN1CD2Ev {{[^@]*}}@_ZN1CD0Ev {{[^@]*}}] // r194296 replaced C::~C with B::~B without emitting the later. class A { diff --git a/test/CodeGenCXX/cxx11-exception-spec.cpp b/test/CodeGenCXX/cxx11-exception-spec.cpp index 6a3a394e047a..fbff07802676 100644 --- a/test/CodeGenCXX/cxx11-exception-spec.cpp +++ b/test/CodeGenCXX/cxx11-exception-spec.cpp @@ -121,7 +121,7 @@ void j() { } // CHECK: attributes [[NONE]] = { {{.*}} } -// CHECK: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } // CHECK: attributes [[NUW2]] = { nounwind{{.*}} } diff --git a/test/CodeGenCXX/cxx11-noreturn.cpp b/test/CodeGenCXX/cxx11-noreturn.cpp index b876bb9661ba..58a5a377133a 100644 --- a/test/CodeGenCXX/cxx11-noreturn.cpp +++ b/test/CodeGenCXX/cxx11-noreturn.cpp @@ -7,4 +7,4 @@ int g(); while (g()) {} } -// CHECK: attributes [[NR]] = { noreturn nounwind{{.*}} } +// CHECK: attributes [[NR]] = { noinline noreturn nounwind{{.*}} } diff --git a/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp b/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp index 50629b590562..6d0ae8a09e65 100644 --- a/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp +++ b/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp @@ -51,8 +51,8 @@ C n{}; // CHECK: store i32 0, i32* getelementptr inbounds ({{.*}} @a, i32 0, i32 0) // CHECK: store i8* {{.*}} @[[STR_A]]{{.*}}, i8** getelementptr inbounds ({{.*}} @a, i32 0, i32 1) -// CHECK: load i32, i32* getelementptr inbounds ({{.*}} @a, i32 0, i32 0) // CHECK: load i8*, i8** getelementptr inbounds ({{.*}} @a, i32 0, i32 1) +// CHECK: load i32, i32* getelementptr inbounds ({{.*}} @a, i32 0, i32 0) // CHECK: getelementptr inbounds i8, i8* %{{.*}}, {{.*}} %{{.*}} // CHECK: store i8 %{{.*}}, i8* getelementptr inbounds ({{.*}} @a, i32 0, i32 2) // CHECK: call i32 @_ZN1A1fEv({{.*}} @a) diff --git a/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp b/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp index 8c0b8c22096d..bc775568aaf1 100644 --- a/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp +++ b/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -std=c++1y -O1 -disable-llvm-optzns %s -o - | FileCheck %s -check-prefix=CHECKA -check-prefix=CHECK -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -std=c++1y -O1 -disable-llvm-optzns -fcxx-exceptions %s -o - | FileCheck %s -check-prefix=CHECKB -check-prefix=CHECK +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -std=c++1y -O1 -disable-llvm-passes %s -o - | FileCheck %s -check-prefix=CHECKA -check-prefix=CHECK +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -std=c++1y -O1 -disable-llvm-passes -fcxx-exceptions %s -o - | FileCheck %s -check-prefix=CHECKB -check-prefix=CHECK // expected-no-diagnostics // The variable template specialization x generated in each file diff --git a/test/CodeGenCXX/cxx1z-aligned-allocation.cpp b/test/CodeGenCXX/cxx1z-aligned-allocation.cpp new file mode 100644 index 000000000000..437597d963b0 --- /dev/null +++ b/test/CodeGenCXX/cxx1z-aligned-allocation.cpp @@ -0,0 +1,206 @@ +// Check that delete exprs call aligned (de)allocation functions if +// -faligned-allocation is passed in both C++11 and C++14. +// RUN: %clang_cc1 -std=c++11 -fexceptions -fsized-deallocation -faligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s +// RUN: %clang_cc1 -std=c++14 -fexceptions -fsized-deallocation -faligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s +// RUN: %clang_cc1 -std=c++1z -fexceptions -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s + +// Check that we don't used aligned (de)allocation without -faligned-allocation or C++1z. +// RUN: %clang_cc1 -std=c++14 -DUNALIGNED -fexceptions %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED +// RUN: %clang_cc1 -std=c++1z -DUNALIGNED -fexceptions -fno-aligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED + +// CHECK-UNALIGNED-NOT: _Znwm_St11align_val_t +// CHECK-UNALIGNED-NOT: _Znam_St11align_val_t +// CHECK-UNALIGNED-NOT: _ZdlPv_St11align_val_t +// CHECK-UNALIGNED-NOT: _ZdaPv_St11align_val_t +// CHECK-UNALIGNED-NOT: _ZdlPvm_St11align_val_t +// CHECK-UNALIGNED-NOT: _ZdaPvm_St11align_val_t + +typedef decltype(sizeof(0)) size_t; +namespace std { enum class align_val_t : size_t {}; } + +#define OVERALIGNED alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2) + +// Global new and delete. +// ====================== +struct OVERALIGNED A { A(); int n[128]; }; + +// CHECK-LABEL: define {{.*}} @_Z2a0v() +// CHECK: %[[ALLOC:.*]] = call i8* @_ZnwmSt11align_val_t(i64 512, i64 32) +// CHECK: call void @_ZdlPvSt11align_val_t(i8* %[[ALLOC]], i64 32) +void *a0() { return new A; } + +// CHECK-LABEL: define {{.*}} @_Z2a1l( +// CHECK: %[[ALLOC:.*]] = call i8* @_ZnamSt11align_val_t(i64 %{{.*}}, i64 32) +// No array cookie. +// CHECK-NOT: store +// CHECK: invoke void @_ZN1AC1Ev( +// CHECK: call void @_ZdaPvSt11align_val_t(i8* %[[ALLOC]], i64 32) +void *a1(long n) { return new A[n]; } + +// CHECK-LABEL: define {{.*}} @_Z2a2P1A( +// CHECK: call void @_ZdlPvmSt11align_val_t(i8* %{{.*}}, i64 512, i64 32) #9 +void a2(A *p) { delete p; } + +// CHECK-LABEL: define {{.*}} @_Z2a3P1A( +// CHECK: call void @_ZdaPvSt11align_val_t(i8* %{{.*}}, i64 32) #9 +void a3(A *p) { delete[] p; } + + +// Class-specific usual new and delete. +// ==================================== +struct OVERALIGNED B { + B(); + // These are just a distraction. We should ignore them. + void *operator new(size_t); + void operator delete(void*, size_t); + void operator delete[](void*, size_t); + + void *operator new(size_t, std::align_val_t); + void operator delete(void*, std::align_val_t); + void operator delete[](void*, std::align_val_t); + + int n[128]; +}; + +// CHECK-LABEL: define {{.*}} @_Z2b0v() +// CHECK: %[[ALLOC:.*]] = call i8* @_ZN1BnwEmSt11align_val_t(i64 512, i64 32) +// CHECK: call void @_ZN1BdlEPvSt11align_val_t(i8* %[[ALLOC]], i64 32) +void *b0() { return new B; } + +// CHECK-LABEL: define {{.*}} @_Z2b1l( +// CHECK: %[[ALLOC:.*]] = call i8* @_ZnamSt11align_val_t(i64 %{{.*}}, i64 32) +// No array cookie. +// CHECK-NOT: store +// CHECK: invoke void @_ZN1BC1Ev( +// CHECK: call void @_ZN1BdaEPvSt11align_val_t(i8* %[[ALLOC]], i64 32) +void *b1(long n) { return new B[n]; } + +// CHECK-LABEL: define {{.*}} @_Z2b2P1B( +// CHECK: call void @_ZN1BdlEPvSt11align_val_t(i8* %{{.*}}, i64 32) +void b2(B *p) { delete p; } + +// CHECK-LABEL: define {{.*}} @_Z2b3P1B( +// CHECK: call void @_ZN1BdaEPvSt11align_val_t(i8* %{{.*}}, i64 32) +void b3(B *p) { delete[] p; } + +struct OVERALIGNED C { + C(); + void *operator new[](size_t, std::align_val_t); + void operator delete[](void*, size_t, std::align_val_t); + + // It doesn't matter that we have an unaligned operator delete[] that doesn't + // want the size. What matters is that the aligned one does. + void operator delete[](void*); +}; + +// This one has an array cookie. +// CHECK-LABEL: define {{.*}} @_Z2b4l( +// CHECK: call {{.*}} @llvm.umul.with.overflow{{.*}}i64 32 +// CHECK: call {{.*}} @llvm.uadd.with.overflow{{.*}}i64 32 +// CHECK: %[[ALLOC:.*]] = call i8* @_ZN1CnaEmSt11align_val_t(i64 %{{.*}}, i64 32) +// CHECK: store +// CHECK: call void @_ZN1CC1Ev( +// +// Note, we're still calling a placement allocation function, and there is no +// matching placement operator delete. =( +// FIXME: This seems broken. +// CHECK-NOT: call void @_ZN1CdaEPvmSt11align_val_t( +#ifndef UNALIGNED +void *b4(long n) { return new C[n]; } +#endif + +// CHECK-LABEL: define {{.*}} @_Z2b5P1C( +// CHECK: mul i64{{.*}} 32 +// CHECK: add i64{{.*}} 32 +// CHECK: call void @_ZN1CdaEPvmSt11align_val_t( +void b5(C *p) { delete[] p; } + + +// Global placement new. +// ===================== + +struct Q { int n; } q; +void *operator new(size_t, Q); +void *operator new(size_t, std::align_val_t, Q); +void operator delete(void*, Q); +void operator delete(void*, std::align_val_t, Q); + +// CHECK-LABEL: define {{.*}} @_Z2c0v( +// CHECK: %[[ALLOC:.*]] = call i8* @_ZnwmSt11align_val_t1Q(i64 512, i64 32, i32 % +// CHECK: call void @_ZdlPvSt11align_val_t1Q(i8* %[[ALLOC]], i64 32, i32 % +void *c0() { return new (q) A; } + + +// Class-specific placement new. +// ============================= + +struct OVERALIGNED D { + D(); + void *operator new(size_t, Q); + void *operator new(size_t, std::align_val_t, Q); + void operator delete(void*, Q); + void operator delete(void*, std::align_val_t, Q); +}; + +// CHECK-LABEL: define {{.*}} @_Z2d0v( +// CHECK: %[[ALLOC:.*]] = call i8* @_ZN1DnwEmSt11align_val_t1Q(i64 32, i64 32, i32 % +// CHECK: call void @_ZN1DdlEPvSt11align_val_t1Q(i8* %[[ALLOC]], i64 32, i32 % +void *d0() { return new (q) D; } + + +// Calling aligned new with placement syntax. +// ========================================== + +#ifndef UNALIGNED +// CHECK-LABEL: define {{.*}} @_Z2e0v( +// CHECK: %[[ALLOC:.*]] = call i8* @_ZnwmSt11align_val_t(i64 512, i64 5) +// CHECK: call void @_ZdlPvSt11align_val_t(i8* %[[ALLOC]], i64 5) +void *e0() { return new (std::align_val_t(5)) A; } + +// CHECK-LABEL: define {{.*}} @_Z2e1v( +// CHECK: %[[ALLOC:.*]] = call i8* @_ZN1BnwEmSt11align_val_t(i64 512, i64 5) +// CHECK: call void @_ZN1BdlEPvSt11align_val_t(i8* %[[ALLOC]], i64 5) +void *e1() { return new (std::align_val_t(5)) B; } +#endif + +// Variadic placement/non-placement allocation functions. +// ====================================================== + +struct OVERALIGNED F { + F(); + void *operator new(size_t, ...); + void operator delete(void*, ...); + int n[128]; +}; + +// CHECK-LABEL: define {{.*}} @_Z2f0v( +// CHECK: %[[ALLOC:.*]] = call i8* (i64, ...) @_ZN1FnwEmz(i64 512, i64 32) +// Non-placement allocation function, uses normal deallocation lookup which +// cares about whether a parameter has type std::align_val_t. +// CHECK: call void (i8*, ...) @_ZN1FdlEPvz(i8* %[[ALLOC]]) +void *f0() { return new F; } + +// CHECK-LABEL: define {{.*}} @_Z2f1v( +// CHECK: %[[ALLOC:.*]] = call i8* (i64, ...) @_ZN1FnwEmz(i64 512, i64 32, i32 % +// Placement allocation function, uses placement deallocation matching, which +// passes same arguments and therefore includes alignment. +// CHECK: call void (i8*, ...) @_ZN1FdlEPvz(i8* %[[ALLOC]], i64 32, i32 % +void *f1() { return new (q) F; } + +struct OVERALIGNED G { + G(); + void *operator new(size_t, std::align_val_t, ...); + void operator delete(void*, std::align_val_t, ...); + int n[128]; +}; +#ifndef UNALIGNED +// CHECK-LABEL: define {{.*}} @_Z2g0v +// CHECK: %[[ALLOC:.*]] = call i8* (i64, i64, ...) @_ZN1GnwEmSt11align_val_tz(i64 512, i64 32) +// CHECK: call void (i8*, i64, ...) @_ZN1GdlEPvSt11align_val_tz(i8* %[[ALLOC]], i64 32) +void *g0() { return new G; } + +// CHECK-LABEL: define {{.*}} @_Z2g1v +// CHECK: %[[ALLOC:.*]] = call i8* (i64, i64, ...) @_ZN1GnwEmSt11align_val_tz(i64 512, i64 32, i32 % +// CHECK: call void (i8*, i64, ...) @_ZN1GdlEPvSt11align_val_tz(i8* %[[ALLOC]], i64 32, i32 % +void *g1() { return new (q) G; } +#endif diff --git a/test/CodeGenCXX/cxx1z-constexpr-if.cpp b/test/CodeGenCXX/cxx1z-constexpr-if.cpp index 80a397f51e9a..14695363b331 100644 --- a/test/CodeGenCXX/cxx1z-constexpr-if.cpp +++ b/test/CodeGenCXX/cxx1z-constexpr-if.cpp @@ -2,7 +2,15 @@ void should_be_used_1(); void should_be_used_2(); +void should_be_used_3(); void should_not_be_used(); + +struct A { + constexpr explicit operator bool() const { + return true; + } +}; + void f() { if constexpr (false) should_not_be_used(); @@ -15,7 +23,12 @@ void f() { goto foo; foo: should_not_be_used(); } + if constexpr (A()) + should_be_used_3(); + else + should_not_be_used(); } // CHECK: should_be_used_1 // CHECK: should_be_used_2 +// CHECK: should_be_used_3 diff --git a/test/CodeGenCXX/cxx1z-copy-omission.cpp b/test/CodeGenCXX/cxx1z-copy-omission.cpp new file mode 100644 index 000000000000..234e4b12589c --- /dev/null +++ b/test/CodeGenCXX/cxx1z-copy-omission.cpp @@ -0,0 +1,81 @@ +// RUN: %clang_cc1 -std=c++1z -emit-llvm -triple x86_64-linux-gnu -o - %s | FileCheck %s + +struct A { + A(int); + A(A&&); + A(const A&); + ~A(); + + int arr[10]; +}; + +A f(); +void h(); + +// CHECK-LABEL: define {{.*}} @_Z1gv( +void g() { + // CHECK: %[[A:.*]] = alloca + // CHECK-NOT: alloca + // CHECK-NOT: call + // CHECK: call {{.*}} @_Z1fv({{.*}}* sret %[[A]]) + A a = A( A{ f() } ); + // CHECK-NOT: call + + // CHECK: call void @_Z1hv( + h(); + // CHECK-NOT: call + + // CHECK: call void @_ZN1AD1Ev({{.*}}* %[[A]]) + // CHECK-NOT: call + // CHECK-LABEL: } +} + +void f(A); + +// CHECK-LABEL: define {{.*}} @_Z1hv( +void h() { + // CHECK: %[[A:.*]] = alloca + // CHECK-NOT: alloca + // CHECK-NOT: call + + // CHECK: call {{.*}} @_Z1fv({{.*}}* sret %[[A]]) + // CHECK-NOT: call + // CHECK: call {{.*}} @_Z1f1A({{.*}}* %[[A]]) + f(f()); + // CHECK-NOT: call + // CHECK: call void @_ZN1AD1Ev({{.*}}* %[[A]]) + + // CHECK: call void @_Z1hv( + h(); + + // CHECK-NOT: call + // CHECK-LABEL: } +} + +// We still pass classes with trivial copy/move constructors and destructors in +// registers, even if the copy is formally omitted. +struct B { + B(int); + int n; +}; + +B fB(); +void fB(B); + +// CHECK-LABEL: define {{.*}} @_Z1iv( +void i() { + // CHECK: %[[B:.*]] = alloca + // CHECK-NOT: alloca + // CHECK-NOT: call + + // CHECK: %[[B_N:.*]] = call i32 @_Z2fBv() + // CHECK-NOT: call + // CHECK: store i32 %[[B_N]], + // CHECK-NOT: call + // CHECK: %[[B_N:.*]] = load i32 + // CHECK-NOT: call + // CHECK: call void @_Z2fB1B(i32 %[[B_N]]) + fB(fB()); + + // CHECK-LABEL: } +} diff --git a/test/CodeGenCXX/cxx1z-decomposition.cpp b/test/CodeGenCXX/cxx1z-decomposition.cpp new file mode 100644 index 000000000000..b9212006053b --- /dev/null +++ b/test/CodeGenCXX/cxx1z-decomposition.cpp @@ -0,0 +1,118 @@ +// RUN: %clang_cc1 -std=c++1z -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s + +namespace std { + using size_t = decltype(sizeof(0)); + template struct tuple_size; + template struct tuple_element; +} + +struct Y { int n; }; +struct X { X(); X(Y); X(const X&); ~X(); }; + +struct A { int a : 13; bool b; }; + +struct B {}; +template<> struct std::tuple_size { enum { value = 2 }; }; +template<> struct std::tuple_element<0,B> { using type = X; }; +template<> struct std::tuple_element<1,B> { using type = const int&; }; +template auto get(B) { + if constexpr (N == 0) + return Y(); + else + return 0.0; +} + +using C = int[2]; + +typedef int D __attribute__((ext_vector_type(2))); + +using E = _Complex int; + +template T &make(); + +// CHECK: @_ZDC2a12a2E = global {{.*}} zeroinitializer, align 4 +auto [a1, a2] = make(); +// CHECK: @_ZDC2b12b2E = global {{.*}} zeroinitializer, align 1 +// CHECK: @b1 = global {{.*}}* null, align 8 +// CHECK: @_ZGR2b1_ = internal global {{.*}} zeroinitializer, align 1 +// CHECK: @b2 = global i32* null, align 8 +// CHECK: @_ZGR2b2_ = internal global i32 0, align 4 +auto [b1, b2] = make(); +// CHECK: @_ZDC2c12c2E = global [2 x i32]* null, align 8 +auto &[c1, c2] = make(); +// CHECK: @_ZDC2d12d2E = global <2 x i32> zeroinitializer, align 8 +auto [d1, d2] = make(); +// CHECK: @_ZDC2e12e2E = global { i32, i32 } zeroinitializer, align 4 +auto [e1, e2] = make(); + +// CHECK: call {{.*}}* @_Z4makeI1AERT_v() +// CHECK: call {{.*}}memcpy{{.*}}@_ZDC2a12a2E + +// CHECK: @_Z4makeI1BERT_v() +// CHECK: call i32 @_Z3getILi0EEDa1B() +// CHECK: call void @_ZN1XC1E1Y({{.*}}* @_ZGR2b1_, i32 +// CHECK: call i32 @__cxa_atexit({{.*}}@_ZN1XD1Ev{{.*}}@_ZGR2b1_ +// CHECK: store {{.*}}* @_ZGR2b1_, +// +// CHECK: call double @_Z3getILi1EEDa1B() +// CHECK: fptosi double %{{.*}} to i32 +// CHECK: store i32 %{{.*}}, i32* @_ZGR2b2_ +// CHECK: store i32* @_ZGR2b2_, i32** @b2 + +// CHECK: call {{.*}}* @_Z4makeIA2_iERT_v() +// CHECK: store {{.*}}, [2 x i32]** @_ZDC2c12c2E + +// CHECK: call {{.*}}* @_Z4makeIDv2_iERT_v() +// CHECK: store {{.*}}, <2 x i32>* @_ZDC2d12d2E, align 8 + +// CHECK: call {{.*}}* @_Z4makeICiERT_v() +// CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @_ZDC2e12e2E, i32 0, i32 0) +// CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @_ZDC2e12e2E, i32 0, i32 1) + +// CHECK: define i32 @_Z12test_globalsv() +int test_globals() { + return a2 + b2 + c2 + d2 + e2; + // CHECK: load i8, i8* getelementptr inbounds (%struct.A, %struct.A* @_ZDC2a12a2E, i32 0, i32 1) + // + // CHECK: %[[b2:.*]] = load i32*, i32** @b2 + // CHECK: load i32, i32* %[[b2]] + // + // CHECK: %[[c1c2:.*]] = load [2 x i32]*, [2 x i32]** @_ZDC2c12c2E + // CHECK: %[[c2:.*]] = getelementptr inbounds [2 x i32], [2 x i32]* %[[c1c2]], i64 0, i64 1 + // CHECK: load i32, i32* %[[c2]] + // + // CHECK: %[[d1d2:.*]] = load <2 x i32>, <2 x i32>* @_ZDC2d12d2E + // CHECK: extractelement <2 x i32> %[[d1d2]], i32 1 + // + // CHECK: load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @_ZDC2e12e2E, i32 0, i32 1) +} + +// CHECK: define i32 @_Z11test_localsv() +int test_locals() { + auto [b1, b2] = make(); + + // CHECK: @_Z4makeI1BERT_v() + // CHECK: call i32 @_Z3getILi0EEDa1B() + // CHECK: call void @_ZN1XC1E1Y({{.*}}* %[[b1:.*]], i32 + // + // CHECK: call double @_Z3getILi1EEDa1B() + // CHECK: %[[cvt:.*]] = fptosi double %{{.*}} to i32 + // CHECK: store i32 %[[cvt]], i32* %[[b2:.*]], + // CHECK: store i32* %[[b2]], i32** %[[b2ref:.*]], + + return b2; + // CHECK: %[[b2:.*]] = load i32*, i32** %[[b2ref]] + // CHECK: load i32, i32* %[[b2]] + + // CHECK: call {{.*}}@_ZN1XD1Ev({{.*}}%[[b1]]) +} + +// CHECK: define void @_Z13test_bitfieldR1A( +void test_bitfield(A &a) { + auto &[a1, a2] = a; + a1 = 5; + // CHECK: load i16, i16* %[[BITFIELD:.*]], + // CHECK: and i16 %{{.*}}, -8192 + // CHECK: or i16 %{{.*}}, 5 + // CHECK: store i16 %{{.*}}, i16* %[[BITFIELD]], +} diff --git a/test/CodeGenCXX/cxx1z-eval-order.cpp b/test/CodeGenCXX/cxx1z-eval-order.cpp new file mode 100644 index 000000000000..1106719a4748 --- /dev/null +++ b/test/CodeGenCXX/cxx1z-eval-order.cpp @@ -0,0 +1,271 @@ +// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple %itanium_abi_triple | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ITANIUM +// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple i686-windows | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-WINDOWS +// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple x86_64-windows | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-WINDOWS + +struct B; +struct A { + A(); + A(const A&); + + void operator[](B b); + + int a_member_f(B); +}; +struct B { + B(); + ~B(); +}; + +struct C { + operator int *(); + A *operator->(); + void operator->*(A); + friend void operator->*(C, B); + + friend void operator<<(C, B); + friend void operator>>(C, B); + void operator<<(A); + void operator>>(A); + + void operator=(A); + void operator+=(A); + friend void operator+=(C, B); + + void operator,(A); + friend void operator,(C, B); + + void operator&&(A); + void operator||(A); + friend void operator&&(C, B); + friend void operator||(C, B); +}; + +A make_a(); +A *make_a_ptr(); +int A::*make_mem_ptr_a(); +void (A::*make_mem_fn_ptr_a())(); +B make_b(); +C make_c(); +void side_effect(); + +void callee(A); +void (*get_f())(A); + + +// CHECK-LABEL: define {{.*}}@{{.*}}postfix_before_args{{.*}}( +void postfix_before_args() { + // CHECK: call {{.*}}@{{.*}}get_f{{.*}}( + // CHECK-ITANIUM: call {{.*}}@_ZN1AC1Ev( + // CHECK-WINDOWS: call {{.*}}@"\01??0A@@Q{{AE|EAA}}@XZ"( + // CHECK: call {{.*}}%{{.*}}( + get_f()(A{}); + + // CHECK: call {{.*}}@{{.*}}side_effect{{.*}}( + // CHECK-ITANIUM: call {{.*}}@_ZN1AC1Ev( + // CHECK-WINDOWS: call {{.*}}@"\01??0A@@Q{{AE|EAA}}@XZ"( + // CHECK: call {{.*}}@{{.*}}callee{{.*}}( + (side_effect(), callee)(A{}); +// CHECK: } +} + + +// CHECK-LABEL: define {{.*}}@{{.*}}dot_lhs_before_rhs{{.*}}( +void dot_lhs_before_rhs() { + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( + // CHECK: call {{.*}}@{{.*}}a_member_f{{.*}}( + make_a().a_member_f(make_b()); + + // CHECK: call {{.*}}@{{.*}}make_a_ptr{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( + // CHECK: call {{.*}}@{{.*}}a_member_f{{.*}}( + make_a_ptr()->a_member_f(make_b()); + + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( + // CHECK: call {{.*}}@{{.*}}a_member_f{{.*}}( + make_c()->a_member_f(make_b()); +// CHECK: } +} + + +// CHECK-LABEL: define {{.*}}@{{.*}}array_lhs_before_rhs{{.*}}( +void array_lhs_before_rhs() { + int (&get_arr())[10]; + extern int get_index(); + + // CHECK: call {{.*}}@{{.*}}get_arr{{.*}}( + // CHECK: call {{.*}}@{{.*}}get_index{{.*}}( + get_arr()[get_index()] = 0; + + // CHECK: call {{.*}}@{{.*}}get_index{{.*}}( + // CHECK: call {{.*}}@{{.*}}get_arr{{.*}}( + get_index()[get_arr()] = 0; + + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( + // CHECK: call + make_a()[make_b()]; + + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}get_index{{.*}}( + // CHECK: call + make_c()[get_index()] = 0; + + // CHECK: call {{.*}}@{{.*}}get_index{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call + get_index()[make_c()] = 0; +// CHECK: } +} + + +void *operator new(decltype(sizeof(0)), C); + +// CHECK-LABEL: define {{.*}}@{{.*}}alloc_before_init{{.*}}( +void alloc_before_init() { + struct Q { Q(A) {} }; + // CHECK-ITANIUM: call {{.*}}@_Znw{{.*}}( + // CHECK-WINDOWS: call {{.*}}@"\01??2@YAP{{EAX_K|AXI}}@Z"( + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + delete new Q(make_a()); + + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + new (make_c()) Q(make_a()); +// CHECK: } +} + + +// CHECK-LABEL: define {{.*}}@{{.*}}dotstar_lhs_before_rhs{{.*}}( +int dotstar_lhs_before_rhs() { + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_mem_ptr_a{{.*}}( + int a = make_a().*make_mem_ptr_a(); + + // CHECK: call {{.*}}@{{.*}}make_a_ptr{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_mem_ptr_a{{.*}}( + int b = make_a_ptr()->*make_mem_ptr_a(); + + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + make_c()->*make_a(); + + // FIXME: For MS ABI, the order of destruction of parameters here will not be + // reverse construction order (parameters are destroyed left-to-right in the + // callee). That sadly seems unavoidable; the rules are not implementable as + // specified. If we changed parameter destruction order for these functions + // to right-to-left, we could make the destruction order match for all cases + // other than indirect calls, but we can't completely avoid the problem. + // + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( + make_c()->*make_b(); + + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_mem_fn_ptr_a{{.*}}( + // CHECK: call + (make_a().*make_mem_fn_ptr_a())(); + + // CHECK: call {{.*}}@{{.*}}make_a_ptr{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_mem_fn_ptr_a{{.*}}( + // CHECK: call + (make_a_ptr()->*make_mem_fn_ptr_a())(); + + return a + b; +// CHECK: } +} + + +// CHECK-LABEL: define {{.*}}@{{.*}}assign_rhs_before_lhs{{.*}}( +void assign_rhs_before_lhs() { + extern int &lhs_ref(), rhs(); + + // CHECK: call {{.*}}@{{.*}}rhs{{.*}}( + // CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}( + lhs_ref() = rhs(); + + // CHECK: call {{.*}}@{{.*}}rhs{{.*}}( + // CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}( + lhs_ref() += rhs(); + + // CHECK: call {{.*}}@{{.*}}rhs{{.*}}( + // CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}( + lhs_ref() %= rhs(); + + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + make_c() = make_a(); + + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + make_c() += make_a(); + + // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + make_c() += make_b(); +// CHECK: } +} + +// CHECK-LABEL: define {{.*}}@{{.*}}shift_lhs_before_rhs{{.*}}( +void shift_lhs_before_rhs() { + extern int lhs(), rhs(); + + // CHECK: call {{.*}}@{{.*}}lhs{{.*}}( + // CHECK: call {{.*}}@{{.*}}rhs{{.*}}( + (void)(lhs() << rhs()); + + // CHECK: call {{.*}}@{{.*}}lhs{{.*}}( + // CHECK: call {{.*}}@{{.*}}rhs{{.*}}( + (void)(lhs() >> rhs()); + + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + make_c() << make_a(); + + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + make_c() >> make_a(); + + // FIXME: This is not correct for Windows ABIs, see above. + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( + make_c() << make_b(); + + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( + make_c() >> make_b(); +// CHECK: } +} + +// CHECK-LABEL: define {{.*}}@{{.*}}comma_lhs_before_rhs{{.*}}( +void comma_lhs_before_rhs() { + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + make_c() , make_a(); + + // FIXME: This is not correct for Windows ABIs, see above. + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( + make_c() , make_b(); +} + +// CHECK-LABEL: define {{.*}}@{{.*}}andor_lhs_before_rhs{{.*}}( +void andor_lhs_before_rhs() { + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + make_c() && make_a(); + + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + make_c() || make_a(); + + // FIXME: This is not correct for Windows ABIs, see above. + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( + make_c() && make_b(); + + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( + make_c() || make_b(); +} diff --git a/test/CodeGenCXX/cxx1z-noexcept-function-type.cpp b/test/CodeGenCXX/cxx1z-noexcept-function-type.cpp new file mode 100644 index 000000000000..d2d06fbd2654 --- /dev/null +++ b/test/CodeGenCXX/cxx1z-noexcept-function-type.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -std=c++1z -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s + +// CHECK-LABEL: define {{.*}} @_Z11builtin_newm( +// CHECK: call {{.*}} @_Znwm( +void *builtin_new(unsigned long n) { return __builtin_operator_new(n); } + +// CHECK-LABEL: define {{.*}} @_Z14builtin_deletePv( +// CHECK: call {{.*}} @_ZdlPv( +void builtin_delete(void *p) { return __builtin_operator_delete(p); } diff --git a/test/CodeGenCXX/debug-info-access.cpp b/test/CodeGenCXX/debug-info-access.cpp index 41b7f71fcecb..82f29ea4d38a 100644 --- a/test/CodeGenCXX/debug-info-access.cpp +++ b/test/CodeGenCXX/debug-info-access.cpp @@ -39,6 +39,6 @@ private: // CHECK-SAME: flags: DIFlagPrototyped, void free() {} +U u; A a; B b; -U u; diff --git a/test/CodeGenCXX/debug-info-alias.cpp b/test/CodeGenCXX/debug-info-alias.cpp index 90476439e782..8c3f8447de69 100644 --- a/test/CodeGenCXX/debug-info-alias.cpp +++ b/test/CodeGenCXX/debug-info-alias.cpp @@ -14,8 +14,6 @@ bar } // CHECK: !DIGlobalVariable(name: "bi",{{.*}} type: [[BINT:![0-9]+]] -// CHECK: [[BINT]] = !DIDerivedType(tag: DW_TAG_typedef, name: "bar" -// CHECK-SAME: line: 42, x::bar bi; // CHECK: !DIGlobalVariable(name: "bf",{{.*}} type: [[BFLOAT:![0-9]+]] // CHECK: [[BFLOAT]] = !DIDerivedType(tag: DW_TAG_typedef, name: "bar" @@ -37,3 +35,6 @@ tv *tvp; using v = void; // CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "v" v *vp; + +// CHECK: [[BINT]] = !DIDerivedType(tag: DW_TAG_typedef, name: "bar" +// CHECK-SAME: line: 42, diff --git a/test/CodeGenCXX/debug-info-anon-namespace.cpp b/test/CodeGenCXX/debug-info-anon-namespace.cpp index 4e3e08af2b74..79298deaf8b1 100644 --- a/test/CodeGenCXX/debug-info-anon-namespace.cpp +++ b/test/CodeGenCXX/debug-info-anon-namespace.cpp @@ -19,8 +19,9 @@ int *b2 = &a2; // PS4: [[NS:![0-9]+]] = !DINamespace +// PS4: [[CU:![0-9]+]] = distinct !DICompileUnit // PS4: [[NS2:![0-9]+]] = !DINamespace -// PS4: !DIImportedEntity(tag: DW_TAG_imported_module, scope: !0, entity: [[NS]]) +// PS4: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CU]], entity: [[NS]]) // PS4: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[NS]], entity: [[NS2]], line: {{[0-9]+}}) // NON-PS4-NOT: !DIImportedEntity diff --git a/test/CodeGenCXX/debug-info-anon-union-vars.cpp b/test/CodeGenCXX/debug-info-anon-union-vars.cpp index b844d429447b..61b3c7c0526c 100644 --- a/test/CodeGenCXX/debug-info-anon-union-vars.cpp +++ b/test/CodeGenCXX/debug-info-anon-union-vars.cpp @@ -45,8 +45,8 @@ void instantiate(int x) { } // CHECK: !DIGlobalVariable(name: "c",{{.*}} file: [[FILE:.*]], line: 6,{{.*}} isLocal: true, isDefinition: true -// CHECK: [[FILE]] = !DIFile(filename: "{{.*}}debug-info-anon-union-vars.cpp", // CHECK: !DIGlobalVariable(name: "d",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true +// CHECK: [[FILE]] = !DIFile(filename: "{{.*}}debug-info-anon-union-vars.cpp", // CHECK: !DIGlobalVariable(name: "a",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true // CHECK: !DIGlobalVariable(name: "b",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true // CHECK: !DIGlobalVariable(name: "result", {{.*}} isLocal: false, isDefinition: true diff --git a/test/CodeGenCXX/debug-info-calling-conventions.cpp b/test/CodeGenCXX/debug-info-calling-conventions.cpp index 51d801e35ef6..db7fbd23405d 100644 --- a/test/CodeGenCXX/debug-info-calling-conventions.cpp +++ b/test/CodeGenCXX/debug-info-calling-conventions.cpp @@ -8,7 +8,7 @@ void A::thiscallcc() {} // CHECK: !DISubprogram(name: "thiscallcc", {{.*}} type: ![[thiscallty:[^,]*]], {{.*}}) // CHECK: ![[thiscallty]] = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: ![[thisargs:[^,)]*]]) // CHECK: ![[thisargs]] = !{null, ![[thisptrty:[^,}]*]]} -// CHECK: ![[thisptrty]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{.*}}, size: 32, align: 32, flags: DIFlagArtificial | DIFlagObjectPointer) +// CHECK: ![[thisptrty]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{.*}}, size: 32, flags: DIFlagArtificial | DIFlagObjectPointer) void cdeclcc() {} void __fastcall fastcallcc() {} diff --git a/test/CodeGenCXX/debug-info-class-nolimit.cpp b/test/CodeGenCXX/debug-info-class-nolimit.cpp index ce47f9fa495a..0b3b38dd17b1 100644 --- a/test/CodeGenCXX/debug-info-class-nolimit.cpp +++ b/test/CodeGenCXX/debug-info-class-nolimit.cpp @@ -1,8 +1,26 @@ -// RUN: %clang_cc1 -triple x86_64-unk-unk -debug-info-kind=standalone -o - -emit-llvm %s | FileCheck %s -// On Darwin, "full" debug info is the default, so really these tests are -// identical, as cc1 no longer chooses the effective value of DebugInfoKind. // RUN: %clang_cc1 -triple x86_64-apple-darwin -debug-info-kind=standalone -o - -emit-llvm %s | FileCheck %s +// We had a bug in -fstandalone-debug where UnicodeString would not be completed +// when it was required to be complete. This orginally manifested as an +// assertion in CodeView emission on Windows with some dllexport stuff, but it's +// more general than that. + +struct UnicodeString; +UnicodeString *force_fwd_decl; +struct UnicodeString { +private: + virtual ~UnicodeString(); +}; +struct UseCompleteType { + UseCompleteType(); + ~UseCompleteType(); + UnicodeString currencySpcAfterSym[1]; +}; +UseCompleteType require_complete; +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "UnicodeString" +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} + namespace rdar14101097_1 { // see also PR16214 // Check that we emit debug info for the definition of a struct if the // definition is available, even if it's used via a pointer wrapped in a diff --git a/test/CodeGenCXX/debug-info-class.cpp b/test/CodeGenCXX/debug-info-class.cpp index d03c0845dd6b..d572eef68abf 100644 --- a/test/CodeGenCXX/debug-info-class.cpp +++ b/test/CodeGenCXX/debug-info-class.cpp @@ -122,6 +122,7 @@ int main(int argc, char **argv) { // CHECK: [[C_DTOR]] = !DISubprogram(name: "~C" // CHECK: [[D:![0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "D" +// CHECK-NOT: size: // CHECK-SAME: DIFlagFwdDecl // CHECK-SAME: identifier: "_ZTS1D" // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "E" diff --git a/test/CodeGenCXX/debug-info-codeview-injected-class.cpp b/test/CodeGenCXX/debug-info-codeview-injected-class.cpp new file mode 100644 index 000000000000..b421b2bf8bd9 --- /dev/null +++ b/test/CodeGenCXX/debug-info-codeview-injected-class.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 %s -std=c++11 -triple=i686-pc-windows-msvc -debug-info-kind=limited -gcodeview -emit-llvm -o - | FileCheck %s + +// The injected class names in this test were accidentally making it into our +// nested class record debug info. Make sure they don't appear there. + +// PR28790 + +struct A { + const char *m_fn1(); + template class B; + template class C; + template class C>; +}; +const char *A::m_fn1() { return nullptr; } + +// CHECK: ![[A:[^ ]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A", +// CHECK-SAME: elements: ![[elements:[0-9]+]] + +// CHECK: ![[elements]] = !{![[m_fn1:[0-9]+]]} + +// CHECK: ![[m_fn1]] = !DISubprogram(name: "m_fn1", diff --git a/test/CodeGenCXX/debug-info-cxx1y.cpp b/test/CodeGenCXX/debug-info-cxx1y.cpp index 36b3e09180c6..403424e2d6a8 100644 --- a/test/CodeGenCXX/debug-info-cxx1y.cpp +++ b/test/CodeGenCXX/debug-info-cxx1y.cpp @@ -3,9 +3,6 @@ // CHECK: imports: [[IMPS:![0-9]*]] // CHECK: [[EMPTY:![0-9]*]] = !{} -// CHECK: [[FOO:![0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo", -// CHECK-SAME: elements: [[EMPTY]] - // CHECK: [[IMPS]] = !{[[IMP:![0-9]*]]} // CHECK: [[IMP]] = !DIImportedEntity( // CHECK-SAME: entity: [[F3:![0-9]*]] @@ -15,6 +12,9 @@ // CHECK: [[TYPE_LIST]] = !{[[INT:![0-9]*]]} // CHECK: [[INT]] = !DIBasicType(name: "int" +// CHECK: [[FOO:![0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo", +// CHECK-SAME: elements: [[EMPTY]] + // 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]] diff --git a/test/CodeGenCXX/debug-info-dllimport-base-class.cpp b/test/CodeGenCXX/debug-info-dllimport-base-class.cpp new file mode 100644 index 000000000000..855ecaaa4c90 --- /dev/null +++ b/test/CodeGenCXX/debug-info-dllimport-base-class.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -triple i386-pc-windows -emit-llvm -gcodeview -debug-info-kind=limited -fms-compatibility %s -x c++ -o - | FileCheck %s + +// Ensure we emit debug info for the full definition of base classes that will +// be imported from a DLL. Otherwise, the debugger wouldn't be able to show the +// members. + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ImportedAfterCompletion", +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "OutOfLineCtor", +// CHECK-SAME: DIFlagFwdDecl +// CHECK-SAME: ){{$}} + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ImportedBase", +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ImportedMethod", +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} + + +struct ImportedAfterCompletion; +ImportedAfterCompletion *force_fwd_decl; +struct __declspec(dllimport) ImportedAfterCompletion { + virtual ~ImportedAfterCompletion(); +}; + +struct OutOfLineCtor { + OutOfLineCtor(); + virtual void Foo(); +}; + +struct __declspec(dllimport) ImportedBase { + ImportedBase(); + virtual void Foo(); +}; + +struct DerivedFromImported : public ImportedBase {}; + +struct ImportedMethod { + ImportedMethod(); + virtual void Foo(); + static void __declspec(dllimport) create(); +}; + +int main() { + ImportedAfterCompletion c; + OutOfLineCtor o; + DerivedFromImported d; + ImportedMethod m; +} diff --git a/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp b/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp index f7a2cfe7bae6..3b23ebf7dedc 100644 --- a/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp +++ b/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp @@ -19,6 +19,6 @@ protected: Test t; -// CHECK: !DIDerivedType(tag: DW_TAG_pointer_type // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "data" +// CHECK: !DIDerivedType(tag: DW_TAG_pointer_type // CHECK-NOT: !DICompositeType(tag: DW_TAG_structure_type, name: "data" diff --git a/test/CodeGenCXX/debug-info-enum-class.cpp b/test/CodeGenCXX/debug-info-enum-class.cpp index 44daf412d3ac..b615d5b09626 100644 --- a/test/CodeGenCXX/debug-info-enum-class.cpp +++ b/test/CodeGenCXX/debug-info-enum-class.cpp @@ -13,7 +13,7 @@ D d; // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "A" // CHECK-SAME: line: 3 // CHECK-SAME: baseType: ![[INT:[0-9]+]] -// CHECK-SAME: size: 32, align: 32 +// CHECK-SAME: size: 32 // CHECK-NOT: offset: // CHECK-NOT: flags: // CHECK-SAME: ){{$}} @@ -21,7 +21,7 @@ D d; // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "B" // CHECK-SAME: line: 4 // CHECK-SAME: baseType: ![[ULONG:[0-9]+]] -// CHECK-SAME: size: 64, align: 64 +// CHECK-SAME: size: 64 // CHECK-NOT: offset: // CHECK-NOT: flags: // CHECK-SAME: ){{$}} @@ -29,7 +29,7 @@ D d; // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "C" // CHECK-SAME: line: 5 // CHECK-NOT: baseType: -// CHECK-SAME: size: 32, align: 32 +// CHECK-SAME: size: 32 // CHECK-NOT: offset: // CHECK-NOT: flags: // CHECK-SAME: ){{$}} @@ -91,7 +91,7 @@ void f2(E) { // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "D" // CHECK-SAME: line: 6 -// CHECK-SAME: size: 16, align: 16 +// CHECK-SAME: size: 16 // CHECK-NOT: offset: // CHECK-SAME: flags: DIFlagFwdDecl diff --git a/test/CodeGenCXX/debug-info-flex-member.cpp b/test/CodeGenCXX/debug-info-flex-member.cpp deleted file mode 100644 index 8dcdaeb935d0..000000000000 --- a/test/CodeGenCXX/debug-info-flex-member.cpp +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin %s -o - | FileCheck %s - -// CHECK: !DISubrange(count: -1) - -struct StructName { - int member[]; -}; - -struct StructName SN; diff --git a/test/CodeGenCXX/debug-info-global.cpp b/test/CodeGenCXX/debug-info-global.cpp index 795602380d20..5abc050431d1 100644 --- a/test/CodeGenCXX/debug-info-global.cpp +++ b/test/CodeGenCXX/debug-info-global.cpp @@ -15,7 +15,8 @@ int f1() { // CHECK: [[GLOBALS]] = !{[[CNST:![0-9]*]]} -// CHECK: [[CNST]] = distinct !DIGlobalVariable(name: "cnst", -// CHECK-SAME: scope: [[NS:![0-9]*]] +// CHECK: [[CNST]] = !DIGlobalVariableExpression(var: [[CNSTV:.*]], expr: +// CHECK: [[CNSTV]] = distinct !DIGlobalVariable(name: "cnst", +// CHECK-SAME: scope: [[NS:![0-9]*]] // CHECK: [[NS]] = !DINamespace(name: "ns" diff --git a/test/CodeGenCXX/debug-info-indirect-field-decl.cpp b/test/CodeGenCXX/debug-info-indirect-field-decl.cpp index 70b233cac4dc..126e1f6bd1b8 100644 --- a/test/CodeGenCXX/debug-info-indirect-field-decl.cpp +++ b/test/CodeGenCXX/debug-info-indirect-field-decl.cpp @@ -11,13 +11,13 @@ struct Bar { // CHECK: !DIDerivedType(tag: DW_TAG_member, scope: // CHECK-SAME: line: [[@LINE+4]] // CHECK-SAME: baseType: ![[UNION:[0-9]+]] - // CHECK-SAME: size: 32, align: 32, offset: 32 + // CHECK-SAME: size: 32, offset: 32 // CHECK: ![[UNION]] = distinct !DICompositeType(tag: DW_TAG_union_type,{{.*}} identifier: "_ZTSN3BarUt_E") union { // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "i2", // CHECK-SAME: line: [[@LINE+5]] // CHECK-SAME: baseType: ![[INT]] - // CHECK-SAME: size: 32, align: 32 + // CHECK-SAME: size: 32 // CHECK-NOT: offset: // CHECK-SAME: ){{$}} int i2; diff --git a/test/CodeGenCXX/debug-info-line-if.cpp b/test/CodeGenCXX/debug-info-line-if.cpp index b3f9c32e0911..41770b135619 100644 --- a/test/CodeGenCXX/debug-info-line-if.cpp +++ b/test/CodeGenCXX/debug-info-line-if.cpp @@ -53,15 +53,19 @@ int main() { // CHECK-DAG: [[DBG3]] = !DILocation(line: 300, scope: !{{.*}}) // CHECK-DAG: [[DBG4]] = !DILocation(line: 401, scope: !{{.*}}) - // CHECK-DAG: [[L1]] = distinct !{[[L1]], [[LDBG1:![0-9]*]]} - // CHECK-DAG: [[LDBG1]] = !DILocation(line: 100, scope: !{{.*}}) + // CHECK-DAG: [[L1]] = distinct !{[[L1]], [[SLDBG1:![0-9]*]], [[ELDBG1:![0-9]*]]} + // CHECK-DAG: [[SLDBG1]] = !DILocation(line: 100, scope: !{{.*}}) + // CHECK-DAG: [[ELDBG1]] = !DILocation(line: 104, scope: !{{.*}}) - // CHECK-DAG: [[L2]] = distinct !{[[L2]], [[LDBG2:![0-9]*]]} - // CHECK-DAG: [[LDBG2]] = !DILocation(line: 200, scope: !{{.*}}) + // CHECK-DAG: [[L2]] = distinct !{[[L2]], [[SLDBG2:![0-9]*]], [[ELDBG2:![0-9]*]]} + // CHECK-DAG: [[SLDBG2]] = !DILocation(line: 200, scope: !{{.*}}) + // CHECK-DAG: [[ELDBG2]] = !DILocation(line: 204, scope: !{{.*}}) - // CHECK-DAG: [[L3]] = distinct !{[[L3]], [[LDBG3:![0-9]*]]} - // CHECK-DAG: [[LDBG3]] = !DILocation(line: 300, scope: !{{.*}}) + // CHECK-DAG: [[L3]] = distinct !{[[L3]], [[SLDBG3:![0-9]*]], [[ELDBG3:![0-9]*]]} + // CHECK-DAG: [[SLDBG3]] = !DILocation(line: 300, scope: !{{.*}}) + // CHECK-DAG: [[ELDBG3]] = !DILocation(line: 304, scope: !{{.*}}) - // CHECK-DAG: [[L4]] = distinct !{[[L4]], [[LDBG4:![0-9]*]]} - // CHECK-DAG: [[LDBG4]] = !DILocation(line: 401, scope: !{{.*}}) + // CHECK-DAG: [[L4]] = distinct !{[[L4]], [[SLDBG4:![0-9]*]], [[ELDBG4:![0-9]*]]} + // CHECK-DAG: [[SLDBG4]] = !DILocation(line: 401, scope: !{{.*}}) + // CHECK-DAG: [[ELDBG4]] = !DILocation(line: 405, scope: !{{.*}}) } diff --git a/test/CodeGenCXX/debug-info-line.cpp b/test/CodeGenCXX/debug-info-line.cpp index 11653040109c..a1c4ef9eea25 100644 --- a/test/CodeGenCXX/debug-info-line.cpp +++ b/test/CodeGenCXX/debug-info-line.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -w -debug-info-kind=line-tables-only -std=c++11 -fexceptions -fcxx-exceptions -S -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 -emit-llvm %s -o - -triple i686-linux-gnu | 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 %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 int &src(); int *sink(); diff --git a/test/CodeGenCXX/debug-info-loops.cpp b/test/CodeGenCXX/debug-info-loops.cpp new file mode 100644 index 000000000000..69948ea0f880 --- /dev/null +++ b/test/CodeGenCXX/debug-info-loops.cpp @@ -0,0 +1,49 @@ +// RUN: %clang -g -gcolumn-info -std=c++11 -S -emit-llvm %s -o - | FileCheck %s +extern int v[2]; +int a = 0, b = 0; +int main() { +#line 100 + for (int x : v) { + if (x) + ++b; + else + ++a; + } + + // CHECK: br label {{.*}}, !dbg [[DBG1:![0-9]*]], !llvm.loop [[L1:![0-9]*]] + +#line 200 + while (a) + if (b) + ++b; + else + ++a; + // CHECK: br label {{.*}}, !dbg [[DBG2:![0-9]*]], !llvm.loop [[L2:![0-9]*]] + +#line 300 + for (unsigned i = 0; i < 100; i++) { + a++; + for (int y : v) + ++b; + } + + // CHECK: br label {{.*}}, !dbg [[DBG3:![0-9]*]], !llvm.loop [[L3:![0-9]*]] + // CHECK: br label {{.*}}, !dbg [[DBG3:![0-9]*]], !llvm.loop [[L4:![0-9]*]] + + + // CHECK-DAG: [[L1]] = distinct !{[[L1]], [[SLDBG1:![0-9]*]], [[ELDBG1:![0-9]*]]} + // CHECK-DAG: [[SLDBG1]] = !DILocation(line: 100, column: 3, scope: !{{.*}}) + // CHECK-DAG: [[ELDBG1]] = !DILocation(line: 105, column: 3, scope: !{{.*}}) + + // CHECK-DAG: [[L2]] = distinct !{[[L2]], [[SLDBG2:![0-9]*]], [[ELDBG2:![0-9]*]]} + // CHECK-DAG: [[SLDBG2]] = !DILocation(line: 200, column: 3, scope: !{{.*}}) + // CHECK-DAG: [[ELDBG2]] = !DILocation(line: 204, column: 9, scope: !{{.*}}) + + // CHECK-DAG: [[L3]] = distinct !{[[L3]], [[SLDBG3:![0-9]*]], [[ELDBG3:![0-9]*]]} + // CHECK-DAG: [[SLDBG3]] = !DILocation(line: 302, column: 5, scope: !{{.*}}) + // CHECK-DAG: [[ELDBG3]] = !DILocation(line: 303, column: 9, scope: !{{.*}}) + // + // CHECK-DAG: [[L4]] = distinct !{[[L4]], [[SLDBG4:![0-9]*]], [[ELDBG4:![0-9]*]]} + // CHECK-DAG: [[SLDBG4]] = !DILocation(line: 300, column: 3, scope: !{{.*}}) + // CHECK-DAG: [[ELDBG4]] = !DILocation(line: 304, column: 3, scope: !{{.*}}) +} diff --git a/test/CodeGenCXX/debug-info-method.cpp b/test/CodeGenCXX/debug-info-method.cpp index 73d8b928269a..e0f9a284f2cf 100644 --- a/test/CodeGenCXX/debug-info-method.cpp +++ b/test/CodeGenCXX/debug-info-method.cpp @@ -1,10 +1,10 @@ // RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -debug-info-kind=limited %s -o - | FileCheck %s +// CHECK: !DIDerivedType(tag: DW_TAG_ptr_to_member_type // CHECK: ![[A:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "A",{{.*}} identifier: "_ZTS1A") // CHECK: !DISubprogram(name: "foo", linkageName: "_ZN1A3fooEiS_3$_0" // CHECK-SAME: DIFlagProtected // CHECK: ![[THISTYPE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[A]] // CHECK-SAME: DIFlagArtificial -// CHECK: !DIDerivedType(tag: DW_TAG_ptr_to_member_type // CHECK: !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: ![[MEMFUNTYPE:[0-9]+]] // CHECK: ![[MEMFUNTYPE]] = !DISubroutineType({{(cc: DW_CC_BORLAND_thiscall, )?}}types: ![[MEMFUNARGS:[0-9]+]]) // CHECK: ![[MEMFUNARGS]] = {{.*}}, ![[THISTYPE]], diff --git a/test/CodeGenCXX/debug-info-ms-abi.cpp b/test/CodeGenCXX/debug-info-ms-abi.cpp index a146ce94176e..1bf8bab5f41c 100644 --- a/test/CodeGenCXX/debug-info-ms-abi.cpp +++ b/test/CodeGenCXX/debug-info-ms-abi.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -debug-info-kind=limited -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -debug-info-kind=limited -gcodeview -emit-llvm -o - | FileCheck %s // Tests that certain miscellaneous features work in the MS ABI. @@ -11,20 +11,30 @@ struct Foo { Foo f; Foo::Nested n; +// CHECK: ![[Nested:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Nested", +// CHECK-SAME: identifier: ".?AUNested@Foo@@" + // CHECK: ![[Foo:[^ ]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", +// CHECK-SAME: elements: ![[elements:[0-9]+]] // CHECK-SAME: identifier: ".?AUFoo@@" -// CHECK: !DISubprogram(name: "f", +// CHECK: ![[elements]] = !{![[vshape:[0-9]+]], ![[vptr:[0-9]+]], ![[Nested]], ![[f:[0-9]+]], ![[g:[0-9]+]], ![[h:[0-9]+]]} + +// CHECK: ![[vshape]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__vtbl_ptr_type", baseType: null, size: 96) + +// CHECK: ![[vptr]] = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$Foo", +// CHECK-SAME: baseType: ![[vptr_ty:[0-9]+]], + +// 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: flags: DIFlagPrototyped | DIFlagIntroducedVirtual, -// CHECK: !DISubprogram(name: "g", +// CHECK: ![[g]] = !DISubprogram(name: "g", // CHECK-SAME: containingType: ![[Foo]], virtuality: DW_VIRTUALITY_virtual, virtualIndex: 1, // CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual, -// CHECK: !DISubprogram(name: "h", +// CHECK: ![[h]] = !DISubprogram(name: "h", // CHECK-SAME: containingType: ![[Foo]], virtuality: DW_VIRTUALITY_virtual, virtualIndex: 2, // CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual, - -// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Nested", -// CHECK-SAME: identifier: ".?AUNested@Foo@@" diff --git a/test/CodeGenCXX/debug-info-ms-anonymous-tag.cpp b/test/CodeGenCXX/debug-info-ms-anonymous-tag.cpp index cef1eb8c5a09..5e2cb2190f0d 100644 --- a/test/CodeGenCXX/debug-info-ms-anonymous-tag.cpp +++ b/test/CodeGenCXX/debug-info-ms-anonymous-tag.cpp @@ -4,7 +4,6 @@ typedef struct { } test1; test1 gv1; -// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "test1" struct { } test2; @@ -18,3 +17,5 @@ test3 gv3; void *use_test3 = &gv3; // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "" + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "test1" diff --git a/test/CodeGenCXX/debug-info-ms-bitfields.cpp b/test/CodeGenCXX/debug-info-ms-bitfields.cpp index 07d4c0c6c78a..e42330143bba 100644 --- a/test/CodeGenCXX/debug-info-ms-bitfields.cpp +++ b/test/CodeGenCXX/debug-info-ms-bitfields.cpp @@ -7,4 +7,4 @@ struct S { short x : 8; } s; -// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "x", {{.*}}, size: 8, align: 16, offset: 16, flags: DIFlagBitField, extraData: i64 8) +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "x", {{.*}}, size: 8, offset: 16, flags: DIFlagBitField, extraData: i64 8) diff --git a/test/CodeGenCXX/debug-info-ms-ptr-to-member.cpp b/test/CodeGenCXX/debug-info-ms-ptr-to-member.cpp index 4b9f2a146896..1f4c90484b89 100644 --- a/test/CodeGenCXX/debug-info-ms-ptr-to-member.cpp +++ b/test/CodeGenCXX/debug-info-ms-ptr-to-member.cpp @@ -23,7 +23,6 @@ int Incomplete::**ppmd; void (Incomplete::**ppmf)(); // CHECK: distinct !DIGlobalVariable(name: "pmd_a", {{.*}} type: ![[pmd_a:[^, ]*]], {{.*}}) -// CHECK: ![[pmd_a]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{.*}}, size: 32, flags: DIFlagSingleInheritance, {{.*}}) // CHECK: distinct !DIGlobalVariable(name: "pmd_b", {{.*}} type: ![[pmd_b:[^, ]*]], {{.*}}) // CHECK: ![[pmd_b]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{.*}}, size: 32, flags: DIFlagMultipleInheritance, {{.*}}) // CHECK: distinct !DIGlobalVariable(name: "pmd_c", {{.*}} type: ![[pmd_c:[^, ]*]], {{.*}}) @@ -45,8 +44,10 @@ void (Incomplete::**ppmf)(); // CHECK-SAME: ){{$}} // CHECK: distinct !DIGlobalVariable(name: "ppmd", {{.*}} type: ![[ppmd:[^, ]*]], {{.*}}) -// CHECK: ![[ppmd]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[ppmd2:[^ ]*]], size: 64, align: 64) +// CHECK: ![[ppmd]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[ppmd2:[^ ]*]], size: 64) // CHECK: ![[ppmd2]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{[0-9]*}}, extraData: !{{[0-9]*}}){{$}} // CHECK: distinct !DIGlobalVariable(name: "ppmf", {{.*}} type: ![[ppmf:[^, ]*]], {{.*}}) -// CHECK: ![[ppmf]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[ppmf2:[^ ]*]], size: 64, align: 64) +// CHECK: ![[ppmf]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[ppmf2:[^ ]*]], size: 64) // CHECK: ![[ppmf2]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{[0-9]*}}, extraData: !{{[0-9]*}}){{$}} + +// CHECK: ![[pmd_a]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{.*}}, size: 32, flags: DIFlagSingleInheritance, {{.*}}) diff --git a/test/CodeGenCXX/debug-info-ms-vbase.cpp b/test/CodeGenCXX/debug-info-ms-vbase.cpp new file mode 100644 index 000000000000..3de3a751cba1 --- /dev/null +++ b/test/CodeGenCXX/debug-info-ms-vbase.cpp @@ -0,0 +1,68 @@ +// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -debug-info-kind=limited -gcodeview -emit-llvm -o - | FileCheck %s + +// Tests virtual bases in the MS ABI. + +// CHECK: ![[NoPrimaryBase:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "NoPrimaryBase", +// CHECK-SAME: elements: ![[elements:[0-9]+]] + +// CHECK: ![[elements]] = !{![[NoPrimaryBase_base:[0-9]+]]} + +// CHECK: ![[NoPrimaryBase_base]] = !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[NoPrimaryBase]], +// CHECK-SAME: baseType: ![[HasVirtualMethod:[0-9]+]], offset: 4, flags: DIFlagVirtual) + +// CHECK: ![[HasVirtualMethod]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "HasVirtualMethod" + +// CHECK: ![[HasPrimaryBase:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "HasPrimaryBase", +// CHECK-SAME: elements: ![[elements:[0-9]+]] + +// CHECK: ![[elements]] = !{![[SecondaryVTable_base:[0-9]+]], ![[HasVirtualMethod_base:[0-9]+]], ![[vshape:[0-9]+]]} + +// CHECK: ![[SecondaryVTable_base]] = !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[HasPrimaryBase]], +// CHECK-SAME: baseType: ![[SecondaryVTable:[0-9]+]], offset: 4, flags: DIFlagVirtual) + +// CHECK: ![[SecondaryVTable]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "SecondaryVTable" + +// CHECK: ![[HasVirtualMethod_base]] = !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[HasPrimaryBase]], baseType: ![[HasVirtualMethod]]) + +// CHECK: ![[HasIndirectVirtualBase:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "HasIndirectVirtualBase" +// CHECK-SAME: elements: ![[elements:[0-9]+]] + +// CHECK: !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[HasIndirectVirtualBase]], baseType: ![[HasPrimaryBase]] +// CHECK-NOT: DIFlagIndirectVirtualBase +// CHECK-SAME: ) + +// CHECK: !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[HasIndirectVirtualBase]], baseType: ![[SecondaryVTable]] +// CHECK-SAME: flags: +// CHECK-SAME: DIFlagIndirectVirtualBase + +// CHECK: ![[DynamicNoVFPtr:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "DynamicNoVFPtr", +// CHECK-SAME: elements: ![[elements:[0-9]+]] + +// CHECK: ![[elements]] = !{![[POD_base:[0-9]+]]} + +// CHECK: ![[POD_base]] = !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[DynamicNoVFPtr]], +// CHECK-SAME: baseType: ![[POD:[0-9]+]], offset: 4, flags: DIFlagVirtual) + +// CHECK: ![[POD]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "POD" + +struct POD { int pod; }; + +struct DynamicNoVFPtr : virtual POD { }; + +DynamicNoVFPtr dynamic_no_vfptr; + +struct HasVirtualMethod { virtual void f(); }; + +struct NoPrimaryBase : virtual HasVirtualMethod { }; + +NoPrimaryBase no_primary_base; + +struct SecondaryVTable { virtual void g(); }; + +struct HasPrimaryBase : virtual SecondaryVTable, HasVirtualMethod { }; + +HasPrimaryBase has_primary_base; + +struct HasIndirectVirtualBase : public HasPrimaryBase {}; + +HasIndirectVirtualBase has_indirect_virtual_base; diff --git a/test/CodeGenCXX/debug-info-namespace.cpp b/test/CodeGenCXX/debug-info-namespace.cpp index 060a5cea636c..c75c40766a37 100644 --- a/test/CodeGenCXX/debug-info-namespace.cpp +++ b/test/CodeGenCXX/debug-info-namespace.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -debug-info-kind=limited -S -emit-llvm %s -o - | FileCheck %s -// RUN: %clang_cc1 -debug-info-kind=line-tables-only -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-GMLT %s -// RUN: %clang_cc1 -debug-info-kind=standalone -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-NOLIMIT %s +// 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=standalone -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-NOLIMIT %s namespace A { #line 1 "foo.cpp" @@ -49,14 +49,15 @@ using B::i; namespace B { int var_fwd = i; } +inline namespace I { +int var_i; +} } void B::func_fwd() {} // This should work even if 'i' and 'func' were declarations & not definitions, // but it doesn't yet. -// CHECK: [[CU:![0-9]+]] = distinct !DICompileUnit( -// CHECK-SAME: imports: [[MODULES:![0-9]*]] // CHECK: [[I:![0-9]+]] = distinct !DIGlobalVariable(name: "i",{{.*}} scope: [[NS:![0-9]+]], // CHECK: [[NS]] = !DINamespace(name: "B", scope: [[CTXT:![0-9]+]], file: [[FOOCPP:![0-9]+]], line: 1) // CHECK: [[FOOCPP]] = !DIFile(filename: "foo.cpp" @@ -65,6 +66,10 @@ void B::func_fwd() {} // CHECK: [[VAR_FWD:![0-9]+]] = distinct !DIGlobalVariable(name: "var_fwd",{{.*}} scope: [[NS]], // CHECK-SAME: line: 44 // CHECK-SAME: isDefinition: true +// CHECK: distinct !DIGlobalVariable(name: "var_i",{{.*}} scope: [[INLINE:![0-9]+]], +// CHECK: [[INLINE]] = !DINamespace(name: "I", scope: [[CTXT]], file: [[FOOCPP]], line: 46, exportSymbols: true) +// CHECK: [[CU:![0-9]+]] = distinct !DICompileUnit( +// CHECK-SAME: imports: [[MODULES:![0-9]*]] // CHECK: [[MODULES]] = !{[[M1:![0-9]+]], [[M2:![0-9]+]], [[M3:![0-9]+]], [[M4:![0-9]+]], [[M5:![0-9]+]], [[M6:![0-9]+]], [[M7:![0-9]+]], [[M8:![0-9]+]], [[M9:![0-9]+]], [[M10:![0-9]+]], [[M11:![0-9]+]], [[M12:![0-9]+]], [[M13:![0-9]+]], [[M14:![0-9]+]], [[M15:![0-9]+]], [[M16:![0-9]+]], [[M17:![0-9]+]]} // CHECK: [[M1]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CTXT]], entity: [[NS]], line: 15) @@ -101,7 +106,7 @@ void B::func_fwd() {} // 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: 47,{{.*}} isDefinition: true +// CHECK: [[FUNC_FWD]] = distinct !DISubprogram(name: "func_fwd",{{.*}} line: 50,{{.*}} isDefinition: true // CHECK: [[M17]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[CTXT]], entity: [[I]] // CHECK-GMLT: [[CU:![0-9]+]] = distinct !DICompileUnit( diff --git a/test/CodeGenCXX/debug-info-rvalue-ref.cpp b/test/CodeGenCXX/debug-info-rvalue-ref.cpp index edb93ae46cda..de0f65ad9a02 100644 --- a/test/CodeGenCXX/debug-info-rvalue-ref.cpp +++ b/test/CodeGenCXX/debug-info-rvalue-ref.cpp @@ -8,5 +8,5 @@ void foo (int &&i) printf("%d\n", i); } -// CHECK: !DIDerivedType(tag: DW_TAG_rvalue_reference_type, baseType: ![[INT:[0-9]+]], size: 64, align: 64) +// CHECK: !DIDerivedType(tag: DW_TAG_rvalue_reference_type, baseType: ![[INT:[0-9]+]], size: 64) // CHECK: ![[INT]] = !DIBasicType(name: "int" diff --git a/test/CodeGenCXX/debug-info-static-member.cpp b/test/CodeGenCXX/debug-info-static-member.cpp index ed8ae015cfc3..c777ccb2aba2 100644 --- a/test/CodeGenCXX/debug-info-static-member.cpp +++ b/test/CodeGenCXX/debug-info-static-member.cpp @@ -3,6 +3,10 @@ // RUN: %clangxx -target x86_64-unknown-unknown -g -std=c++11 %s -emit-llvm -S -o - | FileCheck %s // PR14471 +// CHECK: @_ZN1C1aE = global i32 4, align 4, !dbg [[A:![0-9]+]] +// CHECK: @_ZN1C1bE = global i32 2, align 4, !dbg [[B:![0-9]+]] +// CHECK: @_ZN1C1cE = global i32 1, align 4, !dbg [[C:![0-9]+]] + enum X { Y }; @@ -28,6 +32,10 @@ public: // why the definition of "a" comes before the declarations while // "b" and "c" come after. +// CHECK: [[A]] = !DIGlobalVariableExpression(var: [[AV:.*]]) +// CHECK: [[AV]] = distinct !DIGlobalVariable(name: "a", +// CHECK-SAME: declaration: ![[DECL_A:[0-9]+]]) +// // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "X"{{.*}}, identifier: "_ZTS1X") // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "anon_static_decl_struct" // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "anon_static_decl_var" @@ -36,16 +44,24 @@ public: // CHECK-SAME: ){{$}} // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "static_decl_templ_var" -// CHECK: !DIGlobalVariable(name: "a", {{.*}}variable: i32* @_ZN1C1aE, declaration: ![[DECL_A:[0-9]+]]) int C::a = 4; -// CHECK: ![[DECL_A]] = !DIDerivedType(tag: DW_TAG_member, name: "a" +// CHECK: [[B]] = !DIGlobalVariableExpression(var: [[BV:.*]]) +// CHECK: [[BV]] = distinct !DIGlobalVariable(name: "b", +// CHECK-SAME: declaration: ![[DECL_B:[0-9]+]]) +// CHECK: ![[DECL_B]] = !DIDerivedType(tag: DW_TAG_member, name: "b" // CHECK-NOT: size: // CHECK-NOT: align: // CHECK-NOT: offset: -// CHECK-SAME: flags: DIFlagStaticMember) +// CHECK-SAME: flags: DIFlagProtected | DIFlagStaticMember) // // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "C"{{.*}}, identifier: "_ZTS1C") // +// CHECK: ![[DECL_A]] = !DIDerivedType(tag: DW_TAG_member, name: "a" +// CHECK-NOT: size: +// CHECK-NOT: align: +// CHECK-NOT: offset: +// CHECK-SAME: flags: DIFlagStaticMember) +// // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "const_a" // CHECK-NOT: size: // CHECK-NOT: align: @@ -53,12 +69,6 @@ int C::a = 4; // CHECK-SAME: flags: DIFlagStaticMember, // CHECK-SAME: extraData: i1 true) -// CHECK: ![[DECL_B:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "b" -// CHECK-NOT: size: -// CHECK-NOT: align: -// CHECK-NOT: offset: -// CHECK-SAME: flags: DIFlagProtected | DIFlagStaticMember) -// // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "const_b" // CHECK-NOT: size: // CHECK-NOT: align: @@ -82,9 +92,9 @@ int C::a = 4; // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "x_a" // CHECK-SAME: flags: DIFlagPublic | DIFlagStaticMember) -// CHECK: !DIGlobalVariable(name: "b", {{.*}}variable: i32* @_ZN1C1bE, declaration: ![[DECL_B]]) int C::b = 2; -// CHECK: !DIGlobalVariable(name: "c", {{.*}}variable: i32* @_ZN1C1cE, declaration: ![[DECL_C]]) +// CHECK: [[C]] = !DIGlobalVariableExpression(var: [[CV:.*]]) +// CHECK: [[CV]] = distinct !DIGlobalVariable(name: "c", {{.*}} declaration: ![[DECL_C]]) int C::c = 1; int main() diff --git a/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp b/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp index 08146c25263b..c8d8a1de855d 100644 --- a/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp +++ b/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp @@ -22,9 +22,6 @@ struct b { }; extern template class b; b bi; -// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "b" -// CHECK-NOT: DIFlagFwdDecl -// CHECK-SAME: ){{$}} template struct c { @@ -116,3 +113,7 @@ template <> struct k; template struct k; // CHECK-NOT: !DICompositeType(tag: DW_TAG_structure_type, name: "k" + +// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "b" +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} diff --git a/test/CodeGenCXX/debug-info-template-member.cpp b/test/CodeGenCXX/debug-info-template-member.cpp index 88f024b59abf..2b840745ffeb 100644 --- a/test/CodeGenCXX/debug-info-template-member.cpp +++ b/test/CodeGenCXX/debug-info-template-member.cpp @@ -1,5 +1,7 @@ // RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin %s -o - | FileCheck %s +// CHECK: @x = global %"struct.outer::inner" zeroinitializer, align 4, !dbg [[X:![0-9]+]] + struct MyClass { template int add(int j) { return i + j; @@ -17,9 +19,9 @@ inline int add3(int x) { } // The compile unit pulls in the global variables first. -// CHECK: !DIGlobalVariable(name: "x", -// CHECK-SAME: type: ![[OUTER_FOO_INNER_ID:[0-9]+]] -// CHECK-SAME: variable: %"struct.outer::inner"* @x +// CHECK: [[X]] = !DIGlobalVariableExpression(var: [[XV:.*]]) +// CHECK: [[XV]] = distinct !DIGlobalVariable(name: "x", +// CHECK-SAME: type: ![[OUTER_FOO_INNER_ID:[0-9]+]] // 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" @@ -38,7 +40,7 @@ inline int add3(int x) { // CHECK: [[C_MEM]] = !{[[C_VPTR:![0-9]*]], [[C_FUNC:![0-9]*]]} // CHECK: [[C_VPTR]] = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$MyClass" -// CHECK: [[C_FUNC]] = !DISubprogram(name: "func",{{.*}} line: 7, +// CHECK: [[C_FUNC]] = !DISubprogram(name: "func",{{.*}} line: 9, // CHECK: !DISubprogram(name: "add<2>" // CHECK-SAME: scope: [[C]] diff --git a/test/CodeGenCXX/debug-info-template-quals.cpp b/test/CodeGenCXX/debug-info-template-quals.cpp index 7a0d0d4a2755..cfee78d97493 100644 --- a/test/CodeGenCXX/debug-info-template-quals.cpp +++ b/test/CodeGenCXX/debug-info-template-quals.cpp @@ -17,10 +17,10 @@ void foo (const char *c) { // CHECK: [[P:![0-9]*]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[CON:![0-9]*]] // CHECK: [[CON]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: [[CH:![0-9]*]] -// CHECK: [[CH]] = !DIBasicType(name: "char", size: 8, align: 8, encoding: DW_ATE_signed_char) +// CHECK: [[CH]] = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) // CHECK: [[BS:.*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "basic_string" // CHECK-SAME: line: 4 -// CHECK-SAME: size: 8, align: 8 +// CHECK-SAME: size: 8 // CHECK: [[TYPE:![0-9]*]] = !DISubroutineType(types: [[ARGS:.*]]) // CHECK: [[ARGS]] = !{!{{.*}}, !{{.*}}, [[P]], [[R:.*]]} diff --git a/test/CodeGenCXX/debug-info-template.cpp b/test/CodeGenCXX/debug-info-template.cpp index d35bb70fa713..54fac0b36eec 100644 --- a/test/CodeGenCXX/debug-info-template.cpp +++ b/test/CodeGenCXX/debug-info-template.cpp @@ -1,5 +1,9 @@ // RUN: %clang -S -emit-llvm -target x86_64-unknown_unknown -g %s -o - -std=c++11 | FileCheck %s +// CHECK: @tci = global %"struct.TC::nested" zeroinitializer, align 1, !dbg [[TCI:![0-9]+]] +// CHECK: @tcn = global %struct.TC zeroinitializer, align 1, !dbg [[TCN:![0-9]+]] +// CHECK: @nn = global %struct.NN zeroinitializer, align 1, !dbg [[NN:![0-9]+]] + // CHECK: !DICompileUnit( // CHECK: [[EMPTY:![0-9]*]] = !{} @@ -18,13 +22,12 @@ struct TC { }; }; -// CHECK: [[INT:![0-9]+]] = !DIBasicType(name: "int" int glb; void func(); -// CHECK: !DIGlobalVariable(name: "tci", -// CHECK-SAME: type: ![[TCNESTED:[0-9]+]] -// CHECK-SAME: variable: %"struct.TC::nested"* @tci +// CHECK: [[TCI]] = !DIGlobalVariableExpression(var: [[TCIV:.*]]) +// CHECK: [[TCIV]] = distinct !DIGlobalVariable(name: "tci", +// CHECK-SAME: type: ![[TCNESTED:[0-9]+]] // CHECK: ![[TCNESTED]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "nested", // CHECK-SAME: scope: ![[TC:[0-9]+]], @@ -39,7 +42,8 @@ TC 2, // CHECK: [[TCARG3]] = !DITemplateValueParameter(name: "x", type: [[CINTPTR:![0-9]*]], value: i32* @glb) // CHECK: [[CINTPTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, {{.*}}baseType: [[CINT:![0-9]+]] -// CHECK: [[CINT]] = !DIDerivedType(tag: DW_TAG_const_type, {{.*}}baseType: [[INT]] +// CHECK: [[CINT]] = !DIDerivedType(tag: DW_TAG_const_type, {{.*}}baseType: [[INT:![0-9]+]] +// CHECK: [[INT]] = !DIBasicType(name: "int" &glb, // CHECK: [[TCARG4]] = !DITemplateValueParameter(name: "a", type: [[MEMINTPTR:![0-9]*]], value: i64 8) // CHECK: [[MEMINTPTR]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, {{.*}}baseType: [[INT]], {{.*}}extraData: ![[FOO:[0-9]+]]) @@ -59,7 +63,7 @@ TC // CHECK: [[FARG1]] = !DIDerivedType(tag: DW_TAG_pointer_type, // CHECK-SAME: baseType: ![[FOO]] // CHECK-NOT: line: -// CHECK-SAME: size: 64, align: 64 +// CHECK-SAME: size: 64 // CHECK-NOT: offset: 0 // CHECK-SAME: DIFlagArtificial // CHECK: [[FUNTYPE:![0-9]*]] = !DISubroutineType(types: [[FUNARGS:![0-9]*]]) @@ -80,9 +84,9 @@ TC // CHECK: [[TCARG7_3]] = !DITemplateValueParameter(type: [[INT]], value: i32 3) 3>::nested tci; -// CHECK: !DIGlobalVariable(name: "tcn" -// CHECK-SAME: type: ![[TCNT:[0-9]+]] -// CHECK-SAME: variable: %struct.TC* @tcn +// CHECK: [[TCN]] = !DIGlobalVariableExpression(var: [[TCNV:.*]]) +// CHECK: [[TCNV]] = distinct !DIGlobalVariable(name: "tcn" +// CHECK-SAME: type: ![[TCNT:[0-9]+]] TC // CHECK: ![[TCNT]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "TC" // CHECK-SAME: templateParams: [[TCNARGS:![0-9]*]] @@ -121,9 +125,9 @@ template