Hi,
the issue is rather easy to explain: after Alexandre' change in
r266874, which simplified the condition at the beginning of
build_noexcept_spec to evaluate early all the expressions which aren't
deferred or value-dependent, we obviously ICE during error-recovery on
the new testcase because an expression which isn't a potential constant
filters through and cxx_constant_value can't handle it. We can avoid
this in various ways - for example by adding a gate &&
potential_rvalue_constant_expression_p (expr) in the condition at the
beginning of build_noexcept_spec and adjust/remove the final gcc_assert
(which is already a bit obsolete wrt Alexandre' change). Or we can
handle this earlier, in cp_parser_noexcept_specification_opt - in
complete analogy, with, say, cp_parser_initializer_list - thus don't let
through those expressions at all (possible variant: set expr =
error_mark_node), which has the advantage of avoiding a duplicate
potential_rvalue_constant_expression call (note: in the parser
build_no_except_spec is called only by cp_parser_noexcept_specification_opt)
All those variants pass the testsuite on x86_64-linux.
Thanks, Paolo.
////////////////////////////
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 269187)
+++ cp/parser.c (working copy)
@@ -25143,7 +25143,17 @@ cp_parser_noexcept_specification_opt (cp_parser* p
parser->type_definition_forbidden_message
= G_("types may not be defined in an exception-specification");
- expr = cp_parser_constant_expression (parser);
+ bool non_constant_p;
+ expr
+ = cp_parser_constant_expression (parser,
+ /*allow_non_constant=*/true,
+ &non_constant_p);
+ if (non_constant_p
+ && !require_potential_rvalue_constant_expression (expr))
+ {
+ expr = NULL_TREE;
+ return_cond = true;
+ }
/* Restore the saved message. */
parser->type_definition_forbidden_message = saved_message;
Index: testsuite/g++.dg/cpp0x/pr88987.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr88987.C (nonexistent)
+++ testsuite/g++.dg/cpp0x/pr88987.C (working copy)
@@ -0,0 +1,9 @@
+// { dg-do compile { target c++11 } }
+
+int sm;
+
+template <typename T> T
+pk () noexcept (sm) // { dg-error "constant expression" }
+{
+ return 0;
+}