From fa0c6e297b22d5883857d0db4a6a8be0967cb16f Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 4 Feb 2020 18:49:16 -0500 Subject: [PATCH] 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. --- gcc/cp/ChangeLog | 6 ++++++ 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 ++-- 5 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/class-deduction68.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7c24ab8b33b..d3c40e15ee9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2020-02-05 Jason Merrill + + PR c++/92593 + * decl.c (grokdeclarator): Reject field of current class type even + in a template. + 2020-02-05 Bin Cheng * coroutines.cc (maybe_promote_captured_temps): Increase the index 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 +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 // { dg-do compile } -template struct A { A(B); }; +template struct A { A(B); }; // { dg-error "incomplete" } template A::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 (); }; -- 2.30.2