diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-02-29 00:00:28 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-02-29 00:00:28 +0000 |
commit | c60ccf5b4fb657ca40da3019c2bbe15dd8ab9732 (patch) | |
tree | bf8febe982ad17be7edd5d8c40a7180fd96702d2 | |
parent | f76b897c8ff23cef3b7b9dd12e5778b508b002ca (diff) |
Make sure list-initialization of arrays works correctly in explicit type conversions. PR12121.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151674 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 32 | ||||
-rw-r--r-- | test/CodeGenCXX/cxx0x-initializer-array.cpp | 10 | ||||
-rw-r--r-- | test/SemaCXX/cxx0x-initializer-aggregates.cpp | 14 |
4 files changed, 43 insertions, 15 deletions
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index ce0533c7dc..899577c4ed 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -898,7 +898,7 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { return; } - llvm::Value *DestPtr = Dest.getAddr(); + llvm::Value *DestPtr = EnsureSlot(E->getType()).getAddr(); // Handle initialization of an array. if (E->getType()->isArrayType()) { diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 72c069f7da..46ecd9382c 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -787,20 +787,6 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, SourceRange FullRange = SourceRange(TyBeginLoc, ListInitialization ? Exprs[0]->getSourceRange().getEnd() : RParenLoc); - if (Ty->isArrayType()) - return ExprError(Diag(TyBeginLoc, - diag::err_value_init_for_array_type) << FullRange); - if (!Ty->isVoidType() && - RequireCompleteType(TyBeginLoc, Ty, - PDiag(diag::err_invalid_incomplete_type_use) - << FullRange)) - return ExprError(); - - if (RequireNonAbstractType(TyBeginLoc, Ty, - diag::err_allocation_of_abstract_type)) - return ExprError(); - - // C++ [expr.type.conv]p1: // If the expression list is a single expression, the type conversion // expression is equivalent (in definedness, and if defined in meaning) to the @@ -811,6 +797,24 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, return BuildCXXFunctionalCastExpr(TInfo, LParenLoc, Arg, RParenLoc); } + QualType ElemTy = Ty; + if (Ty->isArrayType()) { + if (!ListInitialization) + return ExprError(Diag(TyBeginLoc, + diag::err_value_init_for_array_type) << FullRange); + ElemTy = Context.getBaseElementType(Ty); + } + + if (!Ty->isVoidType() && + RequireCompleteType(TyBeginLoc, ElemTy, + PDiag(diag::err_invalid_incomplete_type_use) + << FullRange)) + return ExprError(); + + if (RequireNonAbstractType(TyBeginLoc, Ty, + diag::err_allocation_of_abstract_type)) + return ExprError(); + InitializedEntity Entity = InitializedEntity::InitializeTemporary(TInfo); InitializationKind Kind = NumExprs ? ListInitialization diff --git a/test/CodeGenCXX/cxx0x-initializer-array.cpp b/test/CodeGenCXX/cxx0x-initializer-array.cpp new file mode 100644 index 0000000000..b773178e6b --- /dev/null +++ b/test/CodeGenCXX/cxx0x-initializer-array.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s | FileCheck %s + +struct A { int a[1]; }; +typedef A x[]; +int f() { + x{{{1}}}; + // CHECK: define i32 @_Z1fv + // CHECK: store i32 1 + // (It's okay if the output changes here, as long as we don't crash.) +} diff --git a/test/SemaCXX/cxx0x-initializer-aggregates.cpp b/test/SemaCXX/cxx0x-initializer-aggregates.cpp index 48888d0eb0..801a82f570 100644 --- a/test/SemaCXX/cxx0x-initializer-aggregates.cpp +++ b/test/SemaCXX/cxx0x-initializer-aggregates.cpp @@ -73,3 +73,17 @@ namespace aggregate { struct C { int a[2]; C():a({1, 2}) { } }; // expected-error {{parenthesized initialization of a member array is a GNU extension}} } + +namespace array_explicit_conversion { + typedef int test1[2]; + typedef int test2[]; + template<int x> struct A { int a[x]; }; // expected-error {{'a' declared as an array with a negative size}} + typedef A<1> test3[]; + typedef A<-1> test4[]; + void f() { + (void)test1{1}; + (void)test2{1}; + (void)test3{{{1}}}; + (void)test4{{{1}}}; // expected-note {{in instantiation of template class 'array_explicit_conversion::A<-1>' requested here}} + } +} |