diff options
author | Nico Weber <nicolasweber@gmx.de> | 2016-02-24 20:58:14 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2016-02-24 20:58:14 +0000 |
commit | 72c57f49c4b5638626f5a6ff91187f33976c321f (patch) | |
tree | 3d8c99b1f56ff215647d1c013746fd6ced3faf02 /clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | |
parent | 57ca270b7abcf143f7931d39b36c38455022ec0f (diff) | |
download | bcm5719-llvm-72c57f49c4b5638626f5a6ff91187f33976c321f.tar.gz bcm5719-llvm-72c57f49c4b5638626f5a6ff91187f33976c321f.zip |
Fix rejects-valid caused by r261297.
r261297 called hasUserProvidedDefaultConstructor() to check if defining a
const object is ok. This is incorrect for this example:
struct X { template<typename ...T> X(T...); int n; };
const X x; // formerly OK, now bogus error
Instead, track if a class has a defaulted default constructor, and disallow
a const object for classes that either have defaulted default constructors or
if they need an implicit constructor.
Bug report and fix approach by Richard Smith, thanks!
llvm-svn: 261770
Diffstat (limited to 'clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp')
-rw-r--r-- | clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp index f671bd190ec..17215fedf0a 100644 --- a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp +++ b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp @@ -74,6 +74,33 @@ struct some_init_container_ctor { struct no_fields_container { no_fields nf; }; +struct param_pack_ctor { + template <typename... T> + param_pack_ctor(T...); + int n; +}; +struct param_pack_ctor_field { + param_pack_ctor ndc; +}; +struct multi_param_pack_ctor { + template <typename... T, typename... U> + multi_param_pack_ctor(T..., U..., int f = 0); + int n; +}; +struct ignored_template_ctor_and_def { + template <class T> ignored_template_ctor_and_def(T* f = nullptr); + ignored_template_ctor_and_def() = default; + int field; +}; +template<bool, typename = void> struct enable_if {}; +template<typename T> struct enable_if<true, T> { typedef T type; }; +struct multi_param_pack_and_defaulted { + template <typename... T, + typename enable_if<sizeof...(T) != 0>::type* = nullptr> + multi_param_pack_and_defaulted(T...); + multi_param_pack_and_defaulted() = default; + int n; +}; void constobjs() { const no_fields nf; // ok @@ -88,6 +115,12 @@ void constobjs() { const some_init_container sicon; // expected-error {{default initialization of an object of const type 'const some_init_container' without a user-provided default constructor}} const some_init_container_ctor siconc; // ok const no_fields_container nfc; // ok + const param_pack_ctor ppc; // ok + const param_pack_ctor_field ppcf; // ok + const multi_param_pack_ctor mppc; // ok + const multi_param_pack_and_defaulted mppad; // expected-error {{default initialization of an object of const type 'const multi_param_pack_and_defaulted' without a user-provided default constructor}} + const ignored_template_ctor_and_def itcad; // expected-error {{default initialization of an object of const type 'const ignored_template_ctor_and_def' without a user-provided default constructor}} + } struct non_const_derived : non_const_copy { |