1 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 %s -emit-llvm -o - | FileCheck %s 2 // RUN: %clang_cc1 -emit-obj -debug-info-kind=constructor -std=c++20 %s -o - 3 4 namespace PR50787 { 5 // This code would previously cause a crash. 6 extern int x_; 7 consteval auto& X() { return x_; } 8 constexpr auto& x1 = X(); 9 auto x2 = X(); 10 11 // CHECK: @_ZN7PR507872x_E = external global i32, align 4 12 // CHECK-NEXT: @_ZN7PR507872x1E = constant ptr @_ZN7PR507872x_E, align 8 13 // CHECK-NEXT: @_ZN7PR507872x2E = global i32 0, align 4 14 } 15 16 namespace PR51484 { 17 // This code would previously cause a crash. 18 struct X { int val; }; 19 consteval X g() { return {0}; } 20 void f() { g(); } 21 22 // CHECK: define dso_local void @_ZN7PR514841fEv() #1 { 23 // CHECK: entry: 24 // CHECK-NOT: call i32 @_ZN7PR514841gEv() 25 // CHECK: ret void 26 // CHECK: } 27 } 28 29 namespace Issue54578 { 30 inline consteval unsigned char operator""_UC(const unsigned long long n) { 31 return static_cast<unsigned char>(n); 32 } 33 34 inline constexpr char f1(const auto octet) { 35 return 4_UC; 36 } 37 38 template <typename Ty> 39 inline constexpr char f2(const Ty octet) { 40 return 4_UC; 41 } 42 43 int foo() { 44 return f1('a') + f2('a'); 45 } 46 47 // Because the consteval functions are inline (implicitly as well as 48 // explicitly), we need to defer the CHECK lines until this point to get the 49 // order correct. We want to ensure there is no definition of the consteval 50 // UDL function, and that the constexpr f1 and f2 functions both return a 51 // constant value. 52 53 // CHECK-NOT: define{{.*}} zeroext i8 @_ZN10Issue54578li3_UCEy 54 // CHECK: define{{.*}} i32 @_ZN10Issue545783fooEv( 55 // CHECK: define{{.*}} signext i8 @_ZN10Issue545782f1IcEEcT_( 56 // CHECK: ret i8 4 57 // CHECK: define{{.*}} signext i8 @_ZN10Issue545782f2IcEEcT_( 58 // CHECK: ret i8 4 59 } 60 61 namespace Issue55871 { 62 struct Item { 63 consteval Item(char c) :_char{c}{} 64 char _char; 65 }; 66 67 int function(const Item& item1, const Item& item2) { 68 return 0; 69 } 70 71 int foo() { 72 return function(Item{'a'}, Item{'a'}); 73 } 74 } // namespace Issue58871 75 76 namespace Issue55065 { 77 struct Base { 78 consteval virtual int Get() const = 0; 79 }; 80 81 struct Derived : Base { 82 consteval int Get() const override { 83 return 42; 84 } 85 }; 86 87 int foo() { 88 constexpr Derived a; 89 90 auto val = a.Get(); 91 return val; 92 } 93 } // namespace Issue55065 94 95 namespace GH60166 { 96 97 struct Base { 98 void* one = nullptr; 99 void* two = nullptr; 100 }; 101 102 struct Derived : Base { 103 void* three = nullptr; 104 consteval Derived() = default; 105 }; 106 107 void method() { 108 // CHECK: %agg.tmp.ensured = alloca %"struct.GH60166::Derived" 109 // CHECK: %0 = getelementptr inbounds nuw { ptr, ptr, ptr }, ptr %agg.tmp.ensured, i32 0, i32 0 110 // CHECK: store ptr null, ptr %0, align 8 111 // CHECK: %1 = getelementptr inbounds nuw { ptr, ptr, ptr }, ptr %agg.tmp.ensured, i32 0, i32 1 112 // CHECK: store ptr null, ptr %1, align 8 113 // CHECK: %2 = getelementptr inbounds nuw { ptr, ptr, ptr }, ptr %agg.tmp.ensured, i32 0, i32 2 114 // CHECK: store ptr null, ptr %2, align 8 115 (void)Derived(); 116 } 117 118 } // namespace GH60166 119 120 namespace GH61142 { 121 122 template <typename T> 123 struct Test { 124 constexpr static void bar() { 125 foo(); 126 } 127 consteval static void foo() {}; 128 }; 129 130 consteval void a() { 131 Test<int>::bar(); 132 } 133 134 void b() { 135 Test<int>::bar(); 136 } 137 138 // Make sure consteval function is not emitted. 139 // CHECK-NOT: call {{.*}}foo{{.*}}() 140 // CHECK-NOT: define {{.*}}foo{{.*}}() 141 142 } // namespace GH61142 143