r313856 - Revert "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:51:56 PDT 2017
Author: vitalybuka
Date: Wed Sep 20 19:51:56 2017
New Revision: 313856
URL: http://llvm.org/viewvc/llvm-project?rev=313856&view=rev
Log:
Revert "Give external linkage and mangling to lambdas inside inline variables and variable templates."
To fix: runtime error: load of value 15, which is not a valid value for type 'clang::LVComputationKind'
This reverts commit r313827.
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=313856&r1=313855&r2=313856&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Wed Sep 20 19:51:56 2017
@@ -676,10 +676,10 @@ LinkageComputer::getLVForNamespaceScopeD
if (!LV.isVisibilityExplicit()) {
// Use global type/value visibility as appropriate.
Visibility globalVisibility;
- if ((computation & ~IgnoreTypeLinkageBit) == LVForValue) {
+ if (computation == LVForValue) {
globalVisibility = Context.getLangOpts().getValueVisibilityMode();
} else {
- assert((computation & ~IgnoreTypeLinkageBit) == LVForType);
+ assert(computation == LVForType);
globalVisibility = Context.getLangOpts().getTypeVisibilityMode();
}
LV.mergeVisibility(globalVisibility, /*explicit*/ false);
@@ -719,8 +719,7 @@ 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) &&
- !(computation & IgnoreTypeLinkageBit)) {
+ if (Context.getLangOpts().CPlusPlus && !isFirstInExternCContext(Var)) {
LinkageInfo TypeLV = getLVForType(*Var->getType(), computation);
if (!isExternallyVisible(TypeLV.getLinkage()))
return LinkageInfo::uniqueExternal();
@@ -760,8 +759,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() &&
- !(computation & IgnoreTypeLinkageBit)) {
+ 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
@@ -1123,18 +1122,8 @@ 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=313856&r1=313855&r2=313856&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Wed Sep 20 19:51:56 2017
@@ -1691,16 +1691,10 @@ 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)) &&
- !isa<ParmVarDecl>(Context)) {
- // FIXME: 'inline auto [a, b] = []{ return ... };' does not get a
- // reasonable mangling here.
+ Context->getDeclContext()->isRecord()) {
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=313856&r1=313855&r2=313856&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Linkage.h (original)
+++ cfe/trunk/lib/AST/Linkage.h Wed Sep 20 19:51:56 2017
@@ -24,8 +24,7 @@
namespace clang {
enum : unsigned {
IgnoreExplicitVisibilityBit = 2,
- IgnoreAllVisibilityBit = 4,
- IgnoreTypeLinkageBit = 8,
+ IgnoreAllVisibilityBit = 4
};
/// 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=313856&r1=313855&r2=313856&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed Sep 20 19:51:56 2017
@@ -2131,37 +2131,6 @@ 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) {
@@ -2239,7 +2208,10 @@ Decl *Parser::ParseDeclarationAfterDecla
else
Diag(ConsumeToken(), diag::err_default_special_members);
} else {
- InitializerScopeRAII InitScope(*this, D, ThisDecl);
+ if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
+ EnterScope(0);
+ Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
+ }
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteInitializer(getCurScope(), ThisDecl);
@@ -2262,7 +2234,10 @@ Decl *Parser::ParseDeclarationAfterDecla
FRI->RangeExpr = Init;
}
- InitScope.pop();
+ if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
+ Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
+ ExitScope();
+ }
if (Init.isInvalid()) {
SmallVector<tok::TokenKind, 2> StopTokens;
@@ -2284,7 +2259,10 @@ Decl *Parser::ParseDeclarationAfterDecla
ExprVector Exprs;
CommaLocsTy CommaLocs;
- InitializerScopeRAII InitScope(*this, D, ThisDecl);
+ if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
+ EnterScope(0);
+ Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
+ }
llvm::function_ref<void()> ExprListCompleter;
auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
@@ -2305,6 +2283,11 @@ 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();
@@ -2312,7 +2295,10 @@ Decl *Parser::ParseDeclarationAfterDecla
assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&
"Unexpected number of commas!");
- InitScope.pop();
+ if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
+ Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
+ ExitScope();
+ }
ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(),
T.getCloseLocation(),
@@ -2325,11 +2311,17 @@ Decl *Parser::ParseDeclarationAfterDecla
// Parse C++0x braced-init-list.
Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
- InitializerScopeRAII InitScope(*this, D, ThisDecl);
+ if (D.getCXXScopeSpec().isSet()) {
+ EnterScope(0);
+ Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
+ }
ExprResult Init(ParseBraceInitializer());
- InitScope.pop();
+ if (D.getCXXScopeSpec().isSet()) {
+ Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
+ ExitScope();
+ }
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=313856&r1=313855&r2=313856&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Sep 20 19:51:56 2017
@@ -14243,22 +14243,21 @@ void Sema::ActOnPureSpecifier(Decl *D, S
Diag(D->getLocation(), diag::err_illegal_initializer);
}
-/// \brief Determine whether the given declaration is a global variable or
-/// static data member.
-static bool isNonlocalVariable(const Decl *D) {
+/// \brief Determine whether the given declaration is a static data member.
+static bool isStaticDataMember(const Decl *D) {
if (const VarDecl *Var = dyn_cast_or_null<VarDecl>(D))
- return Var->hasGlobalStorage();
+ return Var->isStaticDataMember();
return false;
}
-/// Invoked when we are about to parse an initializer for the declaration
-/// 'Dcl'.
+/// 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.
///
/// 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. If the declaration had a scope specifier, a scope will have
-/// been created and passed in for this purpose. Otherwise, S will be null.
+/// class X.
void Sema::ActOnCXXEnterDeclInitializer(Scope *S, Decl *D) {
// If there is no declaration, there was an error parsing it.
if (!D || D->isInvalidDecl())
@@ -14268,27 +14267,28 @@ void Sema::ActOnCXXEnterDeclInitializer(
// might not be out of line if the specifier names the current namespace:
// extern int n;
// int ::n = 0;
- if (S && D->isOutOfLine())
+ if (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 (isNonlocalVariable(D))
+ if (isStaticDataMember(D))
PushExpressionEvaluationContext(
ExpressionEvaluationContext::PotentiallyEvaluated, D);
}
-/// Invoked after we are finished parsing an initializer for the declaration D.
+/// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an
+/// initializer for the out-of-line 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 (isNonlocalVariable(D))
+ if (isStaticDataMember(D))
PopExpressionEvaluationContext();
- if (S && D->isOutOfLine())
+ if (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=313856&r1=313855&r2=313856&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLambda.cpp Wed Sep 20 19:51:56 2017
@@ -288,9 +288,7 @@ Sema::getCurrentMangleNumberContext(cons
Normal,
DefaultArgument,
DataMember,
- StaticDataMember,
- InlineVariable,
- VariableTemplate
+ StaticDataMember
} Kind = Normal;
// Default arguments of member function parameters that appear in a class
@@ -305,14 +303,6 @@ 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;
}
@@ -353,10 +343,6 @@ 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=313856&r1=313855&r2=313856&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Sep 20 19:51:56 2017
@@ -4140,8 +4140,12 @@ void Sema::InstantiateVariableInitialize
Var->setImplicitlyInline();
if (OldVar->getInit()) {
- EnterExpressionEvaluationContext Evaluated(
- *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, Var);
+ if (Var->isStaticDataMember() && !OldVar->isOutOfLine())
+ PushExpressionEvaluationContext(
+ Sema::ExpressionEvaluationContext::ConstantEvaluated, OldVar);
+ else
+ PushExpressionEvaluationContext(
+ Sema::ExpressionEvaluationContext::PotentiallyEvaluated, OldVar);
// Instantiate the initializer.
ExprResult Init;
@@ -4169,6 +4173,8 @@ 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=313856&r1=313855&r2=313856&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-lambdas.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-lambdas.cpp Wed Sep 20 19:51:56 2017
@@ -26,24 +26,6 @@ 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;}(),
@@ -136,7 +118,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
@@ -146,23 +128,23 @@ int (*StaticMembers<T>::f)() = []{return
// CHECK: ret i32 2
template float StaticMembers<float>::x;
-// CHECK-LABEL: define internal void @__cxx_global_var_init
+// CHECK-LABEL: define internal void @__cxx_global_var_init.1()
// 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
+// CHECK-LABEL: define internal void @__cxx_global_var_init.2()
// 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
+// CHECK-LABEL: define internal void @__cxx_global_var_init.3()
// 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
+// CHECK-LABEL: define internal void @__cxx_global_var_init.4
// 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=313856&r1=313855&r2=313856&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/vartemplate-lambda.cpp (original)
+++ cfe/trunk/test/SemaCXX/vartemplate-lambda.cpp Wed Sep 20 19:51:56 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-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-error{{a lambda expression may not appear inside of 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=313856&r1=313855&r2=313856&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp Wed Sep 20 19:51:56 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}} expected-warning {{division by zero}}
+ static const T value = 10 / Divisor; // expected-error{{in-class initializer for static data member is not a constant expression}}
};
int array1[X<int, 2>::value == 5? 1 : -1];
More information about the cfe-commits
mailing list