r242246 - [Sema] Don't emit "pure virtual" warning for fully qualified calls.
Davide Italiano
davide at freebsd.org
Tue Jul 14 16:36:11 PDT 2015
Author: davide
Date: Tue Jul 14 18:36:10 2015
New Revision: 242246
URL: http://llvm.org/viewvc/llvm-project?rev=242246&view=rev
Log:
[Sema] Don't emit "pure virtual" warning for fully qualified calls.
-fapple-kext is an exception because calls will still go through
the vtable in that mode. Add a note to make the user aware of that.
PR: 23215
Differential Revision: http://reviews.llvm.org/D10935
Added:
cfe/trunk/test/SemaCXX/warn-pure-virtual-kext.cpp
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/test/SemaCXX/warn-pure-virtual-call-from-ctor-dtor.cpp
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=242246&r1=242245&r2=242246&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Tue Jul 14 18:36:10 2015
@@ -23,6 +23,7 @@
#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h"
#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/LangOptions.h"
#include "clang/Basic/TypeTraits.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APSInt.h"
@@ -2575,6 +2576,14 @@ public:
HadMultipleCandidates = V;
}
+ /// \brief Returns true if virtual dispatch is performed.
+ /// If the member access is fully qualified, (i.e. X::f()), virtual
+ /// dispatching is not performed. In -fapple-kext mode qualified
+ /// calls to virtual method will still go through the vtable.
+ bool performsVirtualDispatch(const LangOptions &LO) const {
+ return LO.AppleKext || !hasQualifier();
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == MemberExprClass;
}
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=242246&r1=242245&r2=242246&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jul 14 18:36:10 2015
@@ -1100,6 +1100,9 @@ def err_type_defined_in_alias_template :
def note_pure_virtual_function : Note<
"unimplemented pure virtual method %0 in %1">;
+def note_pure_qualified_call_kext : Note<
+ "qualified call to %0::%1 is treated as a virtual call to %1 due to -fapple-kext">;
+
def err_deleted_decl_not_first : Error<
"deleted definition must be first declaration">;
@@ -1312,8 +1315,9 @@ def err_qualified_member_of_unrelated :
"%q0 is not a member of class %1">;
def warn_call_to_pure_virtual_member_function_from_ctor_dtor : Warning<
- "call to pure virtual member function %0; overrides of %0 in subclasses are "
- "not available in the %select{constructor|destructor}1 of %2">;
+ "call to pure virtual member function %0 has undefined behavior; "
+ "overrides of %0 in subclasses are not available in the "
+ "%select{constructor|destructor}1 of %2">;
def note_member_declared_at : Note<"member is declared here">;
def note_ivar_decl : Note<"instance variable is declared here">;
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=242246&r1=242245&r2=242246&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jul 14 18:36:10 2015
@@ -13241,7 +13241,8 @@ static void MarkExprReferenced(Sema &Sem
if (!MD)
return;
// Only attempt to devirtualize if this is truly a virtual call.
- bool IsVirtualCall = MD->isVirtual() && !ME->hasQualifier();
+ bool IsVirtualCall = MD->isVirtual() &&
+ ME->performsVirtualDispatch(SemaRef.getLangOpts());
if (!IsVirtualCall)
return;
const Expr *Base = ME->getBase();
@@ -13275,7 +13276,7 @@ void Sema::MarkMemberReferenced(MemberEx
// expression, is odr-used, unless it is a pure virtual function and its
// name is not explicitly qualified.
bool OdrUse = true;
- if (!E->hasQualifier()) {
+ if (E->performsVirtualDispatch(getLangOpts())) {
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(E->getMemberDecl()))
if (Method->isPure())
OdrUse = false;
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=242246&r1=242245&r2=242246&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Jul 14 18:36:10 2015
@@ -11772,13 +11772,19 @@ Sema::BuildCallToMemberFunction(Scope *S
TheCall->getMethodDecl()->isPure()) {
const CXXMethodDecl *MD = TheCall->getMethodDecl();
- if (isa<CXXThisExpr>(MemExpr->getBase()->IgnoreParenCasts())) {
- Diag(MemExpr->getLocStart(),
+ if (isa<CXXThisExpr>(MemExpr->getBase()->IgnoreParenCasts()) &&
+ MemExpr->performsVirtualDispatch(getLangOpts())) {
+ Diag(MemExpr->getLocStart(),
diag::warn_call_to_pure_virtual_member_function_from_ctor_dtor)
<< MD->getDeclName() << isa<CXXDestructorDecl>(CurContext)
<< MD->getParent()->getDeclName();
Diag(MD->getLocStart(), diag::note_previous_decl) << MD->getDeclName();
+ if (getLangOpts().AppleKext)
+ Diag(MemExpr->getLocStart(),
+ diag::note_pure_qualified_call_kext)
+ << MD->getParent()->getDeclName()
+ << MD->getDeclName();
}
}
return MaybeBindToTemporary(TheCall);
Modified: cfe/trunk/test/SemaCXX/warn-pure-virtual-call-from-ctor-dtor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-pure-virtual-call-from-ctor-dtor.cpp?rev=242246&r1=242245&r2=242246&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-pure-virtual-call-from-ctor-dtor.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-pure-virtual-call-from-ctor-dtor.cpp Tue Jul 14 18:36:10 2015
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 %s -fsyntax-only -verify
struct A {
- A() { f(); } // expected-warning {{call to pure virtual member function 'f'; overrides of 'f' in subclasses are not available in the constructor of 'A'}}
- ~A() { f(); } // expected-warning {{call to pure virtual member function 'f'; overrides of 'f' in subclasses are not available in the destructor of 'A'}}
+ A() { f(); } // expected-warning {{call to pure virtual member function 'f' has undefined behavior; overrides of 'f' in subclasses are not available in the constructor of 'A'}}
+ ~A() { f(); } // expected-warning {{call to pure virtual member function 'f' has undefined behavior; overrides of 'f' in subclasses are not available in the destructor of 'A'}}
virtual void f() = 0; // expected-note 2 {{'f' declared here}}
};
@@ -12,3 +12,11 @@ struct B {
B() { a->f(); };
~B() { a->f(); };
};
+
+// Don't warn if the call is fully qualified. (PR23215)
+struct C {
+ virtual void f() = 0;
+ C() {
+ C::f();
+ }
+};
Added: cfe/trunk/test/SemaCXX/warn-pure-virtual-kext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-pure-virtual-kext.cpp?rev=242246&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-pure-virtual-kext.cpp (added)
+++ cfe/trunk/test/SemaCXX/warn-pure-virtual-kext.cpp Tue Jul 14 18:36:10 2015
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -fapple-kext -fsyntax-only -verify
+
+struct A {
+ virtual void f() = 0; // expected-note {{'f' declared here}}
+ A() {
+ A::f(); // expected-warning {{call to pure virtual member function 'f' has undefined behavior; overrides of 'f' in subclasses are not available in the constructor of 'A'}} // expected-note {{qualified call to 'A'::'f' is treated as a virtual call to 'f' due to -fapple-kext}}
+ }
+};
More information about the cfe-commits
mailing list