On 01/17/2017 03:17 PM, Jason Merrill wrote:
Hmm, what if write_exception_spec checks for a dependent noexcept-specifier first, and noexcept_spec_p second? That seems like it would avoid needing any change to nothrow_spec_p.
that's a better solution. However it was easier for it to check for the nothrow case, rather than call the helper function. (It already checks for NULL spec or spec == noexcept_false_spec, so no additional loss of abstraction.)
Also committed the second patch to cleanup nothrow_spec_p itself, which I found overly confusing.
nathan -- Nathan Sidwell
2017-01-18 Nathan Sidwell <nat...@acm.org> PR c++/79091 * mangle.c (write_exception_spec): Check nothrow explicitly. (write_encoding): Don't increment processing_template_decl around encoding. PR c++/79091 * g++.dg/pr79091.C: New. Index: cp/mangle.c =================================================================== --- cp/mangle.c (revision 244574) +++ cp/mangle.c (working copy) @@ -366,17 +366,19 @@ write_exception_spec (tree spec) return; } - if (nothrow_spec_p (spec)) + if (spec == noexcept_true_spec || spec == empty_except_spec) write_string ("Do"); - else if (TREE_PURPOSE (spec)) + else if (tree expr = TREE_PURPOSE (spec)) { - gcc_assert (uses_template_parms (TREE_PURPOSE (spec))); + /* noexcept (expr) */ + gcc_assert (uses_template_parms (expr)); write_string ("DO"); - write_expression (TREE_PURPOSE (spec)); + write_expression (expr); write_char ('E'); } else { + /* throw (type-list) */ write_string ("Dw"); for (tree t = spec; t; t = TREE_CHAIN (t)) write_type (TREE_VALUE (t)); @@ -829,7 +831,6 @@ write_encoding (const tree decl) if (tmpl) { - ++processing_template_decl; fn_type = get_mostly_instantiated_function_type (decl); /* FN_TYPE will not have parameter types for in-charge or VTT parameters. Therefore, we pass NULL_TREE to @@ -846,9 +847,6 @@ write_encoding (const tree decl) write_bare_function_type (fn_type, mangle_return_type_p (decl), d); - - if (tmpl) - --processing_template_decl; } } Index: testsuite/g++.dg/pr79091.C =================================================================== --- testsuite/g++.dg/pr79091.C (revision 0) +++ testsuite/g++.dg/pr79091.C (working copy) @@ -0,0 +1,25 @@ +// PR 79091 ICE mangling an unnamed enum in a tempate instantiation. + +enum { + One = 1 +}; + +template<int Options> +class Matrix {}; + +template<int Dim> +Matrix<Dim ? One : 0> *Bar () +{ + return 0; +} + +template<int Opt> +Matrix<Opt> *Baz () +{ + return 0; +} + +bool Foo () +{ + return Baz<1> () == Bar<1> (); +}
2017-01-18 Nathan Sidwell <nat...@acm.org> * cp-tree.h: Clarify exception spec node comment. * except.c (nothrow_spec_p): Simplify by checking node-equality. Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 244574) +++ cp/cp-tree.h (working copy) @@ -1212,7 +1212,8 @@ extern GTY(()) tree cp_global_trees[CPTI #define lang_name_c cp_global_trees[CPTI_LANG_NAME_C] #define lang_name_cplusplus cp_global_trees[CPTI_LANG_NAME_CPLUSPLUS] -/* Exception specifier used for throw(). */ +/* Exception specifiers used for throw(), noexcept(true) and + noexcept(false). We rely on these being uncloned. */ #define empty_except_spec cp_global_trees[CPTI_EMPTY_EXCEPT_SPEC] #define noexcept_true_spec cp_global_trees[CPTI_NOEXCEPT_TRUE_SPEC] #define noexcept_false_spec cp_global_trees[CPTI_NOEXCEPT_FALSE_SPEC] Index: cp/except.c =================================================================== --- cp/except.c (revision 244574) +++ cp/except.c (working copy) @@ -1143,15 +1143,17 @@ bool nothrow_spec_p (const_tree spec) { gcc_assert (!DEFERRED_NOEXCEPT_SPEC_P (spec)); - if (spec == NULL_TREE - || TREE_VALUE (spec) != NULL_TREE - || spec == noexcept_false_spec) - return false; - if (TREE_PURPOSE (spec) == NULL_TREE + + if (spec == empty_except_spec || spec == noexcept_true_spec) return true; - gcc_assert (processing_template_decl - || TREE_PURPOSE (spec) == error_mark_node); + + gcc_assert (!spec + || TREE_VALUE (spec) + || spec == noexcept_false_spec + || TREE_PURPOSE (spec) == error_mark_node + || processing_template_decl); + return false; }