c++: Redeclaration of implicit operator== [PR94583]
My last patch rejected a namespace-scope declaration of the implicitly-declared friend operator== before the class, but redeclaring it after the class should be OK. gcc/cp/ChangeLog 2020-04-28 Jason Merrill <jason@redhat.com> PR c++/94583 * decl.c (use_eh_spec_block): Check nothrow type after DECL_DEFAULTED_FN. * pt.c (maybe_instantiate_noexcept): Call synthesize_method for DECL_MAYBE_DELETED fns here. * decl2.c (mark_used): Not here. * method.c (get_defaulted_eh_spec): Reject DECL_MAYBE_DELETED here.
This commit is contained in:
parent
5eae0ac76d
commit
bce54ed494
7 changed files with 38 additions and 21 deletions
|
@ -1,3 +1,13 @@
|
|||
2020-04-28 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/94583
|
||||
* decl.c (use_eh_spec_block): Check nothrow type after
|
||||
DECL_DEFAULTED_FN.
|
||||
* pt.c (maybe_instantiate_noexcept): Call synthesize_method for
|
||||
DECL_MAYBE_DELETED fns here.
|
||||
* decl2.c (mark_used): Not here.
|
||||
* method.c (get_defaulted_eh_spec): Reject DECL_MAYBE_DELETED here.
|
||||
|
||||
2020-04-28 Iain Sandoe <iain@sandoe.co.uk>
|
||||
|
||||
PR c++/94760
|
||||
|
|
|
@ -3169,7 +3169,7 @@ struct GTY(()) lang_decl {
|
|||
(LANG_DECL_FN_CHECK (NODE)->has_dependent_explicit_spec_p)
|
||||
|
||||
/* Nonzero for a defaulted FUNCTION_DECL for which we haven't decided yet if
|
||||
it's deleted. */
|
||||
it's deleted; we will decide in synthesize_method. */
|
||||
#define DECL_MAYBE_DELETED(NODE) \
|
||||
(LANG_DECL_FN_CHECK (NODE)->maybe_deleted)
|
||||
|
||||
|
|
|
@ -16503,7 +16503,6 @@ use_eh_spec_block (tree fn)
|
|||
{
|
||||
return (flag_exceptions && flag_enforce_eh_specs
|
||||
&& !processing_template_decl
|
||||
&& !type_throw_all_p (TREE_TYPE (fn))
|
||||
/* We insert the EH_SPEC_BLOCK only in the original
|
||||
function; then, it is copied automatically to the
|
||||
clones. */
|
||||
|
@ -16516,7 +16515,8 @@ use_eh_spec_block (tree fn)
|
|||
not creating the EH_SPEC_BLOCK we save a little memory,
|
||||
and we avoid spurious warnings about unreachable
|
||||
code. */
|
||||
&& !DECL_DEFAULTED_FN (fn));
|
||||
&& !DECL_DEFAULTED_FN (fn)
|
||||
&& !type_throw_all_p (TREE_TYPE (fn)));
|
||||
}
|
||||
|
||||
/* Helper function to push ARGS into the current lexical scope. DECL
|
||||
|
|
|
@ -5512,17 +5512,6 @@ mark_used (tree decl, tsubst_flags_t complain)
|
|||
if (TREE_CODE (decl) == CONST_DECL)
|
||||
used_types_insert (DECL_CONTEXT (decl));
|
||||
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& DECL_MAYBE_DELETED (decl))
|
||||
{
|
||||
/* ??? Switch other defaulted functions to use DECL_MAYBE_DELETED? */
|
||||
gcc_assert (special_function_p (decl) == sfk_comparison);
|
||||
|
||||
++function_depth;
|
||||
synthesize_method (decl);
|
||||
--function_depth;
|
||||
}
|
||||
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& !maybe_instantiate_noexcept (decl, complain))
|
||||
return false;
|
||||
|
|
|
@ -2411,16 +2411,13 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
|
|||
tree
|
||||
get_defaulted_eh_spec (tree decl, tsubst_flags_t complain)
|
||||
{
|
||||
/* For DECL_MAYBE_DELETED this should already have been handled by
|
||||
synthesize_method. */
|
||||
gcc_assert (!DECL_MAYBE_DELETED (decl));
|
||||
|
||||
if (DECL_CLONED_FUNCTION_P (decl))
|
||||
decl = DECL_CLONED_FUNCTION (decl);
|
||||
special_function_kind sfk = special_function_p (decl);
|
||||
if (sfk == sfk_comparison)
|
||||
{
|
||||
/* We're in synthesize_method. Start with NULL_TREE, build_comparison_op
|
||||
will adjust as needed. */
|
||||
gcc_assert (decl == current_function_decl);
|
||||
return NULL_TREE;
|
||||
}
|
||||
tree ctype = DECL_CONTEXT (decl);
|
||||
tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
|
||||
tree parm_type = TREE_VALUE (parms);
|
||||
|
|
12
gcc/cp/pt.c
12
gcc/cp/pt.c
|
@ -25180,6 +25180,18 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain)
|
|||
&& (!flag_noexcept_type || type_dependent_expression_p (fn)))
|
||||
return true;
|
||||
|
||||
if (DECL_MAYBE_DELETED (fn))
|
||||
{
|
||||
if (fn == current_function_decl)
|
||||
/* We're in start_preparsed_function, keep going. */
|
||||
return true;
|
||||
|
||||
++function_depth;
|
||||
synthesize_method (fn);
|
||||
--function_depth;
|
||||
return !DECL_MAYBE_DELETED (fn);
|
||||
}
|
||||
|
||||
if (DECL_CLONED_FUNCTION_P (fn))
|
||||
fn = DECL_CLONED_FUNCTION (fn);
|
||||
|
||||
|
|
9
gcc/testsuite/g++.dg/cpp2a/spaceship-synth7.C
Normal file
9
gcc/testsuite/g++.dg/cpp2a/spaceship-synth7.C
Normal file
|
@ -0,0 +1,9 @@
|
|||
// PR c++/94583
|
||||
// { dg-do compile { target c++2a } }
|
||||
|
||||
namespace std { struct strong_ordering { }; }
|
||||
|
||||
struct Q {
|
||||
friend std::strong_ordering operator<=>(const Q&, const Q&) = default;
|
||||
};
|
||||
bool operator==(const Q&, const Q&) noexcept;
|
Loading…
Add table
Reference in a new issue