Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -11788,8 +11788,11 @@ TheCall->getMethodDecl()->isPure()) { const CXXMethodDecl *MD = TheCall->getMethodDecl(); - if (isa(MemExpr->getBase()->IgnoreParenCasts())) { - Diag(MemExpr->getLocStart(), + // If the member access is fully qualified, (i.e. X::f), treat + // it as a non-virtual call and don't warn. + if (isa(MemExpr->getBase()->IgnoreParenCasts()) && + !(MemExpr->getQualifier())) { + Diag(MemExpr->getLocStart(), diag::warn_call_to_pure_virtual_member_function_from_ctor_dtor) << MD->getDeclName() << isa(CurContext) << MD->getParent()->getDeclName(); Index: test/SemaCXX/warn-pure-virtual-call-from-ctor-dtor.cpp =================================================================== --- test/SemaCXX/warn-pure-virtual-call-from-ctor-dtor.cpp +++ test/SemaCXX/warn-pure-virtual-call-from-ctor-dtor.cpp @@ -12,3 +12,11 @@ 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(); + } +};