r289413 - Add two new AST nodes to represent initialization of an array in terms of
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 12 16:20:15 PST 2016
On 12 December 2016 at 16:16, Mike Aizatsky <aizatsky at google.com> wrote:
> Richard,
>
> I'm not really sure since I don't have access to windows machine but this
> or http://llvm.org/viewvc/llvm-project?revision=289412&view=revision has
> broken sanitizer-windows bot. Sorry if this is a false alarm.
>
Given that the code added here is not (yet) reachable, I'd be really
surprised if this change is responsible. Can you get a proper backtrace
from one of these crashes?
http://lab.llvm.org:8011/builders/sanitizer-windows/builds/2786
>
> FAILED: projects/compiler-rt/lib/sanitizer_common/tests/
> sanitizer_stacktrace_test.cc.i386.o
> cmd.exe /C "cd /D C:\b\slave\sanitizer-windows\build\projects\compiler-rt\lib\sanitizer_common\tests
> && C:\b\slave\sanitizer-windows\build\.\bin\clang.exe -DWIN32 -D_WINDOWS
> -Wno-unknown-warning-option -fms-compatibility-version=19.00.24215.1
> -D_HAS_EXCEPTIONS=0 -Wno-undefined-inline -DGTEST_NO_LLVM_RAW_OSTREAM=1
> -DGTEST_HAS_RTTI=0 -IC:/b/slave/sanitizer-windows/llvm/utils/unittest/googletest/include
> -IC:/b/slave/sanitizer-windows/llvm/utils/unittest/googletest
> -DGTEST_HAS_SEH=0 -Wno-deprecated-declarations -IC:/b/slave/sanitizer-
> windows/llvm/projects/compiler-rt/include -IC:/b/slave/sanitizer-
> windows/llvm/projects/compiler-rt/lib -IC:/b/slave/sanitizer-
> windows/llvm/projects/compiler-rt/lib/sanitizer_common -fno-rtti -O2
> -Werror=sign-compare -Wno-non-virtual-dtor -fno-exceptions
> -DGTEST_HAS_SEH=0 -gline-tables-only -gcodeview -c -o
> sanitizer_stacktrace_test.cc.i386.o C:/b/slave/sanitizer-windows/
> llvm/projects/compiler-rt/lib/sanitizer_common/tests/
> sanitizer_stacktrace_test.cc"
> Assertion failed: (PtrWord & ~PointerBitMask) == 0 && "Pointer is not
> sufficiently aligned", file C:\b\slave\sanitizer-windows\
> llvm\include\llvm/ADT/PointerIntPair.h, line 160
>
> Wrote crash dump file "C:\Users\buildbot\AppData\
> Local\Temp\clang.exe-692761.dmp"
>
> #0 0x01f8dd87 (C:\b\slave\sanitizer-windows\build\bin\clang.exe+0xd4dd87)
>
> #1 0x70a64672 (C:\windows\SYSTEM32\ucrtbase.DLL+0x84672)
>
> #2 0x70a65cab (C:\windows\SYSTEM32\ucrtbase.DLL+0x85cab)
>
> #3 0x70a650e8 (C:\windows\SYSTEM32\ucrtbase.DLL+0x850e8)
>
> #4 0x70a65da6 (C:\windows\SYSTEM32\ucrtbase.DLL+0x85da6)
>
> #5 0x02ff860d (C:\b\slave\sanitizer-windows\build\bin\clang.exe+0x1db860d)
>
> clang.exe: error: clang frontend command failed due to signal (use -v to
> see invocation)
>
> clang version 4.0.0 (trunk 289413)
>
> Target: i686-pc-windows-msvc
>
> Thread model: posix
>
> InstalledDir: C:\b\slave\sanitizer-windows\build\bin
>
> clang.exe: note: diagnostic msg: PLEASE submit a bug report to
> http://llvm.org/bugs/ and include the crash backtrace, preprocessed
> source, and associated run script.
>
> clang.exe: note: diagnostic msg:
>
> ********************
>
>
> On Sun, Dec 11, 2016 at 7:03 PM Richard Smith via cfe-commits <
> cfe-commits at lists.llvm.org> wrote:
>
>> Author: rsmith
>> Date: Sun Dec 11 20:53:20 2016
>> New Revision: 289413
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=289413&view=rev
>> Log:
>> Add two new AST nodes to represent initialization of an array in terms of
>> initialization of each array element:
>>
>> * ArrayInitLoopExpr is a prvalue of array type with two subexpressions:
>> a common expression (an OpaqueValueExpr) that represents the up-front
>> computation of the source of the initialization, and a subexpression
>> representing a per-element initializer
>> * ArrayInitIndexExpr is a prvalue of type size_t representing the current
>> position in the loop
>>
>> This will be used to replace the creation of explicit index variables in
>> lambda
>> capture of arrays and copy/move construction of classes with array
>> elements,
>> and also C++17 structured bindings of arrays by value (which inexplicably
>> allow
>> copying an array by value, unlike all of C++'s other array declarations).
>>
>> No uses of these nodes are introduced by this change, however.
>>
>> Modified:
>> cfe/trunk/include/clang/AST/Expr.h
>> cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
>> cfe/trunk/include/clang/Basic/StmtNodes.td
>> cfe/trunk/include/clang/Sema/Initialization.h
>> cfe/trunk/include/clang/Serialization/ASTBitCodes.h
>> cfe/trunk/lib/AST/ASTDumper.cpp
>> cfe/trunk/lib/AST/Expr.cpp
>> cfe/trunk/lib/AST/ExprClassification.cpp
>> cfe/trunk/lib/AST/ExprConstant.cpp
>> cfe/trunk/lib/AST/ItaniumMangle.cpp
>> cfe/trunk/lib/AST/StmtPrinter.cpp
>> cfe/trunk/lib/AST/StmtProfile.cpp
>> cfe/trunk/lib/CodeGen/CGExprAgg.cpp
>> cfe/trunk/lib/CodeGen/CGExprScalar.cpp
>> cfe/trunk/lib/CodeGen/CodeGenFunction.h
>> cfe/trunk/lib/Sema/SemaExceptionSpec.cpp
>> cfe/trunk/lib/Sema/SemaInit.cpp
>> cfe/trunk/lib/Sema/TreeTransform.h
>> cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
>> cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
>> cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
>> cfe/trunk/tools/libclang/CXCursor.cpp
>>
>> Modified: cfe/trunk/include/clang/AST/Expr.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
>> clang/AST/Expr.h?rev=289413&r1=289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/include/clang/AST/Expr.h (original)
>> +++ cfe/trunk/include/clang/AST/Expr.h Sun Dec 11 20:53:20 2016
>> @@ -4333,6 +4333,98 @@ public:
>> }
>> };
>>
>> +/// \brief Represents a loop initializing the elements of an array.
>> +///
>> +/// The need to initialize the elements of an array occurs in a number of
>> +/// contexts:
>> +///
>> +/// * in the implicit copy/move constructor for a class with an array
>> member
>> +/// * when a lambda-expression captures an array by value
>> +/// * when a decomposition declaration decomposes an array
>> +///
>> +/// There are two subexpressions: a common expression (the source array)
>> +/// that is evaluated once up-front, and a per-element initializer that
>> +/// runs once for each array element.
>> +///
>> +/// Within the per-element initializer, the common expression may be
>> referenced
>> +/// via an OpaqueValueExpr, and the current index may be obtained via an
>> +/// ArrayInitIndexExpr.
>> +class ArrayInitLoopExpr : public Expr {
>> + Stmt *SubExprs[2];
>> +
>> + explicit ArrayInitLoopExpr(EmptyShell Empty)
>> + : Expr(ArrayInitLoopExprClass, Empty), SubExprs{} {}
>> +
>> +public:
>> + explicit ArrayInitLoopExpr(QualType T, Expr *CommonInit, Expr
>> *ElementInit)
>> + : Expr(ArrayInitLoopExprClass, T, VK_RValue, OK_Ordinary, false,
>> + CommonInit->isValueDependent() ||
>> ElementInit->isValueDependent(),
>> + T->isInstantiationDependentType(),
>> + CommonInit->containsUnexpandedParameterPack() ||
>> + ElementInit->containsUnexpandedParameterPack()),
>> + SubExprs{CommonInit, ElementInit} {}
>> +
>> + /// Get the common subexpression shared by all initializations (the
>> source
>> + /// array).
>> + OpaqueValueExpr *getCommonExpr() const {
>> + return cast<OpaqueValueExpr>(SubExprs[0]);
>> + }
>> +
>> + /// Get the initializer to use for each array element.
>> + Expr *getSubExpr() const { return cast<Expr>(SubExprs[1]); }
>> +
>> + llvm::APInt getArraySize() const {
>> + return cast<ConstantArrayType>(getType()->castAsArrayTypeUnsafe())
>> + ->getSize();
>> + }
>> +
>> + static bool classof(const Stmt *S) {
>> + return S->getStmtClass() == ArrayInitLoopExprClass;
>> + }
>> +
>> + SourceLocation getLocStart() const LLVM_READONLY {
>> + return getCommonExpr()->getLocStart();
>> + }
>> + SourceLocation getLocEnd() const LLVM_READONLY {
>> + return getCommonExpr()->getLocEnd();
>> + }
>> +
>> + child_range children() {
>> + return child_range(SubExprs, SubExprs + 2);
>> + }
>> +
>> + friend class ASTReader;
>> + friend class ASTStmtReader;
>> + friend class ASTStmtWriter;
>> +};
>> +
>> +/// \brief Represents the index of the current element of an array being
>> +/// initialized by an ArrayInitLoopExpr. This can only appear within the
>> +/// subexpression of an ArrayInitLoopExpr.
>> +class ArrayInitIndexExpr : public Expr {
>> + explicit ArrayInitIndexExpr(EmptyShell Empty)
>> + : Expr(ArrayInitIndexExprClass, Empty) {}
>> +
>> +public:
>> + explicit ArrayInitIndexExpr(QualType T)
>> + : Expr(ArrayInitIndexExprClass, T, VK_RValue, OK_Ordinary,
>> + false, false, false, false) {}
>> +
>> + static bool classof(const Stmt *S) {
>> + return S->getStmtClass() == ArrayInitIndexExprClass;
>> + }
>> +
>> + SourceLocation getLocStart() const LLVM_READONLY { return
>> SourceLocation(); }
>> + SourceLocation getLocEnd() const LLVM_READONLY { return
>> SourceLocation(); }
>> +
>> + child_range children() {
>> + return child_range(child_iterator(), child_iterator());
>> + }
>> +
>> + friend class ASTReader;
>> + friend class ASTStmtReader;
>> +};
>> +
>> /// \brief Represents an implicitly-generated value initialization of
>> /// an object of a given type.
>> ///
>>
>> Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
>> clang/AST/RecursiveASTVisitor.h?rev=289413&r1=289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
>> +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Sun Dec 11
>> 20:53:20 2016
>> @@ -2399,6 +2399,8 @@ DEF_TRAVERSE_STMT(ExtVectorElementExpr,
>> DEF_TRAVERSE_STMT(GNUNullExpr, {})
>> DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
>> DEF_TRAVERSE_STMT(NoInitExpr, {})
>> +DEF_TRAVERSE_STMT(ArrayInitLoopExpr, {})
>> +DEF_TRAVERSE_STMT(ArrayInitIndexExpr, {})
>> DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
>>
>> DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
>>
>> Modified: cfe/trunk/include/clang/Basic/StmtNodes.td
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
>> clang/Basic/StmtNodes.td?rev=289413&r1=289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/include/clang/Basic/StmtNodes.td (original)
>> +++ cfe/trunk/include/clang/Basic/StmtNodes.td Sun Dec 11 20:53:20 2016
>> @@ -85,6 +85,8 @@ def DesignatedInitExpr : DStmt<Expr>;
>> def DesignatedInitUpdateExpr : DStmt<Expr>;
>> def ImplicitValueInitExpr : DStmt<Expr>;
>> def NoInitExpr : DStmt<Expr>;
>> +def ArrayInitLoopExpr : DStmt<Expr>;
>> +def ArrayInitIndexExpr : DStmt<Expr>;
>> def ParenListExpr : DStmt<Expr>;
>> def VAArgExpr : DStmt<Expr>;
>> def GenericSelectionExpr : DStmt<Expr>;
>>
>> Modified: cfe/trunk/include/clang/Sema/Initialization.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
>> clang/Sema/Initialization.h?rev=289413&r1=289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/include/clang/Sema/Initialization.h (original)
>> +++ cfe/trunk/include/clang/Sema/Initialization.h Sun Dec 11 20:53:20
>> 2016
>> @@ -120,6 +120,16 @@ private:
>> bool NRVO;
>> };
>>
>> + struct VD {
>> + /// \brief The VarDecl, FieldDecl, or BindingDecl being initialized.
>> + ValueDecl *VariableOrMember;
>> +
>> + /// \brief When Kind == EK_Member, whether this is an implicit member
>> + /// initialization in a copy or move constructor. These can perform
>> array
>> + /// copies.
>> + bool IsImplicitFieldInit;
>> + };
>> +
>> struct C {
>> /// \brief The name of the variable being captured by an
>> EK_LambdaCapture.
>> IdentifierInfo *VarID;
>> @@ -129,9 +139,8 @@ private:
>> };
>>
>> union {
>> - /// \brief When Kind == EK_Variable, EK_Member or EK_Binding, the
>> VarDecl,
>> - /// FieldDecl or BindingDecl, respectively.
>> - ValueDecl *VariableOrMember;
>> + /// \brief When Kind == EK_Variable, EK_Member or EK_Binding, the
>> variable.
>> + VD Variable;
>>
>> /// \brief When Kind == EK_RelatedResult, the ObjectiveC method where
>> /// result type was implicitly changed to accommodate ARC semantics.
>> @@ -165,7 +174,7 @@ private:
>> /// \brief Create the initialization entity for a variable.
>> InitializedEntity(VarDecl *Var, EntityKind EK = EK_Variable)
>> : Kind(EK), Parent(nullptr), Type(Var->getType()),
>> - ManglingNumber(0), VariableOrMember(Var) { }
>> + ManglingNumber(0), Variable{Var, false} { }
>>
>> /// \brief Create the initialization entity for the result of a
>> /// function, throwing an object, performing an explicit cast, or
>> @@ -179,9 +188,11 @@ private:
>> }
>>
>> /// \brief Create the initialization entity for a member subobject.
>> - InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent)
>> + InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent,
>> + bool Implicit)
>> : Kind(EK_Member), Parent(Parent), Type(Member->getType()),
>> - ManglingNumber(0), VariableOrMember(Member) { }
>> + ManglingNumber(0), Variable{Member, Implicit} {
>> + }
>>
>> /// \brief Create the initialization entity for an array element.
>> InitializedEntity(ASTContext &Context, unsigned Index,
>> @@ -299,15 +310,17 @@ public:
>> /// \brief Create the initialization entity for a member subobject.
>> static InitializedEntity
>> InitializeMember(FieldDecl *Member,
>> - const InitializedEntity *Parent = nullptr) {
>> - return InitializedEntity(Member, Parent);
>> + const InitializedEntity *Parent = nullptr,
>> + bool Implicit = false) {
>> + return InitializedEntity(Member, Parent, Implicit);
>> }
>>
>> /// \brief Create the initialization entity for a member subobject.
>> static InitializedEntity
>> InitializeMember(IndirectFieldDecl *Member,
>> - const InitializedEntity *Parent = nullptr) {
>> - return InitializedEntity(Member->getAnonField(), Parent);
>> + const InitializedEntity *Parent = nullptr,
>> + bool Implicit = false) {
>> + return InitializedEntity(Member->getAnonField(), Parent, Implicit);
>> }
>>
>> /// \brief Create the initialization entity for an array element.
>> @@ -401,6 +414,12 @@ public:
>> getType()->
>> getAsArrayTypeUnsafe());
>> }
>>
>> + /// \brief Is this the implicit initialization of a member of a class
>> from
>> + /// a defaulted constructor?
>> + bool isImplicitMemberInitializer() const {
>> + return getKind() == EK_Member && Variable.IsImplicitFieldInit;
>> + }
>> +
>> /// \brief Determine the location of the 'return' keyword when
>> initializing
>> /// the result of a function call.
>> SourceLocation getReturnLoc() const {
>> @@ -708,6 +727,10 @@ public:
>> /// \brief An initialization that "converts" an Objective-C object
>> /// (not a point to an object) to another Objective-C object type.
>> SK_ObjCObjectConversion,
>> + /// \brief Array indexing for initialization by elementwise copy.
>> + SK_ArrayLoopIndex,
>> + /// \brief Array initialization by elementwise copy.
>> + SK_ArrayLoopInit,
>> /// \brief Array initialization (from an array rvalue).
>> /// This is a GNU C extension.
>> SK_ArrayInit,
>> @@ -1096,6 +1119,9 @@ public:
>> /// always a no-op.
>> void AddObjCObjectConversionStep(QualType T);
>>
>> + /// \brief Add an array initialization loop step.
>> + void AddArrayInitLoopStep(QualType T, QualType EltTy);
>> +
>> /// \brief Add an array initialization step.
>> void AddArrayInitStep(QualType T);
>>
>>
>> Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
>> clang/Serialization/ASTBitCodes.h?rev=289413&r1=
>> 289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
>> +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Sun Dec 11
>> 20:53:20 2016
>> @@ -1292,10 +1292,14 @@ namespace clang {
>> EXPR_DESIGNATED_INIT,
>> /// \brief A DesignatedInitUpdateExpr record.
>> EXPR_DESIGNATED_INIT_UPDATE,
>> - /// \brief An ImplicitValueInitExpr record.
>> - EXPR_IMPLICIT_VALUE_INIT,
>> /// \brief An NoInitExpr record.
>> EXPR_NO_INIT,
>> + /// \brief An ArrayInitLoopExpr record.
>> + EXPR_ARRAY_INIT_LOOP,
>> + /// \brief An ArrayInitIndexExpr record.
>> + EXPR_ARRAY_INIT_INDEX,
>> + /// \brief An ImplicitValueInitExpr record.
>> + EXPR_IMPLICIT_VALUE_INIT,
>> /// \brief A VAArgExpr record.
>> EXPR_VA_ARG,
>> /// \brief An AddrLabelExpr record.
>>
>> Modified: cfe/trunk/lib/AST/ASTDumper.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
>> ASTDumper.cpp?rev=289413&r1=289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/AST/ASTDumper.cpp (original)
>> +++ cfe/trunk/lib/AST/ASTDumper.cpp Sun Dec 11 20:53:20 2016
>> @@ -517,6 +517,8 @@ namespace {
>> void VisitFloatingLiteral(const FloatingLiteral *Node);
>> void VisitStringLiteral(const StringLiteral *Str);
>> void VisitInitListExpr(const InitListExpr *ILE);
>> + void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *ILE);
>> + void VisitArrayInitIndexExpr(const ArrayInitIndexExpr *ILE);
>> void VisitUnaryOperator(const UnaryOperator *Node);
>> void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr
>> *Node);
>> void VisitMemberExpr(const MemberExpr *Node);
>> @@ -2024,6 +2026,14 @@ void ASTDumper::VisitInitListExpr(const
>> }
>> }
>>
>> +void ASTDumper::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) {
>> + VisitExpr(E);
>> +}
>> +
>> +void ASTDumper::VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E) {
>> + VisitExpr(E);
>> +}
>> +
>> void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) {
>> VisitExpr(Node);
>> OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
>>
>> Modified: cfe/trunk/lib/AST/Expr.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
>> Expr.cpp?rev=289413&r1=289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/AST/Expr.cpp (original)
>> +++ cfe/trunk/lib/AST/Expr.cpp Sun Dec 11 20:53:20 2016
>> @@ -2899,6 +2899,7 @@ bool Expr::HasSideEffects(const ASTConte
>> case UnaryExprOrTypeTraitExprClass:
>> case AddrLabelExprClass:
>> case GNUNullExprClass:
>> + case ArrayInitIndexExprClass:
>> case NoInitExprClass:
>> case CXXBoolLiteralExprClass:
>> case CXXNullPtrLiteralExprClass:
>> @@ -2975,6 +2976,7 @@ bool Expr::HasSideEffects(const ASTConte
>> case ExtVectorElementExprClass:
>> case DesignatedInitExprClass:
>> case DesignatedInitUpdateExprClass:
>> + case ArrayInitLoopExprClass:
>> case ParenListExprClass:
>> case CXXPseudoDestructorExprClass:
>> case CXXStdInitializerListExprClass:
>>
>> Modified: cfe/trunk/lib/AST/ExprClassification.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
>> ExprClassification.cpp?rev=289413&r1=289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/AST/ExprClassification.cpp (original)
>> +++ cfe/trunk/lib/AST/ExprClassification.cpp Sun Dec 11 20:53:20 2016
>> @@ -185,6 +185,8 @@ static Cl::Kinds ClassifyInternal(ASTCon
>> case Expr::ObjCIndirectCopyRestoreExprClass:
>> case Expr::AtomicExprClass:
>> case Expr::CXXFoldExprClass:
>> + case Expr::ArrayInitLoopExprClass:
>> + case Expr::ArrayInitIndexExprClass:
>> case Expr::NoInitExprClass:
>> case Expr::DesignatedInitUpdateExprClass:
>> case Expr::CoyieldExprClass:
>>
>> Modified: cfe/trunk/lib/AST/ExprConstant.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
>> ExprConstant.cpp?rev=289413&r1=289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/AST/ExprConstant.cpp (original)
>> +++ cfe/trunk/lib/AST/ExprConstant.cpp Sun Dec 11 20:53:20 2016
>> @@ -469,6 +469,10 @@ namespace {
>> /// declaration whose initializer is being evaluated, if any.
>> APValue *EvaluatingDeclValue;
>>
>> + /// The current array initialization index, if we're performing array
>> + /// initialization.
>> + uint64_t ArrayInitIndex = -1;
>> +
>> /// HasActiveDiagnostic - Was the previous diagnostic stored? If so,
>> further
>> /// notes attached to it will also be stored, otherwise they will
>> not be.
>> bool HasActiveDiagnostic;
>> @@ -803,6 +807,20 @@ namespace {
>> bool allowInvalidBaseExpr() const {
>> return EvalMode == EM_DesignatorFold;
>> }
>> +
>> + class ArrayInitLoopIndex {
>> + EvalInfo &Info;
>> + uint64_t OuterIndex;
>> +
>> + public:
>> + ArrayInitLoopIndex(EvalInfo &Info)
>> + : Info(Info), OuterIndex(Info.ArrayInitIndex) {
>> + Info.ArrayInitIndex = 0;
>> + }
>> + ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
>> +
>> + operator uint64_t&() { return Info.ArrayInitIndex; }
>> + };
>> };
>>
>> /// Object used to treat all foldable expressions as constant
>> expressions.
>> @@ -6190,6 +6208,7 @@ namespace {
>> return handleCallExpr(E, Result, &This);
>> }
>> bool VisitInitListExpr(const InitListExpr *E);
>> + bool VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E);
>> bool VisitCXXConstructExpr(const CXXConstructExpr *E);
>> bool VisitCXXConstructExpr(const CXXConstructExpr *E,
>> const LValue &Subobject,
>> @@ -6272,6 +6291,35 @@ bool ArrayExprEvaluator::VisitInitListEx
>> FillerExpr) && Success;
>> }
>>
>> +bool ArrayExprEvaluator::VisitArrayInitLoopExpr(const ArrayInitLoopExpr
>> *E) {
>> + if (E->getCommonExpr() &&
>> + !Evaluate(Info.CurrentCall->createTemporary(E->getCommonExpr(),
>> false),
>> + Info, E->getCommonExpr()->getSourceExpr()))
>> + return false;
>> +
>> + auto *CAT = cast<ConstantArrayType>(E->getType()->
>> castAsArrayTypeUnsafe());
>> +
>> + uint64_t Elements = CAT->getSize().getZExtValue();
>> + Result = APValue(APValue::UninitArray(), Elements, Elements);
>> +
>> + LValue Subobject = This;
>> + Subobject.addArray(Info, E, CAT);
>> +
>> + bool Success = true;
>> + for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements;
>> ++Index) {
>> + if (!EvaluateInPlace(Result.getArrayInitializedElt(Index),
>> + Info, Subobject, E->getSubExpr()) ||
>> + !HandleLValueArrayAdjustment(Info, E, Subobject,
>> + CAT->getElementType(), 1)) {
>> + if (!Info.noteFailure())
>> + return false;
>> + Success = false;
>> + }
>> + }
>> +
>> + return Success;
>> +}
>> +
>> bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr
>> *E) {
>> return VisitCXXConstructExpr(E, This, &Result, E->getType());
>> }
>> @@ -6427,6 +6475,16 @@ public:
>> bool VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E) {
>> return Success(E->getValue(), E);
>> }
>> +
>> + bool VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E) {
>> + if (Info.ArrayInitIndex == uint64_t(-1)) {
>> + // We were asked to evaluate this subexpression independent of the
>> + // enclosing ArrayInitLoopExpr. We can't do that.
>> + Info.FFDiag(E);
>> + return false;
>> + }
>> + return Success(Info.ArrayInitIndex, E);
>> + }
>>
>> // Note, GNU defines __null as an integer, not a pointer.
>> bool VisitGNUNullExpr(const GNUNullExpr *E) {
>> @@ -9590,6 +9648,8 @@ static ICEDiag CheckICE(const Expr* E, c
>> case Expr::CompoundLiteralExprClass:
>> case Expr::ExtVectorElementExprClass:
>> case Expr::DesignatedInitExprClass:
>> + case Expr::ArrayInitLoopExprClass:
>> + case Expr::ArrayInitIndexExprClass:
>> case Expr::NoInitExprClass:
>> case Expr::DesignatedInitUpdateExprClass:
>> case Expr::ImplicitValueInitExprClass:
>>
>> Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
>> ItaniumMangle.cpp?rev=289413&r1=289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
>> +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Sun Dec 11 20:53:20 2016
>> @@ -3301,6 +3301,8 @@ recurse:
>> case Expr::AddrLabelExprClass:
>> case Expr::DesignatedInitUpdateExprClass:
>> case Expr::ImplicitValueInitExprClass:
>> + case Expr::ArrayInitLoopExprClass:
>> + case Expr::ArrayInitIndexExprClass:
>> case Expr::NoInitExprClass:
>> case Expr::ParenListExprClass:
>> case Expr::LambdaExprClass:
>>
>> Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
>> StmtPrinter.cpp?rev=289413&r1=289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
>> +++ cfe/trunk/lib/AST/StmtPrinter.cpp Sun Dec 11 20:53:20 2016
>> @@ -1705,6 +1705,18 @@ void StmtPrinter::VisitInitListExpr(Init
>> OS << "}";
>> }
>>
>> +void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) {
>> + // There's no way to express this expression in any of our supported
>> + // languages, so just emit something terse and (hopefully) clear.
>> + OS << "{";
>> + PrintExpr(Node->getSubExpr());
>> + OS << "}";
>> +}
>> +
>> +void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) {
>> + OS << "*";
>> +}
>> +
>> void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
>> OS << "(";
>> for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
>>
>> Modified: cfe/trunk/lib/AST/StmtProfile.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
>> StmtProfile.cpp?rev=289413&r1=289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/AST/StmtProfile.cpp (original)
>> +++ cfe/trunk/lib/AST/StmtProfile.cpp Sun Dec 11 20:53:20 2016
>> @@ -972,6 +972,14 @@ void StmtProfiler::VisitDesignatedInitUp
>> "initializer");
>> }
>>
>> +void StmtProfiler::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *S) {
>> + VisitExpr(S);
>> +}
>> +
>> +void StmtProfiler::VisitArrayInitIndexExpr(const ArrayInitIndexExpr *S)
>> {
>> + VisitExpr(S);
>> +}
>> +
>> void StmtProfiler::VisitNoInitExpr(const NoInitExpr *S) {
>> llvm_unreachable("Unexpected NoInitExpr in syntactic form of
>> initializer");
>> }
>>
>> Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
>> CGExprAgg.cpp?rev=289413&r1=289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
>> +++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Sun Dec 11 20:53:20 2016
>> @@ -164,6 +164,7 @@ public:
>> void VisitAbstractConditionalOperator(const
>> AbstractConditionalOperator *CO);
>> void VisitChooseExpr(const ChooseExpr *CE);
>> void VisitInitListExpr(InitListExpr *E);
>> + void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E);
>> void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
>> void VisitNoInitExpr(NoInitExpr *E) { } // Do nothing.
>> void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
>> @@ -1308,6 +1309,85 @@ void AggExprEmitter::VisitInitListExpr(I
>> cleanupDominator->eraseFromParent();
>> }
>>
>> +void AggExprEmitter::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E)
>> {
>> + // Emit the common subexpression.
>> + CodeGenFunction::OpaqueValueMapping binding(CGF, E->getCommonExpr());
>> +
>> + Address destPtr = EnsureSlot(E->getType()).getAddress();
>> + uint64_t numElements = E->getArraySize().getZExtValue();
>> +
>> + if (!numElements)
>> + return;
>> +
>> + // FIXME: Dig through nested ArrayInitLoopExprs to find the overall
>> array
>> + // size, and only emit a single loop for a multidimensional array.
>> +
>> + // destPtr is an array*. Construct an elementType* by drilling down a
>> level.
>> + llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
>> + llvm::Value *indices[] = {zero, zero};
>> + llvm::Value *begin = Builder.CreateInBoundsGEP(destPtr.getPointer(),
>> indices,
>> + "arrayinit.begin");
>> +
>> + QualType elementType = E->getSubExpr()->getType();
>> + CharUnits elementSize = CGF.getContext().getTypeSizeInChars(
>> elementType);
>> + CharUnits elementAlign =
>> + destPtr.getAlignment().alignmentOfArrayElement(elementSize);
>> +
>> + // Prepare for a cleanup.
>> + QualType::DestructionKind dtorKind = elementType.isDestructedType();
>> + Address endOfInit = Address::invalid();
>> + EHScopeStack::stable_iterator cleanup;
>> + llvm::Instruction *cleanupDominator = nullptr;
>> + if (CGF.needsEHCleanup(dtorKind)) {
>> + endOfInit = CGF.CreateTempAlloca(begin->getType(),
>> CGF.getPointerAlign(),
>> + "arrayinit.endOfInit");
>> + CGF.pushIrregularPartialArrayCleanup(begin, endOfInit, elementType,
>> + elementAlign,
>> + CGF.getDestroyer(dtorKind));
>> + cleanup = CGF.EHStack.stable_begin();
>> + } else {
>> + dtorKind = QualType::DK_none;
>> + }
>> +
>> + llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
>> + llvm::BasicBlock *bodyBB = CGF.createBasicBlock("arrayinit.body");
>> +
>> + // Jump into the body.
>> + CGF.EmitBlock(bodyBB);
>> + llvm::PHINode *index =
>> + Builder.CreatePHI(zero->getType(), 2, "arrayinit.index");
>> + index->addIncoming(zero, entryBB);
>> + llvm::Value *element = Builder.CreateInBoundsGEP(begin, index);
>> +
>> + // Tell the EH cleanup that we finished with the last element.
>> + if (endOfInit.isValid()) Builder.CreateStore(element, endOfInit);
>> +
>> + // Emit the actual filler expression.
>> + {
>> + CodeGenFunction::ArrayInitLoopExprScope Scope(CGF, index);
>> + LValue elementLV =
>> + CGF.MakeAddrLValue(Address(element, elementAlign), elementType);
>> + EmitInitializationToLValue(E->getSubExpr(), elementLV);
>> + }
>> +
>> + // Move on to the next element.
>> + llvm::Value *nextIndex = Builder.CreateNUWAdd(
>> + index, llvm::ConstantInt::get(CGF.SizeTy, 1), "arrayinit.next");
>> + index->addIncoming(nextIndex, Builder.GetInsertBlock());
>> +
>> + // Leave the loop if we're done.
>> + llvm::Value *done = Builder.CreateICmpEQ(
>> + nextIndex, llvm::ConstantInt::get(CGF.SizeTy, numElements),
>> + "arrayinit.done");
>> + llvm::BasicBlock *endBB = CGF.createBasicBlock("arrayinit.end");
>> + Builder.CreateCondBr(done, endBB, bodyBB);
>> +
>> + CGF.EmitBlock(endBB);
>> +
>> + // Leave the partial-array cleanup if we entered one.
>> + if (dtorKind) CGF.DeactivateCleanupBlock(cleanup, cleanupDominator);
>> +}
>> +
>> void AggExprEmitter::VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr
>> *E) {
>> AggValueSlot Dest = EnsureSlot(E->getType());
>>
>>
>> Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
>> CGExprScalar.cpp?rev=289413&r1=289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
>> +++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Sun Dec 11 20:53:20 2016
>> @@ -311,6 +311,12 @@ public:
>>
>> Value *VisitInitListExpr(InitListExpr *E);
>>
>> + Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
>> + assert(CGF.getArrayInitIndex() &&
>> + "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
>> + return CGF.getArrayInitIndex();
>> + }
>> +
>> Value *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
>> return EmitNullValue(E->getType());
>> }
>>
>> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
>> CodeGenFunction.h?rev=289413&r1=289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
>> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Sun Dec 11 20:53:20 2016
>> @@ -918,6 +918,17 @@ public:
>> e->getCommon());
>> }
>>
>> + /// Build the opaque value mapping for an OpaqueValueExpr whose
>> source
>> + /// expression is set to the expression the OVE represents.
>> + OpaqueValueMapping(CodeGenFunction &CGF, const OpaqueValueExpr *OV)
>> + : CGF(CGF) {
>> + if (OV) {
>> + assert(OV->getSourceExpr() && "wrong form of OpaqueValueMapping
>> used "
>> + "for OVE with no source
>> expression");
>> + Data = OpaqueValueMappingData::bind(CGF, OV,
>> OV->getSourceExpr());
>> + }
>> + }
>> +
>> OpaqueValueMapping(CodeGenFunction &CGF,
>> const OpaqueValueExpr *opaqueValue,
>> LValue lvalue)
>> @@ -1183,6 +1194,23 @@ public:
>> CharUnits OldCXXThisAlignment;
>> };
>>
>> + /// The scope of an ArrayInitLoopExpr. Within this scope, the value of
>> the
>> + /// current loop index is overridden.
>> + class ArrayInitLoopExprScope {
>> + public:
>> + ArrayInitLoopExprScope(CodeGenFunction &CGF, llvm::Value *Index)
>> + : CGF(CGF), OldArrayInitIndex(CGF.ArrayInitIndex) {
>> + CGF.ArrayInitIndex = Index;
>> + }
>> + ~ArrayInitLoopExprScope() {
>> + CGF.ArrayInitIndex = OldArrayInitIndex;
>> + }
>> +
>> + private:
>> + CodeGenFunction &CGF;
>> + llvm::Value *OldArrayInitIndex;
>> + };
>> +
>> class InlinedInheritingConstructorScope {
>> public:
>> InlinedInheritingConstructorScope(CodeGenFunction &CGF, GlobalDecl
>> GD)
>> @@ -1251,6 +1279,10 @@ private:
>> /// this expression.
>> Address CXXDefaultInitExprThis = Address::invalid();
>>
>> + /// The current array initialization index when evaluating an
>> + /// ArrayInitIndexExpr within an ArrayInitLoopExpr.
>> + llvm::Value *ArrayInitIndex = nullptr;
>> +
>> /// The values of function arguments to use when evaluating
>> /// CXXInheritedCtorInitExprs within this context.
>> CallArgList CXXInheritedCtorInitExprArgs;
>> @@ -1953,6 +1985,9 @@ public:
>> return it->second;
>> }
>>
>> + /// Get the index of the current ArrayInitLoopExpr, if any.
>> + llvm::Value *getArrayInitIndex() { return ArrayInitIndex; }
>> +
>> /// getAccessedFieldNo - Given an encoded value and a result number,
>> return
>> /// the input field number being accessed.
>> static unsigned getAccessedFieldNo(unsigned Idx, const llvm::Constant
>> *Elts);
>>
>> Modified: cfe/trunk/lib/Sema/SemaExceptionSpec.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
>> SemaExceptionSpec.cpp?rev=289413&r1=289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Sema/SemaExceptionSpec.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaExceptionSpec.cpp Sun Dec 11 20:53:20 2016
>> @@ -1166,6 +1166,7 @@ CanThrowResult Sema::canThrow(const Expr
>> case Expr::ExprWithCleanupsClass:
>> case Expr::ExtVectorElementExprClass:
>> case Expr::InitListExprClass:
>> + case Expr::ArrayInitLoopExprClass:
>> case Expr::MemberExprClass:
>> case Expr::ObjCIsaExprClass:
>> case Expr::ObjCIvarRefExprClass:
>> @@ -1259,6 +1260,7 @@ CanThrowResult Sema::canThrow(const Expr
>> case Expr::ImaginaryLiteralClass:
>> case Expr::ImplicitValueInitExprClass:
>> case Expr::IntegerLiteralClass:
>> + case Expr::ArrayInitIndexExprClass:
>> case Expr::NoInitExprClass:
>> case Expr::ObjCEncodeExprClass:
>> case Expr::ObjCStringLiteralClass:
>>
>> Modified: cfe/trunk/lib/Sema/SemaInit.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
>> SemaInit.cpp?rev=289413&r1=289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Sema/SemaInit.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaInit.cpp Sun Dec 11 20:53:20 2016
>> @@ -2910,7 +2910,7 @@ DeclarationName InitializedEntity::getNa
>> case EK_Variable:
>> case EK_Member:
>> case EK_Binding:
>> - return VariableOrMember->getDeclName();
>> + return Variable.VariableOrMember->getDeclName();
>>
>> case EK_LambdaCapture:
>> return DeclarationName(Capture.VarID);
>> @@ -2938,7 +2938,7 @@ ValueDecl *InitializedEntity::getDecl()
>> case EK_Variable:
>> case EK_Member:
>> case EK_Binding:
>> - return VariableOrMember;
>> + return Variable.VariableOrMember;
>>
>> case EK_Parameter:
>> case EK_Parameter_CF_Audited:
>> @@ -3065,6 +3065,8 @@ void InitializationSequence::Step::Destr
>> case SK_CAssignment:
>> case SK_StringInit:
>> case SK_ObjCObjectConversion:
>> + case SK_ArrayLoopIndex:
>> + case SK_ArrayLoopInit:
>> case SK_ArrayInit:
>> case SK_ParenthesizedArrayInit:
>> case SK_PassByIndirectCopyRestore:
>> @@ -3307,6 +3309,17 @@ void InitializationSequence::AddArrayIni
>> Steps.push_back(S);
>> }
>>
>> +void InitializationSequence::AddArrayInitLoopStep(QualType T, QualType
>> EltT) {
>> + Step S;
>> + S.Kind = SK_ArrayLoopIndex;
>> + S.Type = EltT;
>> + Steps.insert(Steps.begin(), S);
>> +
>> + S.Kind = SK_ArrayLoopInit;
>> + S.Type = T;
>> + Steps.push_back(S);
>> +}
>> +
>> void InitializationSequence::AddParenthesizedArrayInitStep(QualType T) {
>> Step S;
>> S.Kind = SK_ParenthesizedArrayInit;
>> @@ -3552,6 +3565,9 @@ ResolveConstructorOverload(Sema &S, Sour
>> /// \brief Attempt initialization by constructor (C++ [dcl.init]), which
>> /// enumerates the constructors of the initialized entity and performs
>> overload
>> /// resolution to select the best.
>> +/// \param DestType The destination class type.
>> +/// \param DestArrayType The destination type, which is either DestType
>> or
>> +/// a (possibly multidimensional) array of
>> DestType.
>> /// \param IsListInit Is this list-initialization?
>> /// \param IsInitListCopy Is this non-list-initialization resulting from
>> a
>> /// list-initialization from {x} where x is the
>> same
>> @@ -3560,6 +3576,7 @@ static void TryConstructorInitialization
>> const InitializedEntity &Entity,
>> const InitializationKind &Kind,
>> MultiExprArg Args, QualType
>> DestType,
>> + QualType DestArrayType,
>> InitializationSequence
>> &Sequence,
>> bool IsListInit = false,
>> bool IsInitListCopy = false) {
>> @@ -3703,7 +3720,7 @@ static void TryConstructorInitialization
>> // subsumed by the initialization.
>> bool HadMultipleCandidates = (CandidateSet.size() > 1);
>> Sequence.AddConstructorInitializationStep(
>> - Best->FoundDecl, CtorDecl, DestType, HadMultipleCandidates,
>> + Best->FoundDecl, CtorDecl, DestArrayType, HadMultipleCandidates,
>> IsListInit | IsInitListCopy, AsInitializerList);
>> }
>>
>> @@ -3871,8 +3888,9 @@ static void TryListInitialization(Sema &
>> S.IsDerivedFrom(InitList->getLocStart(), InitType, DestType))
>> {
>> Expr *InitListAsExpr = InitList;
>> TryConstructorInitialization(S, Entity, Kind, InitListAsExpr,
>> DestType,
>> - Sequence, /*InitListSyntax*/ false,
>> - /*IsInitListCopy*/ true);
>> + DestType, Sequence,
>> + /*InitListSyntax*/false,
>> + /*IsInitListCopy*/true);
>> return;
>> }
>> }
>> @@ -3927,7 +3945,7 @@ static void TryListInitialization(Sema &
>> // - Otherwise, if T is a class type, constructors are
>> considered.
>> Expr *InitListAsExpr = InitList;
>> TryConstructorInitialization(S, Entity, Kind, InitListAsExpr,
>> DestType,
>> - Sequence, /*InitListSyntax*/ true);
>> + DestType, Sequence,
>> /*InitListSyntax*/true);
>> } else
>> Sequence.SetFailed(InitializationSequence::FK_
>> InitListBadDestinationType);
>> return;
>> @@ -4580,8 +4598,10 @@ static void TryValueInitialization(Sema
>> MultiExprArg Args(&InitListAsExpr, InitList ? 1 : 0);
>> bool InitListSyntax = InitList;
>>
>> - return TryConstructorInitialization(S, Entity, Kind, Args, T,
>> Sequence,
>> - InitListSyntax);
>> + // FIXME: Instead of creating a CXXConstructExpr of non-array type
>> here,
>> + // wrap a class-typed CXXConstructExpr in an ArrayInitLoopExpr.
>> + return TryConstructorInitialization(
>> + S, Entity, Kind, Args, T, Entity.getType(), Sequence,
>> InitListSyntax);
>> }
>> }
>>
>> @@ -4604,7 +4624,8 @@ static void TryDefaultInitialization(Sem
>> // constructor for T is called (and the initialization is
>> ill-formed if
>> // T has no accessible default constructor);
>> if (DestType->isRecordType() && S.getLangOpts().CPlusPlus) {
>> - TryConstructorInitialization(S, Entity, Kind, None, DestType,
>> Sequence);
>> + TryConstructorInitialization(S, Entity, Kind, None, DestType,
>> + Entity.getType(), Sequence);
>> return;
>> }
>>
>> @@ -5030,6 +5051,42 @@ static bool isExprAnUnaddressableFunctio
>> cast<FunctionDecl>(DRE->getDecl()));
>> }
>>
>> +/// Determine whether we can perform an elementwise array copy for this
>> kind
>> +/// of entity.
>> +static bool canPerformArrayCopy(const InitializedEntity &Entity) {
>> + switch (Entity.getKind()) {
>> + case InitializedEntity::EK_LambdaCapture:
>> + // C++ [expr.prim.lambda]p24:
>> + // For array members, the array elements are direct-initialized in
>> + // increasing subscript order.
>> + return true;
>> +
>> + case InitializedEntity::EK_Variable:
>> + // C++ [dcl.decomp]p1:
>> + // [...] each element is copy-initialized or direct-initialized
>> from the
>> + // corresponding element of the assignment-expression [...]
>> + return isa<DecompositionDecl>(Entity.getDecl());
>> +
>> + case InitializedEntity::EK_Member:
>> + // C++ [class.copy.ctor]p14:
>> + // - if the member is an array, each element is direct-initialized
>> with
>> + // the corresponding subobject of x
>> + return Entity.isImplicitMemberInitializer();
>> +
>> + case InitializedEntity::EK_ArrayElement:
>> + // All the above cases are intended to apply recursively, even
>> though none
>> + // of them actually say that.
>> + if (auto *E = Entity.getParent())
>> + return canPerformArrayCopy(*E);
>> + break;
>> +
>> + default:
>> + break;
>> + }
>> +
>> + return false;
>> +}
>> +
>> void InitializationSequence::InitializeFrom(Sema &S,
>> const InitializedEntity
>> &Entity,
>> const InitializationKind
>> &Kind,
>> @@ -5152,6 +5209,34 @@ void InitializationSequence::InitializeF
>> }
>> }
>>
>> + // Some kinds of initialization permit an array to be initialized
>> from
>> + // another array of the same type, and perform elementwise
>> initialization.
>> + if (Initializer && isa<ConstantArrayType>(DestAT) &&
>> + S.Context.hasSameUnqualifiedType(Initializer->getType(),
>> + Entity.getType()) &&
>> + canPerformArrayCopy(Entity)) {
>> + // If source is a prvalue, use it directly.
>> + if (Initializer->getValueKind() == VK_RValue) {
>> + // FIXME: This produces a bogus extwarn
>> + AddArrayInitStep(DestType);
>> + return;
>> + }
>> +
>> + // Emit element-at-a-time copy loop.
>> + InitializedEntity Element =
>> + InitializedEntity::InitializeElement(S.Context, 0, Entity);
>> + QualType InitEltT =
>> + Context.getAsArrayType(Initializer->getType())->
>> getElementType();
>> + OpaqueValueExpr OVE(SourceLocation(), InitEltT,
>> + Initializer->getValueKind());
>> + Expr *OVEAsExpr = &OVE;
>> + InitializeFrom(S, Element, Kind, OVEAsExpr, TopLevelOfInitList,
>> + TreatUnavailableAsInvalid);
>> + if (!Failed())
>> + AddArrayInitLoopStep(Entity.getType(), InitEltT);
>> + return;
>> + }
>> +
>> // Note: as an GNU C extension, we allow initialization of an
>> // array from a compound literal that creates an array of the same
>> // type, so long as the initializer has no side effects.
>> @@ -5225,7 +5310,7 @@ void InitializationSequence::InitializeF
>> (Context.hasSameUnqualifiedType(SourceType, DestType) ||
>> S.IsDerivedFrom(Initializer->getLocStart(), SourceType,
>> DestType))))
>> TryConstructorInitialization(S, Entity, Kind, Args,
>> - DestType, *this);
>> + DestType, DestType, *this);
>> // - Otherwise (i.e., for the remaining copy-initialization
>> cases),
>> // user-defined conversion sequences that can convert from the
>> source
>> // type to the destination type or (when a conversion function
>> is
>> @@ -5842,7 +5927,7 @@ PerformConstructorInitialization(Sema &S
>> // If the entity allows NRVO, mark the construction as elidable
>> // unconditionally.
>> if (Entity.allowsNRVO())
>> - CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
>> + CurInit = S.BuildCXXConstructExpr(Loc, Step.Type,
>> Step.Function.FoundDecl,
>> Constructor, /*Elidable=*/true,
>> ConstructorArgs,
>> @@ -5853,7 +5938,7 @@ PerformConstructorInitialization(Sema &S
>> ConstructKind,
>> ParenOrBraceRange);
>> else
>> - CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
>> + CurInit = S.BuildCXXConstructExpr(Loc, Step.Type,
>> Step.Function.FoundDecl,
>> Constructor,
>> ConstructorArgs,
>> @@ -6403,6 +6488,7 @@ InitializationSequence::Perform(Sema &S,
>> Entity.getType();
>>
>> ExprResult CurInit((Expr *)nullptr);
>> + SmallVector<Expr*, 4> ArrayLoopCommonExprs;
>>
>> // For initialization steps that start with a single initializer,
>> // grab the only argument out the Args and place it into the "current"
>> @@ -6430,6 +6516,8 @@ InitializationSequence::Perform(Sema &S,
>> case SK_CAssignment:
>> case SK_StringInit:
>> case SK_ObjCObjectConversion:
>> + case SK_ArrayLoopIndex:
>> + case SK_ArrayLoopInit:
>> case SK_ArrayInit:
>> case SK_ParenthesizedArrayInit:
>> case SK_PassByIndirectCopyRestore:
>> @@ -6813,13 +6901,15 @@ InitializationSequence::Perform(Sema &S,
>> bool UseTemporary = Entity.getType()->isReferenceType();
>> bool IsStdInitListInit =
>> Step->Kind == SK_StdInitializerListConstructorCall;
>> + Expr *Source = CurInit.get();
>> CurInit = PerformConstructorInitialization(
>> - S, UseTemporary ? TempEntity : Entity, Kind, Args, *Step,
>> + S, UseTemporary ? TempEntity : Entity, Kind,
>> + Source ? MultiExprArg(Source) : Args, *Step,
>> ConstructorInitRequiresZeroInit,
>> - /*IsListInitialization*/IsStdInitListInit,
>> - /*IsStdInitListInitialization*/IsStdInitListInit,
>> - /*LBraceLoc*/SourceLocation(),
>> - /*RBraceLoc*/SourceLocation());
>> + /*IsListInitialization*/ IsStdInitListInit,
>> + /*IsStdInitListInitialization*/ IsStdInitListInit,
>> + /*LBraceLoc*/ SourceLocation(),
>> + /*RBraceLoc*/ SourceLocation());
>> break;
>> }
>>
>> @@ -6898,6 +6988,28 @@ InitializationSequence::Perform(Sema &S,
>> CurInit.get()->getValueKind());
>> break;
>>
>> + case SK_ArrayLoopIndex: {
>> + Expr *Cur = CurInit.get();
>> + Expr *BaseExpr = new (S.Context)
>> + OpaqueValueExpr(Cur->getExprLoc(), Cur->getType(),
>> + Cur->getValueKind(), Cur->getObjectKind(),
>> Cur);
>> + Expr *IndexExpr =
>> + new (S.Context) ArrayInitIndexExpr(S.Context.getSizeType());
>> + CurInit = S.CreateBuiltinArraySubscriptExpr(
>> + BaseExpr, Kind.getLocation(), IndexExpr, Kind.getLocation());
>> + ArrayLoopCommonExprs.push_back(BaseExpr);
>> + break;
>> + }
>> +
>> + case SK_ArrayLoopInit: {
>> + assert(!ArrayLoopCommonExprs.empty() &&
>> + "mismatched SK_ArrayLoopIndex and SK_ArrayLoopInit");
>> + Expr *Common = ArrayLoopCommonExprs.pop_back_val();
>> + CurInit = new (S.Context) ArrayInitLoopExpr(Step->Type, Common,
>> + CurInit.get());
>> + break;
>> + }
>> +
>> case SK_ArrayInit:
>> // Okay: we checked everything before creating this step. Note that
>> // this is a GNU extension.
>> @@ -7851,6 +7963,14 @@ void InitializationSequence::dump(raw_os
>> OS << "Objective-C object conversion";
>> break;
>>
>> + case SK_ArrayLoopIndex:
>> + OS << "indexing for array initialization loop";
>> + break;
>> +
>> + case SK_ArrayLoopInit:
>> + OS << "array initialization loop";
>> + break;
>> +
>> case SK_ArrayInit:
>> OS << "array initialization";
>> break;
>>
>> Modified: cfe/trunk/lib/Sema/TreeTransform.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
>> TreeTransform.h?rev=289413&r1=289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Sema/TreeTransform.h (original)
>> +++ cfe/trunk/lib/Sema/TreeTransform.h Sun Dec 11 20:53:20 2016
>> @@ -3221,6 +3221,9 @@ ExprResult TreeTransform<Derived>::Trans
>> if (ExprWithCleanups *ExprTemp = dyn_cast<ExprWithCleanups>(Init))
>> Init = ExprTemp->getSubExpr();
>>
>> + if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Init))
>> + Init = AIL->getCommonExpr();
>> +
>> if (MaterializeTemporaryExpr *MTE = dyn_cast<
>> MaterializeTemporaryExpr>(Init))
>> Init = MTE->GetTemporaryExpr();
>>
>> @@ -9045,6 +9048,20 @@ TreeTransform<Derived>::TransformNoInitE
>> return ExprError();
>> }
>>
>> +template<typename Derived>
>> +ExprResult
>> +TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr
>> *E) {
>> + llvm_unreachable("Unexpected ArrayInitLoopExpr outside of
>> initializer");
>> + return ExprError();
>> +}
>> +
>> +template<typename Derived>
>> +ExprResult
>> +TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr
>> *E) {
>> + llvm_unreachable("Unexpected ArrayInitIndexExpr outside of
>> initializer");
>> + return ExprError();
>> +}
>> +
>> template<typename Derived>
>> ExprResult
>> TreeTransform<Derived>::TransformImplicitValueInitExpr(
>>
>> Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/
>> Serialization/ASTReaderStmt.cpp?rev=289413&r1=289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
>> +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Sun Dec 11 20:53:20
>> 2016
>> @@ -845,6 +845,16 @@ void ASTStmtReader::VisitNoInitExpr(NoIn
>> VisitExpr(E);
>> }
>>
>> +void ASTStmtReader::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
>> + VisitExpr(E);
>> + E->SubExprs[0] = Reader.ReadSubExpr();
>> + E->SubExprs[1] = Reader.ReadSubExpr();
>> +}
>> +
>> +void ASTStmtReader::VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
>> + VisitExpr(E);
>> +}
>> +
>> void ASTStmtReader::VisitImplicitValueInitExpr(ImplicitValueInitExpr
>> *E) {
>> VisitExpr(E);
>> }
>> @@ -3231,6 +3241,14 @@ Stmt *ASTReader::ReadStmtFromStream(Modu
>> S = new (Context) NoInitExpr(Empty);
>> break;
>>
>> + case EXPR_ARRAY_INIT_LOOP:
>> + S = new (Context) ArrayInitLoopExpr(Empty);
>> + break;
>> +
>> + case EXPR_ARRAY_INIT_INDEX:
>> + S = new (Context) ArrayInitIndexExpr(Empty);
>> + break;
>> +
>> case EXPR_VA_ARG:
>> S = new (Context) VAArgExpr(Empty);
>> break;
>>
>> Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/
>> Serialization/ASTWriterStmt.cpp?rev=289413&r1=289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
>> +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Sun Dec 11 20:53:20
>> 2016
>> @@ -792,6 +792,18 @@ void ASTStmtWriter::VisitNoInitExpr(NoIn
>> Code = serialization::EXPR_NO_INIT;
>> }
>>
>> +void ASTStmtWriter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
>> + VisitExpr(E);
>> + Record.AddStmt(E->SubExprs[0]);
>> + Record.AddStmt(E->SubExprs[1]);
>> + Code = serialization::EXPR_ARRAY_INIT_LOOP;
>> +}
>> +
>> +void ASTStmtWriter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
>> + VisitExpr(E);
>> + Code = serialization::EXPR_ARRAY_INIT_INDEX;
>> +}
>> +
>> void ASTStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr
>> *E) {
>> VisitExpr(E);
>> Code = serialization::EXPR_IMPLICIT_VALUE_INIT;
>>
>> Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/
>> StaticAnalyzer/Core/ExprEngine.cpp?rev=289413&r1=
>> 289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
>> +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Sun Dec 11 20:53:20
>> 2016
>> @@ -905,6 +905,8 @@ void ExprEngine::Visit(const Stmt *S, Ex
>> // Cases not handled yet; but will handle some day.
>> case Stmt::DesignatedInitExprClass:
>> case Stmt::DesignatedInitUpdateExprClass:
>> + case Stmt::ArrayInitLoopExprClass:
>> + case Stmt::ArrayInitIndexExprClass:
>> case Stmt::ExtVectorElementExprClass:
>> case Stmt::ImaginaryLiteralClass:
>> case Stmt::ObjCAtCatchStmtClass:
>>
>> Modified: cfe/trunk/tools/libclang/CXCursor.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/
>> libclang/CXCursor.cpp?rev=289413&r1=289412&r2=289413&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/tools/libclang/CXCursor.cpp (original)
>> +++ cfe/trunk/tools/libclang/CXCursor.cpp Sun Dec 11 20:53:20 2016
>> @@ -243,6 +243,8 @@ CXCursor cxcursor::MakeCXCursor(const St
>> case Stmt::ChooseExprClass:
>> case Stmt::DesignatedInitExprClass:
>> case Stmt::DesignatedInitUpdateExprClass:
>> + case Stmt::ArrayInitLoopExprClass:
>> + case Stmt::ArrayInitIndexExprClass:
>> case Stmt::ExprWithCleanupsClass:
>> case Stmt::ExpressionTraitExprClass:
>> case Stmt::ExtVectorElementExprClass:
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>
> --
> Mike
> Sent from phone
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20161212/4e2f7ac2/attachment-0001.html>
More information about the cfe-commits
mailing list