xref: /llvm-project/clang/test/SemaCXX/source_location_err.cpp (revision d61487490022aaacc34249475fac3e208c7d767e)
1 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify -DTEST=1 %s
2 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify -DTEST=2 %s
3 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify -DTEST=3 %s
4 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify -DTEST=4 %s
5 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify -DTEST=5 %s
6 
7 #if TEST == 1
8 auto test1a = __builtin_source_location(); // expected-error {{'std::source_location::__impl' was not found}}
9 
10 namespace std {
11 inline namespace NS {
12   struct source_location;
13 }
14 }
15 
16 auto test1b = __builtin_source_location(); // expected-error {{'std::source_location::__impl' was not found}}
17 
18 namespace std {
19 inline namespace NS {
20   struct source_location {
21     struct __impl;
22   };
23 }
24 }
25 auto test1c = __builtin_source_location(); // expected-error {{'std::source_location::__impl' was not found}}
26 
27 #elif TEST == 2
28 auto test2a = __builtin_source_location(); // expected-error {{'std::source_location::__impl' was not found}}
29 
30 namespace std {
31 inline namespace NS {
32 struct source_location {
33   struct __impl { int x; };
34 };
35 }
36 }
37 auto test2b = __builtin_source_location(); // expected-error {{'std::source_location::__impl' must be standard-layout and have only two 'const char *' fields '_M_file_name' and '_M_function_name', and two integral fields '_M_line' and '_M_column'}}
38 
39 #elif TEST == 3
40 namespace std {
41 struct source_location {
42   struct __impl {
43     int other_member;
44     char _M_line;
45     const char *_M_file_name;
46     char _M_column;
47     const char *_M_function_name;
48   };
49 };
50 }
51 auto test3 = __builtin_source_location(); // expected-error {{'std::source_location::__impl' must be standard-layout and have only two 'const char *' fields '_M_file_name' and '_M_function_name', and two integral fields '_M_line' and '_M_column'}}
52 
53 #elif TEST == 4
54 namespace std {
55 struct source_location {
56   struct parent {};
57   struct __impl : public parent {
58     char _M_line;
59     const char *_M_file_name;
60     char _M_column;
61     const char *_M_function_name;
62   };
63 };
64 }
65 auto test4 = __builtin_source_location(); // expected-error {{'std::source_location::__impl' must be standard-layout and have only two 'const char *' fields '_M_file_name' and '_M_function_name', and two integral fields '_M_line' and '_M_column'}}
66 
67 
68 #elif TEST == 5
69 namespace std {
70 struct source_location {
71   struct __impl {
72     signed char _M_line; // odd integral type to choose, but ok!
73     const char *_M_file_name;
74     signed char _M_column;
75     const char *_M_function_name;
76     static int other_member; // static members are OK
77   };
78   using BuiltinT = decltype(__builtin_source_location()); // OK.
79 };
80 }
81 
82 // Verify that the address cannot be used as a non-type template argument.
83 template <auto X = __builtin_source_location()>
fn1()84 auto fn1() {return X;} // expected-note {{candidate template ignored: substitution failure: non-type template argument does not refer to any declaration}}
85 auto test5a = fn1<>(); // expected-error {{no matching function for call to 'fn1'}}
86 
87 // (But using integer subobjects by value is okay.)
88 template <auto X = __builtin_source_location()->_M_column>
fn2()89 auto fn2() {return X;}
90 auto test5b = fn2<>();
91 
92 // While it's not semantically required, for efficiency, we ensure that two
93 // source-locations with the same content will point to the same object. Given
94 // the odd definition of the struct used here (using 'signed char'), any
95 // line-number modulo 256 will thus have the same content, and be deduplicated.
96 #line 128
97 constexpr auto sl1 = __builtin_source_location();
98 #line 384
99 constexpr auto sl2 = __builtin_source_location();
100 constexpr auto sl3 = __builtin_source_location();
101 static_assert(sl1 == sl2);
102 static_assert(sl1 != sl3);
103 static_assert(sl1->_M_line == -128);
104 
105 #endif
106