The declaration of a special member can require overload resolution to be
performed, to determine whether that special member is deleted or constexpr.
That overload resolution process can in turn trigger the instantiation of a
template, which can do anything, including triggering the declaration of that
very same special member function. When this happens, do not try to recursively
declare the special member -- that's impossible. Instead, only try to realise
the truth. There is no special member.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@168847 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/SemaCXX/implicit-member-functions.cpp b/test/SemaCXX/implicit-member-functions.cpp
index 8451739..b5f7fe1 100644
--- a/test/SemaCXX/implicit-member-functions.cpp
+++ b/test/SemaCXX/implicit-member-functions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
 
 struct A { };
 A::A() { } // expected-error {{definition of implicitly declared default constructor}}
@@ -50,3 +50,70 @@
   };
   C *C::c = new C();
 }
+
+namespace Recursion {
+  template<typename T> struct InvokeCopyConstructor {
+    static const T &get();
+    typedef decltype(T(get())) type; // expected-error {{no matching conver}}
+  };
+  struct B;
+  struct A {
+    typedef B type;
+    template<typename T,
+             typename = typename InvokeCopyConstructor<typename T::type>::type>
+    // expected-note@-1 {{in instantiation of template class}}
+    A(const T &);
+    // expected-note@-1 {{in instantiation of default argument}}
+    // expected-note@-2 {{while substituting deduced template arguments}}
+  };
+  struct B { // expected-note {{candidate constructor (the implicit move }}
+    B(); // expected-note {{candidate constructor not viable}}
+    A a;
+  };
+  // Triggering the declaration of B's copy constructor causes overload
+  // resolution to occur for A's copying constructor, which instantiates
+  // InvokeCopyConstructor<B>, which triggers the declaration of B's copy
+  // constructor. Notionally, this happens when we get to the end of the
+  // definition of 'struct B', so there is no declared copy constructor yet.
+  //
+  // This behavior is g++-compatible, but isn't exactly right; the class is
+  // supposed to be incomplete when we implicitly declare its special members.
+  B b = B();
+
+
+  // Another case, which isn't ill-formed under our rules. This is inspired by
+  // a problem which occurs when combining CGAL with libstdc++-4.7.
+
+  template<typename T> T &&declval();
+  template<typename T, typename U> struct pair {
+    pair();
+    template<typename V, typename W,
+             typename = decltype(T(declval<const V&>())),
+             typename = decltype(U(declval<const W&>()))>
+    pair(const pair<V,W> &);
+  };
+
+  template<typename K> struct Line;
+
+  template<typename K> struct Vector {
+    Vector(const Line<K> &l);
+  };
+
+  template<typename K> struct Point {
+    Vector<K> v;
+  };
+
+  template<typename K> struct Line {
+    pair<Point<K>, Vector<K>> x;
+  };
+
+  // Trigger declaration of Line copy ctor, which causes substitution into
+  // pair's templated constructor, which triggers instantiation of the
+  // definition of Point's copy constructor, which performs overload resolution
+  // on Vector's constructors, which requires declaring all of Line's
+  // constructors. That should not find a copy constructor (because we've not
+  // declared it yet), but by the time we get all the way back here, we should
+  // find the copy constructor.
+  Line<void> L1;
+  Line<void> L2(L1);
+}