llvm-project/clang/test/CodeGenCXX/cxx20-consteval-crash.cpp
Aaron Ballman ca844ab01c Fix template instantiation of UDLs
Previously, we would instantiate the UDL by marking the function as
referenced and potentially binding to a temporary; this skipped
transforming the call when the UDL was dependent on a template
parameter.

Now, we defer all the work to instantiating the call expression for the
UDL. This ensures that constant evaluation occurs at compile time
rather than deferring until runtime.

Fixes Issue 54578.
2022-03-28 14:46:53 -04:00

59 lines
1.6 KiB
C++

// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 %s -emit-llvm -o - | FileCheck %s
namespace PR50787 {
// This code would previously cause a crash.
extern int x_;
consteval auto& X() { return x_; }
constexpr auto& x1 = X();
auto x2 = X();
// CHECK: @_ZN7PR507872x_E = external global i32, align 4
// CHECK-NEXT: @_ZN7PR507872x1E = constant i32* @_ZN7PR507872x_E, align 8
// CHECK-NEXT: @_ZN7PR507872x2E = global i32* @_ZN7PR507872x_E, align 4
}
namespace PR51484 {
// This code would previously cause a crash.
struct X { int val; };
consteval X g() { return {0}; }
void f() { g(); }
// CHECK: define dso_local void @_ZN7PR514841fEv() #0 {
// CHECK: entry:
// CHECK-NOT: call i32 @_ZN7PR514841gEv()
// CHECK: ret void
// CHECK: }
}
namespace Issue54578 {
inline consteval unsigned char operator""_UC(const unsigned long long n) {
return static_cast<unsigned char>(n);
}
inline constexpr char f1(const auto octet) {
return 4_UC;
}
template <typename Ty>
inline constexpr char f2(const Ty octet) {
return 4_UC;
}
int foo() {
return f1('a') + f2('a');
}
// Because the consteval functions are inline (implicitly as well as
// explicitly), we need to defer the CHECK lines until this point to get the
// order correct. We want to ensure there is no definition of the consteval
// UDL function, and that the constexpr f1 and f2 functions both return a
// constant value.
// CHECK-NOT: define{{.*}} zeroext i8 @_ZN10Issue54578li3_UCEy
// CHECK: define{{.*}} i32 @_ZN10Issue545783fooEv(
// CHECK: define{{.*}} signext i8 @_ZN10Issue545782f1IcEEcT_(
// CHECK: ret i8 4
// CHECK: define{{.*}} signext i8 @_ZN10Issue545782f2IcEEcT_(
// CHECK: ret i8 4
}