re PR c++/81675 (attribute(noreturn) of destructor in :? not honored)
authorJakub Jelinek <jakub@gcc.gnu.org>
Mon, 27 Nov 2017 13:13:22 +0000 (14:13 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 27 Nov 2017 13:13:22 +0000 (14:13 +0100)
PR c++/81675
* cp-gimplify.c (cp_fold) <case COND_EXPR>: Don't return immediately
for VOID_TYPE_P COND_EXPRs, instead fold the operands and if op0 is
INTEGER_CST, ensure that both op1 and op2 are non-NULL and fall
through into normal folding, otherwise just rebuild x if any op
changed.

* g++.dg/warn/pr81675.C: New test.

From-SVN: r255167

gcc/cp/ChangeLog
gcc/cp/cp-gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/pr81675.C [new file with mode: 0644]

index 854df5afe9174ba3d161e1c1203c6e5eff2850c1..5dda6046ec42091de69f0debe4dc3bb7a406c6de 100644 (file)
@@ -1,4 +1,15 @@
-2017-11-14 Boris Kolpackov  <boris@codesynthesis.com>
+2017-11-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/81675
+       * cp-gimplify.c (cp_fold) <case COND_EXPR>: Don't return immediately
+       for VOID_TYPE_P COND_EXPRs, instead fold the operands and if op0 is
+       INTEGER_CST, ensure that both op1 and op2 are non-NULL and fall
+       through into normal folding, otherwise just rebuild x if any op
+       changed.
+
+       * g++.dg/warn/pr81675.C: New test.
+
+2017-11-14  Boris Kolpackov  <boris@codesynthesis.com>
 
        * Make-lang.in (c++.install-plugin): Install backend import library.
 
index d597ed99009ab1311db09a9f4c55fe0be742b373..734b15660b33bce2af6de71bfb5036c2bf63457f 100644 (file)
@@ -2299,13 +2299,6 @@ cp_fold (tree x)
 
     case VEC_COND_EXPR:
     case COND_EXPR:
-
-      /* Don't bother folding a void condition, since it can't produce a
-        constant value.  Also, some statement-level uses of COND_EXPR leave
-        one of the branches NULL, so folding would crash.  */
-      if (VOID_TYPE_P (TREE_TYPE (x)))
-       return x;
-
       loc = EXPR_LOCATION (x);
       op0 = cp_fold_rvalue (TREE_OPERAND (x, 0));
       op1 = cp_fold (TREE_OPERAND (x, 1));
@@ -2319,6 +2312,29 @@ cp_fold (tree x)
          if (!VOID_TYPE_P (TREE_TYPE (op2)))
            op2 = cp_truthvalue_conversion (op2);
        }
+      else if (VOID_TYPE_P (TREE_TYPE (x)))
+       {
+         if (TREE_CODE (op0) == INTEGER_CST)
+           {
+             /* If the condition is constant, fold can fold away
+                the COND_EXPR.  If some statement-level uses of COND_EXPR
+                have one of the branches NULL, avoid folding crash.  */
+             if (!op1)
+               op1 = build_empty_stmt (loc);
+             if (!op2)
+               op2 = build_empty_stmt (loc);
+           }
+         else
+           {
+             /* Otherwise, don't bother folding a void condition, since
+                it can't produce a constant value.  */
+             if (op0 != TREE_OPERAND (x, 0)
+                 || op1 != TREE_OPERAND (x, 1)
+                 || op2 != TREE_OPERAND (x, 2))
+               x = build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
+             break;
+           }
+       }
 
       if (op0 != TREE_OPERAND (x, 0)
          || op1 != TREE_OPERAND (x, 1)
index cb3835b3e9de626403186cac2ec77db749629cd2..a52550985af4b74278fc9b83d60aeda0ef014066 100644 (file)
@@ -1,3 +1,8 @@
+2017-11-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/81675
+       * g++.dg/warn/pr81675.C: New test.
+
 2017-11-27  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gnat.dg/unroll1.ads: Remove alignment clause.
diff --git a/gcc/testsuite/g++.dg/warn/pr81675.C b/gcc/testsuite/g++.dg/warn/pr81675.C
new file mode 100644 (file)
index 0000000..24a7a3b
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/81675
+// { dg-do compile }
+// { dg-options "-Wall" }
+
+struct S
+{
+  ~S () __attribute__((noreturn));
+  int a;
+};
+
+int
+foo ()
+{
+  false ? 5 : S ().a;
+}