reverted by r313856 On Wed, Sep 20, 2017 at 6:30 PM, Richard Smith <rich...@metafoo.co.uk> wrote:
> Thanks, I'll fix this tomorrow; if that's not soon enough, please go ahead > and revert (or fix by adding a dummy enumerator in lib/AST/Linkage.h). > > On 20 Sep 2017 17:39, "Vitaly Buka via cfe-commits" < > cfe-commits@lists.llvm.org> wrote: > >> http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/8038/steps/check-clang%20ubsan/logs/stdio >> >> >> -- >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/AST/Decl.cpp:1333:42: >> runtime error: load of value 15, which is not a valid value for type >> 'clang::LVComputationKind' >> #0 0x7084fd9 in >> clang::LinkageComputer::computeLVForDecl(clang::NamedDecl const*, >> clang::LVComputationKind) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/AST/Decl.cpp:1333:42 >> #1 0x7085874 in >> clang::LinkageComputer::getLVForClosure(clang::DeclContext const*, >> clang::Decl*, clang::LVComputationKind) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/AST/Decl.cpp:1135:14 >> #2 0x708224e in clang::LinkageComputer::getLVForDecl(clang::NamedDecl >> const*, clang::LVComputationKind) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/AST/Decl.cpp:1377:20 >> #3 0x7085242 in clang::NamedDecl::getLinkageInternal() const >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/AST/Decl.cpp:1036:28 >> #4 0x731c021 in computeCachedProperties(clang::Type const*) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/AST/Type.cpp:3379:22 >> #5 0x7311b2d in clang::TypePropertyCache<(anonymous >> namespace)::Private>::ensure(clang::Type const*) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/AST/Type.cpp:3330:31 >> #6 0x7311bb2 in clang::TypePropertyCache<(anonymous >> namespace)::Private>::ensure(clang::Type const*) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/AST/Type.cpp:3322:7 >> #7 0x7311a8f in clang::Type::getLinkage() const >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/AST/Type.cpp:3438:3 >> #8 0x7081a61 in clang::LinkageComputer::getLVForType(clang::Type const&, >> clang::LVComputationKind) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/AST/Decl.cpp:194:26 >> #9 0x70831d3 in >> clang::LinkageComputer::getLVForNamespaceScopeDecl(clang::NamedDecl const*, >> clang::LVComputationKind) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/AST/Decl.cpp:724:28 >> #10 0x708224e in clang::LinkageComputer::getLVForDecl(clang::NamedDecl >> const*, clang::LVComputationKind) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/AST/Decl.cpp:1377:20 >> #11 0x7085242 in clang::NamedDecl::getLinkageInternal() const >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/AST/Decl.cpp:1036:28 >> #12 0x38d3ddd in clang::NamedDecl::isExternallyVisible() const >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/include/clang/AST/Decl.h:339:39 >> #13 0x5a69da3 in >> clang::Sema::CheckCompleteVariableDeclaration(clang::VarDecl*) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Sema/SemaDecl.cpp:11042:12 >> #14 0x5a693c9 in clang::Sema::AddInitializerToDecl(clang::Decl*, >> clang::Expr*, bool) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Sema/SemaDecl.cpp:10645:3 >> #15 0x555b6d1 in >> clang::Parser::ParseDeclarationAfterDeclaratorAndAttributes(clang::Declarator&, >> clang::Parser::ParsedTemplateInfo const&, clang::Parser::ForRangeInit*) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Parse/ParseDecl.cpp:2276:17 >> #16 0x5559ce1 in clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, >> unsigned int, clang::SourceLocation*, clang::Parser::ForRangeInit*) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Parse/ParseDecl.cpp:2013:21 >> #17 0x553611a in >> clang::Parser::ParseDeclOrFunctionDefInternal(clang::Parser::ParsedAttributesWithRange&, >> clang::ParsingDeclSpec&, clang::AccessSpecifier) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Parse/Parser.cpp:979:10 >> #18 0x55359a2 in >> clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsedAttributesWithRange&, >> clang::ParsingDeclSpec*, clang::AccessSpecifier) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Parse/Parser.cpp:995:12 >> #19 0x5534fbf in >> clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange&, >> clang::ParsingDeclSpec*) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Parse/Parser.cpp:845:12 >> #20 0x553431c in >> clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Parse/Parser.cpp:613:12 >> #21 0x552f0e0 in clang::ParseAST(clang::Sema&, bool, bool) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Parse/ParseAST.cpp:147:18 >> #22 0x4045c32 in clang::FrontendAction::Execute() >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Frontend/FrontendAction.cpp:897:8 >> #23 0x3fd2d44 in >> clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp:990:11 >> #24 0x41db8cc in >> clang::ExecuteCompilerInvocation(clang::CompilerInstance*) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:252:25 >> #25 0xec2ebe in cc1_main(llvm::ArrayRef<char const*>, char const*, >> void*) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/driver/cc1_main.cpp:221:13 >> #26 0xeb5153 in ExecuteCC1Tool(llvm::ArrayRef<char const*>, >> llvm::StringRef) >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/driver/driver.cpp:309:12 >> #27 0xeb447c in main >> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/driver/driver.cpp:388:12 >> #28 0x7fef65b7182f in __libc_start_main >> (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) >> #29 0xe8ea68 in _start >> (/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm_build_ubsan/bin/clang-6.0+0xe8ea68) >> >> >> On Wed, Sep 20, 2017 at 3:17 PM, Richard Smith via cfe-commits < >> cfe-commits@lists.llvm.org> wrote: >> >>> Author: rsmith >>> Date: Wed Sep 20 15:17:55 2017 >>> New Revision: 313827 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=313827&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 >>> >>> 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.c >>> pp?rev=313827&r1=313826&r2=313827&view=diff >>> ============================================================ >>> ================== >>> --- cfe/trunk/lib/AST/Decl.cpp (original) >>> +++ cfe/trunk/lib/AST/Decl.cpp Wed Sep 20 15:17:55 2017 >>> @@ -676,10 +676,10 @@ LinkageComputer::getLVForNamespaceScopeD >>> if (!LV.isVisibilityExplicit()) { >>> // Use global type/value visibility as appropriate. >>> Visibility globalVisibility; >>> - if (computation == LVForValue) { >>> + if ((computation & ~IgnoreTypeLinkageBit) == LVForValue) { >>> globalVisibility = Context.getLangOpts().getValue >>> VisibilityMode(); >>> } else { >>> - assert(computation == LVForType); >>> + assert((computation & ~IgnoreTypeLinkageBit) == LVForType); >>> globalVisibility = Context.getLangOpts().getTypeV >>> isibilityMode(); >>> } >>> LV.mergeVisibility(globalVisibility, /*explicit*/ false); >>> @@ -719,7 +719,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) && >>> + !(computation & IgnoreTypeLinkageBit)) { >>> LinkageInfo TypeLV = getLVForType(*Var->getType(), computation); >>> if (!isExternallyVisible(TypeLV.getLinkage())) >>> return LinkageInfo::uniqueExternal(); >>> @@ -759,8 +760,8 @@ 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()) { >>> + if (Context.getLangOpts().CPlusPlus && >>> !Function->isInExternCContext() && >>> + !(computation & IgnoreTypeLinkageBit)) { >>> // 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 >>> @@ -1122,8 +1123,18 @@ LinkageInfo LinkageComputer::getLVForClo >>> // calculation determines the lambda has external linkage, it should >>> be >>> // downgraded to VisibleNoLinkage. >>> if (ContextDecl) { >>> + auto *VD = dyn_cast<VarDecl>(ContextDecl); >>> if (isa<ParmVarDecl>(ContextDecl)) >>> DC = ContextDecl->getDeclContext()->getRedeclContext(); >>> + else if (VD && VD->getType()->getContainedDeducedType()) >>> + // If the declaration 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. >>> + return computeLVForDecl( >>> + cast<NamedDecl>(ContextDecl), >>> + LVComputationKind(computation | IgnoreTypeLinkageBit)); >>> else >>> return getLVForDecl(cast<NamedDecl>(ContextDecl), computation); >>> } >>> >>> Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp >>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Itaniu >>> mMangle.cpp?rev=313827&r1=313826&r2=313827&view=diff >>> ============================================================ >>> ================== >>> --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original) >>> +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Wed Sep 20 15:17:55 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/Linkag >>> e.h?rev=313827&r1=313826&r2=313827&view=diff >>> ============================================================ >>> ================== >>> --- cfe/trunk/lib/AST/Linkage.h (original) >>> +++ cfe/trunk/lib/AST/Linkage.h Wed Sep 20 15:17:55 2017 >>> @@ -24,7 +24,8 @@ >>> namespace clang { >>> enum : unsigned { >>> IgnoreExplicitVisibilityBit = 2, >>> - IgnoreAllVisibilityBit = 4 >>> + IgnoreAllVisibilityBit = 4, >>> + IgnoreTypeLinkageBit = 8, >>> }; >>> >>> /// Kinds of LV computation. The linkage side of the computation is >>> >>> Modified: cfe/trunk/lib/Parse/ParseDecl.cpp >>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Pars >>> eDecl.cpp?rev=313827&r1=313826&r2=313827&view=diff >>> ============================================================ >>> ================== >>> --- cfe/trunk/lib/Parse/ParseDecl.cpp (original) >>> +++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed Sep 20 15:17:55 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.g >>> etOpenLocation(), >>> >>> 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/SemaD >>> eclCXX.cpp?rev=313827&r1=313826&r2=313827&view=diff >>> ============================================================ >>> ================== >>> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) >>> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Sep 20 15:17:55 2017 >>> @@ -14240,21 +14240,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()) >>> @@ -14264,28 +14265,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/SemaL >>> ambda.cpp?rev=313827&r1=313826&r2=313827&view=diff >>> ============================================================ >>> ================== >>> --- cfe/trunk/lib/Sema/SemaLambda.cpp (original) >>> +++ cfe/trunk/lib/Sema/SemaLambda.cpp Wed Sep 20 15:17:55 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/SemaT >>> emplateInstantiateDecl.cpp?rev=313827&r1=313826&r2=313827&view=diff >>> ============================================================ >>> ================== >>> --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original) >>> +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Sep 20 >>> 15:17:55 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/CodeGenCX >>> X/mangle-lambdas.cpp?rev=313827&r1=313826&r2=313827&view=diff >>> ============================================================ >>> ================== >>> --- cfe/trunk/test/CodeGenCXX/mangle-lambdas.cpp (original) >>> +++ cfe/trunk/test/CodeGenCXX/mangle-lambdas.cpp Wed Sep 20 15:17:55 >>> 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_cl >>> Ev( >>> +// 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_lambdaIN13StaticMe >>> mbersIfE1zMUlvE_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/v >>> artemplate-lambda.cpp?rev=313827&r1=313826&r2=313827&view=diff >>> ============================================================ >>> ================== >>> --- cfe/trunk/test/SemaCXX/vartemplate-lambda.cpp (original) >>> +++ cfe/trunk/test/SemaCXX/vartemplate-lambda.cpp Wed Sep 20 15:17:55 >>> 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/SemaTempl >>> ate/instantiate-static-var.cpp?rev=313827&r1=313826&r2=313827&view=diff >>> ============================================================ >>> ================== >>> --- cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp (original) >>> +++ cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp Wed Sep 20 >>> 15:17:55 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 >> >>
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits