c++: Fix SEGV with malformed constructor decl.
authorJason Merrill <jason@redhat.com>
Tue, 4 Feb 2020 23:49:16 +0000 (18:49 -0500)
committerJason Merrill <jason@redhat.com>
Wed, 5 Feb 2020 19:14:50 +0000 (14:14 -0500)
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.

PR c++/92593
* decl.c (grokdeclarator): Reject field of current class type even
in a template.

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/g++.dg/cpp1z/class-deduction68.C [new file with mode: 0644]
gcc/testsuite/g++.dg/parse/undefined3.C
gcc/testsuite/g++.dg/template/pr71710.C

index 7c24ab8..d3c40e1 100644 (file)
@@ -1,3 +1,9 @@
+2020-02-05  Jason Merrill  <jason@redhat.com>
+
+       PR c++/92593
+       * decl.c (grokdeclarator): Reject field of current class type even
+       in a template.
+
 2020-02-05  Bin Cheng  <bin.cheng@linux.alibaba.com>
 
        * coroutines.cc (maybe_promote_captured_temps): Increase the index
index 859fd1b..794370d 100644 (file)
@@ -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 (file)
index 0000000..a761e70
--- /dev/null
@@ -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" }
index 6bafd6f..ad445bc 100644 (file)
@@ -2,5 +2,5 @@
 // Origin: Volker Reichelt <reichelt@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 "" }
index 7c394e7..1e78cbb 100644 (file)
@@ -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 ();
 };