c++: Add testcases from some Issaquah DRs

The following patch adds testcases for 5 DRs.  In the DR2475, DR2530 and
CWG2691 my understanding is we already implement the desired behavior,
in DR2478 partially (I've added 2 dg-bogus there, I think we inherit
rather than overwrite DECL_DECLARED_CONSTINIT_P for explicit specialization
somewhere, still far better than clang++) and DR2673 on the other side the
DR was to codify the clang++ behavior rather than GCC.

Not 100% sure if it is better to commit the 2 with dg-bogus or just wait
until the actual fixes are implemented.  BTW, I've noticed
register_specialization does:
              FOR_EACH_CLONE (clone, fn)
                {
                  DECL_DECLARED_INLINE_P (clone)
                    = DECL_DECLARED_INLINE_P (fn);
                  DECL_SOURCE_LOCATION (clone)
                    = DECL_SOURCE_LOCATION (fn);
                  DECL_DELETED_FN (clone)
                    = DECL_DELETED_FN (fn);
                }
but not e.g. constexpr/consteval, have tried to cover that in a testcase
but haven't managed to do so.

2023-02-15  Jakub Jelinek  <jakub@redhat.com>

	* g++.dg/DRs/dr2475.C: New test.
	* g++.dg/DRs/dr2478.C: New test.
	* g++.dg/DRs/dr2530.C: New test.
	* g++.dg/DRs/dr2673.C: New test.
	* c-c++-common/cpp/delimited-escape-seq-8.c: New test.
This commit is contained in:
Jakub Jelinek 2023-02-15 09:34:41 +01:00
parent 86bc090961
commit 1e7a87dc19
5 changed files with 129 additions and 0 deletions

View file

@ -0,0 +1,20 @@
// CWG 2691 - hexadecimal-escape-sequence is too greedy
/* { dg-do run } */
/* { dg-require-effective-target wchar } */
/* { dg-options "-std=gnu99 -Wno-c++-compat" { target c } } */
/* { dg-options "-std=c++23" { target c++ } } */
#ifndef __cplusplus
#include <wchar.h>
typedef __CHAR16_TYPE__ char16_t;
typedef __CHAR32_TYPE__ char32_t;
#endif
const char32_t *a = U"\x{20}ab";
int
main ()
{
if (a[0] != U'\x20' || a[1] != U'a' || a[2] != U'b' || a[3] != U'\0')
__builtin_abort ();
}

View file

@ -0,0 +1,6 @@
// DR 2475 - Object declarations of type cv void
// { dg-do compile }
int f(), x;
extern void g(),
y; // { dg-error "variable or field 'y' declared void" }

View file

@ -0,0 +1,74 @@
// DR 2478 - Properties of explicit specializations of implicitly-instantiated class templates
// { dg-do compile { target c++20 } }
template <typename T>
struct S {
int foo () { return 0; }
constexpr int bar () { return 0; }
int baz () { return 0; }
consteval int qux () { return 0; }
constexpr S () {}
static constinit T x;
static T y;
};
template <typename T>
T S<T>::x = S<T> ().foo (); // { dg-error "'constinit' variable 'S<char>::x' does not have a constant initializer" }
// { dg-error "call to non-'constexpr' function" "" { target *-*-* } .-1 }
template <typename T>
T S<T>::y = S<T> ().foo ();
template <>
constexpr int
S<int>::foo ()
{
return 0;
}
template <>
int
S<int>::bar ()
{
return 0;
}
template <>
consteval int
S<char>::baz ()
{
return 0;
}
template <>
int
S<char>::qux ()
{
return 0;
}
template <>
long S<long>::x = S<long> ().foo (); // { dg-bogus "'constinit' variable 'S<long int>::x' does not have a constant initializer" "" { xfail *-*-* } }
// { dg-bogus "call to non-'constexpr' function" "" { xfail *-*-* } .-1 }
template <>
constinit long S<long>::y = S<long> ().foo (); // { dg-error "'constinit' variable 'S<long int>::y' does not have a constant initializer" }
// { dg-error "call to non-'constexpr' function" "" { target *-*-* } .-1 }
constinit auto a = S<char> ().foo (); // { dg-error "'constinit' variable 'a' does not have a constant initializer" }
// { dg-error "call to non-'constexpr' function" "" { target *-*-* } .-1 }
constinit auto b = S<char> ().bar ();
constinit auto c = S<int> ().foo ();
constinit auto d = S<int> ().bar (); // { dg-error "'constinit' variable 'd' does not have a constant initializer" }
// { dg-error "call to non-'constexpr' function" "" { target *-*-* } .-1 }
constinit auto e = S<char> ().baz ();
constinit auto f = S<char> ().qux (); // { dg-error "'constinit' variable 'f' does not have a constant initializer" }
// { dg-error "call to non-'constexpr' function" "" { target *-*-* } .-1 }
constinit auto g = S<int> ().baz (); // { dg-error "'constinit' variable 'g' does not have a constant initializer" }
// { dg-error "call to non-'constexpr' function" "" { target *-*-* } .-1 }
constinit auto h = S<int> ().qux ();
auto i = S<char>::x;
auto j = S<int>::x;
auto k = S<long>::x;
auto l = S<char>::y;
auto m = S<int>::y;

View file

@ -0,0 +1,5 @@
// DR 2530 - Multiple definitions of enumerators
// { dg-do compile }
enum E { e, e }; // { dg-error "redefinition of 'e'" }
enum F { f = 0, f = 0 }; // { dg-error "redefinition of 'f'" }

View file

@ -0,0 +1,24 @@
// DR 2673 - User-declared spaceship vs. built-in operators
// { dg-do compile { target c++20 } }
#include <compare>
enum class E : int { E1, E2 };
enum class F : int { F1, F2 };
constexpr auto
operator<=> (E lhs, E rhs)
{
return (int) rhs <=> (int) lhs;
}
constexpr bool
operator== (F lhs, F rhs)
{
return (int) lhs != (int) rhs;
}
static_assert ((E::E1 <=> E::E2) == (1 <=> 0));
static_assert (E::E1 > E::E2); // { dg-bogus "static assertion failed" "" { xfail *-*-* } }
static_assert (F::F1 == F::F2);
static_assert (!(F::F1 != F::F2)); // { dg-bogus "static assertion failed" "" { xfail *-*-* } }