From: Richard Trieu Date: Tue, 27 Sep 2016 22:28:59 +0000 (+0000) Subject: Fix defaulted member functions for templated classes. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c56ff5ff150460f7a5c6884ae3b1f253e39b3c35;p=clang Fix defaulted member functions for templated classes. In some cases, non-special member functions were being marked as being defaulted in templated classes. This can cause interactions with later code that expects the default function to be one of the specific member functions. Fix the check so that templated class members are checked the same way as non-templated class members are. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@282547 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index eb8c3d2cc8..91c12d8f5c 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -13850,12 +13850,6 @@ void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation DefaultLoc) { CXXMethodDecl *MD = dyn_cast_or_null(Dcl); if (MD) { - if (MD->getParent()->isDependentType()) { - MD->setDefaulted(); - MD->setExplicitlyDefaulted(); - return; - } - CXXSpecialMember Member = getSpecialMember(MD); if (Member == CXXInvalid) { if (!MD->isInvalidDecl()) @@ -13866,6 +13860,8 @@ void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation DefaultLoc) { MD->setDefaulted(); MD->setExplicitlyDefaulted(); + if (MD->getParent()->isDependentType()) return; + // If this definition appears within the record, do the checking when // the record is complete. const FunctionDecl *Primary = MD; diff --git a/test/SemaCXX/cxx0x-defaulted-functions.cpp b/test/SemaCXX/cxx0x-defaulted-functions.cpp index 16e20ff496..2bbc73012d 100644 --- a/test/SemaCXX/cxx0x-defaulted-functions.cpp +++ b/test/SemaCXX/cxx0x-defaulted-functions.cpp @@ -208,3 +208,31 @@ int fn() { t = true; } } + +namespace templated_class { +template +class X { + X() = default; + X(const X&) = default; + X(X&&) = default; + X &operator=(const X&) = default; + X &operator=(X&&) = default; + ~X() = default; + + X(T) = default; // expected-error {{only special member functions may be defaulted}} + void Run() = default; // expected-error {{only special member functions may be defaulted}} + + }; + template + X::X() = default; // expected-error {{definition of explicitly defaulted}} + template + X::X(const X&) = default; // expected-error {{definition of explicitly defaulted}} + template + X::X(X&&) = default; // expected-error {{definition of explicitly defaulted}} + template + X &X::operator=(const X&) = default; // expected-error {{definition of explicitly defaulted}} + template + X &X::operator=(X&&) = default; // expected-error {{definition of explicitly defaulted}} + template + X::~X() = default; // expected-error {{definition of explicitly defaulted}} +}