]> granicus.if.org Git - clang/commitdiff
Revert r282547 and add test to show correct behavior.
authorRichard Trieu <rtrieu@google.com>
Tue, 27 Sep 2016 23:44:07 +0000 (23:44 +0000)
committerRichard Trieu <rtrieu@google.com>
Tue, 27 Sep 2016 23:44:07 +0000 (23:44 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@282555 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/cxx0x-defaulted-functions.cpp

index 91c12d8f5c11d461c31d9b4a31d514a19047d63f..eb8c3d2cc83795ea6e5e70b6b6ccef1dee440ee1 100644 (file)
@@ -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;
index 2bbc73012d9b5bb237921c5f9721e7eb4a4ce785..08d5dbd285d420dcfbd16f1d48015b501fcae6e3 100644 (file)
@@ -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}}
 }