forked from OSchip/llvm-project
104 lines
3.1 KiB
C++
104 lines
3.1 KiB
C++
// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -o - %s | FileCheck --check-prefixes=CHECK,CHECK-COMMON %s
|
|
// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -O -o - %s | FileCheck %s --check-prefixes=CHECK-OPT,CHECK-COMMON
|
|
// 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
|
|
// 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
|
|
// 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
|
|
|
|
// CHECK-COMMON-LABEL: @_Z9no_return
|
|
int no_return() {
|
|
// CHECK: call void @llvm.trap
|
|
// CHECK-NEXT: unreachable
|
|
|
|
// CHECK-OPT-NOT: call void @llvm.trap
|
|
// CHECK-OPT: unreachable
|
|
|
|
// -fno-strict-return should not emit trap + unreachable but it should return
|
|
// an undefined value instead.
|
|
|
|
// CHECK-NOSTRICT: alloca
|
|
// CHECK-NOSTRICT-NEXT: load
|
|
// CHECK-NOSTRICT-NEXT: ret i32
|
|
// CHECK-NOSTRICT-NEXT: }
|
|
|
|
// CHECK-NOSTRICT-OPT: ret i32 undef
|
|
}
|
|
|
|
enum Enum {
|
|
A, B
|
|
};
|
|
|
|
// CHECK-COMMON-LABEL: @_Z27returnNotViableDontOptimize4Enum
|
|
int returnNotViableDontOptimize(Enum e) {
|
|
switch (e) {
|
|
case A: return 1;
|
|
case B: return 2;
|
|
}
|
|
// Undefined behaviour optimization shouldn't be used when -fno-strict-return
|
|
// is turned on, even if all the enum cases are covered in this function.
|
|
|
|
// CHECK-NOSTRICT-NOT: call void @llvm.trap
|
|
// CHECK-NOSTRICT-NOT: unreachable
|
|
}
|
|
|
|
struct Trivial {
|
|
int x;
|
|
};
|
|
|
|
// CHECK-NOSTRICT-LABEL: @_Z7trivialv
|
|
Trivial trivial() {
|
|
// This function returns a trivial record so -fno-strict-return should avoid
|
|
// the undefined behaviour optimization.
|
|
|
|
// CHECK-NOSTRICT-NOT: call void @llvm.trap
|
|
// CHECK-NOSTRICT-NOT: unreachable
|
|
}
|
|
|
|
struct NonTrivialCopy {
|
|
NonTrivialCopy(const NonTrivialCopy &);
|
|
};
|
|
|
|
// CHECK-NOSTRICT-LABEL: @_Z14nonTrivialCopyv
|
|
NonTrivialCopy nonTrivialCopy() {
|
|
// CHECK-NOSTRICT-NOT: call void @llvm.trap
|
|
// CHECK-NOSTRICT-NOT: unreachable
|
|
}
|
|
|
|
struct NonTrivialDefaultConstructor {
|
|
int x;
|
|
|
|
NonTrivialDefaultConstructor() { }
|
|
};
|
|
|
|
// CHECK-NOSTRICT-LABEL: @_Z28nonTrivialDefaultConstructorv
|
|
NonTrivialDefaultConstructor nonTrivialDefaultConstructor() {
|
|
// CHECK-NOSTRICT-NOT: call void @llvm.trap
|
|
// CHECK-NOSTRICT-NOT: unreachable
|
|
}
|
|
|
|
// Functions that return records with non-trivial destructors should always use
|
|
// the -fstrict-return optimization.
|
|
|
|
struct NonTrivialDestructor {
|
|
~NonTrivialDestructor();
|
|
};
|
|
|
|
// CHECK-NOSTRICT-LABEL: @_Z20nonTrivialDestructorv
|
|
NonTrivialDestructor nonTrivialDestructor() {
|
|
// CHECK-NOSTRICT: call void @llvm.trap
|
|
// CHECK-NOSTRICT-NEXT: unreachable
|
|
}
|
|
|
|
// The behavior for lambdas should be identical to functions.
|
|
// CHECK-COMMON-LABEL: @_Z10lambdaTestv
|
|
void lambdaTest() {
|
|
auto lambda1 = []() -> int {
|
|
};
|
|
lambda1();
|
|
|
|
// CHECK: call void @llvm.trap
|
|
// CHECK-NEXT: unreachable
|
|
|
|
// CHECK-NOSTRICT-NOT: call void @llvm.trap
|
|
// CHECK-NOSTRICT-NOT: unreachable
|
|
}
|