forked from OSchip/llvm-project
AST: Mangle reference temporaries reliably
Summary: Previously, we would generate a single name for all reference temporaries and allow LLVM to rename them for us. Instead, number the reference temporaries as we build them in Sema. Reviewers: rsmith Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D3554 llvm-svn: 207776
This commit is contained in:
parent
0db806b7f9
commit
daff37013c
|
@ -3784,39 +3784,51 @@ public:
|
|||
/// temporary. When either happens, the expression will also track the
|
||||
/// declaration which is responsible for the lifetime extension.
|
||||
class MaterializeTemporaryExpr : public Expr {
|
||||
public:
|
||||
/// \brief The temporary-generating expression whose value will be
|
||||
/// materialized.
|
||||
Stmt *Temporary;
|
||||
private:
|
||||
struct ExtraState {
|
||||
/// \brief The temporary-generating expression whose value will be
|
||||
/// materialized.
|
||||
Stmt *Temporary;
|
||||
|
||||
/// \brief The declaration which lifetime-extended this reference, if any.
|
||||
/// Either a VarDecl, or (for a ctor-initializer) a FieldDecl.
|
||||
const ValueDecl *ExtendingDecl;
|
||||
/// \brief The declaration which lifetime-extended this reference, if any.
|
||||
/// Either a VarDecl, or (for a ctor-initializer) a FieldDecl.
|
||||
const ValueDecl *ExtendingDecl;
|
||||
|
||||
unsigned ManglingNumber;
|
||||
};
|
||||
llvm::PointerUnion<Stmt *, ExtraState *> State;
|
||||
|
||||
friend class ASTStmtReader;
|
||||
friend class ASTStmtWriter;
|
||||
|
||||
void initializeExtraState(const ValueDecl *ExtendedBy,
|
||||
unsigned ManglingNumber);
|
||||
|
||||
public:
|
||||
MaterializeTemporaryExpr(QualType T, Expr *Temporary,
|
||||
bool BoundToLvalueReference,
|
||||
const ValueDecl *ExtendedBy)
|
||||
bool BoundToLvalueReference)
|
||||
: Expr(MaterializeTemporaryExprClass, T,
|
||||
BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary,
|
||||
Temporary->isTypeDependent(), Temporary->isValueDependent(),
|
||||
Temporary->isInstantiationDependent(),
|
||||
Temporary->containsUnexpandedParameterPack()),
|
||||
Temporary(Temporary), ExtendingDecl(ExtendedBy) {
|
||||
}
|
||||
State(Temporary) {}
|
||||
|
||||
MaterializeTemporaryExpr(EmptyShell Empty)
|
||||
: Expr(MaterializeTemporaryExprClass, Empty) { }
|
||||
|
||||
Stmt *getTemporary() const {
|
||||
return State.is<Stmt *>() ? State.get<Stmt *>()
|
||||
: State.get<ExtraState *>()->Temporary;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the temporary-generating subexpression whose value will
|
||||
/// be materialized into a glvalue.
|
||||
Expr *GetTemporaryExpr() const { return static_cast<Expr *>(Temporary); }
|
||||
Expr *GetTemporaryExpr() const { return static_cast<Expr *>(getTemporary()); }
|
||||
|
||||
/// \brief Retrieve the storage duration for the materialized temporary.
|
||||
StorageDuration getStorageDuration() const {
|
||||
const ValueDecl *ExtendingDecl = getExtendingDecl();
|
||||
if (!ExtendingDecl)
|
||||
return SD_FullExpression;
|
||||
// FIXME: This is not necessarily correct for a temporary materialized
|
||||
|
@ -3828,10 +3840,15 @@ public:
|
|||
|
||||
/// \brief Get the declaration which triggered the lifetime-extension of this
|
||||
/// temporary, if any.
|
||||
const ValueDecl *getExtendingDecl() const { return ExtendingDecl; }
|
||||
const ValueDecl *getExtendingDecl() const {
|
||||
return State.is<Stmt *>() ? nullptr
|
||||
: State.get<ExtraState *>()->ExtendingDecl;
|
||||
}
|
||||
|
||||
void setExtendingDecl(const ValueDecl *ExtendedBy) {
|
||||
ExtendingDecl = ExtendedBy;
|
||||
void setExtendingDecl(const ValueDecl *ExtendedBy, unsigned ManglingNumber);
|
||||
|
||||
unsigned getManglingNumber() const {
|
||||
return State.is<Stmt *>() ? 0 : State.get<ExtraState *>()->ManglingNumber;
|
||||
}
|
||||
|
||||
/// \brief Determine whether this materialized temporary is bound to an
|
||||
|
@ -3841,10 +3858,10 @@ public:
|
|||
}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY {
|
||||
return Temporary->getLocStart();
|
||||
return getTemporary()->getLocStart();
|
||||
}
|
||||
SourceLocation getLocEnd() const LLVM_READONLY {
|
||||
return Temporary->getLocEnd();
|
||||
return getTemporary()->getLocEnd();
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
|
@ -3852,7 +3869,13 @@ public:
|
|||
}
|
||||
|
||||
// Iterators
|
||||
child_range children() { return child_range(&Temporary, &Temporary + 1); }
|
||||
child_range children() {
|
||||
if (State.is<Stmt *>())
|
||||
return child_range(State.getAddrOfPtr1(), State.getAddrOfPtr1() + 1);
|
||||
|
||||
auto ES = State.get<ExtraState *>();
|
||||
return child_range(&ES->Temporary, &ES->Temporary + 1);
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
|
|
@ -130,6 +130,7 @@ public:
|
|||
const ThisAdjustment &ThisAdjustment,
|
||||
raw_ostream &) = 0;
|
||||
virtual void mangleReferenceTemporary(const VarDecl *D,
|
||||
unsigned ManglingNumber,
|
||||
raw_ostream &) = 0;
|
||||
virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
|
||||
virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
|
||||
|
|
|
@ -103,6 +103,9 @@ private:
|
|||
/// \brief The type of the object or reference being initialized.
|
||||
QualType Type;
|
||||
|
||||
/// \brief The mangling number for the next reference temporary to be created.
|
||||
mutable unsigned ManglingNumber;
|
||||
|
||||
struct LN {
|
||||
/// \brief When Kind == EK_Result, EK_Exception, EK_New, the
|
||||
/// location of the 'return', 'throw', or 'new' keyword,
|
||||
|
@ -155,11 +158,11 @@ private:
|
|||
struct C Capture;
|
||||
};
|
||||
|
||||
InitializedEntity() { }
|
||||
InitializedEntity() : ManglingNumber(0) {}
|
||||
|
||||
/// \brief Create the initialization entity for a variable.
|
||||
InitializedEntity(VarDecl *Var)
|
||||
: Kind(EK_Variable), Parent(0), Type(Var->getType()),
|
||||
: Kind(EK_Variable), Parent(0), Type(Var->getType()), ManglingNumber(0),
|
||||
VariableOrMember(Var) { }
|
||||
|
||||
/// \brief Create the initialization entity for the result of a
|
||||
|
@ -167,7 +170,7 @@ private:
|
|||
/// initializing a parameter for which there is no declaration.
|
||||
InitializedEntity(EntityKind Kind, SourceLocation Loc, QualType Type,
|
||||
bool NRVO = false)
|
||||
: Kind(Kind), Parent(0), Type(Type)
|
||||
: Kind(Kind), Parent(0), Type(Type), ManglingNumber(0)
|
||||
{
|
||||
LocAndNRVO.Location = Loc.getRawEncoding();
|
||||
LocAndNRVO.NRVO = NRVO;
|
||||
|
@ -176,7 +179,7 @@ private:
|
|||
/// \brief Create the initialization entity for a member subobject.
|
||||
InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent)
|
||||
: Kind(EK_Member), Parent(Parent), Type(Member->getType()),
|
||||
VariableOrMember(Member) { }
|
||||
ManglingNumber(0), VariableOrMember(Member) { }
|
||||
|
||||
/// \brief Create the initialization entity for an array element.
|
||||
InitializedEntity(ASTContext &Context, unsigned Index,
|
||||
|
@ -184,7 +187,7 @@ private:
|
|||
|
||||
/// \brief Create the initialization entity for a lambda capture.
|
||||
InitializedEntity(IdentifierInfo *VarID, QualType FieldType, SourceLocation Loc)
|
||||
: Kind(EK_LambdaCapture), Parent(0), Type(FieldType)
|
||||
: Kind(EK_LambdaCapture), Parent(0), Type(FieldType), ManglingNumber(0)
|
||||
{
|
||||
Capture.VarID = VarID;
|
||||
Capture.Location = Loc.getRawEncoding();
|
||||
|
@ -418,6 +421,8 @@ public:
|
|||
Kind = EK_Parameter_CF_Audited;
|
||||
}
|
||||
|
||||
unsigned allocateManglingNumber() const { return ++ManglingNumber; }
|
||||
|
||||
/// Dump a representation of the initialized entity to standard error,
|
||||
/// for debugging purposes.
|
||||
void dump() const;
|
||||
|
|
|
@ -1446,6 +1446,25 @@ FunctionParmPackExpr::CreateEmpty(const ASTContext &Context,
|
|||
FunctionParmPackExpr(QualType(), 0, SourceLocation(), 0, 0);
|
||||
}
|
||||
|
||||
void MaterializeTemporaryExpr::setExtendingDecl(const ValueDecl *ExtendedBy,
|
||||
unsigned ManglingNumber) {
|
||||
// We only need extra state if we have to remember more than just the Stmt.
|
||||
if (!ExtendedBy)
|
||||
return;
|
||||
|
||||
// We may need to allocate extra storage for the mangling number and the
|
||||
// extended-by ValueDecl.
|
||||
if (!State.is<ExtraState *>()) {
|
||||
auto ES = new (ExtendedBy->getASTContext()) ExtraState;
|
||||
ES->Temporary = State.get<Stmt *>();
|
||||
State = ES;
|
||||
}
|
||||
|
||||
auto ES = State.get<ExtraState *>();
|
||||
ES->ExtendingDecl = ExtendedBy;
|
||||
ES->ManglingNumber = ManglingNumber;
|
||||
}
|
||||
|
||||
TypeTraitExpr::TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind,
|
||||
ArrayRef<TypeSourceInfo *> Args,
|
||||
SourceLocation RParenLoc,
|
||||
|
|
|
@ -136,7 +136,8 @@ public:
|
|||
void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
|
||||
const ThisAdjustment &ThisAdjustment,
|
||||
raw_ostream &) override;
|
||||
void mangleReferenceTemporary(const VarDecl *D, raw_ostream &) override;
|
||||
void mangleReferenceTemporary(const VarDecl *D, unsigned ManglingNumber,
|
||||
raw_ostream &) override;
|
||||
void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) override;
|
||||
void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) override;
|
||||
void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
|
||||
|
@ -3782,12 +3783,16 @@ ItaniumMangleContextImpl::mangleItaniumThreadLocalWrapper(const VarDecl *D,
|
|||
}
|
||||
|
||||
void ItaniumMangleContextImpl::mangleReferenceTemporary(const VarDecl *D,
|
||||
unsigned ManglingNumber,
|
||||
raw_ostream &Out) {
|
||||
// We match the GCC mangling here.
|
||||
// <special-name> ::= GR <object name>
|
||||
CXXNameMangler Mangler(*this, Out);
|
||||
Mangler.getStream() << "_ZGR";
|
||||
Mangler.mangleName(D);
|
||||
assert(ManglingNumber > 0 && "Reference temporary mangling number is zero!");
|
||||
if (ManglingNumber > 1)
|
||||
Mangler.mangleNumber(ManglingNumber - 2);
|
||||
}
|
||||
|
||||
void ItaniumMangleContextImpl::mangleCXXVTable(const CXXRecordDecl *RD,
|
||||
|
|
|
@ -117,7 +117,8 @@ public:
|
|||
raw_ostream &) override;
|
||||
void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
|
||||
raw_ostream &) override;
|
||||
void mangleReferenceTemporary(const VarDecl *, raw_ostream &) override;
|
||||
void mangleReferenceTemporary(const VarDecl *, unsigned ManglingNumber,
|
||||
raw_ostream &) override;
|
||||
void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &Out) override;
|
||||
void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) override;
|
||||
void mangleDynamicAtExitDestructor(const VarDecl *D,
|
||||
|
@ -2267,6 +2268,7 @@ void MicrosoftMangleContextImpl::mangleCXXDtor(const CXXDestructorDecl *D,
|
|||
}
|
||||
|
||||
void MicrosoftMangleContextImpl::mangleReferenceTemporary(const VarDecl *VD,
|
||||
unsigned,
|
||||
raw_ostream &) {
|
||||
unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
|
||||
"cannot mangle this reference temporary yet");
|
||||
|
|
|
@ -2828,7 +2828,8 @@ llvm::Constant *CodeGenModule::GetAddrOfGlobalTemporary(
|
|||
// we also need to make the temporaries externally-visible).
|
||||
SmallString<256> Name;
|
||||
llvm::raw_svector_ostream Out(Name);
|
||||
getCXXABI().getMangleContext().mangleReferenceTemporary(VD, Out);
|
||||
getCXXABI().getMangleContext().mangleReferenceTemporary(
|
||||
VD, E->getManglingNumber(), Out);
|
||||
Out.flush();
|
||||
|
||||
APValue *Value = 0;
|
||||
|
|
|
@ -1584,8 +1584,7 @@ static TryCastResult TryConstCast(Sema &Self, ExprResult &SrcExpr,
|
|||
// This is a const_cast from a class prvalue to an rvalue reference type.
|
||||
// Materialize a temporary to store the result of the conversion.
|
||||
SrcExpr = new (Self.Context) MaterializeTemporaryExpr(
|
||||
SrcType, SrcExpr.take(), /*IsLValueReference*/ false,
|
||||
/*ExtendingDecl*/ 0);
|
||||
SrcType, SrcExpr.take(), /*IsLValueReference*/ false);
|
||||
|
||||
return TC_Success;
|
||||
}
|
||||
|
|
|
@ -8885,7 +8885,7 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
|
|||
return QualType();
|
||||
// Materialize the temporary as an lvalue so that we can take its address.
|
||||
OrigOp = op = new (Context)
|
||||
MaterializeTemporaryExpr(op->getType(), OrigOp.take(), true, 0);
|
||||
MaterializeTemporaryExpr(op->getType(), OrigOp.take(), true);
|
||||
} else if (isa<ObjCSelectorExpr>(op)) {
|
||||
return Context.getPointerType(op->getType());
|
||||
} else if (lval == Expr::LV_MemberFunction) {
|
||||
|
|
|
@ -5311,25 +5311,25 @@ InitializedEntityOutlivesFullExpression(const InitializedEntity &Entity) {
|
|||
/// Determine the declaration which an initialized entity ultimately refers to,
|
||||
/// for the purpose of lifetime-extending a temporary bound to a reference in
|
||||
/// the initialization of \p Entity.
|
||||
static const ValueDecl *
|
||||
getDeclForTemporaryLifetimeExtension(const InitializedEntity &Entity,
|
||||
const ValueDecl *FallbackDecl = 0) {
|
||||
static const InitializedEntity *getEntityForTemporaryLifetimeExtension(
|
||||
const InitializedEntity *Entity,
|
||||
const InitializedEntity *FallbackDecl = 0) {
|
||||
// C++11 [class.temporary]p5:
|
||||
switch (Entity.getKind()) {
|
||||
switch (Entity->getKind()) {
|
||||
case InitializedEntity::EK_Variable:
|
||||
// The temporary [...] persists for the lifetime of the reference
|
||||
return Entity.getDecl();
|
||||
return Entity;
|
||||
|
||||
case InitializedEntity::EK_Member:
|
||||
// For subobjects, we look at the complete object.
|
||||
if (Entity.getParent())
|
||||
return getDeclForTemporaryLifetimeExtension(*Entity.getParent(),
|
||||
Entity.getDecl());
|
||||
if (Entity->getParent())
|
||||
return getEntityForTemporaryLifetimeExtension(Entity->getParent(),
|
||||
Entity);
|
||||
|
||||
// except:
|
||||
// -- A temporary bound to a reference member in a constructor's
|
||||
// ctor-initializer persists until the constructor exits.
|
||||
return Entity.getDecl();
|
||||
return Entity;
|
||||
|
||||
case InitializedEntity::EK_Parameter:
|
||||
case InitializedEntity::EK_Parameter_CF_Audited:
|
||||
|
@ -5344,7 +5344,7 @@ getDeclForTemporaryLifetimeExtension(const InitializedEntity &Entity,
|
|||
// -- A temporary bound to a reference in a new-initializer persists
|
||||
// until the completion of the full-expression containing the
|
||||
// new-initializer.
|
||||
return 0;
|
||||
return nullptr;
|
||||
|
||||
case InitializedEntity::EK_Temporary:
|
||||
case InitializedEntity::EK_CompoundLiteralInit:
|
||||
|
@ -5352,12 +5352,12 @@ getDeclForTemporaryLifetimeExtension(const InitializedEntity &Entity,
|
|||
// We don't yet know the storage duration of the surrounding temporary.
|
||||
// Assume it's got full-expression duration for now, it will patch up our
|
||||
// storage duration if that's not correct.
|
||||
return 0;
|
||||
return nullptr;
|
||||
|
||||
case InitializedEntity::EK_ArrayElement:
|
||||
// For subobjects, we look at the complete object.
|
||||
return getDeclForTemporaryLifetimeExtension(*Entity.getParent(),
|
||||
FallbackDecl);
|
||||
return getEntityForTemporaryLifetimeExtension(Entity->getParent(),
|
||||
FallbackDecl);
|
||||
|
||||
case InitializedEntity::EK_Base:
|
||||
case InitializedEntity::EK_Delegating:
|
||||
|
@ -5372,17 +5372,20 @@ getDeclForTemporaryLifetimeExtension(const InitializedEntity &Entity,
|
|||
case InitializedEntity::EK_Exception:
|
||||
case InitializedEntity::EK_VectorElement:
|
||||
case InitializedEntity::EK_ComplexElement:
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
llvm_unreachable("unknown entity kind");
|
||||
}
|
||||
|
||||
static void performLifetimeExtension(Expr *Init, const ValueDecl *ExtendingD);
|
||||
static void performLifetimeExtension(Expr *Init,
|
||||
const InitializedEntity *ExtendingEntity);
|
||||
|
||||
/// Update a glvalue expression that is used as the initializer of a reference
|
||||
/// to note that its lifetime is extended.
|
||||
/// \return \c true if any temporary had its lifetime extended.
|
||||
static bool performReferenceExtension(Expr *Init, const ValueDecl *ExtendingD) {
|
||||
static bool
|
||||
performReferenceExtension(Expr *Init,
|
||||
const InitializedEntity *ExtendingEntity) {
|
||||
if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
|
||||
if (ILE->getNumInits() == 1 && ILE->isGLValue()) {
|
||||
// This is just redundant braces around an initializer. Step over it.
|
||||
|
@ -5416,8 +5419,9 @@ static bool performReferenceExtension(Expr *Init, const ValueDecl *ExtendingD) {
|
|||
if (MaterializeTemporaryExpr *ME = dyn_cast<MaterializeTemporaryExpr>(Init)) {
|
||||
// Update the storage duration of the materialized temporary.
|
||||
// FIXME: Rebuild the expression instead of mutating it.
|
||||
ME->setExtendingDecl(ExtendingD);
|
||||
performLifetimeExtension(ME->GetTemporaryExpr(), ExtendingD);
|
||||
ME->setExtendingDecl(ExtendingEntity->getDecl(),
|
||||
ExtendingEntity->allocateManglingNumber());
|
||||
performLifetimeExtension(ME->GetTemporaryExpr(), ExtendingEntity);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -5426,7 +5430,8 @@ static bool performReferenceExtension(Expr *Init, const ValueDecl *ExtendingD) {
|
|||
|
||||
/// Update a prvalue expression that is going to be materialized as a
|
||||
/// lifetime-extended temporary.
|
||||
static void performLifetimeExtension(Expr *Init, const ValueDecl *ExtendingD) {
|
||||
static void performLifetimeExtension(Expr *Init,
|
||||
const InitializedEntity *ExtendingEntity) {
|
||||
// Dig out the expression which constructs the extended temporary.
|
||||
SmallVector<const Expr *, 2> CommaLHSs;
|
||||
SmallVector<SubobjectAdjustment, 2> Adjustments;
|
||||
|
@ -5438,14 +5443,14 @@ static void performLifetimeExtension(Expr *Init, const ValueDecl *ExtendingD) {
|
|||
|
||||
if (CXXStdInitializerListExpr *ILE =
|
||||
dyn_cast<CXXStdInitializerListExpr>(Init)) {
|
||||
performReferenceExtension(ILE->getSubExpr(), ExtendingD);
|
||||
performReferenceExtension(ILE->getSubExpr(), ExtendingEntity);
|
||||
return;
|
||||
}
|
||||
|
||||
if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
|
||||
if (ILE->getType()->isArrayType()) {
|
||||
for (unsigned I = 0, N = ILE->getNumInits(); I != N; ++I)
|
||||
performLifetimeExtension(ILE->getInit(I), ExtendingD);
|
||||
performLifetimeExtension(ILE->getInit(I), ExtendingEntity);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5457,7 +5462,7 @@ static void performLifetimeExtension(Expr *Init, const ValueDecl *ExtendingD) {
|
|||
// bound to temporaries, those temporaries are also lifetime-extended.
|
||||
if (RD->isUnion() && ILE->getInitializedFieldInUnion() &&
|
||||
ILE->getInitializedFieldInUnion()->getType()->isReferenceType())
|
||||
performReferenceExtension(ILE->getInit(0), ExtendingD);
|
||||
performReferenceExtension(ILE->getInit(0), ExtendingEntity);
|
||||
else {
|
||||
unsigned Index = 0;
|
||||
for (const auto *I : RD->fields()) {
|
||||
|
@ -5467,13 +5472,13 @@ static void performLifetimeExtension(Expr *Init, const ValueDecl *ExtendingD) {
|
|||
continue;
|
||||
Expr *SubInit = ILE->getInit(Index);
|
||||
if (I->getType()->isReferenceType())
|
||||
performReferenceExtension(SubInit, ExtendingD);
|
||||
performReferenceExtension(SubInit, ExtendingEntity);
|
||||
else if (isa<InitListExpr>(SubInit) ||
|
||||
isa<CXXStdInitializerListExpr>(SubInit))
|
||||
// This may be either aggregate-initialization of a member or
|
||||
// initialization of a std::initializer_list object. Either way,
|
||||
// we should recursively lifetime-extend that initializer.
|
||||
performLifetimeExtension(SubInit, ExtendingD);
|
||||
performLifetimeExtension(SubInit, ExtendingEntity);
|
||||
++Index;
|
||||
}
|
||||
}
|
||||
|
@ -5759,12 +5764,12 @@ InitializationSequence::Perform(Sema &S,
|
|||
// Even though we didn't materialize a temporary, the binding may still
|
||||
// extend the lifetime of a temporary. This happens if we bind a reference
|
||||
// to the result of a cast to reference type.
|
||||
if (const ValueDecl *ExtendingDecl =
|
||||
getDeclForTemporaryLifetimeExtension(Entity)) {
|
||||
if (performReferenceExtension(CurInit.get(), ExtendingDecl))
|
||||
warnOnLifetimeExtension(S, Entity, CurInit.get(), false,
|
||||
ExtendingDecl);
|
||||
}
|
||||
if (const InitializedEntity *ExtendingEntity =
|
||||
getEntityForTemporaryLifetimeExtension(&Entity))
|
||||
if (performReferenceExtension(CurInit.get(), ExtendingEntity))
|
||||
warnOnLifetimeExtension(S, Entity, CurInit.get(),
|
||||
/*IsInitializerList=*/false,
|
||||
ExtendingEntity->getDecl());
|
||||
|
||||
break;
|
||||
|
||||
|
@ -5776,19 +5781,18 @@ InitializationSequence::Perform(Sema &S,
|
|||
if (S.CheckExceptionSpecCompatibility(CurInit.get(), DestType))
|
||||
return ExprError();
|
||||
|
||||
// Maybe lifetime-extend the temporary's subobjects to match the
|
||||
// entity's lifetime.
|
||||
const ValueDecl *ExtendingDecl =
|
||||
getDeclForTemporaryLifetimeExtension(Entity);
|
||||
if (ExtendingDecl) {
|
||||
performLifetimeExtension(CurInit.get(), ExtendingDecl);
|
||||
warnOnLifetimeExtension(S, Entity, CurInit.get(), false, ExtendingDecl);
|
||||
}
|
||||
|
||||
// Materialize the temporary into memory.
|
||||
MaterializeTemporaryExpr *MTE = new (S.Context) MaterializeTemporaryExpr(
|
||||
Entity.getType().getNonReferenceType(), CurInit.get(),
|
||||
Entity.getType()->isLValueReferenceType(), ExtendingDecl);
|
||||
Entity.getType()->isLValueReferenceType());
|
||||
|
||||
// Maybe lifetime-extend the temporary's subobjects to match the
|
||||
// entity's lifetime.
|
||||
if (const InitializedEntity *ExtendingEntity =
|
||||
getEntityForTemporaryLifetimeExtension(&Entity))
|
||||
if (performReferenceExtension(MTE, ExtendingEntity))
|
||||
warnOnLifetimeExtension(S, Entity, CurInit.get(), /*IsInitializerList=*/false,
|
||||
ExtendingEntity->getDecl());
|
||||
|
||||
// If we're binding to an Objective-C object that has lifetime, we
|
||||
// need cleanups. Likewise if we're extending this temporary to automatic
|
||||
|
@ -6176,19 +6180,19 @@ InitializationSequence::Perform(Sema &S,
|
|||
diag::warn_cxx98_compat_initializer_list_init)
|
||||
<< CurInit.get()->getSourceRange();
|
||||
|
||||
// Maybe lifetime-extend the array temporary's subobjects to match the
|
||||
// entity's lifetime.
|
||||
const ValueDecl *ExtendingDecl =
|
||||
getDeclForTemporaryLifetimeExtension(Entity);
|
||||
if (ExtendingDecl) {
|
||||
performLifetimeExtension(CurInit.get(), ExtendingDecl);
|
||||
warnOnLifetimeExtension(S, Entity, CurInit.get(), true, ExtendingDecl);
|
||||
}
|
||||
|
||||
// Materialize the temporary into memory.
|
||||
MaterializeTemporaryExpr *MTE = new (S.Context)
|
||||
MaterializeTemporaryExpr(CurInit.get()->getType(), CurInit.get(),
|
||||
/*lvalue reference*/ false, ExtendingDecl);
|
||||
/*BoundToLvalueReference=*/false);
|
||||
|
||||
// Maybe lifetime-extend the array temporary's subobjects to match the
|
||||
// entity's lifetime.
|
||||
if (const InitializedEntity *ExtendingEntity =
|
||||
getEntityForTemporaryLifetimeExtension(&Entity))
|
||||
if (performReferenceExtension(MTE, ExtendingEntity))
|
||||
warnOnLifetimeExtension(S, Entity, CurInit.get(),
|
||||
/*IsInitializerList=*/true,
|
||||
ExtendingEntity->getDecl());
|
||||
|
||||
// Wrap it in a construction of a std::initializer_list<T>.
|
||||
CurInit = S.Owned(
|
||||
|
|
|
@ -1572,8 +1572,10 @@ void ASTStmtReader::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
|
|||
|
||||
void ASTStmtReader::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
|
||||
VisitExpr(E);
|
||||
E->Temporary = Reader.ReadSubExpr();
|
||||
E->ExtendingDecl = ReadDeclAs<ValueDecl>(Record, Idx);
|
||||
E->State = Reader.ReadSubExpr();
|
||||
auto VD = ReadDeclAs<ValueDecl>(Record, Idx);
|
||||
unsigned ManglingNumber = Record[Idx++];
|
||||
E->setExtendingDecl(VD, ManglingNumber);
|
||||
}
|
||||
|
||||
void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
|
||||
|
|
|
@ -1567,8 +1567,9 @@ void ASTStmtWriter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
|
|||
|
||||
void ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
|
||||
VisitExpr(E);
|
||||
Writer.AddStmt(E->Temporary);
|
||||
Writer.AddDeclRef(E->ExtendingDecl, Record);
|
||||
Writer.AddStmt(E->getTemporary());
|
||||
Writer.AddDeclRef(E->getExtendingDecl(), Record);
|
||||
Record.push_back(E->getManglingNumber());
|
||||
Code = serialization::EXPR_MATERIALIZE_TEMPORARY;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,16 +54,16 @@ namespace HiddenVariableTemplateWithConstRef {
|
|||
const int &use = i<void>;
|
||||
}
|
||||
|
||||
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE = linkonce_odr constant i32 1
|
||||
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE2 = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE }
|
||||
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE1 = linkonce_odr constant i32 1
|
||||
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE0 = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE1 }
|
||||
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE3 = linkonce_odr constant i32 2
|
||||
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE4 = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE3 }
|
||||
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE2 = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE3 }
|
||||
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE5 = linkonce_odr constant i32 3
|
||||
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE6 = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE5 }
|
||||
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE4 = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE5 }
|
||||
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE7 = linkonce_odr constant i32 4
|
||||
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE8 = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE7 }
|
||||
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE9 = linkonce_odr global {{.*}} { {{.*}} @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE2, {{.*}} @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE4, {{.*}} @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE6, {{.*}} @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE8 }
|
||||
// CHECK: @_ZN24VariableTemplateWithPack1pE = global {{.*}} @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE9
|
||||
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE6 = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE7 }
|
||||
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE = linkonce_odr global %"struct.VariableTemplateWithPack::S" { {{.*}}* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE0, {{.*}}* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE2, {{.*}}* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE4, {{.*}}* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE6 }
|
||||
// CHECK: @_ZN24VariableTemplateWithPack1pE = global {{.*}} @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE
|
||||
namespace VariableTemplateWithPack {
|
||||
struct A {
|
||||
const int &r;
|
||||
|
|
|
@ -55,76 +55,76 @@ std::initializer_list<std::initializer_list<int>> nested = {
|
|||
{1, a}, {3, b}, {5, c}
|
||||
};
|
||||
|
||||
// CHECK-STATIC-BL: @_ZGR6nested = private constant [2 x i32] [i32 1, i32 2], align 4
|
||||
// CHECK-STATIC-BL: @_ZGR6nested0 = private constant [2 x i32] [i32 1, i32 2], align 4
|
||||
// CHECK-STATIC-BL: @_ZGR6nested1 = private constant [2 x i32] [i32 3, i32 4], align 4
|
||||
// CHECK-STATIC-BL: @_ZGR6nested2 = private constant [2 x i32] [i32 5, i32 6], align 4
|
||||
// CHECK-STATIC-BL: @_ZGR6nested3 = private constant [3 x {{.*}}] [
|
||||
// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested, i32 0, i32 0), i64 2 },
|
||||
// CHECK-STATIC-BL: @_ZGR6nested = private constant [3 x {{.*}}] [
|
||||
// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0, i32 0, i32 0), i64 2 },
|
||||
// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i32 0, i32 0), i64 2 },
|
||||
// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i32 0, i32 0), i64 2 }
|
||||
// CHECK-STATIC-BL: ], align 8
|
||||
// CHECK-STATIC-BL: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested3, i32 0, i32 0), i64 3 }, align 8
|
||||
// CHECK-STATIC-BL: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i32 0, i32 0), i64 3 }, align 8
|
||||
|
||||
// CHECK-DYNAMIC-BL: @nested = global
|
||||
// CHECK-DYNAMIC-BL: @_ZGR6nested = private global [3 x
|
||||
// CHECK-DYNAMIC-BL: @_ZGR6nested0 = private global [2 x i32] zeroinitializer
|
||||
// CHECK-DYNAMIC-BL: @_ZGR6nested1 = private global [2 x i32] zeroinitializer
|
||||
// CHECK-DYNAMIC-BL: @_ZGR6nested2 = private global [2 x i32] zeroinitializer
|
||||
// CHECK-DYNAMIC-BL: @_ZGR6nested3 = private global [2 x i32] zeroinitializer
|
||||
// CHECK-DYNAMIC-BL: store i32 1, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0)
|
||||
// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 1)
|
||||
// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0),
|
||||
// CHECK-DYNAMIC-BL: store i32 1, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0, i64 0, i64 0)
|
||||
// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0, i64 0, i64 1)
|
||||
// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0, i64 0, i64 0),
|
||||
// CHECK-DYNAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 0), align 8
|
||||
// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 1), align 8
|
||||
// CHECK-DYNAMIC-BL: store i32 3, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0)
|
||||
// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 1)
|
||||
// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0),
|
||||
// CHECK-DYNAMIC-BL: store i32 3, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0)
|
||||
// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 1)
|
||||
// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0),
|
||||
// CHECK-DYNAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 0), align 8
|
||||
// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 1), align 8
|
||||
// CHECK-DYNAMIC-BL: store i32 5, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 0)
|
||||
// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 1)
|
||||
// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 0),
|
||||
// CHECK-DYNAMIC-BL: store i32 5, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0)
|
||||
// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 1)
|
||||
// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0),
|
||||
// CHECK-DYNAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 0), align 8
|
||||
// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 1), align 8
|
||||
// CHECK-DYNAMIC-BL: store {{.*}}* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0),
|
||||
// CHECK-DYNAMIC-BL: {{.*}}** getelementptr inbounds ({{.*}}* @nested, i32 0, i32 0), align 8
|
||||
// CHECK-DYNAMIC-BL: store i64 3, i64* getelementptr inbounds ({{.*}}* @nested, i32 0, i32 1), align 8
|
||||
|
||||
// CHECK-STATIC-BE: @_ZGR6nested = private constant [2 x i32] [i32 1, i32 2], align 4
|
||||
// CHECK-STATIC-BE: @_ZGR6nested0 = private constant [2 x i32] [i32 1, i32 2], align 4
|
||||
// CHECK-STATIC-BE: @_ZGR6nested1 = private constant [2 x i32] [i32 3, i32 4], align 4
|
||||
// CHECK-STATIC-BE: @_ZGR6nested2 = private constant [2 x i32] [i32 5, i32 6], align 4
|
||||
// CHECK-STATIC-BE: @_ZGR6nested3 = private constant [3 x {{.*}}] [
|
||||
// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested, i32 0, i32 0),
|
||||
// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested to i8*), i64 8) to i32*) }
|
||||
// CHECK-STATIC-BE: @_ZGR6nested = private constant [3 x {{.*}}] [
|
||||
// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0, i32 0, i32 0),
|
||||
// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested0 to i8*), i64 8) to i32*) }
|
||||
// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i32 0, i32 0),
|
||||
// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested1 to i8*), i64 8) to i32*) }
|
||||
// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i32 0, i32 0),
|
||||
// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested2 to i8*), i64 8) to i32*) }
|
||||
// CHECK-STATIC-BE: ], align 8
|
||||
// CHECK-STATIC-BE: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested3, i32 0, i32 0),
|
||||
// CHECK-STATIC-BE: {{.*}} bitcast ({{.*}}* getelementptr (i8* bitcast ([3 x {{.*}}]* @_ZGR6nested3 to i8*), i64 48) to {{.*}}*) }
|
||||
// CHECK-STATIC-BE: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i32 0, i32 0),
|
||||
// CHECK-STATIC-BE: {{.*}} bitcast ({{.*}}* getelementptr (i8* bitcast ([3 x {{.*}}]* @_ZGR6nested to i8*), i64 48) to {{.*}}*) }
|
||||
|
||||
// CHECK-DYNAMIC-BE: @nested = global
|
||||
// CHECK-DYNAMIC-BE: @_ZGR6nested = private global [3 x
|
||||
// CHECK-DYNAMIC-BE: @_ZGR6nested0 = private global [2 x i32] zeroinitializer
|
||||
// CHECK-DYNAMIC-BE: @_ZGR6nested1 = private global [2 x i32] zeroinitializer
|
||||
// CHECK-DYNAMIC-BE: @_ZGR6nested2 = private global [2 x i32] zeroinitializer
|
||||
// CHECK-DYNAMIC-BE: @_ZGR6nested3 = private global [2 x i32] zeroinitializer
|
||||
// CHECK-DYNAMIC-BE: store i32 1, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0)
|
||||
// CHECK-DYNAMIC-BE: store i32 1, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0, i64 0, i64 0)
|
||||
// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0, i64 0, i64 1)
|
||||
// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0, i64 0, i64 0),
|
||||
// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 0), align 8
|
||||
// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0, i64 1, i64 0),
|
||||
// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 1), align 8
|
||||
// CHECK-DYNAMIC-BE: store i32 3, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0)
|
||||
// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 1)
|
||||
// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0),
|
||||
// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 0), align 8
|
||||
// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 0), align 8
|
||||
// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 1, i64 0),
|
||||
// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 1), align 8
|
||||
// CHECK-DYNAMIC-BE: store i32 3, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0)
|
||||
// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 1), align 8
|
||||
// CHECK-DYNAMIC-BE: store i32 5, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0)
|
||||
// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 1)
|
||||
// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0),
|
||||
// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 0), align 8
|
||||
// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 1, i64 0),
|
||||
// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 1), align 8
|
||||
// CHECK-DYNAMIC-BE: store i32 5, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 0)
|
||||
// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 1)
|
||||
// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 0),
|
||||
// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 0), align 8
|
||||
// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 1, i64 0),
|
||||
// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 1, i64 0),
|
||||
// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 1), align 8
|
||||
// CHECK-DYNAMIC-BE: store {{.*}}* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0),
|
||||
// CHECK-DYNAMIC-BE: {{.*}}** getelementptr inbounds ({{.*}}* @nested, i32 0, i32 0), align 8
|
||||
|
|
Loading…
Reference in New Issue