PR c++/71406 - ICE with scope-ref'd template id exprs
authorNathan Sidwell <nathan@acm.org>
Mon, 23 Jan 2017 20:19:07 +0000 (20:19 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Mon, 23 Jan 2017 20:19:07 +0000 (20:19 +0000)
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.

From-SVN: r244832

gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/pr71406.C [new file with mode: 0644]

index d1ad2eb..c56c840 100644 (file)
@@ -1,3 +1,10 @@
+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.
+
 2017-01-20  Nathan Sidwell  <nathan@acm.org>
 
        PR c++/78495 - wrong code inherited ctor and invisi-ref parm
index 579c580..f677b48 100644 (file)
@@ -2730,19 +2730,9 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p,
     {
       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 object, tree name, bool template_p,
                       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 object, tree name, bool template_p,
              return error_mark_node;
            }
        }
-      else
-       {
-         scope = NULL_TREE;
-         access_path = object_type;
-       }
 
       if (TREE_CODE (name) == BIT_NOT_EXPR)
        {
index 10c34cc..f3ac5e5 100644 (file)
@@ -1,3 +1,9 @@
+2017-01-23  Nathan Sidwell  <nathan@acm.org>
+
+       PR c++/71406
+       PR c++/77508
+       * g++.dg/template/pr71406.C: New.
+
 2017-01-23  Thomas Koenig  <tkoenig@netcologne.de>
 
        * gfortran.dg/integer_exponentiation_7.f90:  New test.
diff --git a/gcc/testsuite/g++.dg/template/pr71406.C b/gcc/testsuite/g++.dg/template/pr71406.C
new file mode 100644 (file)
index 0000000..3629d7a
--- /dev/null
@@ -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 ();
+}