2009-12-16 04:14:24 +08:00
|
|
|
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
2015-11-12 03:34:47 +08:00
|
|
|
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
|
|
|
|
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
|
|
|
|
|
2008-11-05 23:29:30 +08:00
|
|
|
class X {
|
|
|
|
public:
|
2020-01-10 04:27:48 +08:00
|
|
|
explicit X(const X&); // expected-note 2{{not a candidate}}
|
2010-04-18 10:16:12 +08:00
|
|
|
X(int*); // expected-note 3{{candidate constructor}}
|
2020-01-10 04:27:48 +08:00
|
|
|
explicit X(float*); // expected-note {{candidate constructor}} expected-note 2{{not a candidate}}
|
2008-11-05 23:29:30 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
class Y : public X { };
|
|
|
|
|
|
|
|
void f(Y y, int *ip, float *fp) {
|
2010-03-10 19:27:22 +08:00
|
|
|
X x1 = y; // expected-error{{no matching constructor for initialization of 'X'}}
|
2010-11-12 11:34:06 +08:00
|
|
|
X x2 = 0;
|
|
|
|
X x3 = ip;
|
2009-12-19 11:01:41 +08:00
|
|
|
X x4 = fp; // expected-error{{no viable conversion}}
|
2010-04-18 10:16:12 +08:00
|
|
|
X x2a(0); // expected-error{{call to constructor of 'X' is ambiguous}}
|
|
|
|
X x3a(ip);
|
|
|
|
X x4a(fp);
|
2008-11-05 23:29:30 +08:00
|
|
|
}
|
2009-02-19 08:52:42 +08:00
|
|
|
|
|
|
|
struct foo {
|
2010-11-16 16:04:45 +08:00
|
|
|
void bar(); // expected-note{{declared here}}
|
2009-02-19 08:52:42 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
// PR3600
|
2018-01-01 02:27:29 +08:00
|
|
|
void test(const foo *P) { P->bar(); } // expected-error{{'this' argument to member function 'bar' has type 'const foo', but function is not marked const}}
|
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.
llvm-svn: 100196
2010-04-03 02:24:57 +08:00
|
|
|
|
|
|
|
namespace PR6757 {
|
|
|
|
struct Foo {
|
2016-09-07 10:14:33 +08:00
|
|
|
Foo(); // expected-note{{not viable}}
|
2010-04-18 06:01:05 +08:00
|
|
|
Foo(Foo&); // expected-note{{candidate constructor not viable}}
|
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.
llvm-svn: 100196
2010-04-03 02:24:57 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct Bar {
|
|
|
|
operator const Foo&() const;
|
|
|
|
};
|
|
|
|
|
2010-04-18 06:01:05 +08:00
|
|
|
void f(Foo);
|
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.
llvm-svn: 100196
2010-04-03 02:24:57 +08:00
|
|
|
|
|
|
|
void g(Foo foo) {
|
2010-09-05 08:17:29 +08:00
|
|
|
f(Bar()); // expected-error{{no viable constructor copying parameter of type 'const PR6757::Foo'}}
|
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.
llvm-svn: 100196
2010-04-03 02:24:57 +08:00
|
|
|
f(foo);
|
|
|
|
}
|
|
|
|
}
|
2012-02-12 03:22:50 +08:00
|
|
|
|
|
|
|
namespace DR5 {
|
|
|
|
// Core issue 5: if a temporary is created in copy-initialization, it is of
|
|
|
|
// the cv-unqualified version of the destination type.
|
|
|
|
namespace Ex1 {
|
|
|
|
struct C { };
|
|
|
|
C c;
|
|
|
|
struct A {
|
|
|
|
A(const A&);
|
|
|
|
A(const C&);
|
|
|
|
};
|
|
|
|
const volatile A a = c; // ok
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace Ex2 {
|
|
|
|
struct S {
|
2015-11-12 03:34:47 +08:00
|
|
|
S(S&&);
|
|
|
|
#if __cplusplus <= 199711L // C++03 or earlier modes
|
|
|
|
// expected-warning@-2 {{rvalue references are a C++11 extension}}
|
|
|
|
#endif
|
2012-02-12 03:22:50 +08:00
|
|
|
S(int);
|
|
|
|
};
|
|
|
|
const S a(0);
|
|
|
|
const S b = 0;
|
|
|
|
}
|
|
|
|
}
|
2016-09-07 10:14:33 +08:00
|
|
|
|
|
|
|
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).
|