aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNicola Gigante <nicola.gigante@gmail.com>2011-12-16 22:57:37 +0000
committerNicola Gigante <nicola.gigante@gmail.com>2011-12-16 22:57:37 +0000
commit8a93d27a507d9c455eb802a29dc572aa8577393a (patch)
tree48f16408725f25bd604f382da887835b32a7bbfb /lib
parenta3ca4d655974ad66e432a6c78dd08b277a639edf (diff)
Fix an inconsistency in the syntactic form of InitListExpr in case of initialization that involves a ConstructorConversion
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146766 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Sema/SemaInit.cpp43
1 files changed, 37 insertions, 6 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 7dbf830431..18fd3876e7 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -171,6 +171,9 @@ class InitListChecker {
bool hadError;
bool VerifyOnly; // no diagnostics, no structure building
bool AllowBraceElision;
+ Expr *LastCheckedSubobject;
+ unsigned LastCheckedSubobjectIndex;
+
std::map<InitListExpr *, InitListExpr *> SyntacticToSemantic;
InitListExpr *FullyStructuredList;
@@ -470,7 +473,8 @@ 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) {
+ : SemaRef(S), VerifyOnly(VerifyOnly), AllowBraceElision(AllowBraceElision),
+ LastCheckedSubobject(0), LastCheckedSubobjectIndex(0) {
hadError = false;
unsigned newIndex = 0;
@@ -792,13 +796,40 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity,
if (Seq) {
if (!VerifyOnly) {
- ExprResult Result =
- Seq.Perform(SemaRef, Entity, Kind, MultiExprArg(&expr, 1));
- if (Result.isInvalid())
- hadError = true;
+ // 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<Expr>();
+ }
+
+ LastCheckedSubobject = ResultExpr;
+ LastCheckedSubobjectIndex = Index;
+ }
+
+ // Update the syntactic list
+ IList->setInit(Index, ResultExpr);
UpdateStructuredListElement(StructuredList, StructuredIndex,
- Result.takeAs<Expr>());
+ ResultExpr);
}
++Index;
return;