aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-02-04 18:49:16 -0500
committerJason Merrill <jason@redhat.com>2020-02-05 14:14:50 -0500
commitfa0c6e297b22d5883857d0db4a6a8be0967cb16f (patch)
tree8a1e21632424bc019ca81c1991b8d8e04cfa67d0
parentefe0e5cd64be70690ba287a8dd5841a2b5eefef1 (diff)
downloadgcc-fa0c6e297b22d5883857d0db4a6a8be0967cb16f.zip
gcc-fa0c6e297b22d5883857d0db4a6a8be0967cb16f.tar.gz
gcc-fa0c6e297b22d5883857d0db4a6a8be0967cb16f.tar.bz2
c++: Fix SEGV with malformed constructor decl.
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.
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/decl.c11
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/class-deduction68.C10
-rw-r--r--gcc/testsuite/g++.dg/parse/undefined3.C2
-rw-r--r--gcc/testsuite/g++.dg/template/pr71710.C4
5 files changed, 26 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7c24ab8..d3c40e1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 859fd1b..794370d 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 0000000..a761e70
--- /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 6bafd6f..ad445bc 100644
--- a/gcc/testsuite/g++.dg/parse/undefined3.C
+++ b/gcc/testsuite/g++.dg/parse/undefined3.C
@@ -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 "" }
diff --git a/gcc/testsuite/g++.dg/template/pr71710.C b/gcc/testsuite/g++.dg/template/pr71710.C
index 7c394e7..1e78cbb 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 ();
};