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}} + } +}; _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
