summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-09-07 02:14:33 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-09-07 02:14:33 +0000
commit7c2bcc9eb038df5fa238276749a88f289e9861ae (patch)
treefec04fe63bc882c0526a4301ac9fede9009c8656 /clang/test
parentc1d527d3d832cac86eb9461dcef978011ef8caeb (diff)
downloadbcm5719-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')
-rw-r--r--clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp6
-rw-r--r--clang/test/CXX/drs/dr0xx.cpp6
-rw-r--r--clang/test/CXX/drs/dr1xx.cpp2
-rw-r--r--clang/test/CodeGenCXX/copy-constructor-elim-2.cpp20
-rw-r--r--clang/test/SemaCXX/conditional-expr.cpp2
-rw-r--r--clang/test/SemaCXX/copy-initialization.cpp11
-rw-r--r--clang/test/SemaCXX/cxx0x-initializer-constructor.cpp5
-rw-r--r--clang/test/SemaCXX/cxx11-inheriting-ctors.cpp32
-rw-r--r--clang/test/SemaCXX/cxx98-compat-flags.cpp2
-rw-r--r--clang/test/SemaCXX/cxx98-compat-pedantic.cpp2
10 files changed, 74 insertions, 14 deletions
diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp
index 494cfb57670..7a5caef36e7 100644
--- a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp
+++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp
@@ -19,7 +19,7 @@ private:
};
struct X3 {
- X3();
+ X3(); // expected-note{{requires 0 arguments, but 1 was provided}}
private:
X3(X3&); // expected-note{{candidate constructor not viable: expects an l-value for 1st argument}}
@@ -42,8 +42,8 @@ struct X4 {
// Check for "dangerous" default arguments that could cause recursion.
struct X5 {
- X5();
- X5(const X5&, const X5& = X5()); // expected-warning{{no viable constructor copying parameter of type 'X5'}}
+ X5(); // expected-note {{requires 0 arguments}}
+ X5(const X5&, const X5& = X5()); // expected-warning{{no viable constructor copying parameter of type 'X5'}} expected-note {{requires 2 arguments}}
};
void g1(const X1&);
diff --git a/clang/test/CXX/drs/dr0xx.cpp b/clang/test/CXX/drs/dr0xx.cpp
index 3bb6701b32e..69cb776c330 100644
--- a/clang/test/CXX/drs/dr0xx.cpp
+++ b/clang/test/CXX/drs/dr0xx.cpp
@@ -643,8 +643,8 @@ namespace dr58 { // dr58: yes
namespace dr59 { // dr59: yes
template<typename T> struct convert_to { operator T() const; };
- struct A {}; // expected-note 2{{volatile qualifier}}
- struct B : A {}; // expected-note 2{{volatile qualifier}}
+ struct A {}; // expected-note 2{{volatile qualifier}} expected-note 2{{requires 0 arguments}}
+ struct B : A {}; // expected-note 2{{volatile qualifier}} expected-note 2{{requires 0 arguments}}
#if __cplusplus >= 201103L // move constructors
// expected-note@-3 2{{volatile qualifier}}
// expected-note@-3 2{{volatile qualifier}}
@@ -902,7 +902,7 @@ namespace dr84 { // dr84: yes
struct C {};
struct B {
B(B&); // expected-note {{candidate}}
- B(C);
+ B(C); // expected-note {{no known conversion from 'dr84::B' to 'dr84::C'}}
operator C() const;
};
A a;
diff --git a/clang/test/CXX/drs/dr1xx.cpp b/clang/test/CXX/drs/dr1xx.cpp
index 8d368a5a54e..60d6ccaa875 100644
--- a/clang/test/CXX/drs/dr1xx.cpp
+++ b/clang/test/CXX/drs/dr1xx.cpp
@@ -827,7 +827,7 @@ namespace dr177 { // dr177: yes
struct B {};
struct A {
A(A &); // expected-note {{not viable: expects an l-value}}
- A(const B &);
+ A(const B &); // expected-note {{not viable: no known conversion from 'dr177::A' to}}
};
B b;
A a = b; // expected-error {{no viable constructor copying variable}}
diff --git a/clang/test/CodeGenCXX/copy-constructor-elim-2.cpp b/clang/test/CodeGenCXX/copy-constructor-elim-2.cpp
index c263b7ebf95..26b6b4851f5 100644
--- a/clang/test/CodeGenCXX/copy-constructor-elim-2.cpp
+++ b/clang/test/CodeGenCXX/copy-constructor-elim-2.cpp
@@ -74,3 +74,23 @@ namespace PR12139 {
return a.value;
}
}
+
+namespace ElidableCallIsNotCopyCtor {
+ struct A { A(const A&); };
+ struct B : A {
+ B(B&);
+ B(A);
+ B(int);
+ };
+ void f() {
+ // Here, we construct via B(int) then B(A). The B(A) construction is
+ // elidable, but we don't have an AST representation for the case where we
+ // must elide not only a constructor call but also some argument
+ // conversions, so we don't elide it.
+ // CHECK-LABEL: define void @_ZN25ElidableCallIsNotCopyCtor1fEv(
+ // CHECK: call {{.*}} @_ZN25ElidableCallIsNotCopyCtor1BC1Ei(
+ // CHECK: call {{.*}} @_ZN25ElidableCallIsNotCopyCtor1AC1ERKS0_(
+ // CHECK: call {{.*}} @_ZN25ElidableCallIsNotCopyCtor1BC1ENS_1AE(
+ B b = 0;
+ }
+}
diff --git a/clang/test/SemaCXX/conditional-expr.cpp b/clang/test/SemaCXX/conditional-expr.cpp
index c12efc0be7e..5025990cfd3 100644
--- a/clang/test/SemaCXX/conditional-expr.cpp
+++ b/clang/test/SemaCXX/conditional-expr.cpp
@@ -262,7 +262,7 @@ namespace PR6757 {
struct Foo2 { };
struct Foo3 {
- Foo3();
+ Foo3(); // expected-note{{requires 0 arguments}}
Foo3(Foo3&); // expected-note{{would lose const qualifier}}
};
diff --git a/clang/test/SemaCXX/copy-initialization.cpp b/clang/test/SemaCXX/copy-initialization.cpp
index d219ee508f0..4f6c65cf550 100644
--- a/clang/test/SemaCXX/copy-initialization.cpp
+++ b/clang/test/SemaCXX/copy-initialization.cpp
@@ -30,7 +30,7 @@ void test(const foo *P) { P->bar(); } // expected-error{{'bar' not viable: 'this
namespace PR6757 {
struct Foo {
- Foo();
+ Foo(); // expected-note{{not viable}}
Foo(Foo&); // expected-note{{candidate constructor not viable}}
};
@@ -71,3 +71,12 @@ namespace DR5 {
const S b = 0;
}
}
+
+struct A {};
+struct B : A {
+ B();
+ B(B&);
+ B(A);
+ B(int);
+};
+B b = 0; // ok, calls B(int) then A(const A&) then B(A).
diff --git a/clang/test/SemaCXX/cxx0x-initializer-constructor.cpp b/clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
index 6202bf620fe..c10bee917ac 100644
--- a/clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
+++ b/clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
@@ -267,8 +267,11 @@ namespace PR12120 {
struct A { explicit A(int); A(float); }; // expected-note {{declared here}}
A a = { 0 }; // expected-error {{constructor is explicit}}
- struct B { explicit B(short); B(long); }; // expected-note 2 {{candidate}}
+ struct B { explicit B(short); B(long); }; // expected-note 4{{candidate}}
B b = { 0 }; // expected-error {{ambiguous}}
+
+ struct C { explicit C(short); C(long); }; // expected-note 2{{candidate}}
+ C c = {{ 0 }}; // expected-error {{ambiguous}}
}
namespace PR12498 {
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}}
+}
diff --git a/clang/test/SemaCXX/cxx98-compat-flags.cpp b/clang/test/SemaCXX/cxx98-compat-flags.cpp
index f90ad345e97..62d687c49cf 100644
--- a/clang/test/SemaCXX/cxx98-compat-flags.cpp
+++ b/clang/test/SemaCXX/cxx98-compat-flags.cpp
@@ -16,7 +16,7 @@ namespace CopyCtorIssues {
Private(const Private&); // expected-note {{declared private here}}
};
struct NoViable {
- NoViable();
+ NoViable(); // expected-note {{not viable}}
NoViable(NoViable&); // expected-note {{not viable}}
};
struct Ambiguous {
diff --git a/clang/test/SemaCXX/cxx98-compat-pedantic.cpp b/clang/test/SemaCXX/cxx98-compat-pedantic.cpp
index 8b0dcc87132..c72c44ad5fe 100644
--- a/clang/test/SemaCXX/cxx98-compat-pedantic.cpp
+++ b/clang/test/SemaCXX/cxx98-compat-pedantic.cpp
@@ -55,7 +55,7 @@ namespace CopyCtorIssues {
Private(const Private&); // expected-note {{declared private here}}
};
struct NoViable {
- NoViable();
+ NoViable(); // expected-note {{not viable}}
NoViable(NoViable&); // expected-note {{not viable}}
};
struct Ambiguous {
OpenPOWER on IntegriCloud