blob: 5ffaebda68c13295eef5932faddc83d887bf200f [file] [log] [blame]
// RUN: %clang_cc1 -std=c++98 %s -verify=expected
// RUN: %clang_cc1 -std=c++11 %s -verify=expected
// RUN: %clang_cc1 -std=c++14 %s -verify=expected
// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx17
// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx17
// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx17
// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx17
#if __cplusplus <= 201402L
// expected-no-diagnostics
#endif
namespace cwg2406 { // cwg2406: 5
#if __cplusplus >= 201703L
void fallthrough(int n) {
void g(), h(), i();
switch (n) {
case 1:
case 2:
g();
[[fallthrough]];
case 3: // warning on fallthrough discouraged
do {
[[fallthrough]];
// since-cxx17-error@-1 {{fallthrough annotation does not directly precede switch label}}
} while (false);
case 6:
do {
[[fallthrough]];
// since-cxx17-error@-1 {{fallthrough annotation does not directly precede switch label}}
} while (n);
case 7:
while (false) {
[[fallthrough]];
// since-cxx17-error@-1 {{fallthrough annotation does not directly precede switch label}}
}
case 5:
h();
case 4: // implementation may warn on fallthrough
i();
[[fallthrough]];
// since-cxx17-error@-1 {{fallthrough annotation does not directly precede switch label}}
}
}
#endif
}
namespace cwg2450 { // cwg2450: 18 review P2308R1
#if __cplusplus >= 202302L
struct S {int a;};
template <S s>
void f(){}
void test() {
f<{0}>();
f<{.a= 0}>();
}
#endif
}
namespace cwg2459 { // cwg2459: 18 drafting P2308R1
#if __cplusplus >= 202302L
struct A {
constexpr A(float) {}
};
template<A> struct X {};
X<1> x;
#endif
}
namespace cwg2445 { // cwg2445: 19
#if __cplusplus >= 202002L
template <typename> constexpr bool F = false;
template <typename T> struct A { };
template <typename T, typename U>
bool operator==(T, A<U *>);
template <typename T, typename U>
bool operator!=(A<T>, U) {
static_assert(F<T>, "Isn't this less specialized?");
return false;
}
bool f(A<int> ax, A<int *> ay) { return ay != ax; }
template<class T> concept AlwaysTrue=true;
template <class T> struct B {
template <AlwaysTrue U>
bool operator==(const B<U>&)const;
};
template <typename U>
bool operator==(const B<int>&,const B<U>&) {
static_assert(F<int>, "Isn't this less specialized?");
return false;
}
bool g(B<int> bx, B<int *> by) { return bx == by; }
struct C{
template<AlwaysTrue T>
int operator+(T){return 0;}
template<class T>
void operator-(T){}
};
template<class T>
void operator+(C&&,T){}
template<AlwaysTrue T>
int operator-(C&&,T){return 0;}
void t(int* iptr){
int x1 = C{} + iptr;
int x2 = C{} - iptr;
}
struct D{
template<AlwaysTrue T>
int operator+(T) volatile {return 1;}
};
template<class T>
void operator+(volatile D&,T) {}
int foo(volatile D& d){
return d + 1;
}
#endif
}