[PATCH] D47687: fix: [Bug 18971] - Missing -Wparentheses warning
Higuoxing created this revision. Herald added a subscriber: cfe-commits. Higuoxing edited the summary of this revision. Hi, As you see, to avoid some expression like assert(x || y && "some messages"); clang will skip all the parentheses check if the expression is in `macro`; and this rule is a little bit loose, if a function which takes boolean variables defined in `macros`, clang will not check parentheses for these functions; So, in this patch I add a string type checking, if and only if a function defined in macro and the RHS of boolean expression is a string, then skip the parentheses checking :) Thanks for reviewing :) Repository: rC Clang https://reviews.llvm.org/D47687 Files: lib/Sema/SemaExpr.cpp Index: lib/Sema/SemaExpr.cpp === --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -12310,7 +12310,14 @@ // Warn about arg1 || arg2 && arg3, as GCC 4.3+ does. // We don't warn for 'assert(a || b && "bad")' since this is safe. - if (Opc == BO_LOr && !OpLoc.isMacroID()/* Don't warn in macros. */) { + StringLiteral* diagnoseRHSToBeString += dyn_cast(RHSExpr->IgnoreImpCasts()); + if (Opc == BO_LOr && + !(OpLoc.isMacroID() && + diagnoseRHSToBeString) +/* Don't warn in macros, + if and only if RHS could be + evaluated as string */) { DiagnoseLogicalAndInLogicalOrLHS(Self, OpLoc, LHSExpr, RHSExpr); DiagnoseLogicalAndInLogicalOrRHS(Self, OpLoc, LHSExpr, RHSExpr); } Index: lib/Sema/SemaExpr.cpp === --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -12310,7 +12310,14 @@ // Warn about arg1 || arg2 && arg3, as GCC 4.3+ does. // We don't warn for 'assert(a || b && "bad")' since this is safe. - if (Opc == BO_LOr && !OpLoc.isMacroID()/* Don't warn in macros. */) { + StringLiteral* diagnoseRHSToBeString += dyn_cast(RHSExpr->IgnoreImpCasts()); + if (Opc == BO_LOr && + !(OpLoc.isMacroID() && + diagnoseRHSToBeString) +/* Don't warn in macros, + if and only if RHS could be + evaluated as string */) { DiagnoseLogicalAndInLogicalOrLHS(Self, OpLoc, LHSExpr, RHSExpr); DiagnoseLogicalAndInLogicalOrRHS(Self, OpLoc, LHSExpr, RHSExpr); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47687: fix: [Bug 18971] - Missing -Wparentheses warning
Higuoxing added a comment. As for some test cases, $ cat a.cc #include #include #define bar(x) \ ( \ ( std::cout << x ) \ ) bool x; int val; void foo(bool b) { std::cout << b << std::endl; } int main () { foo(x && val == 4 || (!x && val == 5)); bar(x && val == 4 || (!x && val == 5)); assert(x && val == 4 || (!x && val == 5)); assert(x || val == 4 && "test"); return 0; } And clang will emits a.cc:20:9: warning: '&&' within '||' [-Wlogical-op-parentheses] foo(x && val == 4 || (!x && val == 5)); ~~^~~ ~~ a.cc:20:9: note: place parentheses around the '&&' expression to silence this warning foo(x && val == 4 || (!x && val == 5)); ^ () a.cc:21:9: warning: '&&' within '||' [-Wlogical-op-parentheses] bar(x && val == 4 || (!x && val == 5)); ~~^~~~ a.cc:7:20: note: expanded from macro 'bar' ( std::cout << x ) \ ~^ a.cc:21:9: note: place parentheses around the '&&' expression to silence this warning bar(x && val == 4 || (!x && val == 5)); ~~^~~~ a.cc:7:20: note: expanded from macro 'bar' ( std::cout << x ) \ ~^ a.cc:22:12: warning: '&&' within '||' [-Wlogical-op-parentheses] assert(x && val == 4 || (!x && val == 5)); ~~^~~ ~~ /usr/include/assert.h:93:25: note: expanded from macro 'assert' (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0) ^ a.cc:22:12: note: place parentheses around the '&&' expression to silence this warning assert(x && val == 4 || (!x && val == 5)); ~~^~~ /usr/include/assert.h:93:25: note: expanded from macro 'assert' (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0) ^ 3 warnings generated. Repository: rC Clang https://reviews.llvm.org/D47687 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47687: fix: [Bug 18971] - Missing -Wparentheses warning
Higuoxing added a comment. In https://reviews.llvm.org/D47687#1120226, @lebedev.ri wrote: > In https://reviews.llvm.org/D47687#1120213, @Higuoxing wrote: > > > As for some test cases, > > > The tests need to be within the patch itself, in this case > i guess that should go into `clang/test/Sema/`. > See other tests in there on how to write them. > And they will be run via `$ ninja check-clang` / `$ ninja check-clang-sema`. Hi, Thanks for your reviewing :D I am trying to write the test cases ... Thanks :D Repository: rC Clang https://reviews.llvm.org/D47687 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47687: fix: [Bug 18971] - Missing -Wparentheses warning
Higuoxing updated this revision to Diff 149766. Higuoxing edited the summary of this revision. Higuoxing added a comment. Update with test cases :) https://reviews.llvm.org/D47687 Files: lib/Sema/SemaExpr.cpp test/Sema/parentheses.c Index: test/Sema/parentheses.c === --- test/Sema/parentheses.c +++ test/Sema/parentheses.c @@ -14,6 +14,11 @@ if ((i = 4)) {} } +#define macro_parentheses_check(x) \ + ( \ +( (void)(x) ) \ + ) + void bitwise_rel(unsigned i) { (void)(i & 0x2 == 0); // expected-warning {{& has lower precedence than ==}} \ // expected-note{{place parentheses around the '==' expression to silence this warning}} \ @@ -96,6 +101,23 @@ (void)(i && i || 0); // no warning. (void)(0 || i && i); // no warning. + + macro_parentheses_check(i || i && i); // expected-warning {{'&&' within '||'}} \ +// expected-note {{place parentheses around the '&&' expression to silence this warning}} + + macro_parentheses_check(i || i && "I love LLVM"); // no warning. + macro_parentheses_check("I love LLVM" && i || i); // no warning. + + macro_parentheses_check(i || i && "I love LLVM" || i); // expected-warning {{'&&' within '||'}} \ + // expected-note {{place parentheses around the '&&' expression to silence this warning}} + + + macro_parentheses_check(i || "I love LLVM" && i || i); // expected-warning {{'&&' within '||'}} \ + // expected-note {{place parentheses around the '&&' expression to silence this warning}} + + + macro_parentheses_check(i && i || 0); // no warning. + macro_parentheses_check(0 || i && i); // no warning. } _Bool someConditionFunc(); Index: lib/Sema/SemaExpr.cpp === --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -12205,6 +12205,7 @@ if (EvaluatesAsFalse(S, RHSExpr)) return; // If it's "1 && a || b" don't warn since the precedence doesn't matter. + // And 'assert("some message" && a || b)' don't warn as well. if (!EvaluatesAsTrue(S, Bop->getLHS())) return EmitDiagnosticForLogicalAndInLogicalOr(S, OpLoc, Bop); } else if (Bop->getOpcode() == BO_LOr) { @@ -12227,6 +12228,7 @@ if (EvaluatesAsFalse(S, LHSExpr)) return; // If it's "a || b && 1" don't warn since the precedence doesn't matter. + // And 'assert(a || b && "some message")' don't warn as well. if (!EvaluatesAsTrue(S, Bop->getRHS())) return EmitDiagnosticForLogicalAndInLogicalOr(S, OpLoc, Bop); } @@ -12309,8 +12311,7 @@ } // Warn about arg1 || arg2 && arg3, as GCC 4.3+ does. - // We don't warn for 'assert(a || b && "bad")' since this is safe. - if (Opc == BO_LOr && !OpLoc.isMacroID()/* Don't warn in macros. */) { + if (Opc == BO_LOr) { DiagnoseLogicalAndInLogicalOrLHS(Self, OpLoc, LHSExpr, RHSExpr); DiagnoseLogicalAndInLogicalOrRHS(Self, OpLoc, LHSExpr, RHSExpr); } Index: test/Sema/parentheses.c === --- test/Sema/parentheses.c +++ test/Sema/parentheses.c @@ -14,6 +14,11 @@ if ((i = 4)) {} } +#define macro_parentheses_check(x) \ + ( \ +( (void)(x) ) \ + ) + void bitwise_rel(unsigned i) { (void)(i & 0x2 == 0); // expected-warning {{& has lower precedence than ==}} \ // expected-note{{place parentheses around the '==' expression to silence this warning}} \ @@ -96,6 +101,23 @@ (void)(i && i || 0); // no warning. (void)(0 || i && i); // no warning. + + macro_parentheses_check(i || i && i); // expected-warning {{'&&' within '||'}} \ +// expected-note {{place parentheses around the '&&' expression to silence this warning}} + + macro_parentheses_check(i || i && "I love LLVM"); // no warning. + macro_parentheses_check("I love LLVM" && i || i); // no warning. + + macro_parentheses_check(i || i && "I love LLVM" || i); // expected-warning {{'&&' within '||'}} \ + // expected-note {{place parentheses around the '&&' expression to silence this warning}} + + + macro_parentheses_check(i || "I love LLVM" && i || i); // expected-warning {{'&&' within '||'}} \ + // expected-note {{place parentheses around the '&&' expression to silence this warning}} + + + macro_parentheses_check(i && i || 0); // no warning. + macro_parentheses_check(0 || i && i); // no warning. } _Bool someConditionFunc(); Index: lib/Sema/SemaExpr.cpp === --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -12205,6 +12205,7 @@ if (EvaluatesAsFalse(S, RHSExpr))
[PATCH] D47687: fix: [Bug 18971] - Missing -Wparentheses warning
Higuoxing added a comment. Thanks for reviewing! I think the logic that *do not emit warning in macros* is not so proper ... Best Regards, Xing https://reviews.llvm.org/D47687 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47687: fix: [Bug 18971] - Missing -Wparentheses warning
Higuoxing added a comment. Thanks for reviewing! I think enabling parentheses-checking in macros could be helpful, and `assert(something)` is widely used : ) https://reviews.llvm.org/D47687 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits