[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