From 787744fa5ebdc660fbc23898fe33e4e766714a60 Mon Sep 17 00:00:00 2001
From: Richard Trieu <rtrieu@google.com>
Date: Tue, 15 Nov 2016 01:05:08 +0000
Subject: [PATCH] Merging r282989:
 ------------------------------------------------------------------------
 r282989 | rtrieu | 2016-09-30 17:15:24 -0700 (Fri, 30 Sep 2016) | 10 lines

Fix crash when emitting error.

With templated classes, is possible to not be able to determine is a member
function is a special member function before the class is instantiated.  Only
these special member functions can be defaulted.  In some cases, knowing
whether a function is a special member function can't be determined until
instantiation, so an uninstantiated function could possibly be defaulted too.
Add a case to the error diagnostic when the function marked with a default is
not known to be a special member function.

------------------------------------------------------------------------


git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_39@286922 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/DiagnosticSemaKinds.td |  2 +-
 test/SemaCXX/cxx0x-defaulted-functions.cpp | 35 ++++++++++++++++++++++
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 1a05d4ab5e5..3963f758188 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4291,7 +4291,7 @@ def err_definition_of_implicitly_declared_member : Error<
 def err_definition_of_explicitly_defaulted_member : Error<
   "definition of explicitly defaulted %select{default constructor|copy "
   "constructor|move constructor|copy assignment operator|move assignment "
-  "operator|destructor}0">;
+  "operator|destructor|function}0">;
 def err_redefinition_extern_inline : Error<
   "redefinition of a 'extern inline' function %0 is not supported in "
   "%select{C99 mode|C++}1">;
diff --git a/test/SemaCXX/cxx0x-defaulted-functions.cpp b/test/SemaCXX/cxx0x-defaulted-functions.cpp
index 16e20ff4964..7ec9726095c 100644
--- a/test/SemaCXX/cxx0x-defaulted-functions.cpp
+++ b/test/SemaCXX/cxx0x-defaulted-functions.cpp
@@ -208,3 +208,38 @@ int fn() {
   t = true;
 }
 }
+
+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 Type>
+class E {
+  explicit E(const int &) = default;
+};
+
+template <typename Type>
+E<Type>::E(const int&) {}  // expected-error {{definition of explicitly defaulted function}}
+
+}
-- 
GitLab