Skip to content

Commit 8b1a3a3

Browse files
committed
Merging r370850:
------------------------------------------------------------------------ r370850 | hans | 2019-09-04 10:19:30 +0200 (Wed, 04 Sep 2019) | 20 lines 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 ------------------------------------------------------------------------ llvm-svn: 371040
1 parent 9831a1c commit 8b1a3a3

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

clang/lib/AST/ASTContext.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9814,10 +9814,25 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context,
98149814
return StrongLinkage;
98159815

98169816
case TSK_ExplicitSpecialization:
9817-
return Context.getTargetInfo().getCXXABI().isMicrosoft() &&
9818-
VD->isStaticDataMember()
9819-
? GVA_StrongODR
9820-
: StrongLinkage;
9817+
if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
9818+
// If this is a fully specialized constexpr variable template, pretend it
9819+
// was marked inline. MSVC 14.21.27702 headers define _Is_integral in a
9820+
// header this way, and we don't want to emit non-discardable definitions
9821+
// of these variables in every TU that includes <type_traits>. This
9822+
// behavior is non-conforming, since another TU could use an extern
9823+
// template declaration for this variable, but for constexpr variables,
9824+
// it's unlikely for a user to want to do that. This behavior can be
9825+
// removed if the headers change to explicitly mark such variable template
9826+
// specializations inline.
9827+
if (isa<VarTemplateSpecializationDecl>(VD) && VD->isConstexpr())
9828+
return GVA_DiscardableODR;
9829+
9830+
// Use ODR linkage for static data members of fully specialized templates
9831+
// to prevent duplicate definition errors with MSVC.
9832+
if (VD->isStaticDataMember())
9833+
return GVA_StrongODR;
9834+
}
9835+
return StrongLinkage;
98219836

98229837
case TSK_ExplicitInstantiationDefinition:
98239838
return GVA_StrongODR;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %clang_cc1 -emit-llvm -triple=x86_64-windows-msvc -fms-compatibility %s -o - | FileCheck %s
2+
3+
template <typename> constexpr bool _Is_integer = false;
4+
template <> constexpr bool _Is_integer<int> = true;
5+
template <> constexpr bool _Is_integer<char> = false;
6+
extern "C" const bool *escape = &_Is_integer<int>;
7+
8+
// CHECK: @"??$_Is_integer@H@@3_NB" = linkonce_odr dso_local constant i8 1, comdat, align 1
9+
// Should not emit _Is_integer<char>, since it's not referenced.
10+
// CHECK-NOT: @"??$_Is_integer@D@@3_NB"
11+
// CHECK: @escape = dso_local global i8* @"??$_Is_integer@H@@3_NB", align 8

0 commit comments

Comments
 (0)