backport: re PR c++/81675 (attribute(noreturn) of destructor in :? not honored)

Backported from mainline
	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.

From-SVN: r255718
This commit is contained in:
Jakub Jelinek 2017-12-15 23:06:16 +01:00 committed by Jakub Jelinek
parent 7e27191cf5
commit 4c8c427fcf
4 changed files with 52 additions and 7 deletions

View File

@ -1,6 +1,15 @@
2017-12-15 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
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.
2017-11-23 Jakub Jelinek <jakub@redhat.com>
* parser.c (cp_parser_omp_declare): Change return type to bool from

View File

@ -2278,13 +2278,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));
@ -2298,6 +2291,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)

View File

@ -1,6 +1,11 @@
2017-12-15 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2017-11-27 Jakub Jelinek <jakub@redhat.com>
PR c++/81675
* g++.dg/warn/pr81675.C: New test.
2017-11-25 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/81553

View File

@ -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;
}