[PATCH] D57660: [Sema] SequenceChecker: Handle references and members
riccibruno planned changes to this revision. riccibruno added a comment. This needs more work. Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D57660/new/ https://reviews.llvm.org/D57660 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D57660: [Sema] SequenceChecker: Handle references and members
riccibruno updated this revision to Diff 187035. riccibruno added a comment. Herald added a subscriber: jdoerfert. Rebased. Does this implementation make sense ? Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D57660/new/ https://reviews.llvm.org/D57660 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaChecking.cpp test/SemaCXX/warn-unsequenced.cpp Index: test/SemaCXX/warn-unsequenced.cpp === --- test/SemaCXX/warn-unsequenced.cpp +++ test/SemaCXX/warn-unsequenced.cpp @@ -161,16 +161,17 @@ void S1::member_f(S1 ) { int xs[10]; - ++a + ++a; // cxx11-warning {{multiple unsequenced modifications to 'a'}} - // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}} - a + ++a; // cxx11-warning {{unsequenced modification and access to 'a'}} - // cxx17-warning@-1 {{unsequenced modification and access to 'a'}} + ++a + ++a; // cxx11-warning {{multiple unsequenced modifications to member 'a'}} + // cxx17-warning@-1 {{multiple unsequenced modifications to member 'a'}} + a + ++a; // cxx11-warning {{unsequenced modification and access to member 'a'}} + // cxx17-warning@-1 {{unsequenced modification and access to member '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.a; // cxx11-warning {{multiple unsequenced modifications to member 'a' of 's'}} + // cxx17-warning@-1 {{multiple unsequenced modifications to member 'a' of 's'}} + s.a + ++s.a; // cxx11-warning {{unsequenced modification and access to member 'a' of 's'}} + // cxx17-warning@-1 {{unsequenced modification and access to member 'a' of 's'}} ++s.a + ++s.b; // no-warning s.a + ++s.b; // no-warning @@ -180,16 +181,18 @@ 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@-1 {{multiple unsequenced modifications to 'bf1'}} - bf1 + ++bf1; // cxx11-warning {{unsequenced modification and access to 'bf1'}} - // cxx17-warning@-1 {{unsequenced modification and access to 'bf1'}} + ++bf1 + ++bf1; // cxx11-warning {{multiple unsequenced modifications to member 'bf1'}} + // cxx17-warning@-1 {{multiple unsequenced modifications to member 'bf1'}} + bf1 + ++bf1; // cxx11-warning {{unsequenced modification and access to member 'bf1'}} + // cxx17-warning@-1 {{unsequenced modification and access to member '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.bf1; // cxx11-warning {{multiple unsequenced modifications to member 'bf1' of 's'}} + // cxx17-warning@-1 {{multiple unsequenced modifications to member 'bf1' of 's'}} + s.bf1 + ++s.bf1; // cxx11-warning {{unsequenced modification and access to member 'bf1' of 's'}} + // cxx17-warning@-1 {{unsequenced modification and access to member 'bf1' of 's'}} ++s.bf1 + ++s.bf2; // no-warning TODO {{multiple unsequenced modifications to}} s.bf1 + ++s.bf2; // no-warning TODO {{unsequenced modification and access to}} @@ -205,15 +208,19 @@ }; void S2::f2() { - ++x + ++x; // no-warning TODO {{multiple unsequenced modifications to}} - x + ++x; // no-warning TODO {{unsequenced modification and access to}} + ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to member 'x'}} + // cxx17-warning@-1 {{multiple unsequenced modifications to member 'x'}} + x + ++x; // cxx11-warning {{unsequenced modification and access to member 'x'}} + // cxx17-warning@-1 {{unsequenced modification and access to member 'x'}} ++x + ++y; // no-warning x + ++y; // no-warning } void f2(S2 ) { - ++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.x; // cxx11-warning {{multiple unsequenced modifications to member 'x' of 's'}} + // cxx17-warning@-1 {{multiple unsequenced modifications to member 'x' of 's'}} + s.x + ++s.x; // cxx11-warning {{unsequenced modification and access to member 'x' of 's'}} + // cxx17-warning@-1 {{unsequenced modification and access to member 'x' of 's'}} ++s.x + ++s.y; // no-warning s.x + ++s.y; // no-warning } @@ -229,15
[PATCH] D57660: [Sema] SequenceChecker: Handle references and members
riccibruno updated this revision to Diff 185048. riccibruno added a comment. Added tests for nested/anonymous unions and local structs. Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D57660/new/ https://reviews.llvm.org/D57660 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaChecking.cpp test/SemaCXX/warn-unsequenced.cpp Index: test/SemaCXX/warn-unsequenced.cpp === --- test/SemaCXX/warn-unsequenced.cpp +++ test/SemaCXX/warn-unsequenced.cpp @@ -131,54 +131,53 @@ // 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; // expected-warning {{unsequenced modification and access to member '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 + a++; // expected-warning {{unsequenced modification and access to member 'a'}} + a = a++; // expected-warning {{multiple unsequenced modifications to member '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; // expected-warning {{multiple unsequenced modifications to member 'a'}} + a++ + a++; // expected-warning {{multiple unsequenced modifications to member '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 = xs[a++]; // expected-warning {{multiple unsequenced modifications to member 'a'}} + (a ? xs[0] : xs[1]) = ++a; // expected-warning {{unsequenced modification and access to member 'a'}} a = (++a, ++a); // no-warning a = (a++, ++a); // no-warning - a = (a++, a++); // expected-warning {{multiple unsequenced modifications to 'a'}} + a = (a++, a++); // expected-warning {{multiple unsequenced modifications to member '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'}} + f(a = 0, a); // expected-warning {{unsequenced modification and access to member 'a'}} + f(a, a += 0); // expected-warning {{unsequenced modification and access to member 'a'}} + f(a = 0, a = 0); // expected-warning {{multiple unsequenced modifications to member 'a'}} a = f(++a); // no-warning a = f(a++); // no-warning - a = f(++a, a++); // expected-warning {{multiple unsequenced modifications to 'a'}} + a = f(++a, a++); // expected-warning {{multiple unsequenced modifications to member '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; // expected-warning {{unsequenced modification and access to member 'a' of 's'}} 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 + s.a++; // expected-warning {{unsequenced modification and access to member 'a' of 's'}} + s.a = s.a++; // expected-warning {{multiple unsequenced modifications to member 'a' of 's'}} ++ ++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; // expected-warning {{multiple unsequenced modifications to member 'a' of 's'}} + s.a++ + s.a++; // expected-warning {{multiple unsequenced modifications to member 'a' of 's'}} (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 = xs[s.a++]; // expected-warning {{multiple unsequenced modifications to member 'a' of 's'}} + (s.a ? xs[0] : xs[1]) = ++s.a; // expected-warning {{unsequenced modification and access to member 'a' of 's'}} 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 }} + s.a = (s.a++, s.a++); // expected-warning {{multiple unsequenced modifications to member 'a' of 's'}} f(s.a, s.a); // no-warning - f(s.a = 0, s.a); // no-warning TODO {{unsequenced modification and
[PATCH] D57660: [Sema] SequenceChecker: Handle references and members
riccibruno created this revision. riccibruno added reviewers: aaron.ballman, rsmith. riccibruno added a project: clang. Herald added a subscriber: cfe-commits. Teach the unsequenced operation checker about references and members. To do this introduce a class `MemoryLocation` which will approximate C++ memory locations. We don't handle bit-fields for now but I plan to do this later. I also plan to teach it about the C++17 sequencing rules, and fix a number of corner cases around `||`, `&&` and `?:`. Repository: rC Clang https://reviews.llvm.org/D57660 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaChecking.cpp test/SemaCXX/warn-unsequenced.cpp Index: test/SemaCXX/warn-unsequenced.cpp === --- test/SemaCXX/warn-unsequenced.cpp +++ test/SemaCXX/warn-unsequenced.cpp @@ -131,54 +131,53 @@ // 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; // expected-warning {{unsequenced modification and access to member '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 + a++; // expected-warning {{unsequenced modification and access to member 'a'}} + a = a++; // expected-warning {{multiple unsequenced modifications to member '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; // expected-warning {{multiple unsequenced modifications to member 'a'}} + a++ + a++; // expected-warning {{multiple unsequenced modifications to member '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 = xs[a++]; // expected-warning {{multiple unsequenced modifications to member 'a'}} + (a ? xs[0] : xs[1]) = ++a; // expected-warning {{unsequenced modification and access to member 'a'}} a = (++a, ++a); // no-warning a = (a++, ++a); // no-warning - a = (a++, a++); // expected-warning {{multiple unsequenced modifications to 'a'}} + a = (a++, a++); // expected-warning {{multiple unsequenced modifications to member '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'}} + f(a = 0, a); // expected-warning {{unsequenced modification and access to member 'a'}} + f(a, a += 0); // expected-warning {{unsequenced modification and access to member 'a'}} + f(a = 0, a = 0); // expected-warning {{multiple unsequenced modifications to member 'a'}} a = f(++a); // no-warning a = f(a++); // no-warning - a = f(++a, a++); // expected-warning {{multiple unsequenced modifications to 'a'}} + a = f(++a, a++); // expected-warning {{multiple unsequenced modifications to member '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; // expected-warning {{unsequenced modification and access to member 'a' of 's'}} 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 + s.a++; // expected-warning {{unsequenced modification and access to member 'a' of 's'}} + s.a = s.a++; // expected-warning {{multiple unsequenced modifications to member 'a' of 's'}} ++ ++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; // expected-warning {{multiple unsequenced modifications to member 'a' of 's'}} + s.a++ + s.a++; // expected-warning {{multiple unsequenced modifications to member 'a' of 's'}} (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 = xs[s.a++]; // expected-warning {{multiple unsequenced modifications to member 'a' of 's'}} + (s.a ? xs[0] : xs[1]) = ++s.a; // expected-warning {{unsequenced modification and access to member 'a' of 's'}} s.a = (++s.a, ++s.a); // no-warning s.a = (s.a++, ++s.a);