brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.6 KiB · 9ef5510 Raw
247 lines · c
1// RUN: %clang_cc1 %s -verify=expected,access -fsyntax-only2// RUN: %clang_cc1 %s -std=c2x -verify=expected,access -fsyntax-only3// RUN: %clang_cc1 %s -std=c2x -pedantic -verify=expected,access -fsyntax-only4// RUN: %clang_cc1 %s -verify -fsyntax-only -Wno-atomic-access5// RUN: %clang_cc1 %s -verify=expected,access -fsyntax-only -fexperimental-new-constant-interpreter6// RUN: %clang_cc1 %s -std=c2x -verify=expected,access -fsyntax-only -fexperimental-new-constant-interpreter7// RUN: %clang_cc1 %s -std=c2x -pedantic -verify=expected,access -fsyntax-only -fexperimental-new-constant-interpreter8// RUN: %clang_cc1 %s -verify -fsyntax-only -Wno-atomic-access -fexperimental-new-constant-interpreter9 10 11_Atomic(unsigned int) data1;12int _Atomic data2;13 14// Shift operations15 16int func_01 (int x) {17  return data1 << x;18}19 20int func_02 (int x) {21  return x << data1;22}23 24int func_03 (int x) {25  return data2 << x;26}27 28int func_04 (int x) {29  return x << data2;30}31 32int func_05 (void) {33  return data2 << data1;34}35 36int func_06 (void) {37  return data1 << data2;38}39 40void func_07 (int x) {41  data1 <<= x;42}43 44void func_08 (int x) {45  data2 <<= x;46}47 48void func_09 (int* xp) {49  *xp <<= data1;50}51 52void func_10 (int* xp) {53  *xp <<= data2;54}55 56int func_11 (int x) {57  return data1 == x;58}59 60int func_12 (void) {61  return data1 < data2;62}63 64int func_13 (int x, unsigned y) {65  return x ? data1 : y;66}67 68int func_14 (void) {69  return data1 == 0;70}71 72void func_15(void) {73  // Ensure that the result of an assignment expression properly strips the74  // _Atomic qualifier; Issue 48742.75  _Atomic int x;76  int y = (x = 2);77  int z = (int)(x = 2);78  y = (x = 2);79  z = (int)(x = 2);80  y = (x += 2);81 82  _Static_assert(__builtin_types_compatible_p(__typeof__(x = 2), int), "incorrect");83  _Static_assert(__builtin_types_compatible_p(__typeof__(x += 2), int), "incorrect");84}85 86// Ensure that member access of an atomic structure or union type is properly87// diagnosed as being undefined behavior; Issue 54563.88void func_16(void) {89  // LHS member access.90  _Atomic struct { int val; } x, *xp;91  x.val = 12;   // access-error {{accessing a member of an atomic structure or union is undefined behavior}}92  xp->val = 12; // access-error {{accessing a member of an atomic structure or union is undefined behavior}}93 94  _Atomic union {95    int ival;96    float fval;97  } y, *yp;98  y.ival = 12;     // access-error {{accessing a member of an atomic structure or union is undefined behavior}}99  yp->fval = 1.2f; // access-error {{accessing a member of an atomic structure or union is undefined behavior}}100 101  // RHS member access.102  int xval = x.val; // access-error {{accessing a member of an atomic structure or union is undefined behavior}}103  xval = xp->val;   // access-error {{accessing a member of an atomic structure or union is undefined behavior}}104  int yval = y.ival; // access-error {{accessing a member of an atomic structure or union is undefined behavior}}105  yval = yp->ival;   // access-error {{accessing a member of an atomic structure or union is undefined behavior}}106 107  // Using the type specifier instead of the type qualifier.108  _Atomic(struct { int val; }) z;109  z.val = 12;       // access-error {{accessing a member of an atomic structure or union is undefined behavior}}110  int zval = z.val; // access-error {{accessing a member of an atomic structure or union is undefined behavior}}111 112  // Don't diagnose in an unevaluated context, however.113  (void)sizeof(x.val);114  (void)sizeof(xp->val);115  (void)sizeof(y.ival);116  (void)sizeof(yp->ival);117 118  // Also, do not diagnose in unreachable code paths.119  {120    if (0) {121      x.val = 12;122      xp->val = 12;123      (void)y.ival;124      (void)yp->ival;125    }126 127    return;128 129    x.val = 12;130    xp->val = 12;131    (void)y.ival;132    (void)yp->ival;133  }134}135 136// Ensure that we correctly implement assignment constraints from C2x 6.5.16.1.137void func_17(void) {138  // The left operand has atomic ... arithmetic type, and the right operand has139  // arithmetic type;140  _Atomic int i = 0;141  _Atomic float f = 0.0f;142 143  // the left operand has an atomic ... version of a structure or union type144  // compatible with the type of the right operand;145  struct S { int i; } non_atomic_s;146  _Atomic struct S s = non_atomic_s;147 148  union U { int i; float f; } non_atomic_u;149  _Atomic union U u = non_atomic_u;150 151  // the left operand has atomic ... pointer type, and (considering the type152  // the left operand would have after lvalue conversion) both operands are153  // pointers to qualified or unqualified versions of compatible types, and the154  // type pointed to by the left operand has all the qualifiers of the type155  // pointed to by the right operand;156  const int *cip = 0;157  volatile const int *vcip = 0;158  const int * const cicp = 0;159  _Atomic(const int *) acip = cip;160  _Atomic(const int *) bad_acip = vcip; // expected-warning {{initializing '_Atomic(const int *)' with an expression of type 'const volatile int *' discards qualifiers}}161  _Atomic(const int *) acip2 = cicp;162  _Atomic(int *) aip = &i; // expected-error {{incompatible pointer types initializing '_Atomic(int *)' with an expression of type '_Atomic(int) *'}} \163 164  // the left operand has atomic ... pointer type, and (considering the type165  // the left operand would have after lvalue conversion) one operand is a166  // pointer to an object type, and the other is a pointer to a qualified or167  // unqualified version of void, and the type pointed to by the left operand168  // has all the qualifiers of the type pointed to by the right operand;169  const void *cvp = 0;170  _Atomic(const int *) acip3 = cvp;171  _Atomic(const void *) acvip = cip;172  _Atomic(const int *) acip4 = vcip;   // expected-warning {{initializing '_Atomic(const int *)' with an expression of type 'const volatile int *' discards qualifiers}}173  _Atomic(const void *) acvip2 = vcip; // expected-warning {{initializing '_Atomic(const void *)' with an expression of type 'const volatile int *' discards qualifiers}}174  _Atomic(const int *) acip5 = cicp;175  _Atomic(const void *) acvip3 = cicp;176 177#if __STDC_VERSION__ >= 202311L178  // the left operand has an atomic ... version of the nullptr_t type and the179  // right operand is a null pointer constant or its type is nullptr_t180  typedef typeof(nullptr) nullptr_t;181  nullptr_t n;182  _Atomic nullptr_t cn2 = n;183  _Atomic nullptr_t cn3 = nullptr;184#endif // __STDC_VERSION__ >= 202311L185 186  // the left operand is an atomic ... pointer, and the right operand is a null187  // pointer constant or its type is nullptr_t;188  _Atomic(int *) aip2 = 0;189#if __STDC_VERSION__ >= 202311L190  _Atomic(int *) ip2 = n;191  _Atomic(int *) ip3 = nullptr;192  _Atomic(const int *) ip4 = nullptr;193#endif // __STDC_VERSION__ >= 202311L194}195 196// Ensure that the assignment constraints also work at file scope.197_Atomic int ai = 0;198_Atomic float af = 0.0f;199_Atomic(int *) aip1 = 0;200 201struct S { int a; } non_atomic_s;202_Atomic struct S as = non_atomic_s; // expected-error {{initializer element is not a compile-time constant}}203 204const int *cip = 0;205_Atomic(const int *) acip1 = cip; // expected-error {{initializer element is not a compile-time constant}}206 207const void *cvp = 0;208_Atomic(const int *) acip2 = cvp; // expected-error {{initializer element is not a compile-time constant}}209 210#if __STDC_VERSION__ >= 202311L211  // the left operand has an atomic ... version of the nullptr_t type and the212  // right operand is a null pointer constant or its type is nullptr_t213  typedef typeof(nullptr) nullptr_t;214  nullptr_t n;215  _Atomic nullptr_t cn2 = n; // expected-error {{initializer element is not a compile-time constant}}216  _Atomic(int *) aip2 = nullptr;217#endif // __STDC_VERSION__ >= 202311L218 219// FIXME: &ai is an address constant, so this should be accepted as an220// initializer, but the bit-cast inserted due to the pointer conversion is221// tripping up the test for whether the initializer is a constant expression.222// The warning is correct but the error is not.223_Atomic(int *) aip3 = &ai; /* expected-error {{incompatible pointer types initializing '_Atomic(int *)' with an expression of type '_Atomic(int) *'}}224                              expected-error {{initializer element is not a compile-time constant}}225                            */226 227// Test the behavior when converting the null pointer constant to an atomic228// function pointer.229_Atomic(int (*)(char)) afp = (void *)0;230 231void func_18(void) {232  // Ensure we can cast to atomic scalar types.233  data2 = (_Atomic int)0;234  (void)(_Atomic(int *))0;235 236  // But that we correctly reject casts to atomic aggregate types.237  struct S { int a; } s;238  struct T { int a; };239  (void)(_Atomic struct T)s; // expected-error {{used type 'struct T' where arithmetic or pointer type is required}}240}241 242// Test if we can handle an _Atomic qualified integer in a switch statement.243void func_19(void) {244  _Atomic int a = 0;245  switch (a) { }246}247