I added an assert when recently fixing baselink substitution, but the assert is incorrect as this testcase shows.

Fixing thusly.

nathan
--
Nathan Sidwell
2018-01-23  Nathan Sidwell  <nat...@acm.org>

	PR c++/83988
	* pt.c (tsubst_baselink): Remove optype assert.
	* ptree.c (cxx_print_xnode): <case BASELINK> Print BASELINK_OPTYPE.

	PR c++/83988
	* g++.dg/template/pr83988.C: New.

Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 256981)
+++ cp/pt.c	(working copy)
@@ -14447,11 +14447,8 @@ tsubst_baselink (tree baselink, tree obj
 	fns = BASELINK_FUNCTIONS (baselink);
     }
   else
-    {
-      gcc_assert (optype == BASELINK_OPTYPE (baselink));
-      /* We're going to overwrite pieces below, make a duplicate.  */
-      baselink = copy_node (baselink);
-    }
+    /* We're going to overwrite pieces below, make a duplicate.  */
+    baselink = copy_node (baselink);
 
   /* If lookup found a single function, mark it as used at this point.
      (If lookup found multiple functions the one selected later by
Index: cp/ptree.c
===================================================================
--- cp/ptree.c	(revision 256981)
+++ cp/ptree.c	(working copy)
@@ -215,6 +215,7 @@ cxx_print_xnode (FILE *file, tree node,
       print_node (file, "binfo", BASELINK_BINFO (node), indent + 4);
       print_node (file, "access_binfo", BASELINK_ACCESS_BINFO (node),
 		  indent + 4);
+      print_node (file, "optype", BASELINK_OPTYPE (node), indent + 4);
       break;
     case OVERLOAD:
       print_node (file, "function", OVL_FUNCTION (node), indent+4);
Index: testsuite/g++.dg/template/pr83988.C
===================================================================
--- testsuite/g++.dg/template/pr83988.C	(revision 0)
+++ testsuite/g++.dg/template/pr83988.C	(working copy)
@@ -0,0 +1,16 @@
+// PR 83988 ICE
+
+template<class T> struct optional {};
+struct get_from_json {
+  template<typename GetWhat>
+  operator optional<GetWhat>() const {return optional<GetWhat> ();}
+  template<typename AsWhat>
+  optional<AsWhat> maybe() const
+  {
+    return this->operator optional<AsWhat>();
+  }
+};
+void test()
+{
+  get_from_json().maybe<int>();
+}

Reply via email to