xref: /llvm-project/clang/test/SemaCXX/builtins.cpp (revision d8a281590311010955c323806fb24fa484376f4d)
1 // RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++11 -fcxx-exceptions -fptrauth-intrinsics
2 // RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++1z -fcxx-exceptions -fptrauth-intrinsics
3 typedef const struct __CFString * CFStringRef;
4 #define CFSTR __builtin___CFStringMakeConstantString
5 #define NSSTR __builtin___NSStringMakeConstantString
6 
7 void f() {
8 #if !defined(__MVS__) && !defined(_AIX)
9   // Builtin function __builtin___CFStringMakeConstantString is currently
10   // unsupported on z/OS and AIX.
11   (void)CFStringRef(CFSTR("Hello"));
12 
13   constexpr bool a = CFSTR("Hello") == CFSTR("Hello");
14   // expected-error@-1 {{constant expression}}
15   // expected-note@-2 {{comparison against opaque constant address '&__builtin___CFStringMakeConstantString("Hello")'}}
16   constexpr bool b = NSSTR("Hello") == NSSTR("Hello");
17   // expected-error@-1 {{constant expression}}
18   // expected-note@-2 {{comparison against opaque constant address '&__builtin___NSStringMakeConstantString("Hello")'}}
19 #endif
20 }
21 
22 void a() { __builtin_va_list x, y; ::__builtin_va_copy(x, y); }
23 
24 template<int (*Compare)(const char *s1, const char *s2)>
25 int equal(const char *s1, const char *s2) {
26   return Compare(s1, s2) == 0;
27 }
28 template int equal<&__builtin_strcmp>(const char*, const char*); // expected-error {{builtin functions must be directly called}}
29 
30 // PR13195
31 void f2() {
32   __builtin_isnan; // expected-error {{builtin functions must be directly called}}
33 }
34 
35 // pr14895
36 typedef __typeof(sizeof(int)) size_t;
37 extern "C" void *__builtin_alloca (size_t);
38 
39 namespace addressof {
40   struct S {} s;
41   static_assert(__builtin_addressof(s) == &s, "");
42 
43   struct T { constexpr T *operator&() const { return nullptr; } int n; } t;
44   constexpr T *pt = __builtin_addressof(t);
45   static_assert(&pt->n == &t.n, "");
46 
47   struct U { int n : 5; } u;
48   int *pbf = __builtin_addressof(u.n); // expected-error {{address of bit-field requested}}
49 
50   S *ptmp = __builtin_addressof(S{}); // expected-error {{taking the address of a temporary}} expected-warning {{temporary whose address is used as value of local variable 'ptmp' will be destroyed at the end of the full-expression}}
51 }
52 
53 namespace function_start {
54 void a(void) {}
55 int n;
56 void *p = __builtin_function_start(n);               // expected-error {{argument must be a function}}
57 static_assert(__builtin_function_start(a) == a, ""); // expected-error {{static assertion expression is not an integral constant expression}}
58 // expected-note@-1 {{comparison against opaque constant address '&__builtin_function_start(a)'}}
59 } // namespace function_start
60 
61 void no_ms_builtins() {
62   __assume(1); // expected-error {{use of undeclared}}
63   __noop(1); // expected-error {{use of undeclared}}
64   __debugbreak(); // expected-error {{use of undeclared}}
65 }
66 
67 struct FILE;
68 extern "C" int vfprintf(FILE *__restrict, const char *__restrict,
69                         __builtin_va_list va);
70 
71 void synchronize_args() {
72   __sync_synchronize(0); // expected-error {{too many arguments}}
73 }
74 
75 namespace test_launder {
76 #define TEST_TYPE(Ptr, Type) \
77   static_assert(__is_same(decltype(__builtin_launder(Ptr)), Type), "expected same type")
78 
79 struct Dummy {};
80 
81 using FnType = int(char);
82 using MemFnType = int (Dummy::*)(char);
83 using ConstMemFnType = int (Dummy::*)() const;
84 
85 void foo() {}
86 
87 void test_builtin_empty_parentheses_diags() {
88   __is_trivially_copyable(); // expected-error {{expected a type}}
89   __is_trivially_copyable(1); // expected-error {{expected a type}}
90 }
91 
92 void test_builtin_launder_diags(void *vp, const void *cvp, FnType *fnp,
93                                 MemFnType mfp, ConstMemFnType cmfp, int (&Arr)[5]) {
94   __builtin_launder(vp);   // expected-error {{void pointer argument to '__builtin_launder' is not allowed}}
95   __builtin_launder(cvp);  // expected-error {{void pointer argument to '__builtin_launder' is not allowed}}
96   __builtin_launder(fnp);  // expected-error {{function pointer argument to '__builtin_launder' is not allowed}}
97   __builtin_launder(mfp);  // expected-error {{non-pointer argument to '__builtin_launder' is not allowed}}
98   __builtin_launder(cmfp); // expected-error {{non-pointer argument to '__builtin_launder' is not allowed}}
99   (void)__builtin_launder(&fnp);
100   __builtin_launder(42);      // expected-error {{non-pointer argument to '__builtin_launder' is not allowed}}
101   __builtin_launder(nullptr); // expected-error {{non-pointer argument to '__builtin_launder' is not allowed}}
102   __builtin_launder(foo);     // expected-error {{function pointer argument to '__builtin_launder' is not allowed}}
103   (void)__builtin_launder(Arr);
104 }
105 
106 void test_builtin_launder(char *p, const volatile int *ip, const float *&fp,
107                           double *__restrict dp) {
108   int x;
109   __builtin_launder(x); // expected-error {{non-pointer argument to '__builtin_launder' is not allowed}}
110 
111   TEST_TYPE(p, char*);
112   TEST_TYPE(ip, const volatile int*);
113   TEST_TYPE(fp, const float*);
114   TEST_TYPE(dp, double *__restrict);
115 
116   char *d = __builtin_launder(p);
117   const volatile int *id = __builtin_launder(ip);
118   int *id2 = __builtin_launder(ip); // expected-error {{cannot initialize a variable of type 'int *' with an rvalue of type 'const volatile int *'}}
119   const float* fd = __builtin_launder(fp);
120 }
121 
122 void test_launder_return_type(const int (&ArrayRef)[101], int (&MArrRef)[42][13],
123                               void (**&FuncPtrRef)()) {
124   TEST_TYPE(ArrayRef, const int *);
125   TEST_TYPE(MArrRef, int(*)[13]);
126   TEST_TYPE(FuncPtrRef, void (**)());
127 }
128 
129 template <class Tp>
130 constexpr Tp *test_constexpr_launder(Tp *tp) {
131   return __builtin_launder(tp);
132 }
133 constexpr int const_int = 42;
134 constexpr int const_int2 = 101;
135 constexpr const int *const_ptr = test_constexpr_launder(&const_int);
136 static_assert(&const_int == const_ptr, "");
137 static_assert(const_ptr != test_constexpr_launder(&const_int2), "");
138 
139 void test_non_constexpr() {
140   constexpr int i = 42;                            // expected-note {{address of non-static constexpr variable 'i' may differ on each invocation}}
141   constexpr const int *ip = __builtin_launder(&i); // expected-error {{constexpr variable 'ip' must be initialized by a constant expression}}
142   // expected-note@-1 {{pointer to 'i' is not a constant expression}}
143 }
144 
145 constexpr bool test_in_constexpr(const int &i) {
146   return (__builtin_launder(&i) == &i);
147 }
148 
149 static_assert(test_in_constexpr(const_int), "");
150 void f() {
151   constexpr int i = 42;
152   static_assert(test_in_constexpr(i), "");
153 }
154 
155 struct Incomplete; // expected-note {{forward declaration}}
156 struct IncompleteMember {
157   Incomplete &i;
158 };
159 void test_incomplete(Incomplete *i, IncompleteMember *im) {
160   // expected-error@+1 {{incomplete type 'Incomplete' where a complete type is required}}
161   __builtin_launder(i);
162   __builtin_launder(&i); // OK
163   __builtin_launder(im); // OK
164 }
165 
166 void test_noexcept(int *i) {
167   static_assert(noexcept(__builtin_launder(i)), "");
168 }
169 #undef TEST_TYPE
170 } // end namespace test_launder
171 
172 template<typename T> void test_builtin_complex(T v, double d) {
173   (void)__builtin_complex(v, d); // expected-error {{different types}} expected-error {{not a real floating}}
174   (void)__builtin_complex(d, v); // expected-error {{different types}} expected-error {{not a real floating}}
175   (void)__builtin_complex(v, v); // expected-error {{not a real floating}}
176 }
177 template void test_builtin_complex(double, double);
178 template void test_builtin_complex(float, double); // expected-note {{instantiation of}}
179 template void test_builtin_complex(int, double); // expected-note {{instantiation of}}
180 
181 #ifdef __x86_64__
182 // This previously would cause an assertion when emitting the note diagnostic.
183 static void __builtin_cpu_init(); // expected-error {{static declaration of '__builtin_cpu_init' follows non-static declaration}} \
184                                      expected-note {{'__builtin_cpu_init' is a builtin with type 'void () noexcept'}}
185 #endif
186 
187 #ifdef _MSC_VER
188 constexpr int x = [] {
189   __noop;
190   return 0;
191 }(); // expected-no-diagnostics
192 static_assert([] { return __noop; }() == 0);
193 static_assert([] { return __noop(4); }() == 0);
194 extern int not_accessed;
195 void not_called();
196 static_assert([] { return __noop(not_accessed *= 6); }() == 0);
197 static_assert([] { return __noop(not_called()); }() == 0);
198 static_assert([] { return __noop(throw ""); }() == 0);
199 static_assert([] { return __noop(throw "", throw ""); }() == 0);
200 static_assert([] {
201   int a = 5;
202   __noop(++a);
203   return a;
204 }() == 5);
205 #endif
206