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 17:38:24 PDT 2017
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.cpp?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().
> getValueVisibilityMode();
> } else {
> - assert(computation == LVForType);
> + assert((computation & ~IgnoreTypeLinkageBit) == LVForType);
> globalVisibility = Context.getLangOpts().getTypeVisibilityMode();
> }
> 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/
> ItaniumMangle.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/
> Linkage.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/
> ParseDecl.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.
> 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=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/
> SemaLambda.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/
> SemaTemplateInstantiateDecl.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/
> CodeGenCXX/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_
> 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_lambdaIN13StaticMembersIfE1zMU
> lvE_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=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/
> SemaTemplate/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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170920/475007af/attachment-0001.html>
More information about the cfe-commits
mailing list