From: Richard Smith Date: Tue, 20 Dec 2011 04:00:21 +0000 (+0000) Subject: Revert r146766, and add a testcase for which it introduced a wrong-code bug. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b6f8d28411955bc5349217a657ad5f274f72293a;p=clang Revert r146766, and add a testcase for which it introduced a wrong-code bug. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146961 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 18fd3876e7..7dbf830431 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -171,9 +171,6 @@ class InitListChecker { bool hadError; bool VerifyOnly; // no diagnostics, no structure building bool AllowBraceElision; - Expr *LastCheckedSubobject; - unsigned LastCheckedSubobjectIndex; - std::map SyntacticToSemantic; InitListExpr *FullyStructuredList; @@ -473,8 +470,7 @@ InitListChecker::FillInValueInitializations(const InitializedEntity &Entity, InitListChecker::InitListChecker(Sema &S, const InitializedEntity &Entity, InitListExpr *IL, QualType &T, bool VerifyOnly, bool AllowBraceElision) - : SemaRef(S), VerifyOnly(VerifyOnly), AllowBraceElision(AllowBraceElision), - LastCheckedSubobject(0), LastCheckedSubobjectIndex(0) { + : SemaRef(S), VerifyOnly(VerifyOnly), AllowBraceElision(AllowBraceElision) { hadError = false; unsigned newIndex = 0; @@ -796,40 +792,13 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity, if (Seq) { if (!VerifyOnly) { - // struct S { - // S(int); - // }; - // - // S s[] = { [0 ... 2] = 3 }; - // - // In code like this, we want to perform the initialization and then - // update the syntactic list with the result. However, we reach this - // point once for each subobject, but the update needs - // to be done only once for each syntactic element. For this reason, - // the initialization result and its syntactic Index are cached in - // LastCheckedSubobject and LastCheckedSubobjectIndex and reused until - // we move to the next Index. - Expr *ResultExpr = LastCheckedSubobject; - - if (!ResultExpr || Index != LastCheckedSubobjectIndex) { - ExprResult Result = Seq.Perform(SemaRef, Entity, Kind, MultiExprArg(&expr, 1)); - - if (Result.isInvalid()) { - hadError = true; - ResultExpr = 0; - } else { - ResultExpr = Result.takeAs(); - } - - LastCheckedSubobject = ResultExpr; - LastCheckedSubobjectIndex = Index; - } - - // Update the syntactic list - IList->setInit(Index, ResultExpr); + ExprResult Result = + Seq.Perform(SemaRef, Entity, Kind, MultiExprArg(&expr, 1)); + if (Result.isInvalid()) + hadError = true; UpdateStructuredListElement(StructuredList, StructuredIndex, - ResultExpr); + Result.takeAs()); } ++Index; return; diff --git a/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp b/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp new file mode 100644 index 0000000000..a853a57fd5 --- /dev/null +++ b/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s + +struct A { + A(const char *); +}; + +// CHECK: @arr = global [3 x %struct.S] zeroinitializer +// CHECK: @.str = {{.*}}constant [6 x i8] c"hello\00" +// CHECK: @.str1 = {{.*}}constant [6 x i8] c"world\00" +// CHECK: @.str2 = {{.*}}constant [8 x i8] c"goodbye\00" + +struct S { + int n; + A s; +} arr[] = { + { 0, "hello" }, + { 1, "world" }, + { 2, "goodbye" } +}; + +// CHECK: store i32 0, i32* getelementptr inbounds ([3 x %struct.S]* @arr, i64 0, i64 0, i32 0) +// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S]* @arr, i64 0, i64 0, i32 1), i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0)) +// CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.S]* @arr, i64 0, i64 1, i32 0) +// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S]* @arr, i64 0, i64 1, i32 1), i8* getelementptr inbounds ([6 x i8]* @.str1, i32 0, i32 0)) +// CHECK: store i32 2, i32* getelementptr inbounds ([3 x %struct.S]* @arr, i64 0, i64 2, i32 0) +// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S]* @arr, i64 0, i64 2, i32 1), i8* getelementptr inbounds ([8 x i8]* @.str2, i32 0, i32 0))