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
 | 
						|
}
 |