[cfe-commits] r146766 - /cfe/trunk/lib/Sema/SemaInit.cpp

Richard Smith richard at metafoo.co.uk
Mon Dec 19 20:06:37 PST 2011


Hi Nicola,

I reverted this patch in r146961. It caused a miscompile (see the testcase I
added in that revision). Checking the LastCheckedSubobjectIndex is
insufficient -- the initializer could be a subobject of a different
initializer list, in which case the patch replaces the initializer expression
with an unrelated one.

- Richard

On Fri, December 16, 2011 22:57, Nicola Gigante wrote:
> Author: gigabytes
> Date: Fri Dec 16 16:57:37 2011
> New Revision: 146766
>
>
> URL: http://llvm.org/viewvc/llvm-project?rev=146766&view=rev
> Log:
> Fix an inconsistency in the syntactic form of InitListExpr in case of
> initialization that involves a ConstructorConversion
>
> Modified:
> cfe/trunk/lib/Sema/SemaInit.cpp
>
> Modified: cfe/trunk/lib/Sema/SemaInit.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=14676
> 6&r1=146765&r2=146766&view=diff
> ==============================================================================
>  --- cfe/trunk/lib/Sema/SemaInit.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Dec 16 16:57:37 2011
> @@ -171,6 +171,9 @@
> 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::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 @@
>
>
> 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;
>
>
>
>




More information about the cfe-commits mailing list