This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]