aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaDecl.cpp1
-rw-r--r--lib/Sema/SemaDeclCXX.cpp3
-rw-r--r--test/SemaCXX/cxx0x-defaulted-functions.cpp32
3 files changed, 35 insertions, 1 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index eb5b0cdc72..c1086fbe14 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -7483,6 +7483,7 @@ void Sema::CheckForFunctionRedefinition(FunctionDecl *FD) {
else
Diag(FD->getLocation(), diag::err_redefinition) << FD->getDeclName();
Diag(Definition->getLocation(), diag::note_previous_definition);
+ FD->setInvalidDecl();
}
}
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 8cd134a6a0..9933bd10e1 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -4552,7 +4552,8 @@ bool SpecialMemberDeletionInfo::shouldDeleteForAllConstMembers() {
/// C++11 [class.copy]p23, and C++11 [class.dtor]p5.
bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM,
bool Diagnose) {
- assert(!MD->isInvalidDecl());
+ if (MD->isInvalidDecl())
+ return false;
CXXRecordDecl *RD = MD->getParent();
assert(!RD->isDependentType() && "do deletion after instantiation");
if (!LangOpts.CPlusPlus0x || RD->isInvalidDecl())
diff --git a/test/SemaCXX/cxx0x-defaulted-functions.cpp b/test/SemaCXX/cxx0x-defaulted-functions.cpp
index 61c4c3338c..ce7ee672ea 100644
--- a/test/SemaCXX/cxx0x-defaulted-functions.cpp
+++ b/test/SemaCXX/cxx0x-defaulted-functions.cpp
@@ -117,3 +117,35 @@ namespace DefaultedFnExceptionSpec {
};
OdrUse use; // expected-note {{implicit default constructor for 'DefaultedFnExceptionSpec::OdrUse' first required here}}
}
+
+namespace PR13527 {
+ struct X {
+ X() = delete; // expected-note {{here}}
+ X(const X&) = delete; // expected-note {{here}}
+ X(X&&) = delete; // expected-note {{here}}
+ X &operator=(const X&) = delete; // expected-note {{here}}
+ X &operator=(X&&) = delete; // expected-note {{here}}
+ ~X() = delete; // expected-note {{here}}
+ };
+ X::X() = default; // expected-error {{redefinition}}
+ X::X(const X&) = default; // expected-error {{redefinition}}
+ X::X(X&&) = default; // expected-error {{redefinition}}
+ X &X::operator=(const X&) = default; // expected-error {{redefinition}}
+ X &X::operator=(X&&) = default; // expected-error {{redefinition}}
+ X::~X() = default; // expected-error {{redefinition}}
+
+ struct Y {
+ Y() = default;
+ Y(const Y&) = default;
+ Y(Y&&) = default;
+ Y &operator=(const Y&) = default;
+ Y &operator=(Y&&) = default;
+ ~Y() = default;
+ };
+ Y::Y() = default; // expected-error {{definition of explicitly defaulted}}
+ Y::Y(const Y&) = default; // expected-error {{definition of explicitly defaulted}}
+ Y::Y(Y&&) = default; // expected-error {{definition of explicitly defaulted}}
+ Y &Y::operator=(const Y&) = default; // expected-error {{definition of explicitly defaulted}}
+ Y &Y::operator=(Y&&) = default; // expected-error {{definition of explicitly defaulted}}
+ Y::~Y() = default; // expected-error {{definition of explicitly defaulted}}
+}