r354151 - [Sema][NFC] SequenceChecker: Add tests for references/members, and prepare for the C++17 tests

Bruno Ricci via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 15 10:12:58 PST 2019


Author: brunoricci
Date: Fri Feb 15 10:12:58 2019
New Revision: 354151

URL: http://llvm.org/viewvc/llvm-project?rev=354151&view=rev
Log:
[Sema][NFC] SequenceChecker: Add tests for references/members, and prepare for the C++17 tests

Add some tests for unsequenced operations with members and references.
For now most of it is unhandled but it shows what work needs to be done.

Also merge the tests for the C++17 sequencing rules in warn-unsequenced.cpp
since we want to make sure that the appropriate warnings are still present
in C++17 without duplicating the whole content of warn-unsequenced.cpp.


Removed:
    cfe/trunk/test/SemaCXX/warn-unsequenced-cxx17.cpp
Modified:
    cfe/trunk/test/SemaCXX/warn-unsequenced.cpp

Removed: cfe/trunk/test/SemaCXX/warn-unsequenced-cxx17.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-unsequenced-cxx17.cpp?rev=354150&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-unsequenced-cxx17.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-unsequenced-cxx17.cpp (removed)
@@ -1,8 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 -Wno-unused %s
-
-void test() {
-  int xs[10];
-  int *p = xs;
-  // expected-no-diagnostics
-  p[(long long unsigned)(p = 0)]; // ok
-}

Modified: cfe/trunk/test/SemaCXX/warn-unsequenced.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-unsequenced.cpp?rev=354151&r1=354150&r2=354151&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-unsequenced.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-unsequenced.cpp Fri Feb 15 10:12:58 2019
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wno-unused %s
+// RUN: %clang_cc1 -fsyntax-only -verify=cxx11 -std=c++11 -Wno-unused -Wno-uninitialized -Wunsequenced %s
+// RUN: %clang_cc1 -fsyntax-only -verify=cxx17 -std=c++17 -Wno-unused -Wno-uninitialized -Wunsequenced %s
 
 int f(int, int = 0);
 
@@ -10,81 +11,107 @@ struct S {
   int n;
 };
 
