diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-04-18 07:40:54 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-04-18 07:40:54 +0000 |
| commit | c9cd64eee393798c413ba20392c09c78c2a90ad5 (patch) | |
| tree | c891b19abaef4bfd903053d9fe815cb88932455d /clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp | |
| parent | 554a39889b6d80e109dc33d1e4b7cb12e7caee4b (diff) | |
| download | bcm5719-llvm-c9cd64eee393798c413ba20392c09c78c2a90ad5.tar.gz bcm5719-llvm-c9cd64eee393798c413ba20392c09c78c2a90ad5.zip | |
In C++98/03, when binding a reference to an rvalue of
reference-compatible type, the implementation is permitted to make a
copy of the rvalue (or many such copies, even). However, even though
we don't make that copy, we are required to check for the presence of
a suitable copy constructor. With this change, we do.
Note that in C++0x we are not allowed to make these copies, so we test
both dialects separately.
Also note the FIXME in one of the C++03 tests, where we are not
instantiating default function arguments for the copy constructor we
pick (but do not call). The fix is obvious; eliminating the infinite
recursion it causes is not. Will address that next.
llvm-svn: 101704
Diffstat (limited to 'clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp')
| -rw-r--r-- | clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp | 51 |
1 files changed, 51 insertions, 0 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 new file mode 100644 index 00000000000..5dd68613573 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++03 requires that we check for a copy constructor when binding a +// reference to a temporary, since we are allowed to make a copy, Even +// though we don't actually make that copy, make sure that we diagnose +// cases where that copy constructor is somehow unavailable. + +struct X1 { + X1(); + explicit X1(const X1&); +}; + +struct X2 { + X2(); + +private: + X2(const X2&); // expected-note{{declared private here}} +}; + +struct X3 { + X3(); + +private: + X3(X3&); // expected-note{{candidate constructor not viable: no known conversion from 'X3' to 'X3 &' for 1st argument}} +}; + +template<typename T> +T get_value_badly() { + double *dp = 0; + T *tp = dp; // FIXME: Should get an error here, from instantiating the + // default argument of X4<int> + return T(); +} + +template<typename T> +struct X4 { + X4(); + X4(const X4&, T = get_value_badly<T>()); +}; + +void g1(const X1&); +void g2(const X2&); +void g3(const X3&); +void g4(const X4<int>&); + +void test() { + g1(X1()); // expected-error{{no viable constructor copying parameter of type 'X1'}} + g2(X2()); // expected-error{{calling a private constructor of class 'X2'}} + g3(X3()); // expected-error{{no viable constructor copying parameter of type 'X3'}} + g4(X4<int>()); +} |

