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]

[C++ PATCH] 71406, 77508 scoped template_ids


This patch fixes 71406 and 77508, which are both ICEs dealing with 'X::Foo<...>'. finish_class_member_access_expr wasn't prepared to handle SCOPE_REF (TEMPLATE_ID_EXPR (...)), which is what it was being fed. Fixed by moving the SCOPE_REF splitting to before the TEMPLATE_ID_EXPR handling, but leaving the scope checking where it was.

ok?

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

	PR c++/71406 - ICE with scope-ref'd template id exprs
	PR c++/77508
	* typeck.c (finish_class_member_access_expr): Break up SCOPE_REF
	before breaking up TEMPLATE_ID_EXPR.

	PR c++/71406
	PR c++/77508
	* g++.dg/template/pr71406.C: New.

Index: cp/typeck.c
===================================================================
--- cp/typeck.c	(revision 244819)
+++ cp/typeck.c	(working copy)
@@ -2730,19 +2730,9 @@ finish_class_member_access_expr (cp_expr
     {
       bool is_template_id = false;
       tree template_args = NULL_TREE;
-      tree scope;
+      tree scope = NULL_TREE;
 
-      if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
-	{
-	  is_template_id = true;
-	  template_args = TREE_OPERAND (name, 1);
-	  name = TREE_OPERAND (name, 0);
-
-	  if (TREE_CODE (name) == OVERLOAD)
-	    name = DECL_NAME (get_first_fn (name));
-	  else if (DECL_P (name))
-	    name = DECL_NAME (name);
-	}
+      access_path = object_type;
 
       if (TREE_CODE (name) == SCOPE_REF)
 	{
@@ -2761,9 +2751,25 @@ finish_class_member_access_expr (cp_expr
 		       scope, name, object_type);
 	      return error_mark_node;
 	    }
+	}
+      
+      if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+	{
+	  is_template_id = true;
+	  template_args = TREE_OPERAND (name, 1);
+	  name = TREE_OPERAND (name, 0);
 
+	  if (TREE_CODE (name) == OVERLOAD)
+	    name = DECL_NAME (get_first_fn (name));
+	  else if (DECL_P (name))
+	    name = DECL_NAME (name);
+	}
+
+      if (scope)
+	{
 	  if (TREE_CODE (scope) == ENUMERAL_TYPE)
 	    {
+	      gcc_assert (!is_template_id);
 	      /* Looking up a member enumerator (c++/56793).  */
 	      if (!TYPE_CLASS_SCOPE_P (scope)
 		  || !DERIVED_FROM_P (TYPE_CONTEXT (scope), object_type))
@@ -2812,11 +2818,6 @@ finish_class_member_access_expr (cp_expr
 	      return error_mark_node;
 	    }
 	}
-      else
-	{
-	  scope = NULL_TREE;
-	  access_path = object_type;
-	}
 
       if (TREE_CODE (name) == BIT_NOT_EXPR)
 	{
Index: testsuite/g++.dg/template/pr71406.C
===================================================================
--- testsuite/g++.dg/template/pr71406.C	(revision 0)
+++ testsuite/g++.dg/template/pr71406.C	(working copy)
@@ -0,0 +1,28 @@
+// { dg-do compile }
+// PR c++/71406 ICE with X::template Name
+
+template < typename T >
+struct C : T
+{
+  void foo () { this->C::template bar <>; }
+};
+
+template < typename T >
+struct A
+{ 
+  template < void (T::*Fn) () > void f () {}
+};
+
+template < typename T > struct B : A < B < T > >
+{ 
+  void g ()
+  { 
+    this->B::template f < &B < T >::g > ();
+  }
+};
+
+void Foo ()
+{ 
+  B < int > b;
+  b.g ();
+}

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