diff options
author | dim <dim@FreeBSD.org> | 2013-04-08 18:45:10 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2013-04-08 18:45:10 +0000 |
commit | c72c57c9e9b69944e3e009cd5e209634839581d3 (patch) | |
tree | 4fc2f184c499d106f29a386c452b49e5197bf63d /test/SemaCXX/implicit-member-functions.cpp | |
parent | 5b20025c30d23d521e12c1f33ec8fa6b821952cd (diff) | |
download | FreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.zip FreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.tar.gz |
Vendor import of clang trunk r178860:
http://llvm.org/svn/llvm-project/cfe/trunk@178860
Diffstat (limited to 'test/SemaCXX/implicit-member-functions.cpp')
-rw-r--r-- | test/SemaCXX/implicit-member-functions.cpp | 69 |
1 files changed, 68 insertions, 1 deletions
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 @@ namespace PR7594 { }; 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); +} |