Files
clang-p2996/clang/test/Parser/explicit-bool.cpp
Richard Smith 24ad121582 Add -std=c++20 flag, replace C++2a with C++20 throughout the Clang
user interface and documentation, and update __cplusplus for C++20.

WG21 considers the C++20 standard to be finished (even though it still
has some more steps to pass through in the ISO process).

The old flag names are accepted for compatibility, as usual, and we
still have lots of references to C++2a in comments and identifiers;
those can be cleaned up separately.
2020-02-18 16:16:37 -08:00

63 lines
2.3 KiB
C++

// RUN: %clang_cc1 -std=c++17 -verify=cxx17 -Wc++20-compat %s
// RUN: %clang_cc1 -std=c++20 -verify=cxx20 -Wc++17-compat %s
namespace disambig {
// Cases that are valid in C++17 and before, ill-formed in C++20, and that we
// should not treat as explicit(bool) as an extension.
struct A { // cxx20-note +{{}}
constexpr A() {}
constexpr operator bool() { return true; }
constexpr explicit (A)(int); // #1
// cxx17-warning@#1 {{will be parsed as explicit(bool)}}
// cxx20-error@#1 +{{}} cxx20-note@#1 +{{}}
// cxx20-warning@#1 {{incompatible with C++ standards before C++20}}
// This is ill-formed (via a DR change), and shouldn't be recognized as a
// constructor (the function declarator cannot be parenthesized in a
// constructor declaration). But accepting it as an extension seems
// reasonable.
// FIXME: Produce an ExtWarn for this.
constexpr explicit (A(float)); // #1b
// cxx17-warning@#1b {{will be parsed as explicit(bool)}}
// cxx20-error@#1b +{{}}
// cxx20-warning@#1b {{incompatible with C++ standards before C++20}}
explicit (operator int)(); // #2
// cxx17-warning@#2 {{will be parsed as explicit(bool)}}
// cxx20-error@#2 +{{}}
// cxx20-warning@#2 {{incompatible with C++ standards before C++20}}
explicit (A::operator float)(); // #2b
// cxx17-warning@#2b {{will be parsed as explicit(bool)}}
// cxx17-error@#2b {{extra qualification on member}}
// cxx20-error@#2b +{{}}
// cxx20-warning@#2b {{incompatible with C++ standards before C++20}}
};
constexpr bool operator+(A) { return true; }
constexpr bool C = false;
// Cases that should (ideally) be disambiguated as explicit(bool) in earlier
// language modes as an extension.
struct B {
// Looks like a constructor, but not the constructor of B.
explicit (A()) B(); // #3
// cxx17-warning@#3 {{C++20 extension}}
// cxx20-warning@#3 {{incompatible with C++ standards before C++20}}
// Looks like a 'constructor' of C. Actually a constructor of B.
explicit (C)(B)(A); // #4
// cxx17-warning@#4 {{C++20 extension}}
// cxx20-warning@#4 {{incompatible with C++ standards before C++20}}
explicit (operator+(A())) operator int(); // #5
// cxx17-error@#5 {{requires a type specifier}} cxx17-error@#5 {{expected ';'}}
// cxx17-warning@#5 {{will be parsed as explicit(bool)}}
// cxx20-warning@#5 {{incompatible with C++ standards before C++20}}
};
}