forked from OSchip/llvm-project
Warn when trying to call a pure virtual member function in a class from the class constructor/destructor. Fixes PR7966.
llvm-svn: 130982
This commit is contained in:
parent
5fe4a7dc96
commit
47061ee5bc
|
@ -728,6 +728,10 @@ def err_implicit_object_parameter_init : Error<
|
||||||
def err_qualified_member_of_unrelated : Error<
|
def err_qualified_member_of_unrelated : Error<
|
||||||
"%q0 is not a member of class %1">;
|
"%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">;
|
||||||
|
|
||||||
def note_field_decl : Note<"member is declared here">;
|
def note_field_decl : Note<"member is declared here">;
|
||||||
def note_ivar_decl : Note<"ivar is declared here">;
|
def note_ivar_decl : Note<"ivar is declared here">;
|
||||||
def note_bitfield_decl : Note<"bit-field is declared here">;
|
def note_bitfield_decl : Note<"bit-field is declared here">;
|
||||||
|
|
|
@ -8781,6 +8781,19 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
|
||||||
if (CheckFunctionCall(Method, TheCall))
|
if (CheckFunctionCall(Method, TheCall))
|
||||||
return ExprError();
|
return ExprError();
|
||||||
|
|
||||||
|
if ((isa<CXXConstructorDecl>(CurContext) ||
|
||||||
|
isa<CXXDestructorDecl>(CurContext)) &&
|
||||||
|
TheCall->getMethodDecl()->isPure()) {
|
||||||
|
const CXXMethodDecl *MD = TheCall->getMethodDecl();
|
||||||
|
|
||||||
|
if (isa<CXXThisExpr>(MemExpr->getBase()->IgnoreParenCasts()))
|
||||||
|
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();
|
||||||
|
}
|
||||||
return MaybeBindToTemporary(TheCall);
|
return MaybeBindToTemporary(TheCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +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'}}
|
||||||
|
|
||||||
|
virtual void f() = 0; // expected-note 2 {{'f' declared here}}
|
||||||
|
};
|
Loading…
Reference in New Issue