mirror of git://gcc.gnu.org/git/gcc.git
re PR c++/54020 ([c++0x] incorrectly accepted constexpr functions)
PR c++/54020 * semantics.c (potential_constant_expression_1) [COND_EXPR]: Call maybe_constant_value. From-SVN: r189851
This commit is contained in:
parent
5e7b9f609a
commit
9155a6ddc4
|
|
@ -1,5 +1,9 @@
|
||||||
2012-07-25 Jason Merrill <jason@redhat.com>
|
2012-07-25 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
|
PR c++/54020
|
||||||
|
* semantics.c (potential_constant_expression_1) [COND_EXPR]: Call
|
||||||
|
maybe_constant_value.
|
||||||
|
|
||||||
* cp-tree.h (tsubst_flags): Remove tf_no_access_control.
|
* cp-tree.h (tsubst_flags): Remove tf_no_access_control.
|
||||||
* call.c (standard_conversion): Don't set it.
|
* call.c (standard_conversion): Don't set it.
|
||||||
* class.c (resolve_address_of_overloaded_function): Don't check it.
|
* class.c (resolve_address_of_overloaded_function): Don't check it.
|
||||||
|
|
|
||||||
|
|
@ -8497,10 +8497,17 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
|
||||||
case TRUTH_ORIF_EXPR:
|
case TRUTH_ORIF_EXPR:
|
||||||
tmp = boolean_false_node;
|
tmp = boolean_false_node;
|
||||||
truth:
|
truth:
|
||||||
if (TREE_OPERAND (t, 0) == tmp)
|
{
|
||||||
|
tree op = TREE_OPERAND (t, 0);
|
||||||
|
if (!potential_constant_expression_1 (op, rval, flags))
|
||||||
|
return false;
|
||||||
|
if (!processing_template_decl)
|
||||||
|
op = maybe_constant_value (op);
|
||||||
|
if (tree_int_cst_equal (op, tmp))
|
||||||
return potential_constant_expression_1 (TREE_OPERAND (t, 1), rval, flags);
|
return potential_constant_expression_1 (TREE_OPERAND (t, 1), rval, flags);
|
||||||
else
|
else
|
||||||
return potential_constant_expression_1 (TREE_OPERAND (t, 0), rval, flags);
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
case PLUS_EXPR:
|
case PLUS_EXPR:
|
||||||
case MULT_EXPR:
|
case MULT_EXPR:
|
||||||
|
|
@ -8556,7 +8563,9 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
|
||||||
tmp = TREE_OPERAND (t, 0);
|
tmp = TREE_OPERAND (t, 0);
|
||||||
if (!potential_constant_expression_1 (tmp, rval, flags))
|
if (!potential_constant_expression_1 (tmp, rval, flags))
|
||||||
return false;
|
return false;
|
||||||
else if (integer_zerop (tmp))
|
if (!processing_template_decl)
|
||||||
|
tmp = maybe_constant_value (tmp);
|
||||||
|
if (integer_zerop (tmp))
|
||||||
return potential_constant_expression_1 (TREE_OPERAND (t, 2),
|
return potential_constant_expression_1 (TREE_OPERAND (t, 2),
|
||||||
want_rval, flags);
|
want_rval, flags);
|
||||||
else if (TREE_CODE (tmp) == INTEGER_CST)
|
else if (TREE_CODE (tmp) == INTEGER_CST)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
// PR c++/54020
|
||||||
|
// { dg-do compile { target c++11 } }
|
||||||
|
|
||||||
|
// Preliminaries.
|
||||||
|
extern int nonconst_func(int);
|
||||||
|
constexpr int identity(int x) { return x; }
|
||||||
|
constexpr int zero() { return identity(0); }
|
||||||
|
constexpr int one() { return identity(1); }
|
||||||
|
|
||||||
|
// Correctly accepted.
|
||||||
|
constexpr int three = one() ? 3 : nonconst_func(0);
|
||||||
|
|
||||||
|
// Incorrectly accepted. See [dcl.constexpr] #5:
|
||||||
|
// For a constexpr function, if no function argument values exist
|
||||||
|
// such that the function invocation sub-stitution would produce a
|
||||||
|
// constant expression (5.19), the program is ill-formed; no diagnostic
|
||||||
|
// required.
|
||||||
|
constexpr int bogus() { return zero () ? 3 : nonconst_func(0); } // { dg-error "nonconst_func" }
|
||||||
|
|
||||||
|
// Correctly rejected (not sure why).
|
||||||
|
constexpr int correct_error() { return nonconst_func(0); } // { dg-error "nonconst_func" }
|
||||||
|
|
||||||
|
// Correctly rejected.
|
||||||
|
constexpr int z = bogus(); // { dg-error "" }
|
||||||
|
|
||||||
|
// This is also correctly rejected.
|
||||||
|
constexpr int correct_failure() { return 0 ? 3 : nonconst_func(0); } // { dg-error "nonconst_func" }
|
||||||
Loading…
Reference in New Issue