c++: Fix ICE on defaulted spaceship with pointer return type [PR94162]
The spaceship-synth-neg6.C testcase ICEs because we call cat_tag_for on the explicit return type, but pointer types don't have TYPE_LINKAGE_IDENTIFIER. The patch fixes that by checking for CLASS_TYPE_P only and also adds verification that it is in std namespace, so we don't return non-cc_last for my_namespace::partial_ordering. The g++.dg/cpp2a/spaceship-synth11.C testcase is from a PR that has been fixed with r12-619-gfc178519771db508c03611cff4a1466cf67fce1d (but not backported to 11). 2021-08-12 Jakub Jelinek <jakub@redhat.com> gcc/cp/ PR c++/94162 * method.c (cat_tag_for): Return cc_last for !CLASS_TYPE_P or for classes not in std namespace. gcc/testsuite/ PR c++/99429 * g++.dg/cpp2a/spaceship-synth11.C: New test. PR c++/94162 * g++.dg/cpp2a/spaceship-synth-neg6.C: New test.
This commit is contained in:
parent
c84f79e9e3
commit
9b7ab853bf
@ -1029,6 +1029,8 @@ is_cat (tree type, comp_cat_tag tag)
|
||||
static comp_cat_tag
|
||||
cat_tag_for (tree type)
|
||||
{
|
||||
if (!CLASS_TYPE_P (type) || !decl_in_std_namespace_p (TYPE_MAIN_DECL (type)))
|
||||
return cc_last;
|
||||
for (int i = 0; i < cc_last; ++i)
|
||||
{
|
||||
comp_cat_tag tag = (comp_cat_tag)i;
|
||||
|
11
gcc/testsuite/g++.dg/cpp2a/spaceship-synth-neg6.C
Normal file
11
gcc/testsuite/g++.dg/cpp2a/spaceship-synth-neg6.C
Normal file
@ -0,0 +1,11 @@
|
||||
// PR c++/94162
|
||||
// { dg-do compile { target c++20 } }
|
||||
|
||||
#include <compare>
|
||||
|
||||
struct S {
|
||||
int a; // { dg-error "three-way comparison of 'S::a' has type 'std::strong_ordering', which does not convert to 'int\\*'" }
|
||||
int *operator<=>(const S&) const = default;
|
||||
};
|
||||
|
||||
bool b = S{} < S{}; // { dg-error "use of deleted function 'constexpr int\\* S::operator<=>\\\(const S&\\\) const'" }
|
29
gcc/testsuite/g++.dg/cpp2a/spaceship-synth11.C
Normal file
29
gcc/testsuite/g++.dg/cpp2a/spaceship-synth11.C
Normal file
@ -0,0 +1,29 @@
|
||||
// PR c++/99429
|
||||
// { dg-do compile { target c++20 } }
|
||||
|
||||
namespace std {
|
||||
struct strong_ordering {
|
||||
int _v;
|
||||
constexpr strong_ordering (int v) :_v(v) {}
|
||||
constexpr operator int (void) const { return _v; }
|
||||
static const strong_ordering less;
|
||||
static const strong_ordering equal;
|
||||
static const strong_ordering greater;
|
||||
};
|
||||
constexpr strong_ordering strong_ordering::less = -1;
|
||||
constexpr strong_ordering strong_ordering::equal = 0;
|
||||
constexpr strong_ordering strong_ordering::greater = 1;
|
||||
}
|
||||
|
||||
template <unsigned long N>
|
||||
struct duration {
|
||||
static constexpr const long period = N;
|
||||
constexpr duration (void) = default;
|
||||
constexpr duration (const duration& d) = default;
|
||||
constexpr bool operator== (const duration& d) const = default;
|
||||
constexpr bool operator<=> (const duration& d) const = default;
|
||||
long _d;
|
||||
};
|
||||
|
||||
using nanoseconds = duration<1>;
|
||||
using microseconds = duration<nanoseconds::period * 1000>;
|
Loading…
Reference in New Issue
Block a user