diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-09-07 02:14:33 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-09-07 02:14:33 +0000 |
commit | 7c2bcc9eb038df5fa238276749a88f289e9861ae (patch) | |
tree | fec04fe63bc882c0526a4301ac9fede9009c8656 /clang/test/SemaCXX/cxx11-inheriting-ctors.cpp | |
parent | c1d527d3d832cac86eb9461dcef978011ef8caeb (diff) | |
download | bcm5719-llvm-7c2bcc9eb038df5fa238276749a88f289e9861ae.tar.gz bcm5719-llvm-7c2bcc9eb038df5fa238276749a88f289e9861ae.zip |
Fix clang's handling of the copy performed in the second phase of class
copy-initialization. We previously got this wrong in a couple of ways:
- we only looked for copy / move constructors and constructor templates for
this copy, and thus would fail to copy in cases where doing so should use
some other constructor (but see core issue 670),
- we mishandled the special case for disabling user-defined conversions that
blocks infinite recursion through repeated application of a copy constructor
(applying it in slightly too many cases) -- though as far as I can tell,
this does not ever actually affect the result of overload resolution, and
- we misapplied the special-case rules for constructors taking a parameter
whose type is a (reference to) the same class type by incorrectly assuming
that only happens for copy/move constructors (it also happens for
constructors instantiated from templates and those inherited from base
classes).
These changes should only affect strange corner cases (for instance, where the
copy constructor exists but has a non-const-qualified parameter type), so for
the most part it only causes us to produce more 'candidate' notes, but see the
test changes for other cases whose behavior is affected.
llvm-svn: 280776
Diffstat (limited to 'clang/test/SemaCXX/cxx11-inheriting-ctors.cpp')
-rw-r--r-- | clang/test/SemaCXX/cxx11-inheriting-ctors.cpp | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/clang/test/SemaCXX/cxx11-inheriting-ctors.cpp b/clang/test/SemaCXX/cxx11-inheriting-ctors.cpp index 9c33ac05cc5..5ce8d1aa3e0 100644 --- a/clang/test/SemaCXX/cxx11-inheriting-ctors.cpp +++ b/clang/test/SemaCXX/cxx11-inheriting-ctors.cpp @@ -1,7 +1,5 @@ // RUN: %clang_cc1 -std=c++11 %s -verify -// expected-no-diagnostics - namespace PR15757 { struct S { }; @@ -56,3 +54,33 @@ namespace InvalidConstruction { template<typename T> int &f(...); int &r = f<C>(0); } + +namespace ExplicitConv { + struct B {}; // expected-note 2{{candidate}} + struct D : B { // expected-note 3{{candidate}} + using B::B; // expected-note 2{{inherited}} + }; + struct X { explicit operator B(); } x; + struct Y { explicit operator D(); } y; + + D dx(x); // expected-error {{no matching constructor}} + D dy(y); +} + +namespace NestedListInit { + struct B { B(); } b; // expected-note 5{{candidate}} + struct D : B { // expected-note 3{{candidate}} + using B::B; // expected-note 2{{inherited}} + }; + // This is a bit weird. We're allowed one pair of braces for overload + // resolution, and one more pair of braces due to [over.ics.list]/2. + B b1 = {b}; + B b2 = {{b}}; + B b3 = {{{b}}}; // expected-error {{no match}} + // This is the same, but we get one call to D's version of B::B(const B&) + // before the two permitted calls to D::D(D&&). + D d1 = {b}; + D d2 = {{b}}; + D d3 = {{{b}}}; + D d4 = {{{{b}}}}; // expected-error {{no match}} +} |