[PATCH] D16951: [MS ABI] dllimport'd class cannot have constexpr ctors
David Majnemer via cfe-commits
cfe-commits at lists.llvm.org
Sat Feb 6 18:03:41 PST 2016
majnemer created this revision.
majnemer added reviewers: hans, rsmith, thakis, rnk.
majnemer added a subscriber: cfe-commits.
The installation of a class's vptr cannot be performed without code
being executed. This implies that the constructor of a class cannot be
constexpr.
This fixes PR26506.
http://reviews.llvm.org/D16951
Files:
include/clang/Basic/DiagnosticSemaKinds.td
lib/AST/DeclCXX.cpp
lib/Sema/SemaDeclCXX.cpp
test/CodeGenCXX/dllimport.cpp
test/SemaCXX/dllimport.cpp
Index: test/SemaCXX/dllimport.cpp
===================================================================
--- test/SemaCXX/dllimport.cpp
+++ test/SemaCXX/dllimport.cpp
@@ -1259,6 +1259,15 @@
template <typename T> struct ExpliciallySpecializedClassTemplate {};
template <> struct __declspec(dllimport) ExpliciallySpecializedClassTemplate<int> { void f() {} };
+struct __declspec(dllimport) PR26506_test1 {
+ virtual ~PR26506_test1() {}
+ constexpr PR26506_test1() = default; // expected-error{{defaulted definition of default constructor is not constexpr}}
+};
+
+struct __declspec(dllimport) PR26506_test2 { // expected-note{{due to 'PR26506_test2' being dllimported}}
+ virtual ~PR26506_test2() {}
+ constexpr PR26506_test2() {} // expected-error{{constructor cannot be marked constexpr}}
+};
//===----------------------------------------------------------------------===//
// Classes with template base classes
Index: test/CodeGenCXX/dllimport.cpp
===================================================================
--- test/CodeGenCXX/dllimport.cpp
+++ test/CodeGenCXX/dllimport.cpp
@@ -618,10 +618,10 @@
// GO1-DAG: @_ZTV1W = available_externally dllimport unnamed_addr constant [3 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)]
struct __declspec(dllimport) KeyFuncClass {
- constexpr KeyFuncClass() {}
+ KeyFuncClass() {}
virtual void foo();
};
-extern constexpr KeyFuncClass keyFuncClassVar = {};
+extern KeyFuncClass keyFuncClassVar = {};
// G32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant [3 x i8*]
struct __declspec(dllimport) X : public virtual W {};
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -808,15 +808,25 @@
// constraints:
// - the class shall not have any virtual base classes;
const CXXRecordDecl *RD = MD->getParent();
+ bool IsCtor = isa<CXXConstructorDecl>(NewFD);
if (RD->getNumVBases()) {
Diag(NewFD->getLocation(), diag::err_constexpr_virtual_base)
- << isa<CXXConstructorDecl>(NewFD)
+ << IsCtor
<< getRecordDiagFromTagKind(RD->getTagKind()) << RD->getNumVBases();
for (const auto &I : RD->vbases())
Diag(I.getLocStart(),
diag::note_constexpr_virtual_base_here) << I.getSourceRange();
return false;
}
+ // A constructor for a polymorphic class cannot be constexpr if the class
+ // has been marked dllimport. This is because dllimport data cannot be
+ // resolved in a constant: code must be executed to dereference the __imp
+ // symbol.
+ if (IsCtor && RD->isPolymorphic() && RD->hasAttr<DLLImportAttr>()) {
+ Diag(NewFD->getLocation(), diag::err_constexpr_ctor);
+ Diag(RD->getLocStart(), diag::note_due_to_dllimported_class) << RD;
+ return false;
+ }
}
if (!isa<CXXConstructorDecl>(NewFD)) {
Index: lib/AST/DeclCXX.cpp
===================================================================
--- lib/AST/DeclCXX.cpp
+++ lib/AST/DeclCXX.cpp
@@ -463,6 +463,12 @@
}
}
+ // We cannot have a constexpr default constructor if the class is polymorphic
+ // because it is impossible to synthesize a reference to the imported vtable
+ // without generating code.
+ if (data().Polymorphic && hasAttr<DLLImportAttr>())
+ data().DefaultedDefaultConstructorIsConstexpr = false;
+
// Notify the listener if an implicit member was added after the definition
// was completed.
if (!isBeingDefined() && D->isImplicit())
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -1949,6 +1949,9 @@
"constexpr%select{; did you intend to make it %select{const|static}0?|}1">;
def err_constexpr_tag : Error<
"%select{class|struct|interface|union|enum}0 cannot be marked constexpr">;
+def err_constexpr_ctor : Error<"constructor cannot be marked constexpr">;
+def note_due_to_dllimported_class : Note<
+ "due to %0 being dllimported">;
def err_constexpr_dtor : Error<"destructor cannot be marked constexpr">;
def err_constexpr_no_declarators : Error<
"constexpr can only be used in variable and function declarations">;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D16951.47113.patch
Type: text/x-patch
Size: 4357 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160207/ef75c4f0/attachment.bin>
More information about the cfe-commits
mailing list