diff options
author | Richard Trieu <rtrieu@google.com> | 2016-09-27 23:44:07 +0000 |
---|---|---|
committer | Richard Trieu <rtrieu@google.com> | 2016-09-27 23:44:07 +0000 |
commit | 3d1235a97d805e00222f12dc11dfac83b9164551 (patch) | |
tree | 91de6dcdcfd0edb40495c1e8ba203cb8f25996a7 | |
parent | 08780529b3d6deadbf1e1a1a19ea9689241eb4c1 (diff) | |
download | bcm5719-llvm-3d1235a97d805e00222f12dc11dfac83b9164551.tar.gz bcm5719-llvm-3d1235a97d805e00222f12dc11dfac83b9164551.zip |
Revert r282547 and add test to show correct behavior.
llvm-svn: 282555
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 8 | ||||
-rw-r--r-- | clang/test/SemaCXX/cxx0x-defaulted-functions.cpp | 49 |
2 files changed, 30 insertions, 27 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 91c12d8f5c1..eb8c3d2cc83 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -13850,6 +13850,12 @@ void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation DefaultLoc) { CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(Dcl); if (MD) { + if (MD->getParent()->isDependentType()) { + MD->setDefaulted(); + MD->setExplicitlyDefaulted(); + return; + } + CXXSpecialMember Member = getSpecialMember(MD); if (Member == CXXInvalid) { if (!MD->isInvalidDecl()) @@ -13860,8 +13866,6 @@ 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/clang/test/SemaCXX/cxx0x-defaulted-functions.cpp b/clang/test/SemaCXX/cxx0x-defaulted-functions.cpp index 2bbc73012d9..08d5dbd285d 100644 --- a/clang/test/SemaCXX/cxx0x-defaulted-functions.cpp +++ b/clang/test/SemaCXX/cxx0x-defaulted-functions.cpp @@ -209,30 +209,29 @@ int fn() { } } -namespace templated_class { -template <typename T> -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}} +namespace dependent_classes { +template <bool B, typename X, typename Y> +struct conditional; + +template <typename X, typename Y> +struct conditional<true, X, Y> { typedef X type; }; + +template <typename X, typename Y> +struct conditional<false, X, Y> { typedef Y type; }; + +template<bool B> struct X { + X(); + + // B == false triggers error for = default. + using T = typename conditional<B, const X &, int>::type; + X(T) = default; // expected-error {{only special member functions}} + + // Either value of B creates a constructor that can be default + using U = typename conditional<B, X&&, const X&>::type; + X(U) = default; +}; + +X<true> x1; +X<false> x2; // expected-note {{in instantiation}} - }; - template <typename T> - X<T>::X() = default; // expected-error {{definition of explicitly defaulted}} - template <typename T> - X<T>::X(const X<T>&) = default; // expected-error {{definition of explicitly defaulted}} - template <typename T> - X<T>::X(X<T>&&) = default; // expected-error {{definition of explicitly defaulted}} - template <typename T> - X<T> &X<T>::operator=(const X<T>&) = default; // expected-error {{definition of explicitly defaulted}} - template <typename T> - X<T> &X<T>::operator=(X<T>&&) = default; // expected-error {{definition of explicitly defaulted}} - template <typename T> - X<T>::~X() = default; // expected-error {{definition of explicitly defaulted}} } |