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@PR20947@@3PAPQA@1@HA" = global %[[opaque0]]* null, align 4 +// CHECK-DAG: @"\01?a@PR20947@@3PAPQA@1@HA" = global %{{.*}}* null, align 4 struct B; int B::*&b = b; -// CHECK: @"\01?b@PR20947@@3AAPQB@1@HA" = global %[[opaque1]]* null, align 4 +// CHECK-DAG: @"\01?b@PR20947@@3AAPQB@1@HA" = global %{{.*}}* null, align 4 } namespace PR20017 { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits