• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 +{{}}
Adisambig::A9   constexpr A() {}
operator booldisambig::A10   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 
operator +(A)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