Warn on missing [super dealloc] calls.

This matches gcc's logic. Half of PR10661.

llvm-svn: 138240
This commit is contained in:
Nico Weber 2011-08-22 17:25:57 +00:00
parent 41c6dcc734
commit 715abaf213
8 changed files with 64 additions and 3 deletions

View File

@ -96,6 +96,7 @@ def OutOfLineDeclaration : DiagGroup<"out-of-line-declaration">;
def : DiagGroup<"overflow">;
def OverlengthStrings : DiagGroup<"overlength-strings">;
def OverloadedVirtual : DiagGroup<"overloaded-virtual">;
def ObjCMissingSuperCalls : DiagGroup<"objc-missing-super-calls">;
def Packed : DiagGroup<"packed">;
def Padded : DiagGroup<"padded">;
def PointerArith : DiagGroup<"pointer-arith">;
@ -273,6 +274,7 @@ def Most : DiagGroup<"most", [
UnknownPragmas,
Unused,
VolatileRegisterVar,
ObjCMissingSuperCalls,
OverloadedVirtual
]>;

View File

@ -570,6 +570,9 @@ def error_property_implemented : Error<"property %0 is already implemented">;
def warn_objc_property_attr_mutually_exclusive : Warning<
"property attributes '%0' and '%1' are mutually exclusive">,
InGroup<ReadOnlySetterAttrs>, DefaultIgnore;
def warn_objc_missing_super_dealloc : Warning<
"method possibly missing a [super dealloc] call">,
InGroup<ObjCMissingSuperCalls>;
def warn_undeclared_selector : Warning<
"undeclared selector %0">, InGroup<UndeclaredSelector>, DefaultIgnore;
def warn_implicit_atomic_property : Warning<

View File

@ -489,6 +489,11 @@ public:
/// have been declared.
bool GlobalNewDeleteDeclared;
/// A flag that is set when parsing a -dealloc method and no [super dealloc]
/// call was found yet.
bool ObjCShouldCallSuperDealloc;
/// \brief The set of declarations that have been referenced within
/// a potentially evaluated expression.
typedef SmallVector<std::pair<SourceLocation, Decl *>, 10>

View File

@ -84,6 +84,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
ExprNeedsCleanups(0), LateTemplateParser(0), OpaqueParser(0),
IdResolver(pp.getLangOptions()), CXXTypeInfoDecl(0), MSVCGuidDecl(0),
GlobalNewDeleteDeclared(false),
ObjCShouldCallSuperDealloc(false),
CompleteTranslationUnit(CompleteTranslationUnit),
NumSFINAEErrors(0), SuppressAccessChecking(false),
AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false),

View File

@ -6690,10 +6690,17 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
DiagnoseSizeOfParametersAndReturnValue(MD->param_begin(), MD->param_end(),
MD->getResultType(), MD);
}
if (ObjCShouldCallSuperDealloc) {
Diag(MD->getLocEnd(), diag::warn_objc_missing_super_dealloc);
ObjCShouldCallSuperDealloc = false;
}
} else {
return 0;
}
assert(!ObjCShouldCallSuperDealloc && "This should only be set for "
"ObjC methods, which should have been handled in the block above.");
// Verify and clean out per-function state.
if (Body) {
// C++ constructors that have function-try-blocks can't have return

View File

@ -278,14 +278,22 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) {
}
}
// Warn on implementating deprecated methods under
// -Wdeprecated-implementations flag.
if (ObjCInterfaceDecl *IC = MDecl->getClassInterface())
// Warn on deprecated methods under -Wdeprecated-implementations,
// and prepare for warning on missing super calls.
if (ObjCInterfaceDecl *IC = MDecl->getClassInterface()) {
if (ObjCMethodDecl *IMD =
IC->lookupMethod(MDecl->getSelector(), MDecl->isInstanceMethod()))
DiagnoseObjCImplementedDeprecations(*this,
dyn_cast<NamedDecl>(IMD),
MDecl->getLocation(), 0);
// If this is "dealloc", set some bit here.
// Then in ActOnSuperMessage() (SemaExprObjC), set it back to false.
// Finally, in ActOnFinishFunctionBody() (SemaDecl), warn if flag is set.
// Only do this if the current class actually has a superclass.
if (IC->getSuperClass())
ObjCShouldCallSuperDealloc = MDecl->getMethodFamily() == OMF_dealloc;
}
}
Decl *Sema::

View File

@ -975,6 +975,9 @@ ExprResult Sema::ActOnSuperMessage(Scope *S,
// We are in a method whose class has a superclass, so 'super'
// is acting as a keyword.
if (Method->isInstanceMethod()) {
if (Sel.getMethodFamily() == OMF_dealloc)
ObjCShouldCallSuperDealloc = false;
// Since we are in an instance method, this is an instance
// message to the superclass instance.
QualType SuperTy = Context.getObjCInterfaceType(Super);

View File

@ -0,0 +1,32 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
@protocol NSCopying @end
@interface NSObject <NSCopying>
- (void)dealloc;
@end
@implementation NSObject
- (void)dealloc {
// Root class, shouldn't warn
}
@end
@interface Subclass1 : NSObject
- (void)dealloc;
@end
@implementation Subclass1
- (void)dealloc {
} // expected-warning{{method possibly missing a [super dealloc] call}}
@end
@interface Subclass2 : NSObject
- (void)dealloc;
@end
@implementation Subclass2
- (void)dealloc {
[super dealloc]; // Shouldn't warn
}
@end