aboutsummaryrefslogtreecommitdiff
path: root/test/SemaCXX/copy-initialization.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-04-02 18:24:57 +0000
committerDouglas Gregor <dgregor@apple.com>2010-04-02 18:24:57 +0000
commit2f59979a7cc7929f53c9984423b0abeb83113442 (patch)
tree725da189932269b3f5c78efb3b18c27894559b8f /test/SemaCXX/copy-initialization.cpp
parent8facca6cafa8d471768fe14074b1301e24e08fec (diff)
Rework our handling of copy construction of temporaries, which was a
poor (and wrong) approximation of the actual rules governing when to build a copy and when it can be elided. The correct implementation is actually simpler than the approximation. When we only enumerate constructors as part of initialization (e.g., for direct initialization or when we're copying from a class type or one of its derived classes), we don't create a copy. When we enumerate all conversion functions, we do create a copy. Before, we created some extra copies and missed some others. The new test copy-initialization.cpp shows a case where we missed creating a (required, non-elidable) copy as part of a user-defined conversion, which resulted in a miscompile. This commit also fixes PR6757, where the missing copy made us reject well-formed code in the ternary operator. This commit also cleans up our handling of copy elision in the case where we create an extra copy of a temporary object, which became necessary now that we produce the right copies. The code that seeks to find the temporary object being copied has moved into Expr::getTemporaryObject(); it used to have two different not-quite-the-same implementations, one in Sema and one in CodeGen. Note that we still do not attempt to perform the named return value optimization, so we miss copy elisions for return values and throw expressions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@100196 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/SemaCXX/copy-initialization.cpp')
-rw-r--r--test/SemaCXX/copy-initialization.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/test/SemaCXX/copy-initialization.cpp b/test/SemaCXX/copy-initialization.cpp
index 3a63be0970..e5b1fd766b 100644
--- a/test/SemaCXX/copy-initialization.cpp
+++ b/test/SemaCXX/copy-initialization.cpp
@@ -21,3 +21,23 @@ struct foo {
// PR3600
void test(const foo *P) { P->bar(); } // expected-error{{cannot initialize object parameter of type 'foo' with an expression of type 'foo const'}}
+
+namespace PR6757 {
+ struct Foo {
+ Foo();
+ Foo(Foo&);
+ };
+
+ struct Bar {
+ operator const Foo&() const;
+ };
+
+ void f(Foo); // expected-note{{candidate function not viable: no known conversion from 'PR6757::Bar' to 'PR6757::Foo' for 1st argument}}
+
+ // FIXME: This isn't really the right reason for the failure. We
+ // should fail after overload resolution.
+ void g(Foo foo) {
+ f(Bar()); // expected-error{{no matching function for call to 'f'}}
+ f(foo);
+ }
+}