r370850 - Re-commit r363191 "[MS] Pretend constexpr variable template specializations are inline"

Hans Wennborg via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 5 02:46:39 PDT 2019


Merged to release_90 in r371040.

On Wed, Sep 4, 2019 at 10:17 AM Hans Wennborg via cfe-commits
<cfe-commits at lists.llvm.org> wrote:
>
> Author: hans
> Date: Wed Sep  4 01:19:30 2019
> New Revision: 370850
>
> URL: http://llvm.org/viewvc/llvm-project?rev=370850&view=rev
> Log:
> Re-commit r363191 "[MS] Pretend constexpr variable template specializations are inline"
>
> While the next Visual Studio update (16.3) will fix this issue, that hasn't
> shipped yet. Until then Clang wouldn't work with MSVC's headers which seems
> unfortunate. Let's keep this in until VS 16.3 ships. (See also PR42843.)
>
> > Fixes link errors with clang and the latest Visual C++ 14.21.27702
> > headers, which was reported as PR42027.
> >
> > I chose to intentionally make these things linkonce_odr, i.e.
> > discardable, so that we don't emit definitions of these things in every
> > translation unit that includes STL headers.
> >
> > Note that this is *not* what MSVC does: MSVC has not yet implemented C++
> > DR2387, so they emit fully specialized constexpr variable templates with
> > static / internal linkage.
> >
> > Reviewers: rsmith
> >
> > Differential Revision: https://reviews.llvm.org/D63175
>
> Added:
>     cfe/trunk/test/CodeGenCXX/ms-constexpr-var-template.cpp
> Modified:
>     cfe/trunk/lib/AST/ASTContext.cpp
>
> Modified: cfe/trunk/lib/AST/ASTContext.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=370850&r1=370849&r2=370850&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ASTContext.cpp (original)
> +++ cfe/trunk/lib/AST/ASTContext.cpp Wed Sep  4 01:19:30 2019
> @@ -9905,10 +9905,25 @@ static GVALinkage basicGVALinkageForVari
>      return StrongLinkage;
>
>    case TSK_ExplicitSpecialization:
> -    return Context.getTargetInfo().getCXXABI().isMicrosoft() &&
> -                   VD->isStaticDataMember()
> -               ? GVA_StrongODR
> -               : StrongLinkage;
> +    if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
> +      // If this is a fully specialized constexpr variable template, pretend it
> +      // was marked inline. MSVC 14.21.27702 headers define _Is_integral in a
> +      // header this way, and we don't want to emit non-discardable definitions
> +      // of these variables in every TU that includes <type_traits>. This
> +      // behavior is non-conforming, since another TU could use an extern
> +      // template declaration for this variable, but for constexpr variables,
> +      // it's unlikely for a user to want to do that. This behavior can be
> +      // removed if the headers change to explicitly mark such variable template
> +      // specializations inline.
> +      if (isa<VarTemplateSpecializationDecl>(VD) && VD->isConstexpr())
> +        return GVA_DiscardableODR;
> +
> +      // Use ODR linkage for static data members of fully specialized templates
> +      // to prevent duplicate definition errors with MSVC.
> +      if (VD->isStaticDataMember())
> +        return GVA_StrongODR;
> +    }
> +    return StrongLinkage;
>
>    case TSK_ExplicitInstantiationDefinition:
>      return GVA_StrongODR;
>
> Added: cfe/trunk/test/CodeGenCXX/ms-constexpr-var-template.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/ms-constexpr-var-template.cpp?rev=370850&view=auto
> ==============================================================================
> --- cfe/trunk/test/CodeGenCXX/ms-constexpr-var-template.cpp (added)
> +++ cfe/trunk/test/CodeGenCXX/ms-constexpr-var-template.cpp Wed Sep  4 01:19:30 2019
> @@ -0,0 +1,11 @@
> +// RUN: %clang_cc1 -emit-llvm -triple=x86_64-windows-msvc -fms-compatibility %s -o - | FileCheck %s
> +
> +template <typename> constexpr bool _Is_integer = false;
> +template <> constexpr bool _Is_integer<int> = true;
> +template <> constexpr bool _Is_integer<char> = false;
> +extern "C" const bool *escape = &_Is_integer<int>;
> +
> +// CHECK: @"??$_Is_integer at H@@3_NB" = linkonce_odr dso_local constant i8 1, comdat, align 1
> +//   Should not emit _Is_integer<char>, since it's not referenced.
> +// CHECK-NOT: @"??$_Is_integer at D@@3_NB"
> +// CHECK: @escape = dso_local global i8* @"??$_Is_integer at H@@3_NB", align 8
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


More information about the cfe-commits mailing list