[PATCH] D98904: Instantiate static constexpr data members on MS ABI.
Zoe Carver via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 18 15:49:41 PDT 2021
zoecarver created this revision.
zoecarver added a reviewer: rsmith.
zoecarver requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Because MSVC will not treat the definition of a static data member as part of the declaration, it will not get instantiated. This means Clang won't diagnose instantiation errors until the data member itself is used.
Note: this only happens for constexpr data members because they are the only ones that are marked as implicitly inline and therefore not part of the declaration.
Refs: https://llvm.org/PR49618
Refs: https://github.com/apple/swift/pull/35962
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D98904
Files:
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
clang/test/SemaCXX/windows-data-member-instantiation-errors.cpp
Index: clang/test/SemaCXX/windows-data-member-instantiation-errors.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/windows-data-member-instantiation-errors.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -verify -std=c++11 %s
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -verify -std=c++17 %s
+
+template <class T>
+struct GetTypeValue {
+ // expected-error at +1{{type 'int' cannot be used prior to '::' because it has no members}}
+ static constexpr const bool value = T::value;
+};
+
+using Invalid = GetTypeValue<int>;
+
+// expected-note at +1{{in instantiation of template class 'GetTypeValue<int>' requested here}}
+void test(Invalid) {}
+
+// expected-note at +2{{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const S &' for 1st argument}}
+// expected-note at +1{{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'S &&' for 1st argument}}
+struct S {};
+
+template <class T>
+struct MakeS {
+ // expected-error at +1{{no viable conversion from 'int' to 'const S'}}
+ static constexpr const S value = T();
+};
+
+using Invalid2 = MakeS<int>;
+
+// expected-note at +1{{in instantiation of template class 'MakeS<int>' requested here}}
+void test2(Invalid2) {}
Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -5111,7 +5111,11 @@
InstantiateVariableInitializer(NewVar, OldVar, TemplateArgs);
} else if (InstantiatingSpecFromTemplate ||
(OldVar->isInline() && OldVar->isThisDeclarationADefinition() &&
- !NewVar->isThisDeclarationADefinition())) {
+ !NewVar->isThisDeclarationADefinition() &&
+ // On Microsoft's ABI, the new var's initializer will be part of
+ // the definition. But, we still want to instanciate it so that
+ // we can catch instantiation errors.
+ !Context.getTargetInfo().getCXXABI().isMicrosoft())) {
// Delay instantiation of the initializer for variable template
// specializations or inline static data members until a definition of the
// variable is needed.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D98904.331710.patch
Type: text/x-patch
Size: 2376 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210318/9ea6dc31/attachment-0001.bin>
More information about the cfe-commits
mailing list