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

Reply via email to