summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Sema/Sema.h2
-rw-r--r--clang/lib/Sema/Sema.cpp12
-rw-r--r--clang/lib/Sema/SemaCast.cpp8
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp12
-rw-r--r--clang/lib/Sema/SemaExpr.cpp4
-rw-r--r--clang/lib/Sema/SemaInit.cpp9
-rw-r--r--clang/test/CXX/special/class.dtor/p9.cpp7
-rw-r--r--clang/test/CodeGenCXX/key-function-vtable.cpp2
-rw-r--r--clang/test/SemaCXX/devirtualize-vtable-marking.cpp15
-rw-r--r--clang/test/SemaCXX/microsoft-dtor-lookup.cpp3
-rw-r--r--clang/test/SemaCXX/warn-weak-vtables.cpp26
-rw-r--r--clang/test/SemaTemplate/virtual-member-functions.cpp4
12 files changed, 35 insertions, 69 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index a53eda41e1f..f6d185e4916 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5182,8 +5182,6 @@ public:
// FIXME: I don't like this name.
void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath);
- bool BasePathInvolvesVirtualBase(const CXXCastPath &BasePath);
-
bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
SourceLocation Loc, SourceRange Range,
CXXCastPath *BasePath = nullptr,
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index b9aaf1616d6..ded6c303af8 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -337,18 +337,6 @@ ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty,
if (ExprTy == TypeTy)
return E;
- // If this is a derived-to-base cast to a through a virtual base, we
- // need a vtable.
- if (Kind == CK_DerivedToBase &&
- BasePathInvolvesVirtualBase(*BasePath)) {
- QualType T = E->getType();
- if (const PointerType *Pointer = T->getAs<PointerType>())
- T = Pointer->getPointeeType();
- if (const RecordType *RecordTy = T->getAs<RecordType>())
- MarkVTableUsed(E->getLocStart(),
- cast<CXXRecordDecl>(RecordTy->getDecl()));
- }
-
if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(E)) {
if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) {
ImpCast->setType(Ty);
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index a4c2d9b51c2..3e06a6477d6 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -665,12 +665,6 @@ void CastOperation::CheckDynamicCast() {
}
Kind = CK_DerivedToBase;
-
- // If we are casting to or through a virtual base class, we need a
- // vtable.
- if (Self.BasePathInvolvesVirtualBase(BasePath))
- Self.MarkVTableUsed(OpRange.getBegin(),
- cast<CXXRecordDecl>(SrcRecord->getDecl()));
return;
}
@@ -682,8 +676,6 @@ void CastOperation::CheckDynamicCast() {
<< SrcPointee.getUnqualifiedType() << SrcExpr.get()->getSourceRange();
SrcExpr = ExprError();
}
- Self.MarkVTableUsed(OpRange.getBegin(),
- cast<CXXRecordDecl>(SrcRecord->getDecl()));
// dynamic_cast is not available with -fno-rtti.
// As an exception, dynamic_cast to void* is available because it doesn't
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 1b9ccee9dbe..79732c354ca 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -1745,18 +1745,6 @@ void Sema::BuildBasePathArray(const CXXBasePaths &Paths,
BasePathArray.push_back(const_cast<CXXBaseSpecifier*>(Path[I].Base));
}
-/// \brief Determine whether the given base path includes a virtual
-/// base class.
-bool Sema::BasePathInvolvesVirtualBase(const CXXCastPath &BasePath) {
- for (CXXCastPath::const_iterator B = BasePath.begin(),
- BEnd = BasePath.end();
- B != BEnd; ++B)
- if ((*B)->isVirtual())
- return true;
-
- return false;
-}
-
/// CheckDerivedToBaseConversion - Check whether the Derived-to-Base
/// conversion (where Derived and Base are class types) is
/// well-formed, meaning that the conversion is unambiguous (and
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 4114b567136..8b9950847f5 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -11621,7 +11621,7 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
Destructor = cast<CXXDestructorDecl>(Destructor->getFirstDecl());
if (Destructor->isDefaulted() && !Destructor->isDeleted())
DefineImplicitDestructor(Loc, Destructor);
- if (Destructor->isVirtual())
+ if (Destructor->isVirtual() && getLangOpts().AppleKext)
MarkVTableUsed(Loc, Destructor->getParent());
} else if (CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(Func)) {
if (MethodDecl->isOverloadedOperator() &&
@@ -11641,7 +11641,7 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
DefineImplicitLambdaToBlockPointerConversion(Loc, Conversion);
else
DefineImplicitLambdaToFunctionPointerConversion(Loc, Conversion);
- } else if (MethodDecl->isVirtual())
+ } else if (MethodDecl->isVirtual() && getLangOpts().AppleKext)
MarkVTableUsed(Loc, MethodDecl->getParent());
}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index e7a8e9cacde..9aca373d97b 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -5880,15 +5880,6 @@ InitializationSequence::Perform(Sema &S,
&BasePath, IgnoreBaseAccess))
return ExprError();
- if (S.BasePathInvolvesVirtualBase(BasePath)) {
- QualType T = SourceType;
- if (const PointerType *Pointer = T->getAs<PointerType>())
- T = Pointer->getPointeeType();
- if (const RecordType *RecordTy = T->getAs<RecordType>())
- S.MarkVTableUsed(CurInit.get()->getLocStart(),
- cast<CXXRecordDecl>(RecordTy->getDecl()));
- }
-
ExprValueKind VK =
Step->Kind == SK_CastDerivedToBaseLValue ?
VK_LValue :
diff --git a/clang/test/CXX/special/class.dtor/p9.cpp b/clang/test/CXX/special/class.dtor/p9.cpp
index a03fcdb2495..42a4236a4a0 100644
--- a/clang/test/CXX/special/class.dtor/p9.cpp
+++ b/clang/test/CXX/special/class.dtor/p9.cpp
@@ -89,4 +89,11 @@ namespace test3 {
virtual ~B() {}
static void operator delete(void*);
};
+
+ void f() {
+#ifdef MSABI
+ // expected-note@+2 {{implicit default constructor for 'test3::B' first required here}}
+#endif
+ B use_vtable;
+ }
}
diff --git a/clang/test/CodeGenCXX/key-function-vtable.cpp b/clang/test/CodeGenCXX/key-function-vtable.cpp
index c443b5277e4..80ce497505d 100644
--- a/clang/test/CodeGenCXX/key-function-vtable.cpp
+++ b/clang/test/CodeGenCXX/key-function-vtable.cpp
@@ -41,7 +41,7 @@ struct X1 : X0 {
inline void X1::f() { }
-void use_X1(X1 *x1) { x1->f(); }
+void use_X1() { X1 x1; }
// FIXME: The checks are extremely difficult to get right when the globals
// aren't alphabetized
diff --git a/clang/test/SemaCXX/devirtualize-vtable-marking.cpp b/clang/test/SemaCXX/devirtualize-vtable-marking.cpp
index fc3e8ce7704..1b32182c4f2 100644
--- a/clang/test/SemaCXX/devirtualize-vtable-marking.cpp
+++ b/clang/test/SemaCXX/devirtualize-vtable-marking.cpp
@@ -1,29 +1,32 @@
// RUN: %clang_cc1 -verify -std=c++11 %s
-
+// expected-no-diagnostics
template <typename T> struct OwnPtr {
T *p;
~OwnPtr() {
- // expected-error@+1 {{invalid application of 'sizeof'}}
static_assert(sizeof(T) > 0, "incomplete T");
delete p;
}
};
namespace use_vtable_for_vcall {
-struct Incomplete; // expected-note {{forward declaration}}
+struct Incomplete;
struct A {
virtual ~A() {}
virtual void m() {}
};
-struct B : A { // expected-note {{in instantiation}}
+struct B : A {
B();
virtual void m() { }
virtual void m2() { static_cast<A *>(this)->m(); }
OwnPtr<Incomplete> m_sqlError;
};
-B *f() {
- return new B();
+void f() {
+ // Since B's constructor is declared out of line, nothing in this file
+ // references a vtable, so the destructor doesn't get built.
+ A *b = new B();
+ b->m();
+ delete b;
}
}
diff --git a/clang/test/SemaCXX/microsoft-dtor-lookup.cpp b/clang/test/SemaCXX/microsoft-dtor-lookup.cpp
index 412749f707e..312598e2863 100644
--- a/clang/test/SemaCXX/microsoft-dtor-lookup.cpp
+++ b/clang/test/SemaCXX/microsoft-dtor-lookup.cpp
@@ -23,8 +23,9 @@ struct VC : A, B {
virtual ~VC(); // expected-error {{member 'operator delete' found in multiple base classes of different types}}
};
-void f(VC vc) {
+void f() {
// This marks VC's vtable used.
+ VC vc;
}
}
diff --git a/clang/test/SemaCXX/warn-weak-vtables.cpp b/clang/test/SemaCXX/warn-weak-vtables.cpp
index 671ff297cfa..d3066538715 100644
--- a/clang/test/SemaCXX/warn-weak-vtables.cpp
+++ b/clang/test/SemaCXX/warn-weak-vtables.cpp
@@ -20,15 +20,14 @@ void f() {
virtual void f() { }
};
- A *a;
- a->f();
+ A a;
}
// Use the vtables
-void uses(A &a, B<int> &b, C &c) {
- a.f();
- b.f();
- c.f();
+void uses_abc() {
+ A a;
+ B<int> b;
+ C c;
}
// <rdar://problem/9979458>
@@ -52,10 +51,9 @@ public:
Parent::~Parent() {}
-void uses(Parent &p, Derived &d, VeryDerived &vd) {
- p.getFoo();
- d.getFoo();
- vd.getFoo();
+void uses_derived() {
+ Derived d;
+ VeryDerived vd;
}
template<typename T> struct TemplVirt {
@@ -72,8 +70,8 @@ template<> struct TemplVirt<long> { // expected-warning{{'TemplVirt<long>' has n
virtual void f() {}
};
-void uses(TemplVirt<float>& f, TemplVirt<bool>& b, TemplVirt<long>& l) {
- f.f();
- b.f();
- l.f();
+void uses_templ() {
+ TemplVirt<float> f;
+ TemplVirt<bool> b;
+ TemplVirt<long> l;
}
diff --git a/clang/test/SemaTemplate/virtual-member-functions.cpp b/clang/test/SemaTemplate/virtual-member-functions.cpp
index c2fc2634edd..4044f9e513d 100644
--- a/clang/test/SemaTemplate/virtual-member-functions.cpp
+++ b/clang/test/SemaTemplate/virtual-member-functions.cpp
@@ -110,12 +110,12 @@ namespace PR7114 {
namespace DynamicCast {
struct Y {};
template<typename T> struct X : virtual Y {
- virtual void foo() { T x; } // expected-error {{variable has incomplete type 'void'}}
+ virtual void foo() { T x; }
};
template<typename T> struct X2 : virtual Y {
virtual void foo() { T x; }
};
- Y* f(X<void>* x) { return dynamic_cast<Y*>(x); } // expected-note {{in instantiation of member function 'DynamicCast::X<void>::foo' requested here}}
+ Y* f(X<void>* x) { return dynamic_cast<Y*>(x); }
Y* f2(X<void>* x) { return dynamic_cast<Y*>(x); }
}
OpenPOWER on IntegriCloud