r258839 - [MS ABI] Allow a member pointers' converted type to change
David Majnemer via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 26 11:30:26 PST 2016
Author: majnemer
Date: Tue Jan 26 13:30:26 2016
New Revision: 258839
URL: http://llvm.org/viewvc/llvm-project?rev=258839&view=rev
Log:
[MS ABI] Allow a member pointers' converted type to change
Member pointers in the MS ABI are tricky for a variety of reasons.
The size of a member pointer is indeterminate until the program reaches
a point where the representation is required to be known. However,
*pointers* to member pointers may exist without knowing the pointee
type's representation. In these cases, we synthesize an opaque LLVM
type for the pointee type.
However, we can be in a situation where the underlying member pointer's
representation became known mid-way through the program. To account for
this, we attempted to manicure CodeGen's type-cache so that we can
replace the opaque member pointer type with the real deal while leaving
the pointer types unperturbed. This, unfortunately, is a problematic
approach to take as we will violate CodeGen's invariants.
These violations are mostly harmless but let's do the right thing
instead: invalidate the type-cache if a member pointer's LLVM
representation changes.
This fixes PR26313.
Modified:
cfe/trunk/include/clang/AST/ASTConsumer.h
cfe/trunk/include/clang/Frontend/MultiplexConsumer.h
cfe/trunk/lib/CodeGen/CodeGenAction.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
cfe/trunk/lib/CodeGen/CodeGenTypes.h
cfe/trunk/lib/CodeGen/ModuleBuilder.cpp
cfe/trunk/lib/Frontend/MultiplexConsumer.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
Modified: cfe/trunk/include/clang/AST/ASTConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTConsumer.h?rev=258839&r1=258838&r2=258839&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTConsumer.h (original)
+++ cfe/trunk/include/clang/AST/ASTConsumer.h Tue Jan 26 13:30:26 2016
@@ -121,6 +121,10 @@ public:
/// modified by the introduction of an implicit zero initializer.
virtual void CompleteTentativeDefinition(VarDecl *D) {}
+ /// \brief Callback invoked when an MSInheritanceAttr has been attached to a
+ /// CXXRecordDecl.
+ virtual void AssignInheritanceModel(CXXRecordDecl *RD) {}
+
/// HandleCXXStaticMemberVarInstantiation - Tell the consumer that this
// variable has been instantiated.
virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *D) {}
Modified: cfe/trunk/include/clang/Frontend/MultiplexConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/MultiplexConsumer.h?rev=258839&r1=258838&r2=258839&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/MultiplexConsumer.h (original)
+++ cfe/trunk/include/clang/Frontend/MultiplexConsumer.h Tue Jan 26 13:30:26 2016
@@ -49,6 +49,7 @@ public:
llvm::StringRef Value) override;
void HandleDependentLibrary(llvm::StringRef Lib) override;
void CompleteTentativeDefinition(VarDecl *D) override;
+ void AssignInheritanceModel(CXXRecordDecl *RD) override;
void HandleVTable(CXXRecordDecl *RD) override;
ASTMutationListener *GetASTMutationListener() override;
ASTDeserializationListener *GetASTDeserializationListener() override;
Modified: cfe/trunk/lib/CodeGen/CodeGenAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenAction.cpp?rev=258839&r1=258838&r2=258839&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenAction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenAction.cpp Tue Jan 26 13:30:26 2016
@@ -210,6 +210,10 @@ namespace clang {
Gen->CompleteTentativeDefinition(D);
}
+ void AssignInheritanceModel(CXXRecordDecl *RD) override {
+ Gen->AssignInheritanceModel(RD);
+ }
+
void HandleVTable(CXXRecordDecl *RD) override {
Gen->HandleVTable(RD);
}
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=258839&r1=258838&r2=258839&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Jan 26 13:30:26 2016
@@ -489,6 +489,11 @@ void CodeGenModule::UpdateCompletedType(
Types.UpdateCompletedType(TD);
}
+void CodeGenModule::RefreshTypeCacheForClass(const CXXRecordDecl *RD) {
+ // Make sure that this type is translated.
+ Types.RefreshTypeCacheForClass(RD);
+}
+
llvm::MDNode *CodeGenModule::getTBAAInfo(QualType QTy) {
if (!TBAA)
return nullptr;
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=258839&r1=258838&r2=258839&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Tue Jan 26 13:30:26 2016
@@ -994,6 +994,8 @@ public:
void EmitVTable(CXXRecordDecl *Class);
+ void RefreshTypeCacheForClass(const CXXRecordDecl *Class);
+
/// \brief Appends Opts to the "Linker Options" metadata value.
void AppendLinkerOptions(StringRef Opts);
Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=258839&r1=258838&r2=258839&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Tue Jan 26 13:30:26 2016
@@ -272,6 +272,17 @@ void CodeGenTypes::UpdateCompletedType(c
DI->completeType(RD);
}
+void CodeGenTypes::RefreshTypeCacheForClass(const CXXRecordDecl *RD) {
+ QualType T = Context.getRecordType(RD);
+ T = Context.getCanonicalType(T);
+
+ const Type *Ty = T.getTypePtr();
+ if (RecordsWithOpaqueMemberPointers.count(Ty)) {
+ TypeCache.clear();
+ RecordsWithOpaqueMemberPointers.clear();
+ }
+}
+
static llvm::Type *getTypeForFormat(llvm::LLVMContext &VMContext,
const llvm::fltSemantics &format,
bool UseNativeHalf = false) {
@@ -603,10 +614,13 @@ llvm::Type *CodeGenTypes::ConvertType(Qu
}
case Type::MemberPointer: {
- if (!getCXXABI().isMemberPointerConvertible(cast<MemberPointerType>(Ty)))
- return llvm::StructType::create(getLLVMContext());
- ResultType =
- getCXXABI().ConvertMemberPointerType(cast<MemberPointerType>(Ty));
+ auto *MPTy = cast<MemberPointerType>(Ty);
+ if (!getCXXABI().isMemberPointerConvertible(MPTy)) {
+ RecordsWithOpaqueMemberPointers.insert(MPTy->getClass());
+ ResultType = llvm::StructType::create(getLLVMContext());
+ } else {
+ ResultType = getCXXABI().ConvertMemberPointerType(MPTy);
+ }
break;
}
Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.h?rev=258839&r1=258838&r2=258839&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.h Tue Jan 26 13:30:26 2016
@@ -162,6 +162,8 @@ class CodeGenTypes {
/// corresponding llvm::Type.
llvm::DenseMap<const Type *, llvm::Type *> TypeCache;
+ llvm::SmallSet<const Type *, 8> RecordsWithOpaqueMemberPointers;
+
public:
CodeGenTypes(CodeGenModule &cgm);
~CodeGenTypes();
@@ -214,6 +216,10 @@ public:
/// replace the 'opaque' type we previously made for it if applicable.
void UpdateCompletedType(const TagDecl *TD);
+ /// \brief Remove stale types from the type cache when an inheritance model
+ /// gets assigned to a class.
+ void RefreshTypeCacheForClass(const CXXRecordDecl *RD);
+
/// getNullaryFunctionInfo - Get the function info for a void()
/// function with standard CC.
const CGFunctionInfo &arrangeNullaryFunction();
Modified: cfe/trunk/lib/CodeGen/ModuleBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ModuleBuilder.cpp?rev=258839&r1=258838&r2=258839&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ModuleBuilder.cpp (original)
+++ cfe/trunk/lib/CodeGen/ModuleBuilder.cpp Tue Jan 26 13:30:26 2016
@@ -210,6 +210,13 @@ namespace {
Builder->Release();
}
+ void AssignInheritanceModel(CXXRecordDecl *RD) override {
+ if (Diags.hasErrorOccurred())
+ return;
+
+ Builder->RefreshTypeCacheForClass(RD);
+ }
+
void CompleteTentativeDefinition(VarDecl *D) override {
if (Diags.hasErrorOccurred())
return;
Modified: cfe/trunk/lib/Frontend/MultiplexConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/MultiplexConsumer.cpp?rev=258839&r1=258838&r2=258839&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/MultiplexConsumer.cpp (original)
+++ cfe/trunk/lib/Frontend/MultiplexConsumer.cpp Tue Jan 26 13:30:26 2016
@@ -337,6 +337,11 @@ void MultiplexConsumer::CompleteTentativ
Consumer->CompleteTentativeDefinition(D);
}
+void MultiplexConsumer::AssignInheritanceModel(CXXRecordDecl *RD) {
+ for (auto &Consumer : Consumers)
+ Consumer->AssignInheritanceModel(RD);
+}
+
void MultiplexConsumer::HandleVTable(CXXRecordDecl *RD) {
for (auto &Consumer : Consumers)
Consumer->HandleVTable(RD);
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=258839&r1=258838&r2=258839&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Jan 26 13:30:26 2016
@@ -2255,6 +2255,8 @@ static bool mergeDeclAttribute(Sema &S,
if (NewAttr) {
NewAttr->setInherited(true);
D->addAttr(NewAttr);
+ if (isa<MSInheritanceAttr>(NewAttr))
+ S.Consumer.AssignInheritanceModel(cast<CXXRecordDecl>(D));
return true;
}
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=258839&r1=258838&r2=258839&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Jan 26 13:30:26 2016
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Sema/SemaInternal.h"
+#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclCXX.h"
@@ -4431,8 +4432,10 @@ static void handleMSInheritanceAttr(Sema
D, Attr.getRange(), /*BestCase=*/true,
Attr.getAttributeSpellingListIndex(),
(MSInheritanceAttr::Spelling)Attr.getSemanticSpelling());
- if (IA)
+ if (IA) {
D->addAttr(IA);
+ S.Consumer.AssignInheritanceModel(cast<CXXRecordDecl>(D));
+ }
}
static void handleDeclspecThreadAttr(Sema &S, Decl *D,
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=258839&r1=258838&r2=258839&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Tue Jan 26 13:30:26 2016
@@ -6611,6 +6611,7 @@ static void assignInheritanceModel(Sema
S.ImplicitMSInheritanceAttrLoc.isValid()
? S.ImplicitMSInheritanceAttrLoc
: RD->getSourceRange()));
+ S.Consumer.AssignInheritanceModel(RD);
}
}
Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp?rev=258839&r1=258838&r2=258839&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp Tue Jan 26 13:30:26 2016
@@ -3,16 +3,29 @@
// RUN: %clang_cc1 -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -fms-extensions -verify
// RUN: %clang_cc1 -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -DMEMFUN -fms-extensions -verify
+struct PR26313_Y;
+typedef void (PR26313_Y::*PR26313_FUNC)();
+struct PR26313_X {
+ PR26313_FUNC *ptr;
+ PR26313_X();
+};
+PR26313_X::PR26313_X() {}
+void PR26313_f(PR26313_FUNC *p) { delete p; }
+
+struct PR26313_Z;
+int PR26313_Z::**a = nullptr;
+int PR26313_Z::*b = *a;
+// CHECK-DAG: @"\01?a@@3PAPQPR26313_Z@@HA" = global %0* null, align 4
+// CHECK-DAG: @"\01?b@@3PQPR26313_Z@@HQ1@" = global { i32, i32, i32 } { i32 0, i32 0, i32 -1 }, align 4
+
namespace PR20947 {
struct A;
int A::**a = nullptr;
-// CHECK: %[[opaque0:.*]] = type opaque
-// CHECK: %[[opaque1:.*]] = type opaque
-// CHECK: @"\01?a at PR20947@@3PAPQA at 1@HA" = global %[[opaque0]]* null, align 4
+// CHECK-DAG: @"\01?a at PR20947@@3PAPQA at 1@HA" = global %{{.*}}* null, align 4
struct B;
int B::*&b = b;
-// CHECK: @"\01?b at PR20947@@3AAPQB at 1@HA" = global %[[opaque1]]* null, align 4
+// CHECK-DAG: @"\01?b at PR20947@@3AAPQB at 1@HA" = global %{{.*}}* null, align 4
}
namespace PR20017 {
More information about the cfe-commits
mailing list