diff mbox series

[PR,c++/87269] Mark string operator overload in template defn.

Message ID ca8aaf78-83dc-1e5b-adf4-d2161e30c8df@acm.org
State New
Headers show
Series [PR,c++/87269] Mark string operator overload in template defn. | expand

Commit Message

Nathan Sidwell Nov. 16, 2018, 3:01 p.m. UTC
This was a case of not marking the overloads of a lookup as immutable, 
leading to an assert failure.

Applying to trunk.

nathan
diff mbox series

Patch

2018-11-16  Nathan Sidwell  <nathan@acm.org>

	PR c++/87269
	* parser.c (lookup_literal_operator): Mark overload for keeping
	when inside template.  Refactor.

	* g++.dg/lookup/pr87269.C: New.

Index: cp/parser.c
===================================================================
--- cp/parser.c	(revision 266204)
+++ cp/parser.c	(working copy)
@@ -4259,20 +4259,21 @@  cp_parser_string_literal (cp_parser *par
 static tree
 lookup_literal_operator (tree name, vec<tree, va_gc> *args)
 {
-  tree decl;
-  decl = lookup_name (name);
+  tree decl = lookup_name (name);
   if (!decl || !is_overloaded_fn (decl))
     return error_mark_node;
 
   for (lkp_iterator iter (decl); iter; ++iter)
     {
-      unsigned int ix;
-      bool found = true;
       tree fn = *iter;
-      tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (fn));
-      if (parmtypes != NULL_TREE)
+
+      if (tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (fn)))
 	{
-	  for (ix = 0; ix < vec_safe_length (args) && parmtypes != NULL_TREE;
+	  unsigned int ix;
+	  bool found = true;
+
+	  for (ix = 0;
+	       found && ix < vec_safe_length (args) && parmtypes != NULL_TREE;
 	       ++ix, parmtypes = TREE_CHAIN (parmtypes))
 	    {
 	      tree tparm = TREE_VALUE (parmtypes);
@@ -4285,6 +4286,7 @@  lookup_literal_operator (tree name, vec<
 				       TREE_TYPE (targ))))
 		found = false;
 	    }
+
 	  if (found
 	      && ix == vec_safe_length (args)
 	      /* May be this should be sufficient_parms_p instead,
@@ -4292,7 +4294,11 @@  lookup_literal_operator (tree name, vec<
 		 work in presence of default arguments on the literal
 		 operator parameters.  */
 	      && parmtypes == void_list_node)
-	    return decl;
+	    {
+	      if (processing_template_decl)
+		lookup_keep (decl);
+	      return decl;
+	    }
 	}
     }
 
Index: testsuite/g++.dg/lookup/pr87269.C
===================================================================
--- testsuite/g++.dg/lookup/pr87269.C	(revision 0)
+++ testsuite/g++.dg/lookup/pr87269.C	(working copy)
@@ -0,0 +1,15 @@ 
+// { dg-do compile { target c++11 } }
+// PR c++/87269 ICE failing to keep a lookup
+
+namespace {
+  void  operator"" _a (const char *, unsigned long) {}
+}
+
+void operator"" _a (unsigned long long);
+
+template <typename> void f () { ""_a; }
+
+void frob ()
+{
+  f<int> ();
+}