r313827 - Give external linkage and mangling to lambdas inside inline variables and variable templates.
Vitaly Buka via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 20 19:53:50 PDT 2017
reverted by r313856
On Wed, Sep 20, 2017 at 6:30 PM, Richard Smith <richard at 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 at 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 at 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 at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>>
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170920/b695fe74/attachment-0001.html>
More information about the cfe-commits
mailing list