[PATCH] D29233: Fix linkage of static locals in available_externally functions to be DiscardableODR/linkonce_odr

David Blaikie via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 27 14:43:39 PST 2017


On Fri, Jan 27, 2017 at 2:13 PM Mehdi Amini <mehdi.amini at apple.com> wrote:

> CC Hans.
>
> This is not a regression (AFAICT), but this is a quality improvement, so
> may be worth considering in the 4.0 branch?
>

Perhaps - I'd generally err on the "if it's not a regression, don't hold
the boat". LLVM's been this way for a while (good question as to how long -
looks like at the latest it was introduced in April 2014 (
https://llvm.org/svn/llvm-project/cfe/trunk@207451,
http://reviews.llvm.org/D3515) & no one's noticed). But no big deal either
way if other's feel like it ought to go in.


>
>> Mehdi
>
> > On Jan 27, 2017, at 2:04 PM, David Blaikie via Phabricator <
> reviews at reviews.llvm.org> wrote:
> >
> > dblaikie created this revision.
> >
> > As Mehdi put it, entities should either be
> > available_externally+weak_odr, or linkonce_odr+linkonce_odr. While some
> > functions are emitted a_e/weak, their local variables were emitted
> > a_e/linkonce_odr.
> >
> > While it might be nice to emit them a_e/weak, the Itanium ABI (& best
> > guess at MSVC's behavior as well) requires the local to be
> > linkonce/linkonce.
> >
> >
> > https://reviews.llvm.org/D29233
> >
> > Files:
> >  lib/AST/ASTContext.cpp
> >  test/CodeGenCXX/explicit-instantiation.cpp
> >
> >
> > Index: test/CodeGenCXX/explicit-instantiation.cpp
> > ===================================================================
> > --- test/CodeGenCXX/explicit-instantiation.cpp
> > +++ test/CodeGenCXX/explicit-instantiation.cpp
> > @@ -5,6 +5,9 @@
> > // This check logically is attached to 'template int S<int>::i;' below.
> > // CHECK: @_ZN1SIiE1iE = weak_odr global i32
> >
> > +// This check is logically attached to 'template int
> ExportedStaticLocal::f<int>()' below.
> > +// CHECK-OPT: @_ZZN19ExportedStaticLocal1fIiEEvvE1i = linkonce_odr
> global
> > +
> > template<typename T, typename U, typename Result>
> > struct plus {
> >   Result operator()(const T& t, const U& u) const;
> > @@ -153,3 +156,17 @@
> > template <typename T> void S<T>::g() {}
> > template <typename T> int S<T>::i;
> > template <typename T> void S<T>::S2::h() {}
> > +
> > +namespace ExportedStaticLocal {
> > +void sink(int&);
> > +template <typename T>
> > +inline void f() {
> > +  static int i;
> > +  sink(i);
> > +}
> > +// See the check line at the top of the file.
> > +extern template void f<int>();
> > +void use() {
> > +  f<int>();
> > +}
> > +}
> > Index: lib/AST/ASTContext.cpp
> > ===================================================================
> > --- lib/AST/ASTContext.cpp
> > +++ lib/AST/ASTContext.cpp
> > @@ -8892,22 +8892,27 @@
> >     return GVA_Internal;
> >
> >   if (VD->isStaticLocal()) {
> > -    GVALinkage StaticLocalLinkage = GVA_DiscardableODR;
> >     const DeclContext *LexicalContext = VD->getParentFunctionOrMethod();
> >     while (LexicalContext && !isa<FunctionDecl>(LexicalContext))
> >       LexicalContext = LexicalContext->getLexicalParent();
> >
> > -    // Let the static local variable inherit its linkage from the
> nearest
> > -    // enclosing function.
> > -    if (LexicalContext)
> > -      StaticLocalLinkage =
> > -
> Context.GetGVALinkageForFunction(cast<FunctionDecl>(LexicalContext));
> > -
> > -    // GVA_StrongODR function linkage is stronger than what we need,
> > -    // downgrade to GVA_DiscardableODR.
> > -    // This allows us to discard the variable if we never end up
> needing it.
> > -    return StaticLocalLinkage == GVA_StrongODR ? GVA_DiscardableODR
> > -                                               : StaticLocalLinkage;
> > +    // ObjC Blocks can create local variables that don't have a
> FunctionDecl
> > +    // LexicalContext.
> > +    if (!LexicalContext)
> > +      return GVA_DiscardableODR;
> > +
> > +    // Otherwise, let the static local variable inherit its linkage
> from the
> > +    // nearest enclosing function.
> > +    auto StaticLocalLinkage =
> > +
> Context.GetGVALinkageForFunction(cast<FunctionDecl>(LexicalContext));
> > +
> > +    // Itanium ABI (& MSVC seems to do similarly) requires static
> locals in
> > +    // inline functions to be emitted anywhere they're needed, even if
> the
> > +    // function they are local to is emitted
> StrongODR/AvailableExternally.
> > +    if (StaticLocalLinkage == GVA_StrongODR ||
> > +        StaticLocalLinkage == GVA_AvailableExternally)
> > +      return GVA_DiscardableODR;
> > +    return StaticLocalLinkage;
> >   }
> >
> >   // MSVC treats in-class initialized static data members as definitions.
> >
> >
> > <D29233.86118.patch>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170127/02a01c82/attachment.html>


More information about the cfe-commits mailing list