summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2018-05-31 18:42:29 +0000
committerReid Kleckner <rnk@google.com>2018-05-31 18:42:29 +0000
commit26fc531dbc652a7738f3c8a421b3023ca12ca1ad (patch)
treed3e57bc853792f237164d2769825ed92043aa8e0 /clang
parent38f7bb779854c3812ddd98cae4032788fa2722c4 (diff)
downloadbcm5719-llvm-26fc531dbc652a7738f3c8a421b3023ca12ca1ad.tar.gz
bcm5719-llvm-26fc531dbc652a7738f3c8a421b3023ca12ca1ad.zip
Fix null MSInheritanceAttr deref in CXXRecordDecl::getMSInheritanceModel()
Ensure latest MPT decl has a MSInheritanceAttr when instantiating templates, to avoid null MSInheritanceAttr deref in CXXRecordDecl::getMSInheritanceModel(). See PR#37399 for repo / details. Patch by Andrew Rogers! Differential Revision: https://reviews.llvm.org/D46664 llvm-svn: 333680
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/DeclCXX.h15
-rw-r--r--clang/include/clang/AST/DeclTemplate.h10
-rw-r--r--clang/lib/AST/MicrosoftMangle.cpp4
-rw-r--r--clang/lib/AST/Type.cpp4
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp2
-rw-r--r--clang/lib/Sema/SemaType.cpp2
-rw-r--r--clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp118
7 files changed, 141 insertions, 14 deletions
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 242a9eb4ca8..a64593c79d9 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -751,6 +751,21 @@ public:
return const_cast<CXXRecordDecl*>(this)->getMostRecentDecl();
}
+ CXXRecordDecl *getMostRecentNonInjectedDecl() {
+ CXXRecordDecl *Recent =
+ static_cast<CXXRecordDecl *>(this)->getMostRecentDecl();
+ while (Recent->isInjectedClassName()) {
+ // FIXME: Does injected class name need to be in the redeclarations chain?
+ assert(Recent->getPreviousDecl());
+ Recent = Recent->getPreviousDecl();
+ }
+ return Recent;
+ }
+
+ const CXXRecordDecl *getMostRecentNonInjectedDecl() const {
+ return const_cast<CXXRecordDecl*>(this)->getMostRecentNonInjectedDecl();
+ }
+
CXXRecordDecl *getDefinition() const {
// We only need an update if we don't already know which
// declaration is the definition.
diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h
index e15fe822bb7..a2f00ec9ffa 100644
--- a/clang/include/clang/AST/DeclTemplate.h
+++ b/clang/include/clang/AST/DeclTemplate.h
@@ -1720,14 +1720,8 @@ public:
// it's not clear that we should override that, because the most recent
// declaration as a CXXRecordDecl sometimes is the injected-class-name.
ClassTemplateSpecializationDecl *getMostRecentDecl() {
- CXXRecordDecl *Recent = static_cast<CXXRecordDecl *>(
- this)->getMostRecentDecl();
- while (!isa<ClassTemplateSpecializationDecl>(Recent)) {
- // FIXME: Does injected class name need to be in the redeclarations chain?
- assert(Recent->isInjectedClassName() && Recent->getPreviousDecl());
- Recent = Recent->getPreviousDecl();
- }
- return cast<ClassTemplateSpecializationDecl>(Recent);
+ return cast<ClassTemplateSpecializationDecl>(
+ getMostRecentNonInjectedDecl());
}
/// Retrieve the template that this specialization specializes.
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 159938124be..f7b80d5b277 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -1370,12 +1370,12 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
const NamedDecl *ND = TA.getAsDecl();
if (isa<FieldDecl>(ND) || isa<IndirectFieldDecl>(ND)) {
mangleMemberDataPointer(
- cast<CXXRecordDecl>(ND->getDeclContext())->getMostRecentDecl(),
+ cast<CXXRecordDecl>(ND->getDeclContext())->getMostRecentNonInjectedDecl(),
cast<ValueDecl>(ND));
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
if (MD && MD->isInstance()) {
- mangleMemberFunctionPointer(MD->getParent()->getMostRecentDecl(), MD);
+ mangleMemberFunctionPointer(MD->getParent()->getMostRecentNonInjectedDecl(), MD);
} else {
Out << "$1?";
mangleName(FD);
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index e94ae9329f3..065a77aa507 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2040,7 +2040,7 @@ bool Type::isIncompleteType(NamedDecl **Def) const {
return false;
// The inheritance attribute might only be present on the most recent
// CXXRecordDecl, use that one.
- RD = RD->getMostRecentDecl();
+ RD = RD->getMostRecentNonInjectedDecl();
// Nothing interesting to do if the inheritance attribute is already set.
if (RD->hasAttr<MSInheritanceAttr>())
return false;
@@ -3936,5 +3936,5 @@ QualType::DestructionKind QualType::isDestructedTypeImpl(QualType type) {
}
CXXRecordDecl *MemberPointerType::getMostRecentCXXRecordDecl() const {
- return getClass()->getAsCXXRecordDecl()->getMostRecentDecl();
+ return getClass()->getAsCXXRecordDecl()->getMostRecentNonInjectedDecl();
}
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 2c3e1503857..a8260b49ed9 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -2733,7 +2733,7 @@ MicrosoftCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) {
assert(MD->isInstance() && "Member function must not be static!");
CharUnits NonVirtualBaseAdjustment = CharUnits::Zero();
- const CXXRecordDecl *RD = MD->getParent()->getMostRecentDecl();
+ const CXXRecordDecl *RD = MD->getParent()->getMostRecentNonInjectedDecl();
CodeGenTypes &Types = CGM.getTypes();
unsigned VBTableIndex = 0;
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index b5a90af39ba..6839dd7de21 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -7544,7 +7544,7 @@ bool Sema::hasVisibleDefinition(NamedDecl *D, NamedDecl **Suggested,
/// Locks in the inheritance model for the given class and all of its bases.
static void assignInheritanceModel(Sema &S, CXXRecordDecl *RD) {
- RD = RD->getMostRecentDecl();
+ RD = RD->getMostRecentNonInjectedDecl();
if (!RD->hasAttr<MSInheritanceAttr>()) {
MSInheritanceAttr::Spelling IM;
diff --git a/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp b/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
index 0f54d30ec46..471524ef720 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
@@ -3,6 +3,124 @@
// 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
+namespace pr37399 {
+template <typename T>
+struct Functor {
+ void (T::*PtrToMemberFunction)();
+};
+// CHECK-DAG: %"struct.pr37399::Functor" = type { i8* }
+
+template <typename SomeType>
+class SimpleDerivedFunctor;
+template <typename SomeType>
+class SimpleDerivedFunctor : public Functor<SimpleDerivedFunctor<SomeType>> {};
+// CHECK-DAG: %"class.pr37399::SimpleDerivedFunctor" = type { %"struct.pr37399::Functor" }
+
+SimpleDerivedFunctor<void> SimpleFunctor;
+// CHECK-DAG: @"?SimpleFunctor@pr37399@@3V?$SimpleDerivedFunctor@X@1@A" = dso_local global %"class.pr37399::SimpleDerivedFunctor" zeroinitializer, align 4
+
+short Global = 0;
+template <typename SomeType>
+class DerivedFunctor;
+template <typename SomeType>
+class DerivedFunctor
+ : public Functor<DerivedFunctor<void>> {
+public:
+ void Foo() {
+ Global = 42;
+ }
+};
+
+class MultipleBase {
+public:
+ MultipleBase() : Value() {}
+ short Value;
+};
+// CHECK-DAG: %"class.pr37399::MultipleBase" = type { i16 }
+
+template <typename SomeType>
+class MultiplyDerivedFunctor;
+template <typename SomeType>
+class MultiplyDerivedFunctor
+ : public Functor<MultiplyDerivedFunctor<void>>,
+ public MultipleBase {
+public:
+ void Foo() {
+ MultipleBase::Value = 42*2;
+ }
+};
+
+class VirtualBase {
+public:
+ VirtualBase() : Value() {}
+ short Value;
+};
+// CHECK-DAG: %"class.pr37399::VirtualBase" = type { i16 }
+
+template <typename SomeType>
+class VirtBaseFunctor
+ : public Functor<SomeType>,
+ public virtual VirtualBase{};
+template <typename SomeType>
+class VirtuallyDerivedFunctor;
+template <typename SomeType>
+class VirtuallyDerivedFunctor
+ : public VirtBaseFunctor<VirtuallyDerivedFunctor<void>>,
+ public virtual VirtualBase {
+public:
+ void Foo() {
+ VirtualBase::Value = 42*3;
+ }
+};
+} // namespace pr37399
+
+pr37399::DerivedFunctor<int> BFunctor;
+// CHECK-DAG: @"?BFunctor@@3V?$DerivedFunctor@H@pr37399@@A" = dso_local global %"[[BFUNCTOR:class.pr37399::DerivedFunctor(\.[0-9]+)?]]" zeroinitializer, align 8
+// CHECK-DAG: %"[[BFUNCTOR]]" = type { %"[[BFUNCTORBASE:struct.pr37399::Functor(\.[0-9]+)?]]" }
+// CHECK-DAG: %"[[BFUNCTORBASE]]" = type { { i8*, i32, i32, i32 } }
+pr37399::DerivedFunctor<void> AFunctor;
+// CHECK-DAG: @"?AFunctor@@3V?$DerivedFunctor@X@pr37399@@A" = dso_local global %"[[AFUNCTOR:class.pr37399::DerivedFunctor(\.[0-9]+)?]]" zeroinitializer, align 8
+// CHECK-DAG: %"[[AFUNCTOR]]" = type { %"[[AFUNCTORBASE:struct.pr37399::Functor(\.[0-9]+)?]]" }
+// CHECK-DAG: %"[[AFUNCTORBASE]]" = type { { i8*, i32, i32, i32 } }
+
+pr37399::MultiplyDerivedFunctor<int> DFunctor;
+// CHECK-DAG: @"?DFunctor@@3V?$MultiplyDerivedFunctor@H@pr37399@@A" = dso_local global %"[[DFUNCTOR:class.pr37399::MultiplyDerivedFunctor(\.[0-9]+)?]]" zeroinitializer, align 8
+// CHECK-DAG: %"[[DFUNCTOR]]" = type { %"[[DFUNCTORBASE:struct.pr37399::Functor(\.[0-9]+)?]]", %"class.pr37399::MultipleBase", [6 x i8] }
+// CHECK-DAG: %"[[DFUNCTORBASE]]" = type { { i8*, i32, i32, i32 } }
+pr37399::MultiplyDerivedFunctor<void> CFunctor;
+// CHECK-DAG: @"?CFunctor@@3V?$MultiplyDerivedFunctor@X@pr37399@@A" = dso_local global %"[[CFUNCTOR:class.pr37399::MultiplyDerivedFunctor(\.[0-9]+)?]]" zeroinitializer, align 8
+// CHECK-DAG: %"[[CFUNCTOR]]" = type { %"[[CFUNCTORBASE:struct.pr37399::Functor(\.[0-9]+)?]]", %"class.pr37399::MultipleBase", [6 x i8] }
+// CHECK-DAG: %"[[CFUNCTORBASE]]" = type { { i8*, i32, i32, i32 } }
+
+pr37399::VirtuallyDerivedFunctor<int> FFunctor;
+// CHECK-DAG: @"?FFunctor@@3V?$VirtuallyDerivedFunctor@H@pr37399@@A" = dso_local global %"[[FFUNCTOR:class.pr37399::VirtuallyDerivedFunctor(\.[0-9]+)?]]" zeroinitializer, align 8
+// CHECK-DAG: %"[[FFUNCTOR]]" = type { %"class.pr37399::VirtBaseFunctor.base", %"class.pr37399::VirtualBase" }
+pr37399::VirtuallyDerivedFunctor<void> EFunctor;
+// CHECK-DAG: @"?EFunctor@@3V?$VirtuallyDerivedFunctor@X@pr37399@@A" = dso_local global %"[[EFUNCTOR:class.pr37399::VirtuallyDerivedFunctor(\.[0-9]+)?]]" zeroinitializer, align 8
+// CHECK-DAG: %"[[EFUNCTOR]]" = type { %"class.pr37399::VirtBaseFunctor.base", %"class.pr37399::VirtualBase" }
+
+// CHECK-DAG: %"class.pr37399::VirtBaseFunctor.base" = type <{ %"[[VFUNCTORBASE:struct.pr37399::Functor(\.[0-9]+)?]]", i32*, [4 x i8] }>
+// CHECK-DAG: %"[[VFUNCTORBASE]]" = type { { i8*, i32, i32, i32 } }
+
+namespace pr37399 {
+void SingleInheritanceFnPtrCall() {
+ BFunctor.PtrToMemberFunction = &DerivedFunctor<void>::Foo;
+ (AFunctor.*(BFunctor.PtrToMemberFunction))();
+}
+void MultipleInheritanceFnPtrCall() {
+ DFunctor.PtrToMemberFunction = &MultiplyDerivedFunctor<void>::Foo;
+ Global = CFunctor.MultipleBase::Value;
+ (CFunctor.*(DFunctor.PtrToMemberFunction))();
+ Global = CFunctor.MultipleBase::Value;
+}
+void VirtualInheritanceFnPtrCall() {
+ FFunctor.PtrToMemberFunction = &VirtuallyDerivedFunctor<void>::Foo;
+ Global = EFunctor.VirtualBase::Value;
+ (EFunctor.*(FFunctor.PtrToMemberFunction))();
+ Global = EFunctor.VirtualBase::Value;
+}
+} // namespace pr37399
+
struct PR26313_Y;
typedef void (PR26313_Y::*PR26313_FUNC)();
struct PR26313_X {
OpenPOWER on IntegriCloud