It seems libcxx (with -fmodules) dislikes this change. Any idea? http://bb.pgr.jp/builders/bootstrap-clang-libcxx-lld-i686-linux/builds/238
On Fri, Sep 22, 2017 at 1:26 PM Richard Smith via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: rsmith > Date: Thu Sep 21 21:25:05 2017 > New Revision: 313955 > > URL: http://llvm.org/viewvc/llvm-project?rev=313955&view=rev > Log: > Give external linkage and mangling to lambdas inside inline variables and > variable templates. > > This implements the proposed approach in > https://github.com/itanium-cxx-abi/cxx-abi/issues/33 > > This reinstates r313827, reverted in r313856, with a fix for the > 'out-of-bounds > enumeration value' ubsan error in that change. > > Modified: > cfe/trunk/lib/AST/Decl.cpp > cfe/trunk/lib/AST/ItaniumMangle.cpp > cfe/trunk/lib/AST/Linkage.h > cfe/trunk/lib/Parse/ParseDecl.cpp > cfe/trunk/lib/Sema/SemaDeclCXX.cpp > cfe/trunk/lib/Sema/SemaLambda.cpp > cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp > cfe/trunk/test/CodeGenCXX/mangle-lambdas.cpp > cfe/trunk/test/SemaCXX/vartemplate-lambda.cpp > cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp > > Modified: cfe/trunk/lib/AST/Decl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=313955&r1=313954&r2=313955&view=diff > > ============================================================================== > --- cfe/trunk/lib/AST/Decl.cpp (original) > +++ cfe/trunk/lib/AST/Decl.cpp Thu Sep 21 21:25:05 2017 > @@ -554,7 +554,8 @@ static LinkageInfo getExternalLinkageFor > > LinkageInfo > LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, > - LVComputationKind > computation) { > + LVComputationKind computation, > + bool IgnoreVarTypeLinkage) { > assert(D->getDeclContext()->getRedeclContext()->isFileContext() && > "Not a name having namespace scope"); > ASTContext &Context = D->getASTContext(); > @@ -611,7 +612,7 @@ LinkageComputer::getLVForNamespaceScopeD > // - a data member of an anonymous union. > const VarDecl *VD = IFD->getVarDecl(); > assert(VD && "Expected a VarDecl in this IndirectFieldDecl!"); > - return getLVForNamespaceScopeDecl(VD, computation); > + return getLVForNamespaceScopeDecl(VD, computation, > IgnoreVarTypeLinkage); > } > assert(!isa<FieldDecl>(D) && "Didn't expect a FieldDecl!"); > > @@ -700,7 +701,8 @@ LinkageComputer::getLVForNamespaceScopeD > // > // Note that we don't want to make the variable non-external > // because of this, but unique-external linkage suits us. > - if (Context.getLangOpts().CPlusPlus && !isFirstInExternCContext(Var)) > { > + if (Context.getLangOpts().CPlusPlus && !isFirstInExternCContext(Var) > && > + !IgnoreVarTypeLinkage) { > LinkageInfo TypeLV = getLVForType(*Var->getType(), computation); > if (!isExternallyVisible(TypeLV.getLinkage())) > return LinkageInfo::uniqueExternal(); > @@ -740,15 +742,9 @@ LinkageComputer::getLVForNamespaceScopeD > // unique-external linkage, it's not legally usable from outside > // this translation unit. However, we should use the C linkage > // rules instead for extern "C" declarations. > - if (Context.getLangOpts().CPlusPlus && > - !Function->isInExternCContext()) { > - // Only look at the type-as-written. If this function has an > auto-deduced > - // return type, we can't compute the linkage of that type because > it could > - // require looking at the linkage of this function, and we don't > need this > - // for correctness because the type is not part of the function's > - // signature. > - // FIXME: This is a hack. We should be able to solve this > circularity and > - // the one in getLVForClassMember for Functions some other way. > + if (Context.getLangOpts().CPlusPlus && > !Function->isInExternCContext()) { > + // Only look at the type-as-written. Otherwise, deducing the return > type > + // of a function could change its linkage. > QualType TypeAsWritten = Function->getType(); > if (TypeSourceInfo *TSI = Function->getTypeSourceInfo()) > TypeAsWritten = TSI->getType(); > @@ -831,7 +827,8 @@ LinkageComputer::getLVForNamespaceScopeD > > LinkageInfo > LinkageComputer::getLVForClassMember(const NamedDecl *D, > - LVComputationKind computation) { > + LVComputationKind computation, > + bool IgnoreVarTypeLinkage) { > // Only certain class members have linkage. Note that fields don't > // really have linkage, but it's convenient to say they do for the > // purposes of calculating linkage of pointer-to-data-member > @@ -889,22 +886,14 @@ LinkageComputer::getLVForClassMember(con > const NamedDecl *explicitSpecSuppressor = nullptr; > > if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) { > - // If the type of the function uses a type that has > non-externally-visible > - // linkage, it's not legally usable from outside this translation > unit. > - // But only look at the type-as-written. If this function has an > - // auto-deduced return type, we can't compute the linkage of that type > - // because it could require looking at the linkage of this function, > and we > - // don't need this for correctness because the type is not part of the > - // function's signature. > - // FIXME: This is a hack. We should be able to solve this circularity > and > - // the one in getLVForNamespaceScopeDecl for Functions some other way. > - { > - QualType TypeAsWritten = MD->getType(); > - if (TypeSourceInfo *TSI = MD->getTypeSourceInfo()) > - TypeAsWritten = TSI->getType(); > - if (!isExternallyVisible(TypeAsWritten->getLinkage())) > - return LinkageInfo::uniqueExternal(); > - } > + // Only look at the type-as-written. Otherwise, deducing the return > type > + // of a function could change its linkage. > + QualType TypeAsWritten = MD->getType(); > + if (TypeSourceInfo *TSI = MD->getTypeSourceInfo()) > + TypeAsWritten = TSI->getType(); > + if (!isExternallyVisible(TypeAsWritten->getLinkage())) > + return LinkageInfo::uniqueExternal(); > + > // If this is a method template specialization, use the linkage for > // the template parameters and arguments. > if (FunctionTemplateSpecializationInfo *spec > @@ -941,10 +930,14 @@ LinkageComputer::getLVForClassMember(con > > // Modify the variable's linkage by its type, but ignore the > // type's visibility unless it's a definition. > - LinkageInfo typeLV = getLVForType(*VD->getType(), computation); > - if (!LV.isVisibilityExplicit() && !classLV.isVisibilityExplicit()) > - LV.mergeVisibility(typeLV); > - LV.mergeExternalVisibility(typeLV); > + if (!IgnoreVarTypeLinkage) { > + LinkageInfo typeLV = getLVForType(*VD->getType(), computation); > + // FIXME: If the type's linkage is not externally visible, we can > + // give this static data member UniqueExternalLinkage. > + if (!LV.isVisibilityExplicit() && !classLV.isVisibilityExplicit()) > + LV.mergeVisibility(typeLV); > + LV.mergeExternalVisibility(typeLV); > + } > > if (isExplicitMemberSpecialization(VD)) { > explicitSpecSuppressor = VD; > @@ -1102,22 +1095,33 @@ LinkageInfo LinkageComputer::getLVForClo > Decl *ContextDecl, > LVComputationKind > computation) { > // This lambda has its linkage/visibility determined by its owner. > + const NamedDecl *Owner; > + if (!ContextDecl) > + Owner = dyn_cast<NamedDecl>(DC); > + else if (isa<ParmVarDecl>(ContextDecl)) > + Owner = > + > dyn_cast<NamedDecl>(ContextDecl->getDeclContext()->getRedeclContext()); > + else > + Owner = cast<NamedDecl>(ContextDecl); > + > + // FIXME: If there is no owner, the closure should have no linkage. > + if (!Owner) > + return LinkageInfo::external(); > + > + // If the owner has a deduced type, we need to skip querying the > linkage and > + // visibility of that type, because it might involve this closure > type. The > + // only effect of this is that we might give a lambda VisibleNoLinkage > rather > + // than NoLinkage when we don't strictly need to, which is benign. > + auto *VD = dyn_cast<VarDecl>(Owner); > + LinkageInfo OwnerLinkage = > + VD && VD->getType()->getContainedDeducedType() > + ? computeLVForDecl(Owner, computation, > /*IgnoreVarTypeLinkage*/true) > + : getLVForDecl(Owner, computation); > + > // FIXME: This is wrong. A lambda never formally has linkage; if this > - // calculation determines the lambda has external linkage, it should be > + // calculation determines a lambda has external linkage, it should be > // downgraded to VisibleNoLinkage. > - if (ContextDecl) { > - if (isa<ParmVarDecl>(ContextDecl)) > - DC = ContextDecl->getDeclContext()->getRedeclContext(); > - else > - return getLVForDecl(cast<NamedDecl>(ContextDecl), computation); > - } > - > - if (const auto *ND = dyn_cast<NamedDecl>(DC)) > - return getLVForDecl(ND, computation); > - > - // FIXME: We have a closure at TU scope with no context declaration. > This > - // should probably have no linkage. > - return LinkageInfo::external(); > + return OwnerLinkage; > } > > LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D, > @@ -1215,7 +1219,8 @@ getOutermostEnclosingLambda(const CXXRec > } > > LinkageInfo LinkageComputer::computeLVForDecl(const NamedDecl *D, > - LVComputationKind > computation) { > + LVComputationKind > computation, > + bool IgnoreVarTypeLinkage) { > // Internal_linkage attribute overrides other considerations. > if (D->hasAttr<InternalLinkageAttr>()) > return getInternalLinkageFor(D); > @@ -1303,7 +1308,7 @@ LinkageInfo LinkageComputer::computeLVFo > > // Handle linkage for namespace-scope names. > if (D->getDeclContext()->getRedeclContext()->isFileContext()) > - return getLVForNamespaceScopeDecl(D, computation); > + return getLVForNamespaceScopeDecl(D, computation, > IgnoreVarTypeLinkage); > > // C++ [basic.link]p5: > // In addition, a member function, static data member, a named > @@ -1313,7 +1318,7 @@ LinkageInfo LinkageComputer::computeLVFo > // purposes (7.1.3), has external linkage if the name of the class > // has external linkage. > if (D->getDeclContext()->isRecord()) > - return getLVForClassMember(D, computation); > + return getLVForClassMember(D, computation, IgnoreVarTypeLinkage); > > // C++ [basic.link]p6: > // The name of a function declared in block scope and the name of > > Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=313955&r1=313954&r2=313955&view=diff > > ============================================================================== > --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original) > +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Thu Sep 21 21:25:05 2017 > @@ -1691,10 +1691,16 @@ void CXXNameMangler::mangleLambda(const > // to emit that last part of the prefix here. > if (Decl *Context = Lambda->getLambdaContextDecl()) { > if ((isa<VarDecl>(Context) || isa<FieldDecl>(Context)) && > - Context->getDeclContext()->isRecord()) { > + !isa<ParmVarDecl>(Context)) { > + // FIXME: 'inline auto [a, b] = []{ return ... };' does not get a > + // reasonable mangling here. > if (const IdentifierInfo *Name > = cast<NamedDecl>(Context)->getIdentifier()) { > mangleSourceName(Name); > + const TemplateArgumentList *TemplateArgs = nullptr; > + if (const TemplateDecl *TD = > + isTemplate(cast<NamedDecl>(Context), TemplateArgs)) > + mangleTemplateArgs(*TemplateArgs); > Out << 'M'; > } > } > > Modified: cfe/trunk/lib/AST/Linkage.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Linkage.h?rev=313955&r1=313954&r2=313955&view=diff > > ============================================================================== > --- cfe/trunk/lib/AST/Linkage.h (original) > +++ cfe/trunk/lib/AST/Linkage.h Thu Sep 21 21:25:05 2017 > @@ -117,10 +117,12 @@ class LinkageComputer { > LVComputationKind computation); > > LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, > - LVComputationKind computation); > + LVComputationKind computation, > + bool IgnoreVarTypeLinkage); > > LinkageInfo getLVForClassMember(const NamedDecl *D, > - LVComputationKind computation); > + LVComputationKind computation, > + bool IgnoreVarTypeLinkage); > > LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl, > LVComputationKind computation); > @@ -135,7 +137,8 @@ class LinkageComputer { > > public: > LinkageInfo computeLVForDecl(const NamedDecl *D, > - LVComputationKind computation); > + LVComputationKind computation, > + bool IgnoreVarTypeLinkage = false); > > LinkageInfo getLVForDecl(const NamedDecl *D, LVComputationKind > computation); > > > Modified: cfe/trunk/lib/Parse/ParseDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=313955&r1=313954&r2=313955&view=diff > > ============================================================================== > --- cfe/trunk/lib/Parse/ParseDecl.cpp (original) > +++ cfe/trunk/lib/Parse/ParseDecl.cpp Thu Sep 21 21:25:05 2017 > @@ -2131,6 +2131,37 @@ Decl *Parser::ParseDeclarationAfterDecla > > Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( > Declarator &D, const ParsedTemplateInfo &TemplateInfo, ForRangeInit > *FRI) { > + // RAII type used to track whether we're inside an initializer. > + struct InitializerScopeRAII { > + Parser &P; > + Declarator &D; > + Decl *ThisDecl; > + > + InitializerScopeRAII(Parser &P, Declarator &D, Decl *ThisDecl) > + : P(P), D(D), ThisDecl(ThisDecl) { > + if (ThisDecl && P.getLangOpts().CPlusPlus) { > + Scope *S = nullptr; > + if (D.getCXXScopeSpec().isSet()) { > + P.EnterScope(0); > + S = P.getCurScope(); > + } > + P.Actions.ActOnCXXEnterDeclInitializer(S, ThisDecl); > + } > + } > + ~InitializerScopeRAII() { pop(); } > + void pop() { > + if (ThisDecl && P.getLangOpts().CPlusPlus) { > + Scope *S = nullptr; > + if (D.getCXXScopeSpec().isSet()) > + S = P.getCurScope(); > + P.Actions.ActOnCXXExitDeclInitializer(S, ThisDecl); > + if (S) > + P.ExitScope(); > + } > + ThisDecl = nullptr; > + } > + }; > + > // Inform the current actions module that we just parsed this > declarator. > Decl *ThisDecl = nullptr; > switch (TemplateInfo.Kind) { > @@ -2208,10 +2239,7 @@ Decl *Parser::ParseDeclarationAfterDecla > else > Diag(ConsumeToken(), diag::err_default_special_members); > } else { > - if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { > - EnterScope(0); > - Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); > - } > + InitializerScopeRAII InitScope(*this, D, ThisDecl); > > if (Tok.is(tok::code_completion)) { > Actions.CodeCompleteInitializer(getCurScope(), ThisDecl); > @@ -2234,10 +2262,7 @@ Decl *Parser::ParseDeclarationAfterDecla > FRI->RangeExpr = Init; > } > > - if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { > - Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); > - ExitScope(); > - } > + InitScope.pop(); > > if (Init.isInvalid()) { > SmallVector<tok::TokenKind, 2> StopTokens; > @@ -2259,10 +2284,7 @@ Decl *Parser::ParseDeclarationAfterDecla > ExprVector Exprs; > CommaLocsTy CommaLocs; > > - if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { > - EnterScope(0); > - Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); > - } > + InitializerScopeRAII InitScope(*this, D, ThisDecl); > > llvm::function_ref<void()> ExprListCompleter; > auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl); > @@ -2283,11 +2305,6 @@ Decl *Parser::ParseDeclarationAfterDecla > if (ParseExpressionList(Exprs, CommaLocs, ExprListCompleter)) { > Actions.ActOnInitializerError(ThisDecl); > SkipUntil(tok::r_paren, StopAtSemi); > - > - if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { > - Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); > - ExitScope(); > - } > } else { > // Match the ')'. > T.consumeClose(); > @@ -2295,10 +2312,7 @@ Decl *Parser::ParseDeclarationAfterDecla > assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() && > "Unexpected number of commas!"); > > - if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { > - Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); > - ExitScope(); > - } > + InitScope.pop(); > > ExprResult Initializer = > Actions.ActOnParenListExpr(T.getOpenLocation(), > > T.getCloseLocation(), > @@ -2311,17 +2325,11 @@ Decl *Parser::ParseDeclarationAfterDecla > // Parse C++0x braced-init-list. > Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); > > - if (D.getCXXScopeSpec().isSet()) { > - EnterScope(0); > - Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); > - } > + InitializerScopeRAII InitScope(*this, D, ThisDecl); > > ExprResult Init(ParseBraceInitializer()); > > - if (D.getCXXScopeSpec().isSet()) { > - Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); > - ExitScope(); > - } > + InitScope.pop(); > > if (Init.isInvalid()) { > Actions.ActOnInitializerError(ThisDecl); > > Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=313955&r1=313954&r2=313955&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Sep 21 21:25:05 2017 > @@ -14256,21 +14256,22 @@ void Sema::ActOnPureSpecifier(Decl *D, S > Diag(D->getLocation(), diag::err_illegal_initializer); > } > > -/// \brief Determine whether the given declaration is a static data > member. > -static bool isStaticDataMember(const Decl *D) { > +/// \brief Determine whether the given declaration is a global variable or > +/// static data member. > +static bool isNonlocalVariable(const Decl *D) { > if (const VarDecl *Var = dyn_cast_or_null<VarDecl>(D)) > - return Var->isStaticDataMember(); > + return Var->hasGlobalStorage(); > > return false; > } > > -/// ActOnCXXEnterDeclInitializer - Invoked when we are about to parse > -/// an initializer for the out-of-line declaration 'Dcl'. The scope > -/// is a fresh scope pushed for just this purpose. > +/// Invoked when we are about to parse an initializer for the declaration > +/// 'Dcl'. > /// > /// After this method is called, according to [C++ 3.4.1p13], if 'Dcl' is > a > /// static data member of class X, names should be looked up in the scope > of > -/// class X. > +/// class X. If the declaration had a scope specifier, a scope will have > +/// been created and passed in for this purpose. Otherwise, S will be > null. > void Sema::ActOnCXXEnterDeclInitializer(Scope *S, Decl *D) { > // If there is no declaration, there was an error parsing it. > if (!D || D->isInvalidDecl()) > @@ -14280,28 +14281,27 @@ void Sema::ActOnCXXEnterDeclInitializer( > // might not be out of line if the specifier names the current > namespace: > // extern int n; > // int ::n = 0; > - if (D->isOutOfLine()) > + if (S && D->isOutOfLine()) > EnterDeclaratorContext(S, D->getDeclContext()); > > // If we are parsing the initializer for a static data member, push a > // new expression evaluation context that is associated with this static > // data member. > - if (isStaticDataMember(D)) > + if (isNonlocalVariable(D)) > PushExpressionEvaluationContext( > ExpressionEvaluationContext::PotentiallyEvaluated, D); > } > > -/// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an > -/// initializer for the out-of-line declaration 'D'. > +/// Invoked after we are finished parsing an initializer for the > declaration D. > void Sema::ActOnCXXExitDeclInitializer(Scope *S, Decl *D) { > // If there is no declaration, there was an error parsing it. > if (!D || D->isInvalidDecl()) > return; > > - if (isStaticDataMember(D)) > + if (isNonlocalVariable(D)) > PopExpressionEvaluationContext(); > > - if (D->isOutOfLine()) > + if (S && D->isOutOfLine()) > ExitDeclaratorContext(S); > } > > > Modified: cfe/trunk/lib/Sema/SemaLambda.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=313955&r1=313954&r2=313955&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaLambda.cpp (original) > +++ cfe/trunk/lib/Sema/SemaLambda.cpp Thu Sep 21 21:25:05 2017 > @@ -288,7 +288,9 @@ Sema::getCurrentMangleNumberContext(cons > Normal, > DefaultArgument, > DataMember, > - StaticDataMember > + StaticDataMember, > + InlineVariable, > + VariableTemplate > } Kind = Normal; > > // Default arguments of member function parameters that appear in a > class > @@ -303,6 +305,14 @@ Sema::getCurrentMangleNumberContext(cons > } else if (VarDecl *Var = dyn_cast<VarDecl>(ManglingContextDecl)) { > if (Var->getDeclContext()->isRecord()) > Kind = StaticDataMember; > + else if (Var->getMostRecentDecl()->isInline()) > + Kind = InlineVariable; > + else if (Var->getDescribedVarTemplate()) > + Kind = VariableTemplate; > + else if (auto *VTS = dyn_cast<VarTemplateSpecializationDecl>(Var)) { > + if (!VTS->isExplicitSpecialization()) > + Kind = VariableTemplate; > + } > } else if (isa<FieldDecl>(ManglingContextDecl)) { > Kind = DataMember; > } > @@ -343,6 +353,10 @@ Sema::getCurrentMangleNumberContext(cons > // -- the in-class initializers of class members > case DefaultArgument: > // -- default arguments appearing in class definitions > + case InlineVariable: > + // -- the initializers of inline variables > + case VariableTemplate: > + // -- the initializers of templated variables > return &ExprEvalContexts.back().getMangleNumberingContext(Context); > } > > > Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=313955&r1=313954&r2=313955&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original) > +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Thu Sep 21 21:25:05 > 2017 > @@ -4140,12 +4140,8 @@ void Sema::InstantiateVariableInitialize > Var->setImplicitlyInline(); > > if (OldVar->getInit()) { > - if (Var->isStaticDataMember() && !OldVar->isOutOfLine()) > - PushExpressionEvaluationContext( > - Sema::ExpressionEvaluationContext::ConstantEvaluated, OldVar); > - else > - PushExpressionEvaluationContext( > - Sema::ExpressionEvaluationContext::PotentiallyEvaluated, > OldVar); > + EnterExpressionEvaluationContext Evaluated( > + *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, > Var); > > // Instantiate the initializer. > ExprResult Init; > @@ -4173,8 +4169,6 @@ void Sema::InstantiateVariableInitialize > // because of a bogus initializer. > Var->setInvalidDecl(); > } > - > - PopExpressionEvaluationContext(); > } else { > if (Var->isStaticDataMember()) { > if (!Var->isOutOfLine()) > > Modified: cfe/trunk/test/CodeGenCXX/mangle-lambdas.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-lambdas.cpp?rev=313955&r1=313954&r2=313955&view=diff > > ============================================================================== > --- cfe/trunk/test/CodeGenCXX/mangle-lambdas.cpp (original) > +++ cfe/trunk/test/CodeGenCXX/mangle-lambdas.cpp Thu Sep 21 21:25:05 2017 > @@ -26,6 +26,24 @@ void call_inline_func() { > inline_func(17); > } > > +// CHECK-LABEL: define linkonce_odr i32* @_ZNK10inline_varMUlvE_clEv( > +// CHECK: @_ZZNK10inline_varMUlvE_clEvE1n > +inline auto inline_var = [] { > + static int n = 5; > + return &n; > +}; > + > +int *use_inline_var = inline_var(); > + > +// CHECK-LABEL: define linkonce_odr i32* @_ZNK12var_templateIiEMUlvE_clEv( > +// CHECK: @_ZZNK12var_templateIiEMUlvE_clEvE1n > +template<typename T> auto var_template = [] { > + static int n = 9; > + return &n; > +}; > + > +int *use_var_template = var_template<int>(); > + > struct S { > void f(int = []{return 1;}() > + []{return 2;}(), > @@ -118,7 +136,7 @@ T StaticMembers<T>::z = accept_lambda([] > template<typename T> > int (*StaticMembers<T>::f)() = []{return 5;}; > > -// CHECK-LABEL: define internal void @__cxx_global_var_init() > +// CHECK-LABEL: define internal void @__cxx_global_var_init > // CHECK: call i32 @_ZNK13StaticMembersIfE1xMUlvE_clEv > // CHECK-NEXT: call i32 @_ZNK13StaticMembersIfE1xMUlvE0_clEv > // CHECK-NEXT: add nsw > @@ -128,23 +146,23 @@ int (*StaticMembers<T>::f)() = []{return > // CHECK: ret i32 2 > template float StaticMembers<float>::x; > > -// CHECK-LABEL: define internal void @__cxx_global_var_init.1() > +// CHECK-LABEL: define internal void @__cxx_global_var_init > // CHECK: call i32 @_ZNK13StaticMembersIfE1yMUlvE_clEv > // CHECK-LABEL: define linkonce_odr i32 > @_ZNK13StaticMembersIfE1yMUlvE_clEv > // CHECK: ret i32 3 > template float StaticMembers<float>::y; > > -// CHECK-LABEL: define internal void @__cxx_global_var_init.2() > +// CHECK-LABEL: define internal void @__cxx_global_var_init > // CHECK: call i32 @_Z13accept_lambdaIN13StaticMembersIfE1zMUlvE_EEiT_ > // CHECK: declare i32 > @_Z13accept_lambdaIN13StaticMembersIfE1zMUlvE_EEiT_() > template float StaticMembers<float>::z; > > -// CHECK-LABEL: define internal void @__cxx_global_var_init.3() > +// CHECK-LABEL: define internal void @__cxx_global_var_init > // CHECK: call {{.*}} @_ZNK13StaticMembersIfE1fMUlvE_cvPFivEEv > // CHECK-LABEL: define linkonce_odr i32 ()* > @_ZNK13StaticMembersIfE1fMUlvE_cvPFivEEv > template int (*StaticMembers<float>::f)(); > > -// CHECK-LABEL: define internal void @__cxx_global_var_init.4 > +// CHECK-LABEL: define internal void @__cxx_global_var_init > // CHECK: call i32 @"_ZNK13StaticMembersIdE3$_2clEv" > // CHECK-LABEL: define internal i32 @"_ZNK13StaticMembersIdE3$_2clEv" > // CHECK: ret i32 42 > > Modified: cfe/trunk/test/SemaCXX/vartemplate-lambda.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/vartemplate-lambda.cpp?rev=313955&r1=313954&r2=313955&view=diff > > ============================================================================== > --- cfe/trunk/test/SemaCXX/vartemplate-lambda.cpp (original) > +++ cfe/trunk/test/SemaCXX/vartemplate-lambda.cpp Thu Sep 21 21:25:05 2017 > @@ -8,7 +8,7 @@ template<typename T> auto v1 = [](int a > > struct S { > template<class T> > - static constexpr T t = [](int f = T(7)){return f;}(); // > expected-error{{constexpr variable 't<int>' must be initialized by a > constant expression}} expected-error{{a lambda expression may not appear > inside of a constant expression}} expected-note{{cannot be used in a > constant expression}} > + static constexpr T t = [](int f = T(7)){return f;}(); // > expected-error{{constexpr variable 't<int>' must be initialized by a > constant expression}} expected-note{{cannot be used in a constant > expression}} > }; > > template <typename X> > > Modified: cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp?rev=313955&r1=313954&r2=313955&view=diff > > ============================================================================== > --- cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp (original) > +++ cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp Thu Sep 21 > 21:25:05 2017 > @@ -5,7 +5,7 @@ > template<typename T, T Divisor> > class X { > public: > - static const T value = 10 / Divisor; // expected-error{{in-class > initializer for static data member is not a constant expression}} > + static const T value = 10 / Divisor; // expected-error{{in-class > initializer for static data member is not a constant expression}} > expected-warning {{division by zero}} > }; > > int array1[X<int, 2>::value == 5? 1 : -1]; > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits