1 // RUN: %clang_cc1 -verify=expected,pre20 %s -std=c++11
2 // RUN: %clang_cc1 -verify=expected,pre20 %s -std=c++17
3 // RUN: %clang_cc1 -verify=expected %s -std=c++20
4 
5 // A function that is explicitly defaulted shall
6 struct A {
7   // -- be a special member function [C++20: or a comparison operator function],
8   A(int) = default;
9 #if __cplusplus <= 201703L
10   // expected-error@-2 {{only special member functions may be defaulted}}
11 #else
12   // expected-error@-4 {{only special member functions and comparison operators may be defaulted}}
13 #endif
14   A(A) = default; // expected-error {{must pass its first argument by reference}}
15   void f(A) = default; // expected-error-re {{only special member functions{{( and comparison operators)?}} may be defaulted}}
16 
17   bool operator==(const A&) const = default; // pre20-warning {{defaulted comparison operators are a C++20 extension}}
18   bool operator!=(const A&) const = default; // pre20-warning {{defaulted comparison operators are a C++20 extension}}
19   bool operator<(const A&) const = default; // pre20-error {{only special member functions may be defaulted}}
20   bool operator>(const A&) const = default; // pre20-error {{only special member functions may be defaulted}}
21   bool operator<=(const A&) const = default; // pre20-error {{only special member functions may be defaulted}}
22   bool operator>=(const A&) const = default; // pre20-error {{only special member functions may be defaulted}}
23   bool operator<=>(const A&) const = default; // pre20-error 1+{{}} pre20-warning {{'<=>' is a single token in C++20}}
24 
25   A operator+(const A&) const = default; // expected-error-re {{only special member functions{{( and comparison operators)?}} may be defaulted}}
26 
27   // -- have the same declared function type as if it had been implicitly
28   //    declared
29   void operator=(const A &) = default; // expected-error {{must return 'A &'}}
30   A(...) = default;
31   A(const A &, ...) = default;
32   A &operator=(const A&) const = default;
33   A &operator=(A) const = default; // expected-error {{must be an lvalue refe}}
34 #if __cplusplus <= 201703L
35   // expected-error@-5 {{cannot be variadic}}
36   // expected-error@-5 {{cannot be variadic}}
37   // expected-error@-5 {{may not have 'const'}}
38   // expected-error@-5 {{may not have 'const'}}
39 #else
40   // expected-warning@-10 {{implicitly deleted}} expected-note@-10 {{declared type does not match the type of an implicit default constructor}}
41   // expected-warning@-10 {{implicitly deleted}} expected-note@-10 {{declared type does not match the type of an implicit copy constructor}}
42   // expected-warning@-10 {{implicitly deleted}} expected-note@-10 {{declared type does not match the type of an implicit copy assignment}}
43 #endif
44 
45   //    (except for possibly differing ref-qualifiers
46   A &operator=(A &&) & = default;
47 
48   //    and except that in the case of a copy constructor or copy assignment
49   //    operator, the parameter type may be "reference to non-const T")
50   A(A &) = default;
51   A &operator=(A &) = default;
52 
53   // -- not have default arguments
54   A(double = 0.0) = default; // expected-error {{cannot have default arguments}}
55   A(const A & = 0) = default; // expected-error {{cannot have default arguments}}
56 };
57 
58 struct A2 {
59   A2(...);
60   A2(const A2 &, ...);
61   A2 &operator=(const A2&) const;
62 };
63 A2::A2(...) = default; // expected-error {{cannot be variadic}}
64 A2::A2(const A2&, ...) = default; // expected-error {{cannot be variadic}}
65 A2 &A2::operator=(const A2&) const = default; // expected-error {{may not have 'const'}}
66 
67 struct B {
68   B(B&);
69   B &operator=(B&);
70 };
71 struct C : B {
72   C(const C&) = default;
73   C &operator=(const C&) = default;
74 #if __cplusplus <= 201703L
75   // expected-error@-3 {{is const, but a member or base requires it to be non-const}}
76   // expected-error@-3 {{is const, but a member or base requires it to be non-const}}
77 #else
78   // expected-warning@-6 {{implicitly deleted}} expected-note@-6 {{type does not match}}
79   // expected-warning@-6 {{implicitly deleted}} expected-note@-6 {{type does not match}}
80 #endif
81 };
82 
83 struct D : B { // expected-note 2{{base class}}
84   D(const D&);
85   D &operator=(const D&);
86 };
87 D::D(const D&) = default; // expected-error {{would delete}} expected-error {{is const, but}}
88 D &D::operator=(const D&) = default; // expected-error {{would delete}} expected-error {{is const, but}}
89