blob: f9c2e9ecf461818fbf83951e553f515a80bf6c82 [file] [log] [blame]
// RUN: %clang_cc1 -std=c++98 -pedantic-errors -verify=expected,cxx98 %s
// RUN: %clang_cc1 -std=c++11 -pedantic-errors -verify=expected,since-cxx11 %s
// RUN: %clang_cc1 -std=c++14 -pedantic-errors -verify=expected,since-cxx11 %s
// RUN: %clang_cc1 -std=c++17 -pedantic-errors -verify=expected,since-cxx11 %s
// RUN: %clang_cc1 -std=c++20 -pedantic-errors -verify=expected,since-cxx11,since-cxx20 %s
// RUN: %clang_cc1 -std=c++23 -pedantic-errors -verify=expected,since-cxx11,since-cxx20,since-cxx23 %s
// RUN: %clang_cc1 -std=c++2c -pedantic-errors -verify=expected,since-cxx11,since-cxx20,since-cxx23,since-cxx26 %s
// cxx98-no-diagnostics
namespace cwg2913 { // cwg2913: 20
#if __cplusplus >= 202002L
template<typename T>
struct R {
R(T);
R(T, T);
};
template<typename T>
R(T) -> R<T> requires true;
template<typename T>
R(T, T) requires true -> R<T>;
// since-cxx20-error@-1 {{expected function body after function declarator}}
#endif
} // namespace cwg2913
namespace cwg2915 { // cwg2915: 20
#if __cplusplus >= 202302L
struct A {
void f(this void);
// since-cxx23-error@-1 {{explicit object parameter cannot have 'void' type}}
};
#endif
} // namespace cwg2915
namespace cwg2917 { // cwg2917: 20 review 2024-07-30
#if __cplusplus >= 201103L
template <typename>
class Foo;
template<class ...>
struct C {
struct Nested { };
};
struct S {
template <typename>
friend class Foo, int;
// since-cxx11-error@-1 {{a friend declaration that befriends a template must contain exactly one type-specifier}}
template <typename ...Ts>
friend class C<Ts>::Nested...;
// since-cxx11-error@-1 {{friend declaration expands pack 'Ts' that is declared it its own template parameter list}}
};
#endif
} // namespace cwg2917
namespace cwg2918 { // cwg2918: 21
#if __cplusplus >= 202002L
namespace Example1 {
template<bool B> struct X {
void f(short) requires B;
void f(long);
template<typename> void g(short) requires B;
template<typename> void g(long);
};
void test() {
&X<true>::f; // since-cxx20-error {{reference to overloaded function could not be resolved}}
&X<true>::g<int>; // since-cxx20-error {{reference to overloaded function could not be resolved}}
}
} // namespace Example1
namespace Example2 {
template <bool B> struct X {
static constexpr int f(short) requires B {
return 42;
}
static constexpr int f(short) {
return 24;
}
};
template <typename T>
constexpr int f(T) { return 1; }
template <typename T>
requires __is_same(T, int)
constexpr int f(T) { return 2; }
void test() {
constexpr auto x = &X<true>::f;
static_assert(__is_same(decltype(x), int(*const)(short)), "");
static_assert(x(0) == 42, "");
constexpr auto y = &X<false>::f;
static_assert(__is_same(decltype(y), int(*const)(short)));
static_assert(y(0) == 24, "");
constexpr auto z = &f<int>;
static_assert(__is_same(decltype(z), int(*const)(int)));
static_assert(z(0) == 2, "");
// C++ [temp.deduct.call]p6:
// If the argument is an overload set containing one or more function templates,
// the parameter is treated as a non-deduced context.
auto w = f; // since-cxx20-error {{variable 'w' with type 'auto' has incompatible initializer of type '<overloaded function type>'}}
}
} // namespace Example2
#endif
#if __cplusplus >= 201103L
namespace Example3 {
template <typename T> void f(T &&, void (*)(T &&)); // #cwg2918_f
void g(int &);
inline namespace A {
void g(short &&);
}
inline namespace B {
void g(short &&);
}
void q() {
int x;
f(x, g);
// since-cxx11-error@-1 {{no matching function for call to 'f'}}
// since-cxx11-note@#cwg2918_f {{candidate template ignored: deduced conflicting types for parameter 'T' ('int &' vs. 'short')}}
}
} // namespace Example3
#endif
} // namespace cwg2918
#if __cplusplus > 202302L
namespace std {
using size_t = decltype(sizeof(0));
} // namespace std
void *operator new(std::size_t, void *p) { return p; }
void* operator new[] (std::size_t, void* p) {return p; }
#endif
namespace cwg2922 { // cwg2922: 20
#if __cplusplus > 202302L
union U { int a, b; };
constexpr U nondeterministic(bool i) {
if(i) {
U u;
new (&u) int(); // #cwg2922-placement-new
return u;
}
return {};
}
constexpr U _ = nondeterministic(true);
// since-cxx26-error@-1 {{constexpr variable '_' must be initialized by a constant expression}}
// since-cxx26-note@#cwg2922-placement-new {{placement new would change type of storage from 'U' to 'int'}}
// since-cxx26-note@-3 {{in call to 'nondeterministic(true)'}}
#endif
} // namespace cwg2922