diff options
author | Jason Merrill <jason@redhat.com> | 2022-03-22 01:10:44 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2022-03-24 14:31:16 -0400 |
commit | 346ab5a54a831ad9c78afcbd8dfe98e0e07e3070 (patch) | |
tree | 36735be4a7405f057480072aef7ba5231740aaef /gcc/cp/class.cc | |
parent | f0530882d99abc410bb080051aa04e5cea848f18 (diff) | |
download | gcc-346ab5a54a831ad9c78afcbd8dfe98e0e07e3070.zip gcc-346ab5a54a831ad9c78afcbd8dfe98e0e07e3070.tar.gz gcc-346ab5a54a831ad9c78afcbd8dfe98e0e07e3070.tar.bz2 |
c++: delayed parse DMI [PR96645]
With the changes for PR81359 and PR88368 to make get_nsdmi errors be treated
as substitution failure, we have the problem that if we check
std::is_default_constructible for a complete class that still has unparsed
default member initializers, we get an answer (false) that will be wrong
once the DMIs have been parsed. The traits avoid this problem for regular
incomplete classes by giving an error if the operand is incomplete; we
should do the same if get_nsdmi is going to fail due to unparsed DMI.
PR c++/96645
gcc/cp/ChangeLog:
* cp-tree.h (type_has_default_ctor_to_be_synthesized): Declare.
* class.cc (type_has_default_ctor_to_be_synthesized): New.
(type_has_non_user_provided_default_constructor_1): Support it.
(type_has_non_user_provided_default_constructor): Now a wrapper.
* method.cc (complain_about_unparsed_dmi): New.
(constructible_expr): Call it.
gcc/testsuite/ChangeLog:
* g++.dg/ext/is_constructible3.C: Expect error.
* g++.dg/ext/is_constructible7.C: New test.
Diffstat (limited to 'gcc/cp/class.cc')
-rw-r--r-- | gcc/cp/class.cc | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc index 40e1714..c75b889 100644 --- a/gcc/cp/class.cc +++ b/gcc/cp/class.cc @@ -5415,10 +5415,11 @@ type_has_user_provided_or_explicit_constructor (tree t) /* Returns true iff class T has a non-user-provided (i.e. implicitly declared or explicitly defaulted in the class body) default - constructor. */ + constructor. If SYNTH, only return true if it hasn't been + implicitly defined yet. */ -bool -type_has_non_user_provided_default_constructor (tree t) +static bool +type_has_non_user_provided_default_constructor_1 (tree t, bool synth) { if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (t)) return false; @@ -5431,12 +5432,28 @@ type_has_non_user_provided_default_constructor (tree t) if (TREE_CODE (fn) == FUNCTION_DECL && default_ctor_p (fn) && !user_provided_p (fn)) - return true; + { + if (synth) + return !DECL_INITIAL (fn); + return true; + } } return false; } +bool +type_has_non_user_provided_default_constructor (tree t) +{ + return type_has_non_user_provided_default_constructor_1 (t, false); +} + +bool +type_has_default_ctor_to_be_synthesized (tree t) +{ + return type_has_non_user_provided_default_constructor_1 (t, true); +} + /* TYPE is being used as a virtual base, and has a non-trivial move assignment. Return true if this is due to there being a user-provided move assignment in TYPE or one of its subobjects; if there isn't, then |