riccibruno created this revision.
riccibruno added reviewers: aaron.ballman, rsmith.
riccibruno added a project: clang.
Herald added a subscriber: cfe-commits.
Tests for D57660 <https://reviews.llvm.org/D57660>.
Repository:
rC Clang
https://reviews.llvm.org/D57661
Files:
test/SemaCXX/warn-unsequenced.cpp
Index: test/SemaCXX/warn-unsequenced.cpp
===================================================================
--- test/SemaCXX/warn-unsequenced.cpp
+++ test/SemaCXX/warn-unsequenced.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wno-unused %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wno-unused -Wno-uninitialized -Wunsequenced %s
int f(int, int = 0);
@@ -21,62 +21,62 @@
++ ++a; // ok
(a++, a++); // ok
++a + ++a; // expected-warning {{multiple unsequenced modifications to 'a'}}
- a++ + a++; // expected-warning {{multiple unsequenced modifications}}
+ a++ + a++; // expected-warning {{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++]; // expected-warning {{multiple unsequenced modifications to 'a'}}
+ (a ? xs[0] : xs[1]) = ++a; // expected-warning {{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++); // expected-warning {{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); // expected-warning {{unsequenced modification and access to 'a'}}
+ f(a, a += 0); // expected-warning {{unsequenced modification and access to 'a'}}
+ f(a = 0, a = 0); // expected-warning {{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++); // expected-warning {{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; // expected-warning {{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++ }; // expected-warning {{unsequenced modification and access to 'a'}}
- S str1(a++, a++); // expected-warning {{multiple unsequenced modifications}}
+ S str1(a++, a++); // expected-warning {{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++ }; // expected-warning {{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; // expected-warning {{unsequenced modifications to 'a'}}
+ A { ++a, a++ }.x + A { ++a, a++ }.y; // expected-warning {{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; // expected-warning {{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; // expected-warning {{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; // expected-warning {{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; // expected-warning {{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; // expected-warning {{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; // expected-warning {{unsequenced modification and access to 'a'}}
int *p = xs;
a = *(a++, p); // ok
@@ -102,19 +102,224 @@
(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; // expected-warning {{multiple unsequenced modifications to 'a'}}
+ xs[8] ? 0 : ++a + a++; // expected-warning {{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++); // expected-warning {{multiple unsequenced modifications to 'a'}}
+ xs[8] || (++a + a++); // expected-warning {{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; // expected-warning {{multiple unsequenced modifications to 'a'}}
}
+namespace members {
+
+struct S {
+ unsigned bf1 : 2;
+ unsigned bf2 : 2;
+ unsigned a;
+ unsigned b;
+
+ void member_f(S &s);
+};
+
+void S::member_f(S &s) {
+ int xs[10];
+
+ // Operations with a single member of the implicit object.
+ ++a = 0; // no-warning
+ a + ++a; // expected-warning {{unsequenced modification and access to 'a'}}
+ a = ++a; // no-warning
+ a + a++; // expected-warning {{unsequenced modification and access to 'a'}}
+ a = a++; // expected-warning {{multiple unsequenced modifications to 'a'}}
+ ++ ++a; // no-warning
+ (a++, a++); // no-warning
+ ++a + ++a; // expected-warning {{multiple unsequenced modifications to 'a'}}
+ a++ + a++; // expected-warning {{multiple unsequenced modifications to 'a'}}
+ (a++, a) = 0; // no-warning
+ a = xs[++a]; // no-warning
+ a = xs[a++]; // expected-warning {{multiple unsequenced modifications to 'a'}}
+ (a ? xs[0] : xs[1]) = ++a; // expected-warning {{unsequenced modification and access to 'a'}}
+ a = (++a, ++a); // no-warning
+ a = (a++, ++a); // no-warning
+ a = (a++, a++); // expected-warning {{multiple unsequenced modifications to 'a'}}
+ f(a, a); // no-warning
+ f(a = 0, a); // expected-warning {{unsequenced modification and access to 'a'}}
+ f(a, a += 0); // expected-warning {{unsequenced modification and access to 'a'}}
+ f(a = 0, a = 0); // expected-warning {{multiple unsequenced modifications to 'a'}}
+ a = f(++a); // no-warning
+ a = f(a++); // no-warning
+ a = f(++a, a++); // expected-warning {{multiple unsequenced modifications to 'a'}}
+
+ // Operations with a single member of the other object 's'.
+ // TODO: For now this is completely unhandled.
+ ++s.a = 0; // no-warning
+ s.a + ++s.a; // no-warning TODO {{unsequenced modification and access to }}
+ s.a = ++s.a; // no-warning
+ s.a + s.a++; // no-warning TODO {{unsequenced modification and access to }}
+ s.a = s.a++; // no-warning TODO {{multiple unsequenced modifications to }}
+ ++ ++s.a; // no-warning
+ (s.a++, s.a++); // no-warning
+ ++s.a + ++s.a; // no-warning TODO {{multiple unsequenced modifications to }}
+ s.a++ + s.a++; // no-warning TODO {{multiple unsequenced modifications to }}
+ (s.a++, s.a) = 0; // no-warning
+ s.a = xs[++s.a]; // no-warning
+ s.a = xs[s.a++]; // no-warning TODO {{multiple unsequenced modifications to }}
+ (s.a ? xs[0] : xs[1]) = ++s.a; // no-warning TODO {{unsequenced modification and access to }}
+ s.a = (++s.a, ++s.a); // no-warning
+ s.a = (s.a++, ++s.a); // no-warning
+ s.a = (s.a++, s.a++); // no-warning TODO {{multiple unsequenced modifications to }}
+ f(s.a, s.a); // no-warning
+ f(s.a = 0, s.a); // no-warning TODO {{unsequenced modification and access to }}
+ f(s.a, s.a += 0); // no-warning TODO {{unsequenced modification and access to }}
+ f(s.a = 0, s.a = 0); // no-warning TODO {{multiple unsequenced modifications to }}
+ s.a = f(++s.a); // no-warning
+ s.a = f(s.a++); // no-warning
+ s.a = f(++s.a, s.a++); // no-warning TODO {{multiple unsequenced modifications to }}
+
+ // Operations with two distinct members of the implicit object. All of them are fine.
+ a + ++b; // no-warning
+ a = ++b; // no-warning
+ a + b++; // no-warning
+ a = b++; // no-warning
+ (a++, b++); // no-warning
+ ++a + ++b; // no-warning
+ a++ + b++; // no-warning
+ (a++, b) = 0; // no-warning
+ a = xs[++b]; // no-warning
+ a = xs[b++]; // no-warning
+ (a ? xs[0] : xs[1]) = ++b; // no-warning
+ a = (++a, ++b); // no-warning
+ a = (a++, ++b); // no-warning
+ a = (a++, b++); // no-warning
+ f(a, b); // no-warning
+ f(a = 0, b); // no-warning
+ f(a, b += 0); // no-warning
+ f(a = 0, b = 0); // no-warning
+ a = f(++b); // no-warning
+ a = f(b++); // no-warning
+ a = f(++b, a++); // warning
+
+ // Operations with the same member of two distinct objects. All of them are fine.
+ a + ++s.a; // no-warning
+ a = ++s.a; // no-warning
+ a + s.a++; // no-warning
+ a = s.a++; // no-warning
+ (a++, s.a++); // no-warning
+ ++a + ++s.a; // no-warning
+ a++ + s.a++; // no-warning
+ (a++, s.a) = 0; // no-warning
+ a = xs[++s.a]; // no-warning
+ a = xs[s.a++]; // no-warning
+ (a ? xs[0] : xs[1]) = ++s.a; // no-warning
+ a = (++a, ++s.a); // no-warning
+ a = (a++, ++s.a); // no-warning
+ a = (a++, s.a++); // no-warning
+ f(a, s.a); // no-warning
+ f(a = 0, s.a); // no-warning
+ f(a, s.a += 0); // no-warning
+ f(a = 0, s.a = 0); // no-warning
+ a = f(++s.a); // no-warning
+ a = f(s.a++); // no-warning
+ a = f(++s.a, a++); // warning
+
+ // Operations with two distinct bit-fields which are part of the same
+ // memory location. TODO: We should warn as if they were the same member
+ // since the sequenced-before partial order is defined in terms of memory
+ // locations.
+ ++bf1 = 0; // no-warning
+ bf1 + ++bf2; // no-warning TODO {{unsequenced modification and access to }}
+ bf1 = ++bf2; // no-warning
+ bf1 + bf2++; // no-warning TODO {{unsequenced modification and access to }}
+ bf1 = bf2++; // no-warning TODO {{multiple unsequenced modifications to }}
+ ++ ++bf1; // no-warning
+ (bf1++, bf2++); // no-warning
+ ++bf1 + ++bf2; // no-warning TODO {{multiple unsequenced modifications to }}
+ bf1++ + bf2++; // no-warning TODO {{multiple unsequenced modifications to }}
+ (bf1++, bf2) = 0; // no-warning
+ bf1 = xs[++bf2]; // no-warning
+ bf1 = xs[bf2++]; // no-warning TODO {{multiple unsequenced modifications to }}
+ (bf1 ? xs[0] : xs[1]) = ++bf2; // no-warning TODO {{unsequenced modification and access to }}
+ bf1 = (++bf2, ++bf2); // no-warning
+ bf1 = (bf2++, ++bf2); // no-warning
+ bf1 = (bf2++, bf2++); // no-warning TODO {{multiple unsequenced modifications to }}
+ f(bf1, bf2); // no-warning
+ f(bf1 = 0, bf2); // no-warning TODO {{unsequenced modification and access to }}
+ f(bf1, bf2 += 0); // no-warning TODO {{unsequenced modification and access to }}
+ f(bf1 = 0, bf2 = 0); // no-warning TODO {{multiple unsequenced modifications to }}
+ bf1 = f(++bf2); // no-warning
+ bf1 = f(bf2++); // no-warning
+ bf1 = f(++bf1, bf2++); // no-warning TODO {{multiple unsequenced modifications to }}
+}
+
+} // 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;
+ ++ra1 = 0; // no-warning
+ ra1 + ++ra2; // no-warning TODO: {{unsequenced modification and access to 'a'}}
+ ra1 = ++ra2; // no-warning
+ ra1 + ra2++; // no-warning TODO: {{unsequenced modification and access to 'a'}}
+ ra1 = ra2++; // no-warning TODO: {{multiple unsequenced modifications to 'a'}}
+ ++ ++ra2; // no-warning
+ (ra1++, ra2++); // no-warning
+ ++ra1 + ++ra2; // no-warning TODO: {{multiple unsequenced modifications to 'a'}}
+ ra1++ + ra2++; // no-warning TODO: {{multiple unsequenced modifications to 'a'}}
+ (ra1++, ra2) = 0; // no-warning
+ ra1 = xs[++ra2]; // no-warning
+ ra1 = xs[ra2++]; // no-warning TODO: {{multiple unsequenced modifications to 'a'}}
+ (ra1 ? xs[0] : xs[1]) = ++ra2; // no-warning TODO: {{unsequenced modification and access to 'a'}}
+ ra1 = (++ra2, ++ra2); // no-warning
+ ra1 = (ra2++, ++ra2); // no-warning
+ ra1 = (ra2++, ra2++); // no-warning TODO: {{multiple unsequenced modifications to 'a'}}
+ f(ra1, ra2); // no-warning
+ f(ra1 = 0, ra2); // no-warning TODO: {{unsequenced modification and access to 'a'}}
+ f(ra1, ra2 += 0); // no-warning TODO: {{unsequenced modification and access to 'a'}}
+ f(ra1 = 0, ra2 = 0); // no-warning TODO: {{multiple unsequenced modifications to 'a'}}
+ ra1 = f(++ra2); // no-warning
+ ra1 = f(ra2++); // no-warning
+ ra1 = f(++ra2, ra1++); // no-warning TODO: {{multiple unsequenced modifications to 'a'}}
+
+ // Make sure we don't crash if we have a reference cycle.
+ int &ref_cycle = ref_cycle;
+ ++ref_cycle = 0; // no-warning
+ ref_cycle + ++ref_cycle; // expected-warning {{unsequenced modification and access to 'ref_cycle'}}
+ ref_cycle = ++ref_cycle; // no-warning
+ ref_cycle + ref_cycle++; // expected-warning {{unsequenced modification and access to 'ref_cycle'}}
+ ref_cycle = ref_cycle++; // expected-warning {{multiple unsequenced modifications to 'ref_cycle'}}
+ ++ ++ref_cycle; // no-warning
+ (ref_cycle++, ref_cycle++); // no-warning
+ ++ref_cycle + ++ref_cycle; // expected-warning {{multiple unsequenced modifications to 'ref_cycle'}}
+ ref_cycle++ + ref_cycle++; // expected-warning {{multiple unsequenced modifications to 'ref_cycle'}}
+ (ref_cycle++, ref_cycle) = 0; // no-warning
+ ref_cycle = xs[++ref_cycle]; // no-warning
+ ref_cycle = xs[ref_cycle++]; // expected-warning {{multiple unsequenced modifications to 'ref_cycle'}}
+ (ref_cycle ? xs[0] : xs[1]) = ++ref_cycle; // expected-warning {{unsequenced modification and access to 'ref_cycle'}}
+ ref_cycle = (++ref_cycle, ++ref_cycle); // no-warning
+ ref_cycle = (ref_cycle++, ++ref_cycle); // no-warning
+ ref_cycle = (ref_cycle++, ref_cycle++); // expected-warning {{multiple unsequenced modifications to 'ref_cycle'}}
+ f(ref_cycle, ref_cycle); // no-warning
+ f(ref_cycle = 0, ref_cycle); // expected-warning {{unsequenced modification and access to 'ref_cycle'}}
+ f(ref_cycle, ref_cycle += 0); // expected-warning {{unsequenced modification and access to 'ref_cycle'}}
+ f(ref_cycle = 0, ref_cycle = 0); // expected-warning {{multiple unsequenced modifications to 'ref_cycle'}}
+ ref_cycle = f(++ref_cycle); // no-warning
+ ref_cycle = f(ref_cycle++); // no-warning
+ ref_cycle = f(++ref_cycle, ref_cycle++); // expected-warning {{multiple unsequenced modifications to 'ref_cycle'}}
+}
+} // namespace references
+
namespace templates {
template <typename T>
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits