forked from OSchip/llvm-project
[analyzer] Support implicit parameter 'self' in path note
showBRParamDiagnostics assumed stores happen only via function parameters while that can also happen via implicit parameters like 'self' or 'this'. The regression test caused a failed assert in the original cast to ParmVarDecl. Differential Revision: https://reviews.llvm.org/D133815
This commit is contained in:
parent
ba39a6e14a
commit
85d97aac80
|
@ -1340,13 +1340,12 @@ static void showBRDiagnostics(llvm::raw_svector_ostream &OS, StoreInfo SI) {
|
|||
static void showBRParamDiagnostics(llvm::raw_svector_ostream &OS,
|
||||
StoreInfo SI) {
|
||||
const auto *VR = cast<VarRegion>(SI.Dest);
|
||||
const auto *Param = cast<ParmVarDecl>(VR->getDecl());
|
||||
const auto *D = VR->getDecl();
|
||||
|
||||
OS << "Passing ";
|
||||
|
||||
if (isa<loc::ConcreteInt>(SI.Value)) {
|
||||
OS << (isObjCPointer(Param) ? "nil object reference"
|
||||
: "null pointer value");
|
||||
OS << (isObjCPointer(D) ? "nil object reference" : "null pointer value");
|
||||
|
||||
} else if (SI.Value.isUndef()) {
|
||||
OS << "uninitialized value";
|
||||
|
@ -1361,12 +1360,19 @@ static void showBRParamDiagnostics(llvm::raw_svector_ostream &OS,
|
|||
OS << "value";
|
||||
}
|
||||
|
||||
// Printed parameter indexes are 1-based, not 0-based.
|
||||
unsigned Idx = Param->getFunctionScopeIndex() + 1;
|
||||
OS << " via " << Idx << llvm::getOrdinalSuffix(Idx) << " parameter";
|
||||
if (VR->canPrintPretty()) {
|
||||
OS << " ";
|
||||
VR->printPretty(OS);
|
||||
if (const auto *Param = dyn_cast<ParmVarDecl>(VR->getDecl())) {
|
||||
// Printed parameter indexes are 1-based, not 0-based.
|
||||
unsigned Idx = Param->getFunctionScopeIndex() + 1;
|
||||
OS << " via " << Idx << llvm::getOrdinalSuffix(Idx) << " parameter";
|
||||
if (VR->canPrintPretty()) {
|
||||
OS << " ";
|
||||
VR->printPretty(OS);
|
||||
}
|
||||
} else if (const auto *ImplParam = dyn_cast<ImplicitParamDecl>(D)) {
|
||||
if (ImplParam->getParameterKind() ==
|
||||
ImplicitParamDecl::ImplicitParamKind::ObjCSelf) {
|
||||
OS << " via implicit parameter 'self'";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-output=text -verify %s
|
||||
|
||||
@protocol NSObject
|
||||
@end
|
||||
|
||||
@interface NSObject <NSObject> {}
|
||||
- (id)init;
|
||||
+ (id)alloc;
|
||||
- (id)autorelease;
|
||||
@end
|
||||
|
||||
@interface Foo : NSObject
|
||||
@property(nonatomic) int bar;
|
||||
@end
|
||||
|
||||
@implementation Foo
|
||||
-(int)bar {
|
||||
return 0;
|
||||
}
|
||||
@end
|
||||
|
||||
int baz() {
|
||||
Foo *f = [Foo alloc];
|
||||
// expected-note@-1 {{'f' initialized here}}
|
||||
// expected-note@-2 {{Method returns an instance of Foo with a +1 retain count}}
|
||||
|
||||
return f.bar;
|
||||
// expected-warning@-1 {{Potential leak of an object stored into 'self' [osx.cocoa.RetainCount]}}
|
||||
// expected-note@-2 {{Passing value via implicit parameter 'self'}}
|
||||
// expected-note@-3 {{Object leaked: object allocated and stored into 'self' is not referenced later in this execution path and has a retain count of +1}}
|
||||
}
|
Loading…
Reference in New Issue