[cfe-commits] Uninformative C++98 error when calling a ctor taking const&, where the type passed in has a deleted copy-ctor
Jeff Walden
jwalden+clang at mit.edu
Fri Apr 13 16:13:51 PDT 2012
Just yesterday a few of us SpiderMonkey hackers stumbled upon the apparent C++98 oddity that binding a T temporary to a const U& (where U has a U(const T&) constructor) requires that T's copy constructor be accessible. Here's a demonstration:
> [jwalden at wheres-wally minimal]$ cat test.cpp
> class A
> {
> public:
> A() {}
>
> private:
> A(const A& a)
> #ifdef DELETE_COPY_CTOR
> = delete
> #endif
> ;
> };
>
> class B
> {
> public:
> B(const A& a) {}
> };
>
> int main()
> {
> B b = A();
> }
If you compile this without the =delete, you get warned that the copy constructor is inaccessible, and things still build.
> [jwalden at wheres-wally minimal]$ ~/Programs/clang-build/build/Release/bin/clang++ -Wno-c++11-extensions test.cpp
> test.cpp:22:9: warning: C++98 requires an accessible copy constructor for class 'A' when binding a reference to a temporary; was private
> [-Wbind-to-temporary-copy]
> B b = A();
> ^
> test.cpp:7:5: note: declared private here
> A(const A& a)
> ^
> 1 warning generated.
On the other hand, if you compile this with =delete (as SpiderMonkey's code was doing), you get an error that a deleted constructor was invoked. But you *don't* get a warning telling you that C++98 requires the copy constructor to be accessible.
> [jwalden at wheres-wally minimal]$ ~/Programs/clang-build/build/Release/bin/clang++ -Wno-c++11-extensions -DDELETE_COPY_CTOR test.cpp
> test.cpp:22:9: error: copying parameter of type 'A' invokes deleted constructor
> B b = A();
> ^~~
> test.cpp:7:5: note: function has been explicitly marked deleted here
> A(const A& a)
> ^
> 1 error generated.
We devised a hackaround specific to the situation where we were hitting this problem, but we didn't understand why it was happening. Only later, when reducing it to report a bug or determine that it wasn't a bug, did we discover the C++98 oddity. It would have been much more readily apparent what the problem was if we'd had both diagnostics.
I've attached a patch which, for this testcase at least, causes both errors to be emitted. With it I get this:
> [jwalden at wheres-wally minimal]$ ~/Programs/clang-build/build/Release/bin/clang++ -Wno-c++11-extensions -DDELETE_COPY_CTOR test.cpp
> test.cpp:22:9: error: copying parameter of type 'A' invokes deleted constructor
> B b = A();
> ^~~
> test.cpp:7:5: note: function has been explicitly marked deleted here
> A(const A& a)
> ^
> test.cpp:22:9: warning: C++98 requires an accessible copy constructor for class 'A' when binding a reference to a temporary; was private
> [-Wbind-to-temporary-copy]
> B b = A();
> ^
> test.cpp:7:5: note: declared private here
> A(const A& a)
> ^
> 1 warning and 1 error generated.
Does this patch look reasonable? I'm making pretty huge assumptions about error-toleration here, so please correct me if I'm doing something crazy. :-)
Jeff
-------------- next part --------------
A non-text attachment was scrubbed...
Name: extra-diagnostics.diff
Type: text/x-patch
Size: 591 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120413/7218496b/attachment.bin>
More information about the cfe-commits
mailing list