]> granicus.if.org Git - clang/commitdiff
Fix -Wunsequenced false-positives in code controlled by a branch on
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 2 May 2019 23:21:28 +0000 (23:21 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 2 May 2019 23:21:28 +0000 (23:21 +0000)
__builtin_constant_p.

If the operand of __builtin_constant_p is not constant and has
side-effects, then code controlled by a branch on it is unreachable and
we should not emit runtime behavior warnings in such code.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@359844 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ExprConstant.cpp
test/Sema/warn-unsequenced.c

index 24b28971af357bfc0aad5e83ba9b777f664c23b4..8386ce8f2d4357ed7bd9e5026d684cfc7bbb9553 100644 (file)
@@ -8269,11 +8269,14 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
 
   case Builtin::BI__builtin_constant_p: {
     const Expr *Arg = E->getArg(0);
-    if (EvaluateBuiltinConstantP(Info, Arg))
+    if (EvaluateBuiltinConstantP(Info, Arg)) {
       return Success(true, E);
-    else if (Info.InConstantContext)
+    } else if (Info.InConstantContext || Arg->HasSideEffects(Info.Ctx)) {
+      // Outside a constant context, eagerly evaluate to false in the presence
+      // of side-effects in order to avoid -Wunsequenced false-positives in
+      // a branch on __builtin_constant_p(expr).
       return Success(false, E);
-    else {
+    else {
       Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
       return false;
     }
index 70163dc0de946866f75e499d745f4872e9ee88b1..247a1219419ab3238333f898189918907743bee5 100644 (file)
@@ -93,4 +93,6 @@ void test() {
   _Generic(++a, default: 0) + ++a; // ok
   sizeof(++a) + ++a; // ok
   _Alignof(++a) + ++a; // expected-warning {{extension}}
+
+  __builtin_constant_p(f(++a, 0)) ? f(f(++a, 0), f(++a, 0)) : 0;
 }