warn-unsequenced.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -Wno-unused %s
  2. int f(int, int);
  3. typedef struct A {
  4. int x, y;
  5. } A;
  6. void test() {
  7. int a;
  8. int xs[10];
  9. a + ++a; // expected-warning {{unsequenced modification and access to 'a'}}
  10. a = ++a; // expected-warning {{multiple unsequenced modifications to 'a'}}
  11. a + a++; // expected-warning {{unsequenced modification and access to 'a'}}
  12. a = a++; // expected-warning {{multiple unsequenced modifications to 'a'}}
  13. (a++, a++); // ok
  14. ++a + ++a; // expected-warning {{multiple unsequenced modifications}}
  15. a++ + a++; // expected-warning {{multiple unsequenced modifications}}
  16. a = xs[++a]; // expected-warning {{multiple unsequenced modifications}}
  17. a = xs[a++]; // expected-warning {{multiple unsequenced modifications}}
  18. a = (++a, ++a); // expected-warning {{multiple unsequenced modifications}}
  19. a = (a++, ++a); // expected-warning {{multiple unsequenced modifications}}
  20. a = (a++, a++); // expected-warning {{multiple unsequenced modifications}}
  21. f(a, a); // ok
  22. f(a = 0, a); // expected-warning {{unsequenced modification and access}}
  23. f(a, a += 0); // expected-warning {{unsequenced modification and access}}
  24. f(a = 0, a = 0); // expected-warning {{multiple unsequenced modifications}}
  25. a = f(++a, 0); // ok
  26. a = f(a++, 0); // ok
  27. a = f(++a, a++); // expected-warning {{multiple unsequenced modifications}}
  28. ++a + f(++a, 0); // expected-warning {{multiple unsequenced modifications}}
  29. f(++a, 0) + ++a; // expected-warning {{multiple unsequenced modifications}}
  30. a++ + f(a++, 0); // expected-warning {{multiple unsequenced modifications}}
  31. f(a++, 0) + a++; // expected-warning {{multiple unsequenced modifications}}
  32. a = ++a; // expected-warning {{multiple unsequenced modifications}}
  33. a += ++a; // expected-warning {{unsequenced modification and access}}
  34. A agg1 = { a++, a++ }; // expected-warning {{multiple unsequenced modifications}}
  35. A agg2 = { a++ + a, a++ }; // expected-warning {{unsequenced modification and access}}
  36. (xs[2] && (a = 0)) + a; // ok
  37. (0 && (a = 0)) + a; // ok
  38. (1 && (a = 0)) + a; // expected-warning {{unsequenced modification and access}}
  39. (xs[3] || (a = 0)) + a; // ok
  40. (0 || (a = 0)) + a; // expected-warning {{unsequenced modification and access}}
  41. (1 || (a = 0)) + a; // ok
  42. (xs[4] ? a : ++a) + a; // ok
  43. (0 ? a : ++a) + a; // expected-warning {{unsequenced modification and access}}
  44. (1 ? a : ++a) + a; // ok
  45. (xs[5] ? ++a : ++a) + a; // FIXME: warn here
  46. (++a, xs[6] ? ++a : 0) + a; // expected-warning {{unsequenced modification and access}}
  47. // Here, the read of the fourth 'a' might happen before or after the write to
  48. // the second 'a'.
  49. a += (a++, a) + a; // expected-warning {{unsequenced modification and access}}
  50. int *p = xs;
  51. a = *(a++, p); // ok
  52. a = a++ && a; // ok
  53. A *q = &agg1;
  54. (q = &agg2)->y = q->x; // expected-warning {{unsequenced modification and access to 'q'}}
  55. // This has undefined behavior if a == 0; otherwise, the side-effect of the
  56. // increment is sequenced before the value computation of 'f(a, a)', which is
  57. // sequenced before the value computation of the '&&', which is sequenced
  58. // before the assignment. We treat the sequencing in '&&' as being
  59. // unconditional.
  60. a = a++ && f(a, a);
  61. // This has undefined behavior if a != 0. FIXME: We should diagnose this.
  62. (a && a++) + a;
  63. (xs[7] && ++a) * (!xs[7] && ++a); // ok
  64. xs[0] = (a = 1, a); // ok
  65. xs[8] ? ++a + a++ : 0; // expected-warning {{multiple unsequenced modifications}}
  66. xs[8] ? 0 : ++a + a++; // expected-warning {{multiple unsequenced modifications}}
  67. xs[8] ? ++a : a++; // ok
  68. xs[8] && (++a + a++); // expected-warning {{multiple unsequenced modifications}}
  69. xs[8] || (++a + a++); // expected-warning {{multiple unsequenced modifications}}
  70. (__builtin_classify_type(++a) ? 1 : 0) + ++a; // ok
  71. (__builtin_constant_p(++a) ? 1 : 0) + ++a; // ok
  72. (__builtin_expect(++a, 0) ? 1 : 0) + ++a; // expected-warning {{multiple unsequenced modifications}}
  73. _Generic(++a, default: 0) + ++a; // ok
  74. sizeof(++a) + ++a; // ok
  75. _Alignof(++a) + ++a; // expected-warning {{extension}}
  76. }