]> granicus.if.org Git - clang/commitdiff
Fix defaulted member functions for templated classes.
authorRichard Trieu <rtrieu@google.com>
Tue, 27 Sep 2016 22:28:59 +0000 (22:28 +0000)
committerRichard Trieu <rtrieu@google.com>
Tue, 27 Sep 2016 22:28:59 +0000 (22:28 +0000)
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

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

index eb8c3d2cc83795ea6e5e70b6b6ccef1dee440ee1..91c12d8f5c11d461c31d9b4a31d514a19047d63f 100644 (file)
@@ -13850,12 +13850,6 @@ 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())
@@ -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;
index 16e20ff4964d8c3b786ece267b9a6d977fbe87ef..2bbc73012d9b5bb237921c5f9721e7eb4a4ce785 100644 (file)
@@ -208,3 +208,31 @@ int fn() {
   t = true;
 }
 }
+
+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}}
+
+  };
+  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}}
+}