forked from OSchip/llvm-project
Warn on missing [super dealloc] calls.
This matches gcc's logic. Half of PR10661. llvm-svn: 138240
This commit is contained in:
parent
41c6dcc734
commit
715abaf213
|
@ -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
|
||||
]>;
|
||||
|
||||
|
|
|
@ -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<
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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::
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue