1 // RUN: %clang_cc1 -std=c++17 -verify=cxx17 -Wc++20-compat %s 2 // RUN: %clang_cc1 -std=c++20 -verify=cxx20 -Wc++17-compat %s 3 4 namespace disambig { 5 6 // Cases that are valid in C++17 and before, ill-formed in C++20, and that we 7 // should not treat as explicit(bool) as an extension. 8 struct A { // cxx20-note +{{}} 9 constexpr A() {} 10 constexpr operator bool() { return true; } 11 12 constexpr explicit (A)(int); // #1 13 // cxx17-warning@#1 {{will be parsed as explicit(bool)}} 14 // cxx20-error@#1 +{{}} cxx20-note@#1 +{{}} 15 // cxx20-warning@#1 {{incompatible with C++ standards before C++20}} 16 17 // This is ill-formed (via a DR change), and shouldn't be recognized as a 18 // constructor (the function declarator cannot be parenthesized in a 19 // constructor declaration). But accepting it as an extension seems 20 // reasonable. 21 // FIXME: Produce an ExtWarn for this. 22 constexpr explicit (A(float)); // #1b 23 // cxx17-warning@#1b {{will be parsed as explicit(bool)}} 24 // cxx20-error@#1b +{{}} 25 // cxx20-warning@#1b {{incompatible with C++ standards before C++20}} 26 27 explicit (operator int)(); // #2 28 // cxx17-warning@#2 {{will be parsed as explicit(bool)}} 29 // cxx20-error@#2 +{{}} 30 // cxx20-warning@#2 {{incompatible with C++ standards before C++20}} 31 32 explicit (A::operator float)(); // #2b 33 // cxx17-warning@#2b {{will be parsed as explicit(bool)}} 34 // cxx17-error@#2b {{extra qualification on member}} 35 // cxx20-error@#2b +{{}} 36 // cxx20-warning@#2b {{incompatible with C++ standards before C++20}} 37 }; 38 39 constexpr bool operator+(A) { return true; } 40 41 constexpr bool C = false; 42 43 // Cases that should (ideally) be disambiguated as explicit(bool) in earlier 44 // language modes as an extension. 45 struct B { 46 // Looks like a constructor, but not the constructor of B. 47 explicit (A()) B(); // #3 48 // cxx17-warning@#3 {{C++20 extension}} 49 // cxx20-warning@#3 {{incompatible with C++ standards before C++20}} 50 51 // Looks like a 'constructor' of C. Actually a constructor of B. 52 explicit (C)(B)(A); // #4 53 // cxx17-warning@#4 {{C++20 extension}} 54 // cxx20-warning@#4 {{incompatible with C++ standards before C++20}} 55 56 explicit (operator+(A())) operator int(); // #5 57 // cxx17-error@#5 {{requires a type specifier}} cxx17-error@#5 {{expected ';'}} 58 // cxx17-warning@#5 {{will be parsed as explicit(bool)}} 59 // cxx20-warning@#5 {{incompatible with C++ standards before C++20}} 60 }; 61 62 } 63