1 // RUN: %clang_cc1 -std=c++1z -fblocks %s -triple x86_64-unknown-unknown -emit-llvm -o - | FileCheck %s
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 
get_line_constexpr(int l=__builtin_LINE ())11 constexpr int get_line_constexpr(int l = __builtin_LINE()) {
12   return l;
13 }
14 
get_line_nonconstexpr(int l=__builtin_LINE ())15 int get_line_nonconstexpr(int l = __builtin_LINE()) {
16   return l;
17 }
18 
19 
get_line(int l=__builtin_LINE ())20 int get_line(int l = __builtin_LINE()) {
21   return l;
22 }
23 
get_line2(int l=get_line ())24 int get_line2(int l = get_line()) { return l; }
25 
26 
27 // CHECK: @global_one ={{.*}} global i32 [[@LINE+1]], align 4
28 int global_one = __builtin_LINE();
29 // CHECK-NEXT: @global_two ={{.*}} global i32 [[@LINE+1]], align 4
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();
InClassInitInClassInit43   constexpr InClassInit(Tag1, int l = __builtin_LINE()) : Init(l), Init2(l) {}
InClassInitInClassInit44   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 };
50 // CHECK-LABEL: define{{.*}} void @_ZN11InClassInit10test_classEv()
test_class()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 }
66 // CHECK-LABEL: define{{.*}} void @_ZN11InClassInitC2Ev
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 
InClassInit(Tag3,int l)73 InClassInit::InClassInit(Tag3, int l) : Init(l) {}
74 
75 // CHECK-LABEL: define{{.*}} void @_ZN11InClassInitC2E4Tag4i(%struct.InClassInit* {{[^,]*}} %this, i32 %arg)
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
InClassInit(Tag4,int arg)81 InClassInit::InClassInit(Tag4, int arg) : Init(arg) {}
82 
83 // CHECK-LABEL: define{{.*}} void @_Z13get_line_testv()
get_line_test()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 
foo()93 void foo() {
94   const int N[] = {__builtin_LINE(), get_line_constexpr()};
95 }
96