diff options
Diffstat (limited to 'clang/test')
7 files changed, 265 insertions, 20 deletions
diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp index d61f6e3d198..58d038366c8 100644 --- a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp @@ -4,7 +4,7 @@ namespace std { typedef decltype(sizeof(int)) size_t; template <typename E> - struct initializer_list + struct initializer_list // expected-note 2{{candidate}} { const E *p; size_t n; @@ -113,10 +113,14 @@ namespace bullet8 { namespace rdar13395022 { struct MoveOnly { - MoveOnly(MoveOnly&&); // expected-note{{copy constructor is implicitly deleted because 'MoveOnly' has a user-declared move constructor}} + MoveOnly(MoveOnly&&); }; void test(MoveOnly mo) { - auto &&list = {mo}; // expected-error{{call to implicitly-deleted copy constructor of 'rdar13395022::MoveOnly'}} + // FIXME: These diagnostics are poor. + auto &&list1 = {mo}; // expected-error{{no viable conversion}} + MoveOnly (&&list2)[1] = {mo}; // expected-error{{no viable conversion}} + std::initializer_list<MoveOnly> &&list3 = {}; + MoveOnly (&&list4)[1] = {}; // expected-error{{uninitialized}} } } diff --git a/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp index 14d2f772918..1f698899c62 100644 --- a/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp +++ b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp @@ -1,18 +1,28 @@ -// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - -verify %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-STATIC-BL +// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -emit-llvm -o - %s -Dconstexpr= | FileCheck %s --check-prefix=CHECK-DYNAMIC-BL +// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -emit-llvm -o - %s -DUSE_END | FileCheck %s --check-prefix=CHECK-STATIC-BE +// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -emit-llvm -o - %s -DUSE_END -Dconstexpr= | FileCheck %s --check-prefix=CHECK-DYNAMIC-BE namespace std { typedef decltype(sizeof(int)) size_t; - // libc++'s implementation template <class _E> class initializer_list { const _E* __begin_; +#ifdef USE_END + const _E* __end_; +#else size_t __size_; +#endif - initializer_list(const _E* __b, size_t __s) + constexpr initializer_list(const _E* __b, size_t __s) : __begin_(__b), +#ifdef USE_END + __end_(__b + __s) +#else __size_(__s) +#endif {} public: @@ -24,14 +34,98 @@ namespace std { typedef const _E* iterator; typedef const _E* const_iterator; - initializer_list() : __begin_(nullptr), __size_(0) {} +#ifdef USE_END + constexpr initializer_list() : __begin_(nullptr), __end_(nullptr) {} + + size_t size() const {return __end_ - __begin_;} + const _E* begin() const {return __begin_;} + const _E* end() const {return __end_;} +#else + constexpr 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_;} +#endif }; } -std::initializer_list<std::initializer_list<int>> pleasefail = { - {1, 2}, {3, 4}, {5, 6} // expected-error {{cannot compile}} +std::initializer_list<std::initializer_list<int>> nested = { + {1, 2}, {3, 4}, {5, 6} }; + +// CHECK-STATIC-BL: @_ZGR6nested = private constant [2 x i32] [i32 1, i32 2], align 4 +// CHECK-STATIC-BL: @_ZGR6nested1 = private constant [2 x i32] [i32 3, i32 4], align 4 +// CHECK-STATIC-BL: @_ZGR6nested2 = private constant [2 x i32] [i32 5, i32 6], align 4 +// CHECK-STATIC-BL: @_ZGR6nested3 = private constant [3 x {{.*}}] [ +// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested, i32 0, i32 0), i64 2 }, +// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i32 0, i32 0), i64 2 }, +// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i32 0, i32 0), i64 2 } +// CHECK-STATIC-BL: ], align 8 +// CHECK-STATIC-BL: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested3, i32 0, i32 0), i64 3 }, align 8 + +// CHECK-DYNAMIC-BL: @nested = global +// CHECK-DYNAMIC-BL: @_ZGR6nested = private global [3 x +// CHECK-DYNAMIC-BL: @_ZGR6nested1 = private global [2 x i32] zeroinitializer +// CHECK-DYNAMIC-BL: @_ZGR6nested2 = private global [2 x i32] zeroinitializer +// CHECK-DYNAMIC-BL: @_ZGR6nested3 = private global [2 x i32] zeroinitializer +// CHECK-DYNAMIC-BL: store i32 1, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0) +// CHECK-DYNAMIC-BL: store i32 2, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 1) +// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0), +// CHECK-DYMAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 0), align 8 +// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 1), align 8 +// CHECK-DYNAMIC-BL: store i32 3, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0) +// CHECK-DYNAMIC-BL: store i32 4, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 1) +// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0), +// CHECK-DYNAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 0), align 8 +// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 1), align 8 +// CHECK-DYNAMIC-BL: store i32 5, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 0) +// CHECK-DYNAMIC-BL: store i32 6, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 1) +// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 0), +// CHECK-DYNAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 0), align 8 +// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 1), align 8 +// CHECK-DYNAMIC-BL: store {{.*}}* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0), +// CHECK-DYNAMIC-BL: {{.*}}** getelementptr inbounds ({{.*}}* @nested, i32 0, i32 0), align 8 +// CHECK-DYNAMIC-BL: store i64 3, i64* getelementptr inbounds ({{.*}}* @nested, i32 0, i32 1), align 8 + +// CHECK-STATIC-BE: @_ZGR6nested = private constant [2 x i32] [i32 1, i32 2], align 4 +// CHECK-STATIC-BE: @_ZGR6nested1 = private constant [2 x i32] [i32 3, i32 4], align 4 +// CHECK-STATIC-BE: @_ZGR6nested2 = private constant [2 x i32] [i32 5, i32 6], align 4 +// CHECK-STATIC-BE: @_ZGR6nested3 = private constant [3 x {{.*}}] [ +// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested, i32 0, i32 0), +// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested to i8*), i64 8) to i32*) } +// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i32 0, i32 0), +// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested1 to i8*), i64 8) to i32*) } +// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i32 0, i32 0), +// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested2 to i8*), i64 8) to i32*) } +// CHECK-STATIC-BE: ], align 8 +// CHECK-STATIC-BE: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested3, i32 0, i32 0), +// CHECK-STATIC-BE: {{.*}} bitcast ({{.*}}* getelementptr (i8* bitcast ([3 x {{.*}}]* @_ZGR6nested3 to i8*), i64 48) to {{.*}}*) } + +// CHECK-DYNAMIC-BE: @nested = global +// CHECK-DYNAMIC-BE: @_ZGR6nested = private global [3 x +// CHECK-DYNAMIC-BE: @_ZGR6nested1 = private global [2 x i32] zeroinitializer +// CHECK-DYNAMIC-BE: @_ZGR6nested2 = private global [2 x i32] zeroinitializer +// CHECK-DYNAMIC-BE: @_ZGR6nested3 = private global [2 x i32] zeroinitializer +// CHECK-DYNAMIC-BE: store i32 1, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0) +// CHECK-DYNAMIC-BE: store i32 2, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 1) +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0), +// CHECK-DYMAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 0), align 8 +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 1, i64 0), +// CHECK-DYMAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 1), align 8 +// CHECK-DYNAMIC-BE: store i32 3, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0) +// CHECK-DYNAMIC-BE: store i32 4, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 1) +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0), +// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 0), align 8 +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 1, i64 0), +// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 1), align 8 +// CHECK-DYNAMIC-BE: store i32 5, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 0) +// CHECK-DYNAMIC-BE: store i32 6, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 1) +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 0), +// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 0), align 8 +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 1, i64 0), +// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 1), align 8 +// CHECK-DYNAMIC-BE: store {{.*}}* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0), +// CHECK-DYNAMIC-BE: {{.*}}** getelementptr inbounds ({{.*}}* @nested, i32 0, i32 0), align 8 +// CHECK-DYNAMIC-BE: store {{.*}}* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 1, i64 0), +// CHECK-DYNAMIC-BE: {{.*}}** getelementptr inbounds ({{.*}}* @nested, i32 0, i32 1), align 8 diff --git a/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp index 209ee651385..458dee73c65 100644 --- a/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp +++ b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp @@ -32,8 +32,8 @@ namespace std { }; } -// CHECK: @_ZL25globalInitList1__initlist = internal global [3 x i32] [i32 1, i32 2, i32 3] -// CHECK: @globalInitList1 = global {{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZL25globalInitList1__initlist, {{[^)]*}}), i32* +// CHECK: @_ZGR15globalInitList1 = private constant [3 x i32] [i32 1, i32 2, i32 3] +// CHECK: @globalInitList1 = global {{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZGR15globalInitList1, {{[^)]*}}), i32* std::initializer_list<int> globalInitList1 = {1, 2, 3}; void fn1(int i) { diff --git a/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp index 54d88f565ee..593367c8f13 100644 --- a/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp +++ b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -47,23 +47,43 @@ struct wantslist1 { ~wantslist1(); }; -// CHECK: @_ZL25globalInitList1__initlist = internal global [3 x i32] [i32 1, i32 2, i32 3] -// CHECK: @globalInitList1 = global %{{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZL25globalInitList1__initlist, i32 0, i32 0), i{{32|64}} 3 } +// CHECK: @_ZGR15globalInitList1 = private constant [3 x i32] [i32 1, i32 2, i32 3] +// CHECK: @globalInitList1 = global %{{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZGR15globalInitList1, i32 0, i32 0), i{{32|64}} 3 } std::initializer_list<int> globalInitList1 = {1, 2, 3}; namespace thread_local_global_array { - // CHECK: @_ZN25thread_local_global_arrayL11x__initlistE = internal thread_local global [4 x i32] [i32 1, i32 2, i32 3, i32 4] - // CHECK: @_ZN25thread_local_global_array1xE = thread_local global {{.*}} @_ZN25thread_local_global_arrayL11x__initlistE, {{.*}} i64 4 + // FIXME: We should be able to constant-evaluate this even though the + // initializer is not a constant expression (pointers to thread_local + // objects aren't really a problem). + // + // CHECK: @_ZN25thread_local_global_array1xE = thread_local global + // CHECK: @_ZGRN25thread_local_global_array1xE = private thread_local global [4 x i32] std::initializer_list<int> thread_local x = { 1, 2, 3, 4 }; } -// CHECK: @_ZL25globalInitList2__initlist = internal global [2 x %{{[^ ]*}}] zeroinitializer -// CHECK: @globalInitList2 = global %{{[^ ]+}} { %[[WITHARG:[^ *]+]]* getelementptr inbounds ([2 x +// CHECK: @globalInitList2 = global %{{[^ ]+}} zeroinitializer +// CHECK: @_ZGR15globalInitList2 = private global [2 x %[[WITHARG:[^ ]*]]] zeroinitializer // CHECK: appending global + + +// thread_local initializer: +// CHECK: define internal void +// CHECK: store i32 1, i32* getelementptr inbounds ([4 x i32]* @_ZGRN25thread_local_global_array1xE, i64 0, i64 0) +// CHECK: store i32 2, i32* getelementptr inbounds ([4 x i32]* @_ZGRN25thread_local_global_array1xE, i64 0, i64 1) +// CHECK: store i32 3, i32* getelementptr inbounds ([4 x i32]* @_ZGRN25thread_local_global_array1xE, i64 0, i64 2) +// CHECK: store i32 4, i32* getelementptr inbounds ([4 x i32]* @_ZGRN25thread_local_global_array1xE, i64 0, i64 3) +// CHECK: store i32* getelementptr inbounds ([4 x i32]* @_ZGRN25thread_local_global_array1xE, i64 0, i64 0), +// CHECK: i32** getelementptr inbounds ({{.*}}* @_ZN25thread_local_global_array1xE, i32 0, i32 0), align 8 +// CHECK: store i64 4, i64* getelementptr inbounds ({{.*}}* @_ZN25thread_local_global_array1xE, i32 0, i32 1), align 8 + + // CHECK: define internal void -// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZL25globalInitList2__initlist, i{{32|64}} 0, i{{32|64}} 0 -// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZL25globalInitList2__initlist, i{{32|64}} 0, i{{32|64}} 1 +// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2, i{{32|64}} 0, i{{32|64}} 0 +// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2, i{{32|64}} 0, i{{32|64}} 1 // CHECK: __cxa_atexit +// CHECK: store %[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2, i64 0, i64 0), +// CHECK: %[[WITHARG]]** getelementptr inbounds (%{{.*}}* @globalInitList2, i32 0, i32 0), align 8 +// CHECK: store i64 2, i64* getelementptr inbounds (%{{.*}}* @globalInitList2, i32 0, i32 1), align 8 // CHECK: call void @_ZN10destroyme1D1Ev // CHECK: call void @_ZN10destroyme1D1Ev std::initializer_list<witharg1> globalInitList2 = { @@ -281,10 +301,56 @@ namespace dtors { S(); ~S(); }; + void z(); + + // CHECK: define void @_ZN5dtors1fEv( void f() { + // CHECK: call void @_ZN5dtors1SC1Ev(%"struct.dtors::S"* %arrayinit.begin) + // CHECK: call void @_ZN5dtors1SC1Ev(%"struct.dtors::S"* %arrayinit.element) std::initializer_list<S>{ S(), S() }; + + // Destruction loop for underlying array. + // CHECK: br label + // CHECK: call void @_ZN5dtors1SD1Ev( + // CHECK: br i1 + + // CHECK: call void @_ZN5dtors1zEv( + z(); + + // CHECK-NOT: call void @_ZN5dtors1SD1Ev( } + + // CHECK: define void @_ZN5dtors1gEv( void g() { + // CHECK: call void @_ZN5dtors1SC1Ev(%"struct.dtors::S"* %arrayinit.begin) + // CHECK: call void @_ZN5dtors1SC1Ev(%"struct.dtors::S"* %arrayinit.element) auto x = std::initializer_list<S>{ S(), S() }; + + // Destruction loop for underlying array. + // CHECK: br label + // CHECK: call void @_ZN5dtors1SD1Ev( + // CHECK: br i1 + + // CHECK: call void @_ZN5dtors1zEv( + z(); + + // CHECK-NOT: call void @_ZN5dtors1SD1Ev( + } + + // CHECK: define void @_ZN5dtors1hEv( + void h() { + // CHECK: call void @_ZN5dtors1SC1Ev(%"struct.dtors::S"* %arrayinit.begin) + // CHECK: call void @_ZN5dtors1SC1Ev(%"struct.dtors::S"* %arrayinit.element) + std::initializer_list<S> x = { S(), S() }; + + // CHECK-NOT: call void @_ZN5dtors1SD1Ev( + + // CHECK: call void @_ZN5dtors1zEv( + z(); + + // Destruction loop for underlying array. + // CHECK: br label + // CHECK: call void @_ZN5dtors1SD1Ev( + // CHECK: br i1 } } diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp index 8968ba05f90..e4db1b3405a 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -1596,3 +1596,44 @@ namespace AfterError { } constexpr int k = error(); // expected-error {{must be initialized by a constant expression}} } + +namespace std { + typedef decltype(sizeof(int)) size_t; + + template <class _E> + class initializer_list + { + const _E* __begin_; + size_t __size_; + + constexpr 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; + + constexpr initializer_list() : __begin_(nullptr), __size_(0) {} + + constexpr size_t size() const {return __size_;} + constexpr const _E* begin() const {return __begin_;} + constexpr const _E* end() const {return __begin_ + __size_;} + }; +} + +namespace InitializerList { + constexpr int sum(const int *b, const int *e) { + return b != e ? *b + sum(b+1, e) : 0; + } + constexpr int sum(std::initializer_list<int> ints) { + return sum(ints.begin(), ints.end()); + } + static_assert(sum({1, 2, 3, 4, 5}) == 15, ""); +} diff --git a/clang/test/SemaCXX/constant-expression-cxx1y.cpp b/clang/test/SemaCXX/constant-expression-cxx1y.cpp index 40a98d4ca9f..af44bf8d744 100644 --- a/clang/test/SemaCXX/constant-expression-cxx1y.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx1y.cpp @@ -725,3 +725,43 @@ namespace modify_temporary_during_construction { static_assert(a.y == 54, ""); constexpr int k = a.temporary++; // expected-error {{constant expression}} expected-note {{outside the expression that created the temporary}} } + +namespace std { + typedef decltype(sizeof(int)) size_t; + + template <class _E> + class initializer_list + { + const _E* __begin_; + size_t __size_; + + constexpr 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; + + constexpr initializer_list() : __begin_(nullptr), __size_(0) {} + + constexpr size_t size() const {return __size_;} + constexpr const _E* begin() const {return __begin_;} + constexpr const _E* end() const {return __begin_ + __size_;} + }; +} + +namespace InitializerList { + constexpr int sum(std::initializer_list<int> ints) { + int total = 0; + for (int n : ints) total += n; + return total; + } + static_assert(sum({1, 2, 3, 4, 5}) == 15, ""); +} diff --git a/clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp index 0f7eb77c864..071098440cd 100644 --- a/clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp +++ b/clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -144,7 +144,7 @@ namespace PR12119 { template<typename T> void g(std::initializer_list<std::initializer_list<T>>); void foo() { - f({0, {1}}); + f({0, {1}}); // expected-warning{{braces around scalar initializer}} g({{0, 1}, {2, 3}}); std::initializer_list<int> il = {1, 2}; g({il, {2, 3}}); |