This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C++ PATCH] PR 79091, ICE with unnamed enum mangle
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 <nathan@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 <nathan@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;
}