def : DiagGroup<"char-align">;
def Comment : DiagGroup<"comment">;
def : DiagGroup<"ctor-dtor-privacy">;
-def DefaultArgSpecialMember : DiagGroup<"default-arg-special-member">;
def GNUDesignator : DiagGroup<"gnu-designator">;
def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">;
def err_uninitialized_member_in_ctor : Error<
"%select{|implicit default }0constructor for %1 must explicitly initialize "
"the %select{reference|const}2 member %3">;
-def warn_default_arg_makes_ctor_special : Warning<
+def err_default_arg_makes_ctor_special : Error<
"addition of default argument on redeclaration makes this constructor a "
- "%select{default|copy|move}0 constructor">, InGroup<DefaultArgSpecialMember>;
-def note_previous_declaration_special : Note<
- // The ERRORs are in hopes that if they occur, they'll get reported.
- "previous declaration was %select{*ERROR*|a copy constructor|a move "
- "constructor|*ERROR*|*ERROR*|*ERROR*|not a special member function}0">;
+ "%select{default|copy|move}0 constructor">;
def err_use_of_default_argument_to_function_declared_later : Error<
"use of default argument to function %0 that is declared later in class %1">;
diag::err_param_default_argument_member_template_redecl)
<< WhichKind
<< NewParam->getDefaultArgRange();
- } else if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(New)) {
- CXXSpecialMember NewSM = getSpecialMember(Ctor),
- OldSM = getSpecialMember(cast<CXXConstructorDecl>(Old));
- if (NewSM != OldSM) {
- Diag(NewParam->getLocation(),diag::warn_default_arg_makes_ctor_special)
- << NewParam->getDefaultArgRange() << NewSM;
- Diag(Old->getLocation(), diag::note_previous_declaration_special)
- << OldSM;
- }
}
}
}
+ // DR1344: If a default argument is added outside a class definition and that
+ // default argument makes the function a special member function, the program
+ // is ill-formed. This can only happen for constructors.
+ if (isa<CXXConstructorDecl>(New) &&
+ New->getMinRequiredArguments() < Old->getMinRequiredArguments()) {
+ CXXSpecialMember NewSM = getSpecialMember(cast<CXXMethodDecl>(New)),
+ OldSM = getSpecialMember(cast<CXXMethodDecl>(Old));
+ if (NewSM != OldSM) {
+ ParmVarDecl *NewParam = New->getParamDecl(New->getMinRequiredArguments());
+ assert(NewParam->hasDefaultArg());
+ Diag(NewParam->getLocation(), diag::err_default_arg_makes_ctor_special)
+ << NewParam->getDefaultArgRange() << NewSM;
+ Diag(Old->getLocation(), diag::note_previous_declaration);
+ }
+ }
+
// C++11 [dcl.constexpr]p1: If any declaration of a function or function
// template has a constexpr specifier then all its declarations shall
// contain the constexpr specifier.
struct A {
constexpr A(const A&) {}
A(A&) {}
- constexpr A(int); // expected-note {{previous}}
+ constexpr A(int = 0);
};
- constexpr A::A(int = 0) {} // expected-warning {{default constructor}}
struct B : A {
B() = default;
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
struct S {
S (S); // expected-error {{copy constructor must pass its first argument by reference}}
S a( f() );
}
+class foo {
+ foo(foo&, int); // expected-note {{previous}}
+ foo(int); // expected-note {{previous}}
+ foo(const foo&); // expected-note {{previous}}
+};
+
+foo::foo(foo&, int = 0) { } // expected-error {{makes this constructor a copy constructor}}
+foo::foo(int = 0) { } // expected-error {{makes this constructor a default constructor}}
+foo::foo(const foo& = 0) { } //expected-error {{makes this constructor a default constructor}}
+
namespace PR6064 {
struct A {
A() { }
- inline A(A&, int); // expected-note {{was not a special member function}}
+ inline A(A&, int); // expected-note {{previous}}
};
- A::A(A&, int = 0) { } // expected-warning {{makes this constructor a copy constructor}}
+ A::A(A&, int = 0) { } // expected-error {{makes this constructor a copy constructor}}
void f() {
A const a;
A b(a);
}
}
+
+namespace PR10618 {
+ struct A {
+ A(int, int, int); // expected-note {{previous}}
+ };
+ A::A(int a = 0, // expected-error {{makes this constructor a default constructor}}
+ int b = 0,
+ int c = 0) {}
+
+ struct B {
+ B(int);
+ B(const B&, int); // expected-note {{previous}}
+ };
+ B::B(const B& = B(0), // expected-error {{makes this constructor a default constructor}}
+ int = 0) {
+ }
+
+ struct C {
+ C(const C&, int); // expected-note {{previous}}
+ };
+ C::C(const C&,
+ int = 0) { // expected-error {{makes this constructor a copy constructor}}
+ }
+}
+++ /dev/null
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -Wno-default-arg-special-member -Werror -fsyntax-only %s
-
-class foo {
- foo(foo&, int); // expected-note {{was not a special member function}}
- foo(int); // expected-note {{was not a special member function}}
- foo(const foo&); // expected-note {{was a copy constructor}}
-};
-
-foo::foo(foo&, int = 0) { } // expected-warning {{makes this constructor a copy constructor}}
-foo::foo(int = 0) { } // expected-warning {{makes this constructor a default constructor}}
-foo::foo(const foo& = 0) { } //expected-warning {{makes this constructor a default constructor}}