[PATCH] D70791: Workaround for MSVC 16.3.* pre-c++17 type trait linkage
Erich Keane via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 27 09:41:32 PST 2019
erichkeane created this revision.
erichkeane added reviewers: rnk, rjmccall, majnemer.
MSVC's type_trait header for the 16.3.* release in pre-c++17 mode
exposes explicitly specialized constexpr variables for _Is_integral,
is_void_v, and _Is_floating_point as not-inline (since that isn't
available in pre-C++17). The result is duplicate-symbols in any
program that includes <type_traits> more than once.
This patch works around this issue by making fairly specific cases (in
the system header, in MSVC mode, and in pre-c++17 mode) be weak_odr
linkage rather than External linkage.
https://reviews.llvm.org/D70791
Files:
clang/lib/AST/ASTContext.cpp
clang/test/CodeGenCXX/Inputs/ms-constexpr-typetraits.h
clang/test/CodeGenCXX/microsoft-type-traits-pre-cxx17.cpp
Index: clang/test/CodeGenCXX/microsoft-type-traits-pre-cxx17.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/microsoft-type-traits-pre-cxx17.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm -triple=x86_64-pc-win32 -std=c++14 -o - %s -isystem%S/Inputs | FileCheck %s
+#include <ms-constexpr-typetraits.h>
+
+// CHECK: @"??$_Is_integral at _N@@3_NB" = weak_odr dso_local constant
+// CHECK: @"??$_Is_floating_point at M@@3_NB" = weak_odr dso_local constant
+// CHECK: @"??$is_void_v at X@@3_NB" = weak_odr dso_local constant
+
Index: clang/test/CodeGenCXX/Inputs/ms-constexpr-typetraits.h
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/Inputs/ms-constexpr-typetraits.h
@@ -0,0 +1,17 @@
+template <class>
+constexpr bool _Is_integral = false;
+
+template <>
+constexpr bool _Is_integral<bool> = true;
+
+template <class>
+constexpr bool _Is_floating_point = false;
+
+template <>
+constexpr bool _Is_floating_point<float> = true;
+
+template <class>
+constexpr bool is_void_v = false;
+
+template <>
+constexpr bool is_void_v<void> = true;
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -9860,6 +9860,19 @@
return L;
}
+// The MSVC type_traits header defines a handful of type-trait constexpr
+// variables as non-inline in pre-C++17 mode which causes duplicate symbols.
+// In C++17 cases, they mark these as 'inline', which avoids this issue.
+// This fixup alters the linkage to be odr for this case.
+static bool isMSVCPreCxx17TypeTrait(const ASTContext &Context,
+ const VarDecl *VD) {
+ assert(VD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization &&
+ "Only valid for explicit specializations");
+ return VD->isConstexpr() && !VD->isInline() &&
+ !Context.getLangOpts().CPlusPlus17 &&
+ Context.getSourceManager().isInSystemHeader(VD->getLocation());
+}
+
GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const {
return adjustGVALinkageForExternalDefinitionKind(*this, FD,
adjustGVALinkageForAttributes(*this, FD,
@@ -9926,7 +9939,8 @@
case TSK_ExplicitSpecialization:
return Context.getTargetInfo().getCXXABI().isMicrosoft() &&
- VD->isStaticDataMember()
+ (VD->isStaticDataMember() ||
+ isMSVCPreCxx17TypeTrait(Context, VD))
? GVA_StrongODR
: StrongLinkage;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D70791.231280.patch
Type: text/x-patch
Size: 2625 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20191127/9b0df660/attachment.bin>
More information about the cfe-commits
mailing list