xref: /llvm-project/clang/test/Sema/ms_predefined_expr.cpp (revision 2cb61a1d117e2c20e3372bc23bf12b919feaaca2)
1 // RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions
2 // RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions -fexperimental-new-constant-interpreter
3 
4 using size_t = __SIZE_TYPE__;
5 
6 // Test array initialization
array_init()7 void array_init() {
8  const char a[] = __FUNCTION__; // expected-warning{{initializing an array from a '__FUNCTION__' predefined identifier is a Microsoft extension}}
9  const char b[] = __FUNCDNAME__; // expected-warning{{initializing an array from a '__FUNCDNAME__' predefined identifier is a Microsoft extension}}
10  const char c[] = __FUNCSIG__; // expected-warning{{initializing an array from a '__FUNCSIG__' predefined identifier is a Microsoft extension}}
11  const char d[] = __func__; // expected-warning{{initializing an array from a '__func__' predefined identifier is a Microsoft extension}}
12  const char e[] = __PRETTY_FUNCTION__; // expected-warning{{initializing an array from a '__PRETTY_FUNCTION__' predefined identifier is a Microsoft extension}}
13  const wchar_t f[] = L__FUNCTION__; // expected-warning{{initializing an array from a 'L__FUNCTION__' predefined identifier is a Microsoft extension}}
14  const wchar_t g[] = L__FUNCSIG__; // expected-warning{{initializing an array from a 'L__FUNCSIG__' predefined identifier is a Microsoft extension}}
15 }
16 
17 // Test function local identifiers outside of a function
18 const char* g_function = __FUNCTION__;            // expected-warning{{predefined identifier is only valid inside function}}
19 const char* g_function_lconcat = "" __FUNCTION__; // expected-warning{{predefined identifier is only valid inside function}} \
20                                                   // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
21 const char* g_function_rconcat = __FUNCTION__ ""; // expected-warning{{predefined identifier is only valid inside function}} \
22                                                   // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
23 
24 namespace NS
25 {
26   const char* function = __FUNCTION__;            // expected-warning{{predefined identifier is only valid inside function}}
27   const char* function_lconcat = "" __FUNCTION__; // expected-warning{{predefined identifier is only valid inside function}} \
28                                                   // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
29   const char* function_rconcat = __FUNCTION__ ""; // expected-warning{{predefined identifier is only valid inside function}} \
30                                                   // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
31 
32   struct S
33   {
34     static constexpr const char* function = __FUNCTION__;            // expected-warning{{predefined identifier is only valid inside function}}
35     static constexpr const char* function_lconcat = "" __FUNCTION__; // expected-warning{{predefined identifier is only valid inside function}} \
36                                                                      // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
37     static constexpr const char* function_rconcat = __FUNCTION__ ""; // expected-warning{{predefined identifier is only valid inside function}} \
38                                                                      // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
39   };
40 }
41 
42 template<class T, class U>
43 constexpr bool is_same = false;
44 template<class T>
45 constexpr bool is_same<T, T> = true;
46 
47 template<typename T, size_t N>
equal(const T (& a)[N],const T (& b)[N])48 constexpr bool equal(const T (&a)[N], const T (&b)[N]) {
49   for (size_t i = 0; i < N; i++)
50     if (a[i] != b[i])
51       return false;
52   return true;
53 }
54 
55 #define ASSERT_EQ(X, Y) static_assert(equal(X, Y), "")
56 #define ASSERT_EQ_TY(X, Y) static_assert(is_same<decltype((X)[0]), decltype((Y)[0])>, "")
57 
58 #define _WIDE(s) L##s
59 #define WIDE(s)  _WIDE(s)
60 
61 // Test value
test_value()62 extern "C" void test_value() {
63   ASSERT_EQ(__FUNCTION__, "test_value");
64   ASSERT_EQ(__FUNCSIG__, "void __cdecl test_value(void)");
65 
66   ASSERT_EQ(WIDE(__FUNCTION__), L"test_value");
67   ASSERT_EQ(WIDE(__FUNCSIG__), L"void __cdecl test_value(void)");
68 }
69 
70 namespace PR13206 {
71   template<class T> class A {
72     public:
method()73       void method() {
74         ASSERT_EQ(L__FUNCTION__, L"method");
75       }
76   };
77 
test_template_value()78   void test_template_value() {
79     A<int> x;
80     x.method();
81   }
82 }
83 
84 // Test concatenation
test_concat()85 extern "C" void test_concat() {
86   ASSERT_EQ("left_" __FUNCTION__, "left_test_concat");                   // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
87   ASSERT_EQ("left_" __FUNCDNAME__, "left_test_concat");                  // expected-warning{{expansion of predefined identifier '__FUNCDNAME__' to a string literal is a Microsoft extension}}
88   ASSERT_EQ("left " __FUNCSIG__, "left void __cdecl test_concat(void)"); // expected-warning{{expansion of predefined identifier '__FUNCSIG__' to a string literal is a Microsoft extension}}
89 
90   ASSERT_EQ(__FUNCTION__ "_right", "test_concat_right");                   // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
91   ASSERT_EQ(__FUNCDNAME__ "_right", "test_concat_right");                  // expected-warning{{expansion of predefined identifier '__FUNCDNAME__' to a string literal is a Microsoft extension}}
92   ASSERT_EQ(__FUNCSIG__ " right", "void __cdecl test_concat(void) right"); // expected-warning{{expansion of predefined identifier '__FUNCSIG__' to a string literal is a Microsoft extension}}
93 
94   ASSERT_EQ("left_" __FUNCTION__ "_right", "left_test_concat_right");                   // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
95   ASSERT_EQ("left_" __FUNCDNAME__ "_right", "left_test_concat_right");                  // expected-warning{{expansion of predefined identifier '__FUNCDNAME__' to a string literal is a Microsoft extension}}
96   ASSERT_EQ("left " __FUNCSIG__ " right", "left void __cdecl test_concat(void) right"); // expected-warning{{expansion of predefined identifier '__FUNCSIG__' to a string literal is a Microsoft extension}}
97 
98   ASSERT_EQ(__FUNCTION__ "/" __FUNCSIG__, "test_concat/void __cdecl test_concat(void)"); // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}} \
99                                                                                          // expected-warning{{expansion of predefined identifier '__FUNCSIG__' to a string literal is a Microsoft extension}}
100 }
101 
test_wide_concat()102 extern "C" void test_wide_concat() {
103   // test L"" + ""
104   ASSERT_EQ(L"" __FUNCTION__, L__FUNCTION__); // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
105   ASSERT_EQ(L"" __FUNCSIG__, L__FUNCSIG__);   // expected-warning{{expansion of predefined identifier '__FUNCSIG__' to a string literal is a Microsoft extension}}
106 
107   // test Lx + ""
108   ASSERT_EQ(L__FUNCTION__, L__FUNCTION__ ""); // expected-warning{{expansion of predefined identifier 'L__FUNCTION__' to a string literal is a Microsoft extension}}
109   ASSERT_EQ(L__FUNCSIG__, L__FUNCSIG__ "");   // expected-warning{{expansion of predefined identifier 'L__FUNCSIG__' to a string literal is a Microsoft extension}}
110 
111   ASSERT_EQ(L"left_" L__FUNCTION__, L"left_test_wide_concat");                   // expected-warning{{expansion of predefined identifier 'L__FUNCTION__' to a string literal is a Microsoft extension}}
112   ASSERT_EQ(L"left " L__FUNCSIG__, L"left void __cdecl test_wide_concat(void)"); // expected-warning{{expansion of predefined identifier 'L__FUNCSIG__' to a string literal is a Microsoft extension}}
113 
114   ASSERT_EQ(L__FUNCTION__ L"_right", L"test_wide_concat_right");                   // expected-warning{{expansion of predefined identifier 'L__FUNCTION__' to a string literal is a Microsoft extension}}
115   ASSERT_EQ(L__FUNCSIG__ L" right", L"void __cdecl test_wide_concat(void) right"); // expected-warning{{expansion of predefined identifier 'L__FUNCSIG__' to a string literal is a Microsoft extension}}
116 
117   ASSERT_EQ(L"left_" L__FUNCTION__ L"_right", L"left_test_wide_concat_right");                   // expected-warning{{expansion of predefined identifier 'L__FUNCTION__' to a string literal is a Microsoft extension}}
118   ASSERT_EQ(L"left " L__FUNCSIG__ L" right", L"left void __cdecl test_wide_concat(void) right"); // expected-warning{{expansion of predefined identifier 'L__FUNCSIG__' to a string literal is a Microsoft extension}}
119 
120   ASSERT_EQ(L__FUNCTION__ L"/" L__FUNCSIG__, L"test_wide_concat/void __cdecl test_wide_concat(void)"); // expected-warning{{expansion of predefined identifier 'L__FUNCTION__' to a string literal is a Microsoft extension}} \
121                                                                                                        // expected-warning{{expansion of predefined identifier 'L__FUNCSIG__' to a string literal is a Microsoft extension}}
122 }
123 
test_encoding()124 void test_encoding() {
125   ASSERT_EQ_TY("" __FUNCTION__, "");     // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
126   ASSERT_EQ_TY(L"" __FUNCTION__, L"");   // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
127   ASSERT_EQ_TY(L"" L__FUNCTION__, L"");  // expected-warning{{expansion of predefined identifier 'L__FUNCTION__' to a string literal is a Microsoft extension}}
128   ASSERT_EQ_TY("" L__FUNCTION__, L"");   // expected-warning{{expansion of predefined identifier 'L__FUNCTION__' to a string literal is a Microsoft extension}}
129   ASSERT_EQ_TY(u8"" __FUNCTION__, u8""); // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
130   ASSERT_EQ_TY(u"" __FUNCTION__, u"");   // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
131   ASSERT_EQ_TY(U"" __FUNCTION__, U"");   // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
132                                          //
133   ASSERT_EQ_TY(__FUNCTION__ L"", L"");   // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
134   ASSERT_EQ_TY(__FUNCTION__ u8"", u8""); // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
135   ASSERT_EQ_TY(__FUNCTION__ u"", u"");   // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
136   ASSERT_EQ_TY(__FUNCTION__ U"", U"");   // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
137 }
138 
139 extern "C" void test_��() {
140   ASSERT_EQ(U"" __FUNCTION__, U"test_��");   // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
141   ASSERT_EQ(u"" __FUNCTION__, u"test_��");   // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
142   ASSERT_EQ(u8"" __FUNCTION__, u8"test_��"); // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
143 }
144 
145 template<typename T>
146 void unused(T);
147 
test_invalid_encoding()148 void test_invalid_encoding() {
149   unused(u8"" L__FUNCTION__); // expected-warning{{expansion of predefined identifier 'L__FUNCTION__' to a string literal is a Microsoft extension}} \
150                               // expected-error{{unsupported non-standard concatenation of string literals}}
151   unused(u"" L__FUNCTION__);  // expected-warning{{expansion of predefined identifier 'L__FUNCTION__' to a string literal is a Microsoft extension}} \
152                               // expected-error{{unsupported non-standard concatenation of string literals}}
153   unused(U"" L__FUNCTION__);  // expected-warning{{expansion of predefined identifier 'L__FUNCTION__' to a string literal is a Microsoft extension}} \
154                               // expected-error{{unsupported non-standard concatenation of string literals}}
155 }
156 
operator ""_len(const char *,size_t len)157 constexpr size_t operator""_len(const char*, size_t len) {
158   return len;
159 }
160 
test_udliteral()161 void test_udliteral() {
162   static_assert(__FUNCTION__ ""_len == 14, ""); // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
163 }
164 
test_static_assert()165 void test_static_assert() {
166   static_assert(true, __FUNCTION__); // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
167 }
168 
169 void test_char_injection(decltype(sizeof('"')), decltype(sizeof("()"))) {
170   unused("" __FUNCSIG__); // expected-warning{{expansion of predefined identifier '__FUNCSIG__' to a string literal is a Microsoft extension}}
171 }
172 
test_in_struct_init()173 void test_in_struct_init() {
174   struct {
175     char F[sizeof(__FUNCTION__)];
176   } s1 = { __FUNCTION__ }; // expected-warning{{initializing an array from a '__FUNCTION__' predefined identifier is a Microsoft extension}}
177 
178   struct {
179     char F[sizeof("F:" __FUNCTION__)]; // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
180   } s2 = { "F:" __FUNCTION__ }; // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
181 
182   class C {
183     public:
184       struct {
185         char F[sizeof(__FUNCTION__)];
186       } s;
187   } c1 = { { __FUNCTION__ } }; // expected-warning{{initializing an array from a '__FUNCTION__' predefined identifier is a Microsoft extension}}
188 }
189 
test_in_constexpr_struct_init()190 void test_in_constexpr_struct_init() {
191   struct {
192     char F[sizeof(__FUNCTION__)];
193   } constexpr s1 = { __FUNCTION__ }; // expected-warning{{initializing an array from a '__FUNCTION__' predefined identifier is a Microsoft extension}}
194   ASSERT_EQ(__FUNCTION__, s1.F);
195 
196   struct {
197     char F[sizeof("F:" __FUNCTION__)]; // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
198   } constexpr s2 = { "F:" __FUNCTION__ }; // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
199   ASSERT_EQ("F:" __FUNCTION__, s2.F); // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
200 
201   class C {
202     public:
203       struct {
204         char F[sizeof("F:" __FUNCTION__)]; // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
205       } s;
206   } constexpr c1 = { { "F:" __FUNCTION__ } }; // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
207   ASSERT_EQ("F:" __FUNCTION__, c1.s.F); // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
208 }
209