1 // RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -o - %s | FileCheck --check-prefixes=CHECK,CHECK-COMMON %s
2 // RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -O -o - %s | FileCheck %s --check-prefixes=CHECK-OPT,CHECK-COMMON
3 // RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -fno-strict-return -o - %s | FileCheck %s --check-prefixes=CHECK-NOSTRICT,CHECK-COMMON
4 // RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -fno-strict-return -Wno-return-type -o - %s | FileCheck %s --check-prefixes=CHECK-NOSTRICT,CHECK-COMMON
5 // RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -fno-strict-return -O -o - %s | FileCheck %s --check-prefixes=CHECK-NOSTRICT-OPT,CHECK-COMMON
7 // CHECK-COMMON-LABEL: @_Z9no_return
9 // CHECK: call void @llvm.trap
10 // CHECK-NEXT: unreachable
12 // CHECK-OPT-NOT: call void @llvm.trap
13 // CHECK-OPT: unreachable
15 // -fno-strict-return should not emit trap + unreachable but it should return
16 // an undefined value instead.
18 // CHECK-NOSTRICT: alloca
19 // CHECK-NOSTRICT-NEXT: load
20 // CHECK-NOSTRICT-NEXT: ret i32
21 // CHECK-NOSTRICT-NEXT: }
23 // CHECK-NOSTRICT-OPT: ret i32 undef
30 // CHECK-COMMON-LABEL: @_Z27returnNotViableDontOptimize4Enum
31 int returnNotViableDontOptimize(Enum e
) {
36 // Undefined behaviour optimization shouldn't be used when -fno-strict-return
37 // is turned on, even if all the enum cases are covered in this function.
39 // CHECK-NOSTRICT-NOT: call void @llvm.trap
40 // CHECK-NOSTRICT-NOT: unreachable
47 // CHECK-NOSTRICT-LABEL: @_Z7trivialv
49 // This function returns a trivial record so -fno-strict-return should avoid
50 // the undefined behaviour optimization.
52 // CHECK-NOSTRICT-NOT: call void @llvm.trap
53 // CHECK-NOSTRICT-NOT: unreachable
56 struct NonTrivialCopy
{
57 NonTrivialCopy(const NonTrivialCopy
&);
60 // CHECK-NOSTRICT-LABEL: @_Z14nonTrivialCopyv
61 NonTrivialCopy
nonTrivialCopy() {
62 // CHECK-NOSTRICT-NOT: call void @llvm.trap
63 // CHECK-NOSTRICT-NOT: unreachable
66 struct NonTrivialDefaultConstructor
{
69 NonTrivialDefaultConstructor() { }
72 // CHECK-NOSTRICT-LABEL: @_Z28nonTrivialDefaultConstructorv
73 NonTrivialDefaultConstructor
nonTrivialDefaultConstructor() {
74 // CHECK-NOSTRICT-NOT: call void @llvm.trap
75 // CHECK-NOSTRICT-NOT: unreachable
78 // Functions that return records with non-trivial destructors should always use
79 // the -fstrict-return optimization.
81 struct NonTrivialDestructor
{
82 ~NonTrivialDestructor();
85 // CHECK-NOSTRICT-LABEL: @_Z20nonTrivialDestructorv
86 NonTrivialDestructor
nonTrivialDestructor() {
87 // CHECK-NOSTRICT: call void @llvm.trap
88 // CHECK-NOSTRICT-NEXT: unreachable
91 // The behavior for lambdas should be identical to functions.
92 // CHECK-COMMON-LABEL: @_Z10lambdaTestv
94 auto lambda1
= []() -> int {
98 // CHECK: call void @llvm.trap
99 // CHECK-NEXT: unreachable
101 // CHECK-NOSTRICT-NOT: call void @llvm.trap
102 // CHECK-NOSTRICT-NOT: unreachable