brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.2 KiB · bfeabc9 Raw
308 lines · cpp
1// RUN: %clang_cc1 -emit-llvm %s -std=c++2a -triple x86_64-unknown-linux-gnu -o %t.ll2// RUN: FileCheck -check-prefix=EVAL -input-file=%t.ll %s3// RUN: FileCheck -check-prefix=EVAL-STATIC -input-file=%t.ll %s4// RUN: FileCheck -check-prefix=EVAL-FN -input-file=%t.ll %s5//6// RUN: %clang_cc1 -emit-llvm %s -Dconsteval="" -std=c++2a -triple x86_64-unknown-linux-gnu -o %t.ll7// RUN: FileCheck -check-prefix=EXPR -input-file=%t.ll %s8 9// RUN: %clang_cc1 -emit-llvm %s -std=c++2a -triple x86_64-unknown-linux-gnu -o %t.ll -fexperimental-new-constant-interpreter10// RUN: FileCheck -check-prefix=EVAL -input-file=%t.ll %s11// RUN: FileCheck -check-prefix=EVAL-STATIC -input-file=%t.ll %s12// RUN: FileCheck -check-prefix=EVAL-FN -input-file=%t.ll %s13//14// RUN: %clang_cc1 -emit-llvm %s -Dconsteval="" -std=c++2a -triple x86_64-unknown-linux-gnu -o %t.ll -fexperimental-new-constant-interpreter15// RUN: FileCheck -check-prefix=EXPR -input-file=%t.ll %s16 17// there is two version of symbol checks to ensure18// that the symbol we are looking for are correct19// EVAL-NOT: @__cxx_global_var_init()20// EXPR: @__cxx_global_var_init()21 22// EVAL-NOT: @_Z4ret7v()23// EXPR: @_Z4ret7v()24consteval int ret7() {25  return 7;26}27 28// EVAL-FN-LABEL: @_Z9test_ret7v(29// EVAL-FN-NEXT:  entry:30// EVAL-FN-NEXT:    [[I:%.*]] = alloca i32, align 431// EVAL-FN-NEXT:    store i32 7, ptr [[I]], align 432// EVAL-FN-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I]], align 433// EVAL-FN-NEXT:    ret i32 [[TMP0]]34//35int test_ret7() {36  int i = ret7();37  return i;38}39 40int global_i = ret7();41 42constexpr int i_const = 5;43 44// EVAL-NOT: @_Z4retIv()45// EXPR: @_Z4retIv()46consteval const int &retI() {47  return i_const;48}49 50// EVAL-FN-LABEL: @_Z12test_retRefIv(51// EVAL-FN-NEXT:  entry:52// EVAL-FN-NEXT:    ret ptr @_ZL7i_const53//54const int &test_retRefI() {55  return retI();56}57 58// EVAL-FN-LABEL: @_Z9test_retIv(59// EVAL-FN-NEXT:  entry:60// EVAL-FN-NEXT:    [[TMP0:%.*]] = load i32, ptr @_ZL7i_const, align 461// EVAL-FN-NEXT:    ret i32 [[TMP0]]62//63int test_retI() {64  return retI();65}66 67// EVAL-NOT: @_Z4retIv()68// EXPR: @_Z4retIv()69consteval const int *retIPtr() {70  return &i_const;71}72 73// EVAL-FN-LABEL: @_Z12test_retIPtrv(74// EVAL-FN-NEXT:  entry:75// EVAL-FN-NEXT:    [[TMP0:%.*]] = load i32, ptr @_ZL7i_const, align 476// EVAL-FN-NEXT:    ret i32 [[TMP0]]77//78int test_retIPtr() {79  return *retIPtr();80}81 82// EVAL-FN-LABEL: @_Z13test_retPIPtrv(83// EVAL-FN-NEXT:  entry:84// EVAL-FN-NEXT:    ret ptr @_ZL7i_const85//86const int *test_retPIPtr() {87  return retIPtr();88}89 90// EVAL-NOT: @_Z4retIv()91// EXPR: @_Z4retIv()92consteval const int &&retIRRef() {93  return static_cast<const int &&>(i_const);94}95 96// EVAL-FN-LABEL: @_Z13test_retIRRefv(97// EVAL-FN-NEXT:  entry:98// EVAL-FN-NEXT:    ret ptr @_ZL7i_const99//100const int &&test_retIRRef() {101  return static_cast<const int &&>(retIRRef());102}103 104// EVAL-FN-LABEL: @_Z14test_retIRRefIv(105// EVAL-FN-NEXT:  entry:106// EVAL-FN-NEXT:    [[TMP0:%.*]] = load i32, ptr @_ZL7i_const, align 4107// EVAL-FN-NEXT:    ret i32 [[TMP0]]108//109int test_retIRRefI() {110  return retIRRef();111}112 113struct Agg {114  int a;115  long b;116};117 118// EVAL-NOT: @_Z6retAggv()119// EXPR: @_Z6retAggv()120consteval Agg retAgg() {121  return {13, 17};122}123 124// EVAL-FN-LABEL: @_Z11test_retAggv(125// EVAL-FN-NEXT:  entry:126// EVAL-FN-NEXT:    [[B:%.*]] = alloca i64, align 8127// EVAL-FN-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_AGG:%.*]], align 8128// EVAL-FN-NEXT:    [[TMP0:%.*]] = getelementptr inbounds nuw [[STRUCT_AGG]], ptr [[REF_TMP]], i32 0, i32 0129// EVAL-FN-NEXT:    store i32 13, ptr [[TMP0]], align 8130// EVAL-FN-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw [[STRUCT_AGG]], ptr [[REF_TMP]], i32 0, i32 1131// EVAL-FN-NEXT:    store i64 17, ptr [[TMP1]], align 8132// EVAL-FN-NEXT:    store i64 17, ptr [[B]], align 8133// EVAL-FN-NEXT:    [[TMP2:%.*]] = load i64, ptr [[B]], align 8134// EVAL-FN-NEXT:    ret i64 [[TMP2]]135//136long test_retAgg() {137  long b = retAgg().b;138  return b;139}140 141// EVAL-STATIC: @A ={{.*}} global %struct.Agg { i32 13, i64 17 }, align 8142Agg A = retAgg();143 144// EVAL-NOT: @_Z9retRefAggv()145// EXPR: @_Z9retRefAggv()146consteval const Agg &retRefAgg() {147  const Agg &tmp = A;148  return A;149}150 151// EVAL-FN-LABEL: @_Z14test_retRefAggv(152// EVAL-FN-NEXT:  entry:153// EVAL-FN-NEXT:    [[B:%.*]] = alloca i64, align 8154// EVAL-FN-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_AGG:%.*]], align 8155// EVAL-FN-NEXT:    [[TMP0:%.*]] = getelementptr inbounds nuw [[STRUCT_AGG]], ptr [[REF_TMP]], i32 0, i32 0156// EVAL-FN-NEXT:    store i32 13, ptr [[TMP0]], align 8157// EVAL-FN-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw [[STRUCT_AGG]], ptr [[REF_TMP]], i32 0, i32 1158// EVAL-FN-NEXT:    store i64 17, ptr [[TMP1]], align 8159// EVAL-FN-NEXT:    store i64 17, ptr [[B]], align 8160// EVAL-FN-NEXT:    [[TMP2:%.*]] = load i64, ptr [[B]], align 8161// EVAL-FN-NEXT:    ret i64 [[TMP2]]162//163long test_retRefAgg() {164  long b = retAgg().b;165  return b;166}167 168// EVAL-NOT: @_Z8is_constv()169// EXPR: @_Z8is_constv()170consteval Agg is_const() {171  return {5, 19 * __builtin_is_constant_evaluated()};172}173 174// EVAL-FN-LABEL: @_Z13test_is_constv(175// EVAL-FN-NEXT:  entry:176// EVAL-FN-NEXT:    [[B:%.*]] = alloca i64, align 8177// EVAL-FN-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_AGG:%.*]], align 8178// EVAL-FN-NEXT:    [[TMP0:%.*]] = getelementptr inbounds nuw [[STRUCT_AGG]], ptr [[REF_TMP]], i32 0, i32 0179// EVAL-FN-NEXT:    store i32 5, ptr [[TMP0]], align 8180// EVAL-FN-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw [[STRUCT_AGG]], ptr [[REF_TMP]], i32 0, i32 1181// EVAL-FN-NEXT:    store i64 19, ptr [[TMP1]], align 8182// EVAL-FN-NEXT:    store i64 19, ptr [[B]], align 8183// EVAL-FN-NEXT:    [[TMP2:%.*]] = load i64, ptr [[B]], align 8184// EVAL-FN-NEXT:    ret i64 [[TMP2]]185//186long test_is_const() {187  long b = is_const().b;188  return b;189}190 191// EVAL-NOT: @_ZN7AggCtorC192// EXPR: @_ZN7AggCtorC193struct AggCtor {194  consteval AggCtor(int a = 3, long b = 5) : a(a * a), b(a * b) {}195  int a;196  long b;197};198 199// EVAL-FN-LABEL: @_Z12test_AggCtorv(200// EVAL-FN-NEXT:  entry:201// EVAL-FN-NEXT:    [[I:%.*]] = alloca i32, align 4202// EVAL-FN-NEXT:    [[C:%.*]] = alloca [[STRUCT_AGGCTOR:%.*]], align 8203// EVAL-FN-NEXT:    store i32 2, ptr [[I]], align 4204// EVAL-FN-NEXT:    [[TMP0:%.*]] = getelementptr inbounds nuw [[STRUCT_AGGCTOR]], ptr [[C]], i32 0, i32 0205// EVAL-FN-NEXT:    store i32 4, ptr [[TMP0]], align 8206// EVAL-FN-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw [[STRUCT_AGGCTOR]], ptr [[C]], i32 0, i32 1207// EVAL-FN-NEXT:    store i64 10, ptr [[TMP1]], align 8208// EVAL-FN-NEXT:    [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_AGGCTOR]], ptr [[C]], i32 0, i32 0209// EVAL-FN-NEXT:    [[TMP2:%.*]] = load i32, ptr [[A]], align 8210// EVAL-FN-NEXT:    [[CONV:%.*]] = sext i32 [[TMP2]] to i64211// EVAL-FN-NEXT:    [[B:%.*]] = getelementptr inbounds nuw [[STRUCT_AGGCTOR]], ptr [[C]], i32 0, i32 1212// EVAL-FN-NEXT:    [[TMP3:%.*]] = load i64, ptr [[B]], align 8213// EVAL-FN-NEXT:    [[ADD:%.*]] = add nsw i64 [[CONV]], [[TMP3]]214// EVAL-FN-NEXT:    ret i64 [[ADD]]215//216long test_AggCtor() {217  const int i = 2;218  AggCtor C(i);219  return C.a + C.b;220}221 222struct UserConv {223  consteval operator int() const noexcept { return 42; }224};225 226// EVAL-FN-LABEL: @_Z13test_UserConvv(227// EVAL-FN-NEXT:  entry:228// EVAL-FN-NEXT:    ret i32 42229//230int test_UserConv() {231  return UserConv();232}233 234// EVAL-FN-LABEL: @_Z28test_UserConvOverload_helperi(235// EVAL-FN-NEXT:  entry:236// EVAL-FN-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4237// EVAL-FN-NEXT:    store i32 [[A:%.*]], ptr [[A_ADDR]], align 4238// EVAL-FN-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4239// EVAL-FN-NEXT:    ret i32 [[TMP0]]240//241int test_UserConvOverload_helper(int a) { return a; }242 243// EVAL-FN-LABEL: @_Z21test_UserConvOverloadv(244// EVAL-FN-NEXT:  entry:245// EVAL-FN-NEXT:    [[CALL:%.*]] = call noundef i32 @_Z28test_UserConvOverload_helperi(i32 noundef 42)246// EVAL-FN-NEXT:    ret i32 [[CALL]]247//248int test_UserConvOverload() {249  return test_UserConvOverload_helper(UserConv());250}251 252consteval int test_UserConvOverload_helper_ceval(int a) { return a; }253 254// EVAL-FN-LABEL: @_Z27test_UserConvOverload_cevalv(255// EVAL-FN-NEXT:  entry:256// EVAL-FN-NEXT:    ret i32 42257//258int test_UserConvOverload_ceval() {259  return test_UserConvOverload_helper_ceval(UserConv());260}261 262consteval void void_test() {}263void void_call() { // EVAL-FN-LABEL: define {{.*}} @_Z9void_call264  // EVAL-FN-NOT: call265  void_test();266  // EVAL-FN: {{^}}}267}268 269 270namespace GH82154 {271struct S1 { consteval S1(int) {} };272struct S3 { constexpr S3(int) {} };273 274void f() {275    struct S2 {276        S1 s = 0;277        S3 s2 = 0;278    };279    S2 s;280    // EVAL-FN-LABEL: define {{.*}} void @_ZZN7GH821541fEvEN2S2C2Ev281    // EVAL-FN-NOT: call void @_ZN7GH821542S1C2Ei282    // EVAL-FN:     call void @_ZN7GH821542S3C2Ei283}284}285 286namespace GH93040 {287struct C { char c = 1; };288struct Empty { consteval Empty() {} };289struct Empty2 { consteval Empty2() {} };290struct Test : C, Empty {291  [[no_unique_address]] Empty2 e;292};293static_assert(sizeof(Test) == 1);294void f() {295  Test test;296 297// Make sure we don't overwrite the initialization of c.298 299// EVAL-FN-LABEL: define {{.*}} void @_ZN7GH930404TestC2Ev300// EVAL-FN: entry:301// EVAL-FN-NEXT:  [[THIS_ADDR:%.*]] = alloca ptr, align 8302// EVAL-FN-NEXT:  store ptr {{.*}}, ptr [[THIS_ADDR]], align 8303// EVAL-FN-NEXT:  [[THIS:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8304// EVAL-FN-NEXT:  call void @_ZN7GH930401CC2Ev(ptr noundef nonnull align 1 dereferenceable(1) [[THIS]])305// EVAL-FN-NEXT:  ret void306}307}308