Clang Project

clang_source_code/test/SemaCXX/builtins.cpp
1// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++11 -fcxx-exceptions
2// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++1z -fcxx-exceptions
3typedef const struct __CFString * CFStringRef;
4#define CFSTR __builtin___CFStringMakeConstantString
5
6void f() {
7  (void)CFStringRef(CFSTR("Hello"));
8}
9
10void a() { __builtin_va_list x, y; ::__builtin_va_copy(x, y); }
11
12// <rdar://problem/10063539>
13template<int (*Compare)(const char *s1, const char *s2)>
14int equal(const char *s1, const char *s2) {
15  return Compare(s1, s2) == 0;
16}
17// FIXME: Our error recovery here sucks
18template int equal<&__builtin_strcmp>(const char*, const char*); // expected-error {{builtin functions must be directly called}} expected-error {{expected unqualified-id}} expected-error {{expected ')'}} expected-note {{to match this '('}}
19
20// PR13195
21void f2() {
22  __builtin_isnan; // expected-error {{builtin functions must be directly called}}
23}
24
25// pr14895
26typedef __typeof(sizeof(int)) size_t;
27extern "C" void *__builtin_alloca (size_t);
28
29namespace addressof {
30  struct S {} s;
31  static_assert(__builtin_addressof(s) == &s, "");
32
33  struct T { constexpr T *operator&() const { return nullptr; } int n; } t;
34  constexpr T *pt = __builtin_addressof(t);
35  static_assert(&pt->n == &t.n, "");
36
37  struct U { int n : 5; } u;
38  int *pbf = __builtin_addressof(u.n); // expected-error {{address of bit-field requested}}
39
40  S *ptmp = __builtin_addressof(S{}); // expected-error {{taking the address of a temporary}}
41}
42
43void no_ms_builtins() {
44  __assume(1); // expected-error {{use of undeclared}}
45  __noop(1); // expected-error {{use of undeclared}}
46  __debugbreak(); // expected-error {{use of undeclared}}
47}
48
49struct FILE;
50extern "C" int vfprintf(FILE *__restrict, const char *__restrict,
51                        __builtin_va_list va);
52
53void synchronize_args() {
54  __sync_synchronize(0); // expected-error {{too many arguments}}
55}
56
57namespace test_launder {
58#define TEST_TYPE(Ptr, Type) \
59  static_assert(__is_same(decltype(__builtin_launder(Ptr)), Type), "expected same type")
60
61struct Dummy {};
62
63using FnType = int(char);
64using MemFnType = int (Dummy::*)(char);
65using ConstMemFnType = int (Dummy::*)() const;
66
67void foo() {}
68
69void test_builtin_launder_diags(void *vp, const void *cvp, FnType *fnp,
70                                MemFnType mfp, ConstMemFnType cmfp, int (&Arr)[5]) {
71  __builtin_launder(vp);   // expected-error {{void pointer argument to '__builtin_launder' is not allowed}}
72  __builtin_launder(cvp);  // expected-error {{void pointer argument to '__builtin_launder' is not allowed}}
73  __builtin_launder(fnp);  // expected-error {{function pointer argument to '__builtin_launder' is not allowed}}
74  __builtin_launder(mfp);  // expected-error {{non-pointer argument to '__builtin_launder' is not allowed}}
75  __builtin_launder(cmfp); // expected-error {{non-pointer argument to '__builtin_launder' is not allowed}}
76  (void)__builtin_launder(&fnp);
77  __builtin_launder(42);      // expected-error {{non-pointer argument to '__builtin_launder' is not allowed}}
78  __builtin_launder(nullptr); // expected-error {{non-pointer argument to '__builtin_launder' is not allowed}}
79  __builtin_launder(foo);     // expected-error {{function pointer argument to '__builtin_launder' is not allowed}}
80  (void)__builtin_launder(Arr);
81}
82
83void test_builtin_launder(char *p, const volatile int *ip, const float *&fp,
84                          double *__restrict dp) {
85  int x;
86  __builtin_launder(x); // expected-error {{non-pointer argument to '__builtin_launder' is not allowed}}
87
88  TEST_TYPE(p, char*);
89  TEST_TYPE(ip, const volatile int*);
90  TEST_TYPE(fp, const float*);
91  TEST_TYPE(dp, double *__restrict);
92
93  char *d = __builtin_launder(p);
94  const volatile int *id = __builtin_launder(ip);
95  int *id2 = __builtin_launder(ip); // expected-error {{cannot initialize a variable of type 'int *' with an rvalue of type 'const volatile int *'}}
96  const float* fd = __builtin_launder(fp);
97}
98
99void test_launder_return_type(const int (&ArrayRef)[101], int (&MArrRef)[42][13],
100                              void (**&FuncPtrRef)()) {
101  TEST_TYPE(ArrayRef, const int *);
102  TEST_TYPE(MArrRef, int(*)[13]);
103  TEST_TYPE(FuncPtrRef, void (**)());
104}
105
106template <class Tp>
107constexpr Tp *test_constexpr_launder(Tp *tp) {
108  return __builtin_launder(tp);
109}
110constexpr int const_int = 42;
111constexpr int const_int2 = 101;
112constexpr const int *const_ptr = test_constexpr_launder(&const_int);
113static_assert(&const_int == const_ptr, "");
114static_assert(const_ptr != test_constexpr_launder(&const_int2), "");
115
116void test_non_constexpr() {
117  constexpr int i = 42;                            // expected-note {{declared here}}
118  constexpr const int *ip = __builtin_launder(&i); // expected-error {{constexpr variable 'ip' must be initialized by a constant expression}}
119  // expected-note@-1 {{pointer to 'i' is not a constant expression}}
120}
121
122constexpr bool test_in_constexpr(const int &i) {
123  return (__builtin_launder(&i) == &i);
124}
125
126static_assert(test_in_constexpr(const_int), "");
127void f() {
128  constexpr int i = 42;
129  static_assert(test_in_constexpr(i), "");
130}
131
132struct Incomplete; // expected-note {{forward declaration}}
133struct IncompleteMember {
134  Incomplete &i;
135};
136void test_incomplete(Incomplete *i, IncompleteMember *im) {
137  // expected-error@+1 {{incomplete type 'test_launder::Incomplete' where a complete type is required}}
138  __builtin_launder(i);
139  __builtin_launder(&i); // OK
140  __builtin_launder(im); // OK
141}
142
143void test_noexcept(int *i) {
144  static_assert(noexcept(__builtin_launder(i)), "");
145}
146#undef TEST_TYPE
147} // end namespace test_launder
148