The problem here was that finish_qualified_id_expr was throwing away
the nested-name-specifier, which is necessary to avoid this error.

Tested x86_64-pc-linux-gnu, applying to trunk and 8.
commit b96ede757f83783d388623b26312a0514bfec8a6
Author: Jason Merrill <ja...@redhat.com>
Date:   Tue Jun 5 01:05:09 2018 +0200

            PR c++/85731 - wrong error with qualified-id in template.
    
            * semantics.c (finish_qualified_id_expr): build_qualified_name
            for unbound names in the current class.

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index e00331a3ea4..a3426623385 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2098,6 +2098,8 @@ finish_qualified_id_expr (tree qualifying_class,
 	 non-type template argument handling.  */
       if (processing_template_decl
 	  && (!currently_open_class (qualifying_class)
+	      || TREE_CODE (expr) == IDENTIFIER_NODE
+	      || TREE_CODE (expr) == TEMPLATE_ID_EXPR
 	      || TREE_CODE (expr) == BIT_NOT_EXPR))
 	expr = build_qualified_name (TREE_TYPE (expr),
 				     qualifying_class, expr,
diff --git a/gcc/testsuite/g++.dg/template/qualified-id7.C b/gcc/testsuite/g++.dg/template/qualified-id7.C
new file mode 100644
index 00000000000..fd952f6fbcf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/qualified-id7.C
@@ -0,0 +1,15 @@
+// PR c++/85731
+// { dg-do compile { target c++11 } }
+
+    template <typename T>
+    struct Outer {
+        struct Inner;
+        template <int I> static void f();
+    };
+
+    template <typename T>
+    struct Outer<T>::Inner {
+        decltype(Outer<T>::f<42>()) f();
+    };
+
+    int main() { Outer<int>::Inner().f(); }

Reply via email to