Eric Fiselier | b42c73d | 2019-05-16 21:51:39 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -std=c++1z -fblocks %s -triple x86_64-unknown-unknown -emit-llvm -o - | FileCheck %s |
Eric Fiselier | 708afb5 | 2019-05-16 21:04:15 +0000 | [diff] [blame] | 2 | |
| 3 | extern "C" int sink; |
| 4 | extern "C" const volatile void* volatile ptr_sink = nullptr; |
| 5 | |
| 6 | struct Tag1 {}; |
| 7 | struct Tag2 {}; |
| 8 | struct Tag3 {}; |
| 9 | struct Tag4 {}; |
| 10 | |
| 11 | constexpr int get_line_constexpr(int l = __builtin_LINE()) { |
| 12 | return l; |
| 13 | } |
| 14 | |
| 15 | int get_line_nonconstexpr(int l = __builtin_LINE()) { |
| 16 | return l; |
| 17 | } |
| 18 | |
| 19 | |
| 20 | int get_line(int l = __builtin_LINE()) { |
| 21 | return l; |
| 22 | } |
| 23 | |
| 24 | int get_line2(int l = get_line()) { return l; } |
| 25 | |
| 26 | |
Fangrui Song | dbc96b5 | 2020-02-03 10:09:39 -0800 | [diff] [blame] | 27 | // CHECK: @global_one = global i32 [[@LINE+1]], align 4 |
Eric Fiselier | 708afb5 | 2019-05-16 21:04:15 +0000 | [diff] [blame] | 28 | int global_one = __builtin_LINE(); |
Fangrui Song | dbc96b5 | 2020-02-03 10:09:39 -0800 | [diff] [blame] | 29 | // CHECK-NEXT: @global_two = global i32 [[@LINE+1]], align 4 |
Eric Fiselier | 708afb5 | 2019-05-16 21:04:15 +0000 | [diff] [blame] | 30 | int global_two = get_line_constexpr(); |
| 31 | // CHECK: @_ZL12global_three = internal constant i32 [[@LINE+1]], align 4 |
| 32 | const int global_three(get_line_constexpr()); |
| 33 | |
| 34 | // CHECK-LABEL: define internal void @__cxx_global_var_init |
| 35 | // CHECK: %call = call i32 @_Z21get_line_nonconstexpri(i32 [[@LINE+2]]) |
| 36 | // CHECK-NEXT: store i32 %call, i32* @global_four, align 4 |
| 37 | int global_four = get_line_nonconstexpr(); |
| 38 | |
| 39 | struct InClassInit { |
| 40 | int Init = __builtin_LINE(); |
| 41 | int Init2 = get_line2(); |
| 42 | InClassInit(); |
| 43 | constexpr InClassInit(Tag1, int l = __builtin_LINE()) : Init(l), Init2(l) {} |
| 44 | constexpr InClassInit(Tag2) : Init(__builtin_LINE()), Init2(__builtin_LINE()) {} |
| 45 | InClassInit(Tag3, int l = __builtin_LINE()); |
| 46 | InClassInit(Tag4, int l = get_line2()); |
| 47 | |
| 48 | static void test_class(); |
| 49 | }; |
Fangrui Song | dbc96b5 | 2020-02-03 10:09:39 -0800 | [diff] [blame] | 50 | // CHECK-LABEL: define void @_ZN11InClassInit10test_classEv() |
Eric Fiselier | 708afb5 | 2019-05-16 21:04:15 +0000 | [diff] [blame] | 51 | void InClassInit::test_class() { |
| 52 | // CHECK: call void @_ZN11InClassInitC1Ev(%struct.InClassInit* %test_one) |
| 53 | InClassInit test_one; |
| 54 | // CHECK-NEXT: call void @_ZN11InClassInitC1E4Tag1i(%struct.InClassInit* %test_two, i32 [[@LINE+1]]) |
| 55 | InClassInit test_two{Tag1{}}; |
| 56 | // CHECK-NEXT: call void @_ZN11InClassInitC1E4Tag2(%struct.InClassInit* %test_three) |
| 57 | InClassInit test_three{Tag2{}}; |
| 58 | // CHECK-NEXT: call void @_ZN11InClassInitC1E4Tag3i(%struct.InClassInit* %test_four, i32 [[@LINE+1]]) |
| 59 | InClassInit test_four(Tag3{}); |
| 60 | // CHECK-NEXT: %[[CALL:.+]] = call i32 @_Z8get_linei(i32 [[@LINE+3]]) |
| 61 | // CHECK-NEXT: %[[CALL2:.+]] = call i32 @_Z9get_line2i(i32 %[[CALL]]) |
| 62 | // CHECK-NEXT: call void @_ZN11InClassInitC1E4Tag4i(%struct.InClassInit* %test_five, i32 %[[CALL2]]) |
| 63 | InClassInit test_five(Tag4{}); |
| 64 | |
| 65 | } |
Fangrui Song | dbc96b5 | 2020-02-03 10:09:39 -0800 | [diff] [blame] | 66 | // CHECK-LABEL: define void @_ZN11InClassInitC2Ev |
Eric Fiselier | 708afb5 | 2019-05-16 21:04:15 +0000 | [diff] [blame] | 67 | // CHECK: store i32 [[@LINE+4]], i32* %Init, align 4 |
| 68 | // CHECK: %call = call i32 @_Z8get_linei(i32 [[@LINE+3]]) |
| 69 | // CHECK-NEXT: %call2 = call i32 @_Z9get_line2i(i32 %call) |
| 70 | // CHECK-NEXT: store i32 %call2, i32* %Init2, align 4 |
| 71 | InClassInit::InClassInit() = default; |
| 72 | |
| 73 | InClassInit::InClassInit(Tag3, int l) : Init(l) {} |
| 74 | |
Fangrui Song | dbc96b5 | 2020-02-03 10:09:39 -0800 | [diff] [blame] | 75 | // CHECK-LABEL: define void @_ZN11InClassInitC2E4Tag4i(%struct.InClassInit* %this, i32 %arg) |
Eric Fiselier | 708afb5 | 2019-05-16 21:04:15 +0000 | [diff] [blame] | 76 | // CHECK: %[[TEMP:.+]] = load i32, i32* %arg.addr, align 4 |
| 77 | // CHECK-NEXT: store i32 %[[TEMP]], i32* %Init, align 4 |
| 78 | // CHECK: %[[CALL:.+]] = call i32 @_Z8get_linei(i32 [[@LINE+3]]) |
| 79 | // CHECK-NEXT: %[[CALL2:.+]] = call i32 @_Z9get_line2i(i32 %[[CALL]]) |
| 80 | // CHECK-NEXT: store i32 %[[CALL2]], i32* %Init2, align 4 |
| 81 | InClassInit::InClassInit(Tag4, int arg) : Init(arg) {} |
| 82 | |
Fangrui Song | dbc96b5 | 2020-02-03 10:09:39 -0800 | [diff] [blame] | 83 | // CHECK-LABEL: define void @_Z13get_line_testv() |
Eric Fiselier | 708afb5 | 2019-05-16 21:04:15 +0000 | [diff] [blame] | 84 | void get_line_test() { |
| 85 | // CHECK: %[[CALL:.+]] = call i32 @_Z8get_linei(i32 [[@LINE+2]]) |
| 86 | // CHECK-NEXT: store i32 %[[CALL]], i32* @sink, align 4 |
| 87 | sink = get_line(); |
| 88 | // CHECK-NEXT: store i32 [[@LINE+1]], i32* @sink, align 4 |
| 89 | sink = __builtin_LINE(); |
| 90 | ptr_sink = &global_three; |
| 91 | } |
| 92 | |
| 93 | void foo() { |
| 94 | const int N[] = {__builtin_LINE(), get_line_constexpr()}; |
| 95 | } |