+// TODO: Implement the C++17 sequencing rules.
 void test() {
   int a;
   int xs[10];
   ++a = 0; // ok
-  a + ++a; // expected-warning {{unsequenced modification and access to 'a'}}
+  a + ++a; // cxx11-warning {{unsequenced modification and access to 'a'}}
+           // cxx17-warning at -1 {{unsequenced modification and access to 'a'}}
   a = ++a; // ok
-  a + a++; // expected-warning {{unsequenced modification and access to 'a'}}
-  a = a++; // expected-warning {{multiple unsequenced modifications to 'a'}}
+  a + a++; // cxx11-warning {{unsequenced modification and access to 'a'}}
+           // cxx17-warning at -1 {{unsequenced modification and access to 'a'}}
+  a = a++; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+           // TODO cxx17-warning at -1 {{multiple unsequenced modifications to 'a'}}
   ++ ++a; // ok
   (a++, a++); // ok
-  ++a + ++a; // expected-warning {{multiple unsequenced modifications to 'a'}}
-  a++ + a++; // expected-warning {{multiple unsequenced modifications}}
+  ++a + ++a; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+             // cxx17-warning at -1 {{multiple unsequenced modifications to 'a'}}
+  a++ + a++; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+             // cxx17-warning at -1 {{multiple unsequenced modifications to 'a'}}
   (a++, a) = 0; // ok, increment is sequenced before value computation of LHS
   a = xs[++a]; // ok
-  a = xs[a++]; // expected-warning {{multiple unsequenced modifications}}
-  (a ? xs[0] : xs[1]) = ++a; // expected-warning {{unsequenced modification and access}}
+  a = xs[a++]; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+               // TODO cxx17-warning at -1 {{multiple unsequenced modifications to 'a'}}
+  (a ? xs[0] : xs[1]) = ++a; // cxx11-warning {{unsequenced modification and access to 'a'}}
+                             // TODO cxx17-warning at -1 {{unsequenced modification and access to 'a'}}
   a = (++a, ++a); // ok
   a = (a++, ++a); // ok
-  a = (a++, a++); // expected-warning {{multiple unsequenced modifications}}
+  a = (a++, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+                  // TODO cxx17-warning at -1 {{multiple unsequenced modifications to 'a'}}
   f(a, a); // ok
-  f(a = 0, a); // expected-warning {{unsequenced modification and access}}
-  f(a, a += 0); // expected-warning {{unsequenced modification and access}}
-  f(a = 0, a = 0); // expected-warning {{multiple unsequenced modifications}}
+  f(a = 0, a); // cxx11-warning {{unsequenced modification and access to 'a'}}
+               // cxx17-warning at -1 {{unsequenced modification and access to 'a'}}
+  f(a, a += 0); // cxx11-warning {{unsequenced modification and access to 'a'}}
+                // cxx17-warning at -1 {{unsequenced modification and access to 'a'}}
+  f(a = 0, a = 0); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+                   // cxx17-warning at -1 {{multiple unsequenced modifications to 'a'}}
   a = f(++a); // ok
   a = f(a++); // ok
-  a = f(++a, a++); // expected-warning {{multiple unsequenced modifications}}
+  a = f(++a, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+                   // cxx17-warning at -1 {{multiple unsequenced modifications to 'a'}}
 
   // Compound assignment "A OP= B" is equivalent to "A = A OP B" except that A
   // is evaluated only once.
   (++a, a) = 1; // ok
   (++a, a) += 1; // ok
   a = ++a; // ok
-  a += ++a; // expected-warning {{unsequenced modification and access}}
+  a += ++a; // cxx11-warning {{unsequenced modification and access to 'a'}}
+            // TODO cxx17-warning at -1 {{unsequenced modification and access to 'a'}}
 
   A agg1 = { a++, a++ }; // ok
-  A agg2 = { a++ + a, a++ }; // expected-warning {{unsequenced modification and access}}
+  A agg2 = { a++ + a, a++ }; // cxx11-warning {{unsequenced modification and access to 'a'}}
+                             // cxx17-warning at -1 {{unsequenced modification and access to 'a'}}
 
-  S str1(a++, a++); // expected-warning {{multiple unsequenced modifications}}
+  S str1(a++, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+                    // cxx17-warning at -1 {{multiple unsequenced modifications to 'a'}}
   S str2 = { a++, a++ }; // ok
-  S str3 = { a++ + a, a++ }; // expected-warning {{unsequenced modification and access}}
+  S str3 = { a++ + a, a++ }; // cxx11-warning {{unsequenced modification and access to 'a'}}
+                             // cxx17-warning at -1 {{unsequenced modification and access to 'a'}}
 
   struct Z { A a; S s; } z = { { ++a, ++a }, { ++a, ++a } }; // ok
   a = S { ++a, a++ }.n; // ok
   A { ++a, a++ }.x; // ok
-  a = A { ++a, a++ }.x; // expected-warning {{unsequenced modifications}}
-  A { ++a, a++ }.x + A { ++a, a++ }.y; // expected-warning {{unsequenced modifications}}
+  a = A { ++a, a++ }.x; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+                        // TODO cxx17-warning at -1 {{multiple unsequenced modifications to 'a'}}
+  A { ++a, a++ }.x + A { ++a, a++ }.y; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+                                       // cxx17-warning at -1 {{multiple unsequenced modifications to 'a'}}
 
   (xs[2] && (a = 0)) + a; // ok
   (0 && (a = 0)) + a; // ok
-  (1 && (a = 0)) + a; // expected-warning {{unsequenced modification and access}}
+  (1 && (a = 0)) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
+                      // cxx17-warning at -1 {{unsequenced modification and access to 'a'}}
 
   (xs[3] || (a = 0)) + a; // ok
-  (0 || (a = 0)) + a; // expected-warning {{unsequenced modification and access}}
+  (0 || (a = 0)) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
+                      // cxx17-warning at -1 {{unsequenced modification and access to 'a'}}
   (1 || (a = 0)) + a; // ok
 
   (xs[4] ? a : ++a) + a; // ok
-  (0 ? a : ++a) + a; // expected-warning {{unsequenced modification and access}}
+  (0 ? a : ++a) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
+                     // cxx17-warning at -1 {{unsequenced modification and access to 'a'}}
   (1 ? a : ++a) + a; // ok
-  (0 ? a : a++) + a; // expected-warning {{unsequenced modification and access}}
+  (0 ? a : a++) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
+                     // cxx17-warning at -1 {{unsequenced modification and access to 'a'}}
   (1 ? a : a++) + a; // ok
   (xs[5] ? ++a : ++a) + a; // FIXME: warn here
 
-  (++a, xs[6] ? ++a : 0) + a; // expected-warning {{unsequenced modification and access}}
+  (++a, xs[6] ? ++a : 0) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
+                              // cxx17-warning at -1 {{unsequenced modification and access to 'a'}}
 
   // Here, the read of the fourth 'a' might happen before or after the write to
   // the second 'a'.
-  a += (a++, a) + a; // expected-warning {{unsequenced modification and access}}
+  a += (a++, a) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
+                     // cxx17-warning at -1 {{unsequenced modification and access to 'a'}}
 
   int *p = xs;
   a = *(a++, p); // ok
   a = a++ && a; // ok
-  p[(long long unsigned)(p = 0)]; // expected-warning {{unsequenced modification and access to 'p'}}
+  p[(long long unsigned)(p = 0)]; // cxx11-warning {{unsequenced modification and access to 'p'}}
 
   A *q = &agg1;
-  (q = &agg2)->y = q->x; // expected-warning {{unsequenced modification and access to 'q'}}
+  (q = &agg2)->y = q->x; // cxx11-warning {{unsequenced modification and access to 'q'}}
+                         // TODO cxx17-warning at -1 {{unsequenced modification and access to 'q'}}
 
   // This has undefined behavior if a == 0; otherwise, the side-effect of the
   // increment is sequenced before the value computation of 'f(a, a)', which is
@@ -102,19 +129,196 @@ void test() {
   (a -= 128) &= 128; // ok
   ++a += 1; // ok
 
-  xs[8] ? ++a + a++ : 0; // expected-warning {{multiple unsequenced modifications}}
-  xs[8] ? 0 : ++a + a++; // expected-warning {{multiple unsequenced modifications}}
+  xs[8] ? ++a + a++ : 0; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+                         // cxx17-warning at -1 {{multiple unsequenced modifications to 'a'}}
+  xs[8] ? 0 : ++a + a++; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+                         // cxx17-warning at -1 {{multiple unsequenced modifications to 'a'}}
   xs[8] ? ++a : a++; // ok
 
-  xs[8] && (++a + a++); // expected-warning {{multiple unsequenced modifications}}
-  xs[8] || (++a + a++); // expected-warning {{multiple unsequenced modifications}}
+  xs[8] && (++a + a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+                        // cxx17-warning at -1 {{multiple unsequenced modifications to 'a'}}
+  xs[8] || (++a + a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+                        // cxx17-warning at -1 {{multiple unsequenced modifications to 'a'}}
 
   (__builtin_classify_type(++a) ? 1 : 0) + ++a; // ok
   (__builtin_constant_p(++a) ? 1 : 0) + ++a; // ok
   (__builtin_object_size(&(++a, a), 0) ? 1 : 0) + ++a; // ok
-  (__builtin_expect(++a, 0) ? 1 : 0) + ++a; // expected-warning {{multiple unsequenced modifications}}
+  (__builtin_expect(++a, 0) ? 1 : 0) + ++a; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+                                            // cxx17-warning at -1 {{multiple unsequenced modifications to 'a'}}
 }
 
+namespace members {
+
+struct S1 {
+  unsigned bf1 : 2;
+  unsigned bf2 : 2;
+  unsigned a;
+  unsigned b;
+
+  void member_f(S1 &s);
+};
+
+void S1::member_f(S1 &s) {
+  int xs[10];
+
+  ++a + ++a; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+             // cxx17-warning at -1 {{multiple unsequenced modifications to 'a'}}
+  a + ++a; // cxx11-warning {{unsequenced modification and access to 'a'}}
+           // cxx17-warning at -1 {{unsequenced modification and access to 'a'}}
+  ++a + ++b; // no-warning
+  a + ++b; // no-warning
+
+  // TODO: Warn here.
+  ++s.a + ++s.a; // no-warning TODO {{multiple unsequenced modifications to}}
+  s.a + ++s.a; // no-warning TODO {{unsequenced modification and access to}}
+  ++s.a + ++s.b; // no-warning
+  s.a + ++s.b; // no-warning
+
+  ++a + ++s.a; // no-warning
+  a + ++s.a; // no-warning
+  ++a + ++s.b; // no-warning
+  a + ++s.b; // no-warning
+
+  // TODO Warn here for bit-fields in the same memory location.
+  ++bf1 + ++bf1; // cxx11-warning {{multiple unsequenced modifications to 'bf1'}}
+                 // cxx17-warning at -1 {{multiple unsequenced modifications to 'bf1'}}
+  bf1 + ++bf1; // cxx11-warning {{unsequenced modification and access to 'bf1'}}
+               // cxx17-warning at -1 {{unsequenced modification and access to 'bf1'}}
+  ++bf1 + ++bf2; // no-warning TODO {{multiple unsequenced modifications to}}
+  bf1 + ++bf2; // no-warning TODO {{unsequenced modification and access to}}
+
+  // TODO Warn here for bit-fields in the same memory location.
+  ++s.bf1 + ++s.bf1; // no-warning TODO {{multiple unsequenced modifications to}}
+  s.bf1 + ++s.bf1; // no-warning TODO {{unsequenced modification and access to}}
+  ++s.bf1 + ++s.bf2; // no-warning TODO {{multiple unsequenced modifications to}}
+  s.bf1 + ++s.bf2; // no-warning TODO {{unsequenced modification and access to}}
+
+  ++bf1 + ++s.bf1; // no-warning
+  bf1 + ++s.bf1; // no-warning
+  ++bf1 + ++s.bf2; // no-warning
+  bf1 + ++s.bf2; // no-warning
+}
+
+struct S2 {
+  union { unsigned x, y; };
+  void f2();
+};
+
+void S2::f2() {
+  ++x + ++x; // no-warning TODO {{multiple unsequenced modifications to}}
+  x + ++x; // no-warning TODO {{unsequenced modification and access to}}
+  ++x + ++y; // no-warning
+  x + ++y; // no-warning
+}
+
+void f2(S2 &s) {
+  ++s.x + ++s.x; // no-warning TODO {{multiple unsequenced modifications to}}
+  s.x + ++s.x; // no-warning TODO {{unsequenced modification and access to}}
+  ++s.x + ++s.y; // no-warning
+  s.x + ++s.y; // no-warning
+}
+
+struct S3 {
+  union {
+    union {
+      unsigned x;
+    };
+  };
+  unsigned y;
+  void f3();
+};
+
+void S3::f3() {
+  ++x + ++x; // no-warning TODO {{multiple unsequenced modifications to}}
+  x + ++x; // no-warning TODO {{unsequenced modification and access to}}
+  ++x + ++y; // no-warning
+  x + ++y; // no-warning
+}
+
+void f3(S3 &s) {
+  ++s.x + ++s.x; // no-warning TODO {{multiple unsequenced modifications to}}
+  s.x + ++s.x; // no-warning TODO {{unsequenced modification and access to}}
+  ++s.x + ++s.y; // no-warning
+  s.x + ++s.y; // no-warning
+}
+
+struct S4 : S3 {
+  unsigned y;
+  void f4();
+};
+
+void S4::f4() {
+  ++x + ++x; // no-warning TODO {{multiple unsequenced modifications to}}
+  x + ++x; // no-warning TODO {{unsequenced modification and access to}}
+  ++x + ++y; // no-warning
+  x + ++y; // no-warning
+  ++S3::y + ++y; // no-warning
+  S3::y + ++y; // no-warning
+}
+
+void f4(S4 &s) {
+  ++s.x + ++s.x; // no-warning TODO {{multiple unsequenced modifications to}}
+  s.x + ++s.x; // no-warning TODO {{unsequenced modification and access to}}
+  ++s.x + ++s.y; // no-warning
+  s.x + ++s.y; // no-warning
+  ++s.S3::y + ++s.y; // no-warning
+  s.S3::y + ++s.y; // no-warning
+}
+
+static union {
+  unsigned Ux;
+  unsigned Uy;
+};
+
+void f5() {
+  ++Ux + ++Ux; // no-warning TODO {{multiple unsequenced modifications to}}
+  Ux + ++Ux; // no-warning TODO {{unsequenced modification and access to}}
+  ++Ux + ++Uy; // no-warning
+  Ux + ++Uy; // no-warning
+}
+
+void f6() {
+  struct S { unsigned x, y; } s;
+  ++s.x + ++s.x; // no-warning TODO {{multiple unsequenced modifications to}}
+  s.x + ++s.x; // no-warning TODO {{unsequenced modification and access to}}
+  ++s.x + ++s.y; // no-warning
+  s.x + ++s.y; // no-warning
+
+  struct { unsigned x, y; } t;
+  ++t.x + ++t.x; // no-warning TODO {{multiple unsequenced modifications to}}
+  t.x + ++t.x; // no-warning TODO {{unsequenced modification and access to}}
+  ++t.x + ++t.y; // no-warning
+  t.x + ++t.y; // no-warning
+}
+
+} // namespace members
+
+namespace references {
+void reference_f() {
+  // TODO: Check that we can see through references.
+  // For now this is completely unhandled.
+  int a;
+  int xs[10];
+  int &b = a;
+  int &c = b;
+  int &ra1 = c;
+  int &ra2 = b;
+  int other;
+
+  ++ra1 + ++ra2; // no-warning TODO {{multiple unsequenced modifications to}}
+  ra1 + ++ra2; // no-warning TODO {{unsequenced modification and access to}}
+  ++ra1 + ++other; // no-warning
+  ra1 + ++other; // no-warning
+
+  // Make sure we handle reference cycles.
+  int &ref_cycle = ref_cycle;
+  ++ref_cycle + ++ref_cycle; // cxx11-warning {{multiple unsequenced modifications to 'ref_cycle'}}
+                             // cxx17-warning at -1 {{multiple unsequenced modifications to 'ref_cycle'}}
+  ref_cycle + ++ref_cycle; // cxx11-warning {{unsequenced modification and access to 'ref_cycle'}}
+                           // cxx17-warning at -1 {{unsequenced modification and access to 'ref_cycle'}}
+}
+} // namespace references
+
 namespace templates {
 
 template <typename T>
@@ -146,26 +350,31 @@ int Foo<X>::Run() {
   if (static_cast<E>((num = bar.get()) < 5) || static_cast<E>(num < 10)) { }
 
   if (static_cast<E>((num = bar.get()) < 5) && static_cast<E>(num < 10)) { }
-  // expected-warning at -1 {{unsequenced modification and access to 'num'}}
+  // cxx11-warning at -1 {{unsequenced modification and access to 'num'}}
+  // cxx17-warning at -2 {{unsequenced modification and access to 'num'}}
 
   foo(num++, num++);
-  // expected-warning at -1 2{{multiple unsequenced modifications to 'num'}}
+  // cxx11-warning at -1 2{{multiple unsequenced modifications to 'num'}}
+  // cxx17-warning at -2 2{{multiple unsequenced modifications to 'num'}}
   return 1;
 }
 
 int x = Foo<int>().Run();
-// expected-note at -1 {{in instantiation of member function 'templates::Foo<int>::Run'}}
+// cxx11-note at -1 {{in instantiation of member function 'templates::Foo<int>::Run'}}
+// cxx17-note at -2 {{in instantiation of member function 'templates::Foo<int>::Run'}}
 
 
 template <typename T>
 int Run2() {
   T t = static_cast<T>(0);
   return (t = static_cast<T>(1)) && t;
-  // expected-warning at -1 {{unsequenced modification and access to 't'}}
+  // cxx11-warning at -1 {{unsequenced modification and access to 't'}}
+  // cxx17-warning at -2 {{unsequenced modification and access to 't'}}
 }
 
 int y = Run2<bool>();
 int z = Run2<E>();
-// expected-note at -1{{in instantiation of function template specialization 'templates::Run2<templates::E>' requested here}}
+// cxx11-note at -1{{in instantiation of function template specialization 'templates::Run2<templates::E>' requested here}}
+// cxx17-note at -2{{in instantiation of function template specialization 'templates::Run2<templates::E>' requested here}}
 
 }




More information about the cfe-commits mailing list