summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td7
-rw-r--r--clang/lib/Sema/SemaDecl.cpp8
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp9
-rw-r--r--clang/test/SemaCXX/copy-constructor-error.cpp4
-rw-r--r--clang/test/SemaCXX/default-arg-special-member.cpp11
5 files changed, 33 insertions, 6 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f36f3475c1b..5e1f3f58188 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1416,6 +1416,13 @@ def note_first_required_here : Note<
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<
+ "addition of default argument on redeclaration makes this constructor a "
+ "%select{default|copy|move}0 constructor">;
+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">;
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">;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index dae7ba20b1f..77bd5b79ae0 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -1505,14 +1505,14 @@ struct GNUCompatibleParamWarning {
/// getSpecialMember - get the special member enum for a method.
Sema::CXXSpecialMember Sema::getSpecialMember(const CXXMethodDecl *MD) {
if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(MD)) {
+ if (Ctor->isDefaultConstructor())
+ return Sema::CXXDefaultConstructor;
+
if (Ctor->isCopyConstructor())
return Sema::CXXCopyConstructor;
-
+
if (Ctor->isMoveConstructor())
return Sema::CXXMoveConstructor;
-
- if (Ctor->isDefaultConstructor())
- return Sema::CXXDefaultConstructor;
} else if (isa<CXXDestructorDecl>(MD)) {
return Sema::CXXDestructor;
} else if (MD->isCopyAssignmentOperator()) {
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 6870f3c46b2..2fd4cf58cad 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -457,6 +457,15 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) {
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;
+ }
}
}
}
diff --git a/clang/test/SemaCXX/copy-constructor-error.cpp b/clang/test/SemaCXX/copy-constructor-error.cpp
index 9809bfc84bb..64a7d58e19e 100644
--- a/clang/test/SemaCXX/copy-constructor-error.cpp
+++ b/clang/test/SemaCXX/copy-constructor-error.cpp
@@ -13,10 +13,10 @@ void g() {
namespace PR6064 {
struct A {
A() { }
- inline A(A&, int);
+ inline A(A&, int); // expected-note {{was not a special member function}}
};
- A::A(A&, int = 0) { }
+ A::A(A&, int = 0) { } // expected-warning {{makes this constructor a copy constructor}}
void f() {
A const a;
diff --git a/clang/test/SemaCXX/default-arg-special-member.cpp b/clang/test/SemaCXX/default-arg-special-member.cpp
new file mode 100644
index 00000000000..aadbbeb2fcd
--- /dev/null
+++ b/clang/test/SemaCXX/default-arg-special-member.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %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}}
OpenPOWER on IntegriCloud