In the testcase, since there's no declaration of T, ref_view(T) declares a
non-static data member T of type ref_view, the same type as its enclosing
class.  Then when we try to do C++20 aggregate class template argument
deduction we recursively try to adjust the braced-init-list to match the
template class definition until we run out of stack.

Fixed by rejecting the template data member.  I was interested to see that
there was another test in the suite with this same wrong declaration.

Tested x86_64-pc-linux-gnu, applying to trunk.

        PR c++/92593
        * decl.c (grokdeclarator): Reject field of current class type even
        in a template.
---
 gcc/cp/decl.c                                  | 11 +++++++----
 gcc/testsuite/g++.dg/cpp1z/class-deduction68.C | 10 ++++++++++
 gcc/testsuite/g++.dg/parse/undefined3.C        |  2 +-
 gcc/testsuite/g++.dg/template/pr71710.C        |  4 ++--
 4 files changed, 20 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1z/class-deduction68.C

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 859fd1bb931..794370d0ff9 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -13259,10 +13259,13 @@ grokdeclarator (const cp_declarator *declarator,
            if (declspecs->explicit_specifier)
              store_explicit_specifier (decl, declspecs->explicit_specifier);
          }
-       else if (!staticp && !dependent_type_p (type)
-                && !COMPLETE_TYPE_P (complete_type (type))
-                && (!complete_or_array_type_p (type)
-                    || initialized == 0))
+       else if (!staticp
+                && ((current_class_type
+                     && same_type_p (type, current_class_type))
+                    || (!dependent_type_p (type)
+                        && !COMPLETE_TYPE_P (complete_type (type))
+                        && (!complete_or_array_type_p (type)
+                            || initialized == 0))))
          {
            if (TREE_CODE (type) != ARRAY_TYPE
                || !COMPLETE_TYPE_P (TREE_TYPE (type)))
diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction68.C 
b/gcc/testsuite/g++.dg/cpp1z/class-deduction68.C
new file mode 100644
index 00000000000..a761e70e09c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction68.C
@@ -0,0 +1,10 @@
+// PR c++/92593
+// { dg-do compile { target c++17 } }
+
+template<int I>
+struct ref_view
+{
+  ref_view(T) { };             // { dg-error "incomplete" }
+};
+
+ref_view r{1};                 // { dg-error "no match|deduction failed" }
diff --git a/gcc/testsuite/g++.dg/parse/undefined3.C 
b/gcc/testsuite/g++.dg/parse/undefined3.C
index 6bafd6fc695..ad445bcdf2f 100644
--- a/gcc/testsuite/g++.dg/parse/undefined3.C
+++ b/gcc/testsuite/g++.dg/parse/undefined3.C
@@ -2,5 +2,5 @@
 // Origin: Volker Reichelt <reich...@igpm.rwth-aachen.de>
 // { dg-do compile }
 
-template<typename T> struct A { A(B); };
+template<typename T> struct A { A(B); }; // { dg-error "incomplete" }
 template<typename T> A<T>::A(B) {} // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/template/pr71710.C 
b/gcc/testsuite/g++.dg/template/pr71710.C
index 7c394e793b7..1e78cbb62fe 100644
--- a/gcc/testsuite/g++.dg/template/pr71710.C
+++ b/gcc/testsuite/g++.dg/template/pr71710.C
@@ -3,8 +3,8 @@
 
 template < typename > struct A
 {
-  A a;
+  A a;                        // { dg-error "incomplete" }
   template < int > using B = decltype (a);
-  B < 0 > b;
+  B < 0 > b;                  // { dg-prune-output "B. does not name a type" }
   template < int C > B < C > foo ();
 };

base-commit: efe0e5cd64be70690ba287a8dd5841a2b5eefef1
-- 
2.18.1

Reply via email to