bolt/deps/llvm-18.1.8/clang/test/CXX/drs/dr18xx.cpp
2025-02-14 19:21:04 +01:00

461 lines
14 KiB
C++

// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected,cxx98-14,cxx98 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,cxx98-14,cxx11-17,since-cxx11 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,cxx98-14,cxx11-17,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx17,cxx11-17,since-cxx11,since-cxx14,cxx17 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
#if __cplusplus == 199711L
#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
// cxx98-error@-1 {{variadic macros are a C99 feature}}
#endif
namespace dr1800 { // dr1800: 2.9
struct A { union { int n; }; };
static_assert(__is_same(__decltype(&A::n), int A::*), "");
} // namespace dr1800
namespace dr1801 { // dr1801: 2.8
static union {
int i;
};
template <int &> struct S {}; // #dr1801-S
S<i> V; // #dr1801-S-i
// cxx98-14-error@-1 {{non-type template argument does not refer to any declaration}}
// cxx98-14-note@#dr1801-S {{template parameter is declared here}}
// cxx17-error@#dr1801-S-i {{non-type template argument refers to subobject '.i'}}
}
namespace dr1802 { // dr1802: 3.1
#if __cplusplus >= 201103L
// Using a Wikipedia example of surrogate pair:
// https://en.wikipedia.org/wiki/UTF-16#Examples
constexpr char16_t a[3] = u"\U00010437";
static_assert(a[0] == 0xD801, "");
static_assert(a[1] == 0xDC37, "");
static_assert(a[2] == 0x0, "");
#endif
} // namespace dr1802
namespace dr1803 { // dr1803: 2.9
#if __cplusplus >= 201103L
struct A {
enum E : int;
enum E : int {};
enum class EC;
enum class EC {};
enum struct ES;
enum struct ES {};
};
#endif
} // namespace dr1803
namespace dr1804 { // dr1804: 2.7
template <typename, typename>
struct A {
void f1();
template <typename V>
void f2(V);
class B {
void f3();
};
template <typename>
class C {
void f4();
};
};
template <typename U>
struct A<int, U> {
void f1();
template <typename V>
void f2(V);
class B {
void f3();
};
template <typename>
class C {
void f4();
};
};
class D {
int i;
template <typename, typename>
friend struct A;
};
template <typename U>
struct A<double, U> {
void f1();
template <typename V>
void f2(V);
class B {
void f3();
};
template <typename>
class C {
void f4();
};
};
template <typename U>
void A<int, U>::f1() {
D d;
d.i = 0;
}
template <typename U>
void A<double, U>::f1() {
D d;
d.i = 0;
}
template <typename U>
template <typename V>
void A<int, U>::f2(V) {
D d;
d.i = 0;
}
template <typename U>
template <typename V>
void A<double, U>::f2(V) {
D d;
d.i = 0;
}
template <typename U>
void A<int, U>::B::f3() {
D d;
d.i = 0;
}
template <typename U>
void A<double, U>::B::f3() {
D d;
d.i = 0;
}
template <typename U>
template <typename V>
void A<int, U>::C<V>::f4() {
D d;
d.i = 0;
}
template <typename U>
template <typename V>
void A<double, U>::C<V>::f4() {
D d;
d.i = 0;
}
} // namespace dr1804
// dr1807 is in dr1807.cpp
namespace dr1812 { // dr1812: no
// NB: dup 1710
#if __cplusplus >= 201103L
template <typename T> struct A {
using B = typename T::C<int>;
// since-cxx11-error@-1 {{use 'template' keyword to treat 'C' as a dependent template name}}
};
#endif
} // namespace dr1812
namespace dr1813 { // dr1813: 7
struct B { int i; };
struct C : B {};
struct D : C {};
struct E : D { char : 4; };
static_assert(__is_standard_layout(B), "");
static_assert(__is_standard_layout(C), "");
static_assert(__is_standard_layout(D), "");
static_assert(!__is_standard_layout(E), "");
struct Q {};
struct S : Q {};
struct T : Q {};
struct U : S, T {};
static_assert(__is_standard_layout(Q), "");
static_assert(__is_standard_layout(S), "");
static_assert(__is_standard_layout(T), "");
static_assert(!__is_standard_layout(U), "");
}
namespace dr1814 { // dr1814: yes
#if __cplusplus >= 201103L
void test() {
auto lam = [](int x = 42) { return x; };
}
#endif
}
namespace dr1815 { // dr1815: no
#if __cplusplus >= 201402L
// FIXME: needs codegen test
struct A { int &&r = 0; }; // #dr1815-A
A a = {};
// since-cxx14-warning@-1 {{lifetime extension of temporary created by aggregate initialization using a default member initializer is not yet supported; lifetime of temporary will end at the end of the full-expression}} FIXME
// since-cxx14-note@#dr1815-A {{initializing field 'r' with default member initializer}}
struct B { int &&r = 0; }; // #dr1815-B
// since-cxx14-error@-1 {{reference member 'r' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
// since-cxx14-note@#dr1815-B {{initializing field 'r' with default member initializer}}
// since-cxx14-note@#dr1815-b {{in implicit default constructor for 'dr1815::B' first required here}}
B b; // #dr1815-b
#endif
}
namespace dr1821 { // dr1821: 2.9
struct A {
template <typename> struct B {
void f();
};
template <typename T> void B<T>::f(){};
// expected-error@-1 {{non-friend class member 'f' cannot have a qualified name}}
struct C {
void f();
};
void C::f() {}
// expected-error@-1 {{non-friend class member 'f' cannot have a qualified name}}
};
} // namespace dr1821
namespace dr1822 { // dr1822: yes
#if __cplusplus >= 201103L
double a;
auto x = [] (int a) {
static_assert(__is_same(decltype(a), int), "should be resolved to lambda parameter");
};
#endif
}
namespace dr1837 { // dr1837: 3.3
#if __cplusplus >= 201103L
template <typename T>
struct Fish { static const bool value = true; };
struct Other {
int p();
auto q() -> decltype(p()) *;
};
class Outer {
friend auto Other::q() -> decltype(this->p()) *;
// since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}}
int g();
int f() {
extern void f(decltype(this->g()) *);
struct Inner {
static_assert(Fish<decltype(this->g())>::value, "");
// since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}}
enum { X = Fish<decltype(this->f())>::value };
// since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}}
struct Inner2 : Fish<decltype(this->g())> { };
// since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}}
friend void f(decltype(this->g()) *);
// since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}}
friend auto Other::q() -> decltype(this->p()) *;
// since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}}
};
return 0;
}
};
struct A {
int f();
bool b = [] {
struct Local {
static_assert(sizeof(this->f()) == sizeof(int), "");
};
};
};
#endif
}
namespace dr1872 { // dr1872: 9
#if __cplusplus >= 201103L
template<typename T> struct A : T {
constexpr int f() const { return 0; }
};
struct X {};
struct Y { virtual int f() const; };
struct Z : virtual X {};
constexpr int x = A<X>().f();
constexpr int y = A<Y>().f();
// cxx11-17-error@-1 {{constexpr variable 'y' must be initialized by a constant expression}}
// cxx11-17-note@-2 {{cannot evaluate call to virtual function in a constant expression in C++ standards before C++20}}
#if __cplusplus >= 202002L
static_assert(y == 0);
#endif
// Note, this is invalid even though it would not use virtual dispatch.
constexpr int y2 = A<Y>().A<Y>::f();
// cxx11-17-error@-1 {{constexpr variable 'y2' must be initialized by a constant expression}}
// cxx11-17-note@-2 {{cannot evaluate call to virtual function in a constant expression in C++ standards before C++20}}
#if __cplusplus >= 202002L
static_assert(y == 0);
#endif
constexpr int z = A<Z>().f();
// since-cxx11-error@-1 {{constexpr variable 'z' must be initialized by a constant expression}}
// since-cxx11-note@-2 {{non-literal type 'A<Z>' cannot be used in a constant expression}}
#endif
}
namespace dr1878 { // dr1878: 18
#if __cplusplus >= 201402L
#if __cplusplus >= 202002L
template <typename T>
concept C = true;
#endif
struct S {
template <typename T>
operator auto() const { return short(); }
// since-cxx14-error@-1 {{'auto' not allowed in declaration of conversion function template}}
template <typename T>
operator const auto() const { return int(); }
// since-cxx14-error@-1 {{'auto' not allowed in declaration of conversion function template}}
template <typename T>
operator const auto&() const { return char(); }
// since-cxx14-error@-1 {{'auto' not allowed in declaration of conversion function template}}
template <typename T>
operator const auto*() const { return long(); }
// since-cxx14-error@-1 {{'auto' not allowed in declaration of conversion function template}}
template <typename T>
operator decltype(auto)() const { return unsigned(); }
// since-cxx14-error@-1 {{'decltype(auto)' not allowed in declaration of conversion function template}}
#if __cplusplus >= 202002L
template <typename T>
operator C auto() const { return float(); }
// since-cxx20-error@-1 {{'auto' not allowed in declaration of conversion function template}}
template <typename T>
operator C decltype(auto)() const { return double(); }
// since-cxx20-error@-1 {{'decltype(auto)' not allowed in declaration of conversion function template}}
#endif
};
#endif
}
namespace dr1881 { // dr1881: 7
struct A { int a : 4; };
struct B : A { int b : 3; };
static_assert(__is_standard_layout(A), "");
static_assert(!__is_standard_layout(B), "");
struct C { int : 0; };
struct D : C { int : 0; };
static_assert(__is_standard_layout(C), "");
static_assert(!__is_standard_layout(D), "");
}
namespace dr1890 { // dr1890: no drafting
// FIXME: current consensus for CWG2335 is that the examples are well-formed.
namespace ex1 {
#if __cplusplus >= 201402L
struct A {
struct B {
auto foo() { return 0; } // #dr1890-foo
};
decltype(B().foo()) x;
// since-cxx14-error@-1 {{function 'foo' with deduced return type cannot be used before it is defined}}
// since-cxx14-note@#dr1890-foo {{'foo' declared here}}
};
#endif
} // namespace ex1
namespace ex2 {
#if __cplusplus >= 201103L
struct Bar {
struct Baz {
int a = 0;
};
static_assert(__is_constructible(Baz), "");
// since-cxx11-error@-1 {{static assertion failed due to requirement '__is_constructible(dr1890::ex2::Bar::Baz)'}}
};
#endif
} // namespace ex2
} // namespace dr1890
void dr1891() { // dr1891: 4
#if __cplusplus >= 201103L
int n;
auto a = []{}; // #dr1891-a
auto b = [=]{ return n; }; // #dr1891-b
typedef decltype(a) A;
typedef decltype(b) B;
static_assert(!__has_trivial_constructor(A), "");
// since-cxx20-error@-1 {{failed}}
static_assert(!__has_trivial_constructor(B), "");
// C++20 allows default construction for non-capturing lambdas (P0624R2).
A x;
// cxx11-17-error@-1 {{no matching constructor for initialization of 'A' (aka '(lambda at}}
// cxx11-17-note@#dr1891-a {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided}}
// cxx11-17-note@#dr1891-a {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided}}
B y;
// since-cxx11-error@-1 {{no matching constructor for initialization of 'B' (aka '(lambda at}}
// since-cxx11-note@#dr1891-b {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided}}
// since-cxx11-note@#dr1891-b {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided}}
// C++20 allows assignment for non-capturing lambdas (P0624R2).
a = a;
// cxx11-17-error-re@-1 {{{{object of type '\(lambda at .+\)' cannot be assigned because its copy assignment operator is implicitly deleted}}}}
// cxx11-17-note@#dr1891-a {{lambda expression begins here}}
a = static_cast<A&&>(a);
// cxx11-17-error-re@-1 {{{{object of type '\(lambda at .+\)' cannot be assigned because its copy assignment operator is implicitly deleted}}}}
// cxx11-17-note@#dr1891-a {{lambda expression begins here}}
b = b;
// since-cxx11-error-re@-1 {{{{object of type '\(lambda at .+\)' cannot be assigned because its copy assignment operator is implicitly deleted}}}}
// since-cxx11-note@#dr1891-b {{lambda expression begins here}}
b = static_cast<B&&>(b);
// since-cxx11-error-re@-1 {{{{object of type '\(lambda at .+\)' cannot be assigned because its copy assignment operator is implicitly deleted}}}}
// since-cxx11-note@#dr1891-b {{lambda expression begins here}}
#endif
}
namespace dr1894 { // dr1894: 3.8
// NB: reusing part of dr407 test
namespace A {
struct S {};
}
namespace B {
typedef int S;
}
namespace E {
typedef A::S S;
using A::S;
struct S s;
}
namespace F {
typedef A::S S;
}
namespace G {
using namespace A;
using namespace F;
struct S s;
}
namespace H {
using namespace F;
using namespace A;
struct S s;
}
}