diff options
author | Jason Merrill <jason@redhat.com> | 2020-02-04 18:49:16 -0500 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2020-02-05 14:14:50 -0500 |
commit | fa0c6e297b22d5883857d0db4a6a8be0967cb16f (patch) | |
tree | 8a1e21632424bc019ca81c1991b8d8e04cfa67d0 | |
parent | efe0e5cd64be70690ba287a8dd5841a2b5eefef1 (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/decl.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/class-deduction68.C | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/undefined3.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/pr71710.C | 4 |
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 (); }; |