diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2012-02-11 23:51:08 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2012-02-11 23:51:08 +0000 |
commit | 56a04287a1c713870d1e03206cce785e985cc866 (patch) | |
tree | cb416982131036464cc0b9e37a0e30de8c7429e0 /test/SemaCXX/cxx0x-initializer-constructor.cpp | |
parent | 15d0ae170c2037815b6383c532253585fcd3d04e (diff) |
Fix parsing new expressions using init lists. Probably still do the wrong thing in cases involving array new.
Show that many cases using initializer list constructors work, in that they parse and pass semantic analysis.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150316 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/SemaCXX/cxx0x-initializer-constructor.cpp')
-rw-r--r-- | test/SemaCXX/cxx0x-initializer-constructor.cpp | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/test/SemaCXX/cxx0x-initializer-constructor.cpp b/test/SemaCXX/cxx0x-initializer-constructor.cpp index c083366865..4858d7af9d 100644 --- a/test/SemaCXX/cxx0x-initializer-constructor.cpp +++ b/test/SemaCXX/cxx0x-initializer-constructor.cpp @@ -3,6 +3,38 @@ struct one { char c[1]; }; struct two { char c[2]; }; +namespace std { + typedef decltype(sizeof(int)) size_t; + + // libc++'s implementation + template <class _E> + class initializer_list + { + const _E* __begin_; + size_t __size_; + + initializer_list(const _E* __b, size_t __s) + : __begin_(__b), + __size_(__s) + {} + + public: + typedef _E value_type; + typedef const _E& reference; + typedef const _E& const_reference; + typedef size_t size_type; + + typedef const _E* iterator; + typedef const _E* const_iterator; + + initializer_list() : __begin_(nullptr), __size_(0) {} + + size_t size() const {return __size_;} + const _E* begin() const {return __begin_;} + const _E* end() const {return __begin_ + __size_;} + }; +} + namespace objects { struct X1 { X1(int); }; @@ -15,6 +47,19 @@ namespace objects { }; template <int N> + struct F { + F() { static_assert(N == 0, ""); } + F(int, double) { static_assert(N == 1, ""); } + F(std::initializer_list<int>) { static_assert(N == 3, ""); } + }; + + template <int N> + struct D { + D(std::initializer_list<int>) { static_assert(N == 0, ""); } // expected-note 1 {{candidate}} + D(std::initializer_list<double>) { static_assert(N == 1, ""); } // expected-note 1 {{candidate}} + }; + + template <int N> struct E { E(int, int) { static_assert(N == 0, ""); } E(X1, int) { static_assert(N == 1, ""); } @@ -26,6 +71,22 @@ namespace objects { { A<1> a{1, 1.0}; } { A<1> a = {1, 1.0}; } + { F<0> f{}; } + { F<0> f = {}; } + // Narrowing conversions don't affect viability. The next two choose + // the initializer_list constructor. + // FIXME: Emit narrowing conversion errors. + { F<3> f{1, 1.0}; } // xpected-error {{narrowing conversion}} + { F<3> f = {1, 1.0}; } // xpected-error {{narrowing conversion}} + { F<3> f{1, 2, 3, 4, 5, 6, 7, 8}; } + { F<3> f = {1, 2, 3, 4, 5, 6, 7, 8}; } + { F<3> f{1, 2, 3, 4, 5, 6, 7, 8}; } + { F<3> f{1, 2}; } + + { D<0> d{1, 2, 3}; } + { D<1> d{1.0, 2.0, 3.0}; } + { D<-1> d{1, 2.0}; } // expected-error {{ambiguous}} + { E<0> e{1, 2}; } } @@ -57,6 +118,8 @@ namespace objects { void inline_init() { (void) C{1, 1.0}; (void) new C{1, 1.0}; + (void) A<1>{1, 1.0}; + (void) new A<1>{1, 1.0}; } struct B { // expected-note 2 {{candidate constructor}} @@ -77,5 +140,10 @@ namespace objects { static_assert(sizeof(ov1({{1, 1.0}, 2, {3, 4}})) == sizeof(one), "bad overload"); ov1({1}); // expected-error {{no matching function}} + + one ov2(int); + two ov2(F<3>); + static_assert(sizeof(ov2({1})) == sizeof(one), "bad overload"); // list -> int ranks as identity + static_assert(sizeof(ov2({1, 2, 3})) == sizeof(two), "bad overload"); // list -> F only viable } } |