PR c++/92774 - ICE with implicitly deleted operator<=>.

Missing error-recovery code.  While I was poking at this I also figured we
don't need to iterate over the members of a union.

	* method.c (comp_info::~comp_info): Factor out of...
	(build_comparison_op): Here.  Handle error return from build_new_op.

From-SVN: r279235
This commit is contained in:
Jason Merrill 2019-12-11 11:51:05 -05:00 committed by Jason Merrill
parent d6e8c01cff
commit 60e457d9ca
3 changed files with 50 additions and 12 deletions

View File

@ -1,5 +1,9 @@
2019-12-11 Jason Merrill <jason@redhat.com>
PR c++/92774 - ICE with implicitly deleted operator<=>.
* method.c (comp_info::~comp_info): Factor out of...
(build_comparison_op): Here. Handle error return from build_new_op.
PR c++/92859 - ADL and bit-field.
* name-lookup.c: Use unlowered_expr_type.

View File

@ -1244,6 +1244,21 @@ struct comp_info
if (noex && !expr_noexcept_p (expr, tf_none))
noex = false;
}
~comp_info ()
{
if (first_time)
{
DECL_DECLARED_CONSTEXPR_P (fndecl) = constexp || was_constexp;
tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fndecl));
if (!raises || UNEVALUATED_NOEXCEPT_SPEC_P (raises))
{
raises = noex ? noexcept_true_spec : noexcept_false_spec;
TREE_TYPE (fndecl) = build_exception_variant (TREE_TYPE (fndecl),
raises);
}
}
}
};
/* Build up the definition of a defaulted comparison operator. Unlike other
@ -1282,6 +1297,7 @@ build_comparison_op (tree fndecl, tsubst_flags_t complain)
if (complain & tf_error)
inform (info.loc, "cannot default compare union %qT", ctype);
DECL_DELETED_FN (fndecl) = true;
return;
}
tree compound_stmt = NULL_TREE;
@ -1335,6 +1351,11 @@ build_comparison_op (tree fndecl, tsubst_flags_t complain)
NULL_TREE);
tree comp = build_new_op (info.loc, code, flags, lhs_mem, rhs_mem,
NULL_TREE, NULL, complain);
if (comp == error_mark_node)
{
DECL_DELETED_FN (fndecl) = true;
continue;
}
comps.safe_push (comp);
}
if (code == SPACESHIP_EXPR && is_auto (rettype))
@ -1430,18 +1451,6 @@ build_comparison_op (tree fndecl, tsubst_flags_t complain)
finish_compound_stmt (compound_stmt);
else
--cp_unevaluated_operand;
if (info.first_time)
{
DECL_DECLARED_CONSTEXPR_P (fndecl) = info.constexp || info.was_constexp;
tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fndecl));
if (!raises || UNEVALUATED_NOEXCEPT_SPEC_P (raises))
{
raises = info.noex ? noexcept_true_spec : noexcept_false_spec;
TREE_TYPE (fndecl) = build_exception_variant (TREE_TYPE (fndecl),
raises);
}
}
}
/* Synthesize FNDECL, a non-static member function. */

View File

@ -0,0 +1,25 @@
// PR c++/92774
// { dg-do compile { target c++2a } }
#include <compare>
template<typename T>
struct X { };
template<typename T>
bool operator==(const X<T>&, const X<T>&) { return true; }
template<typename T>
bool operator<(const X<T>&, const X<T>&) { return true; }
struct Y
{
int a;
X<int> c;
auto operator <=>(Y const&) const = default; // { dg-error "no match" }
};
void f()
{
auto x = Y() < Y(); // { dg-error "deleted" }
}