diff options
-rw-r--r-- | lib/AST/VTableBuilder.cpp | 10 | ||||
-rw-r--r-- | test/CodeGenCXX/vtable-layout.cpp | 26 |
2 files changed, 31 insertions, 5 deletions
diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp index 35f84ff483..7a45972649 100644 --- a/lib/AST/VTableBuilder.cpp +++ b/lib/AST/VTableBuilder.cpp @@ -466,10 +466,10 @@ public: static bool HasSameVirtualSignature(const CXXMethodDecl *LHS, const CXXMethodDecl *RHS) { - ASTContext &C = LHS->getASTContext(); // TODO: thread this down - CanQual<FunctionProtoType> - LT = C.getCanonicalType(LHS->getType()).getAs<FunctionProtoType>(), - RT = C.getCanonicalType(RHS->getType()).getAs<FunctionProtoType>(); + const FunctionProtoType *LT = + cast<FunctionProtoType>(LHS->getType().getCanonicalType()); + const FunctionProtoType *RT = + cast<FunctionProtoType>(RHS->getType().getCanonicalType()); // Fast-path matches in the canonical types. if (LT == RT) return true; @@ -477,7 +477,7 @@ static bool HasSameVirtualSignature(const CXXMethodDecl *LHS, // Force the signatures to match. We can't rely on the overrides // list here because there isn't necessarily an inheritance // relationship between the two methods. - if (LT.getQualifiers() != RT.getQualifiers() || + if (LT->getTypeQuals() != RT->getTypeQuals() || LT->getNumArgs() != RT->getNumArgs()) return false; for (unsigned I = 0, E = LT->getNumArgs(); I != E; ++I) diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp index bd696813c8..d7644b98ae 100644 --- a/test/CodeGenCXX/vtable-layout.cpp +++ b/test/CodeGenCXX/vtable-layout.cpp @@ -42,6 +42,7 @@ // RUN: FileCheck --check-prefix=CHECK-41 %s < %t // RUN: FileCheck --check-prefix=CHECK-42 %s < %t // RUN: FileCheck --check-prefix=CHECK-43 %s < %t +// RUN: FileCheck --check-prefix=CHECK-44 %s < %t // For now, just verify this doesn't crash. namespace test0 { @@ -1701,3 +1702,28 @@ struct C : B { C* C::f() { return 0; } } + +// rdar://problem/10959710 +namespace Test38 { + struct A { + virtual void *foo(); + virtual const void *foo() const; + }; + + // CHECK-44: Vtable for 'Test38::B' (7 entries). + // CHECK-44-NEXT: 0 | vbase_offset (0) + // CHECK-44-NEXT: 1 | vcall_offset (0) + // CHECK-44-NEXT: 2 | vcall_offset (0) + // CHECK-44-NEXT: 3 | offset_to_top (0) + // CHECK-44-NEXT: 4 | Test38::B RTTI + // CHECK-44-NEXT: -- (Test38::A, 0) vtable address -- + // CHECK-44-NEXT: -- (Test38::B, 0) vtable address -- + // CHECK-44-NEXT: 5 | void *Test38::B::foo() + // CHECK-44-NEXT: 6 | const void *Test38::B::foo() const + class B : virtual public A { + void *foo(); + const void *foo() const; + }; + + void *B::foo() { return 0; } +} |