aboutsummaryrefslogtreecommitdiff
path: root/test/SemaCXX/cxx0x-initializer-constructor.cpp
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2012-02-11 23:51:08 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2012-02-11 23:51:08 +0000
commit56a04287a1c713870d1e03206cce785e985cc866 (patch)
treecb416982131036464cc0b9e37a0e30de8c7429e0 /test/SemaCXX/cxx0x-initializer-constructor.cpp
parent15d0ae170c2037815b6383c532253585fcd3d04e (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.cpp68
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
}
}