[pulse][objcpp][npe] Basic examples

Summary: Added some basic examples for Objective-C we want to address next in pulse nullptr dereference analysis. In particular, we should not get a `nil` dereference error when we call a method on `nil`, except if the method returns a non-POD (Plain Old Data) type.

Reviewed By: ezgicicek

Differential Revision: D26053402

fbshipit-source-id: 66f4600c3
master
Daiva Naudziuniene 4 years ago committed by Facebook GitHub Bot
parent 802dce02d1
commit e0f0022fa1

@ -0,0 +1,67 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/NSObject.h>
#include <memory>
@interface SomeObject : NSObject
@property int x;
@property std::shared_ptr<int> ptr;
- (int)returnsPOD;
- (std::shared_ptr<int>)returnsnonPOD;
@end
@implementation SomeObject
- (int)returnsPOD {
return _x;
}
- (std::shared_ptr<int>)returnsnonPOD {
return std::shared_ptr<int>(new int(_x));
}
@end
int dereferenceNilBad() {
int* int_ptr = nil;
return *int_ptr;
}
int FP_testCallMethodReturnsPODOk() {
SomeObject* obj = nil;
return [obj returnsPOD];
}
std::shared_ptr<int> testCallMethodReturnsnonPODBad() {
SomeObject* obj = nil;
std::shared_ptr<int> d = [obj returnsnonPOD]; // UB
return d;
}
int FP_testAccessPropertyAccessorOk() {
SomeObject* obj = nil;
return obj.x; // calls property accessor method
}
std::shared_ptr<int> testAccessPropertyAccessorBad() {
SomeObject* obj = nil;
return obj.ptr; // calls property accessor method, but return type is non-POD
}
int methodReturnsPOD(SomeObject* obj) { return [obj returnsPOD]; };
int FP_methodReturnsPODNilOk() { return methodReturnsPOD(nil); };
int methodReturnsPODNotNilOK() {
SomeObject* o = [SomeObject new];
return methodReturnsPOD(o);
}

@ -1,3 +1,9 @@
codetoanalyze/objcpp/pulse/AllocPatternMemLeak.mm, A.create_no_release_leak_bad, 1, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by call to `ABFDataCreate` (modelled),allocation part of the trace ends here,memory becomes unreachable here] codetoanalyze/objcpp/pulse/AllocPatternMemLeak.mm, A.create_no_release_leak_bad, 1, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by call to `ABFDataCreate` (modelled),allocation part of the trace ends here,memory becomes unreachable here]
codetoanalyze/objcpp/pulse/NPEBasic.mm, FP_methodReturnsPODNilOk, 0, NULLPTR_DEREFERENCE, no_bucket, ERROR, [invalidation part of the trace starts here,assigned,is the null pointer,use-after-lifetime part of the trace starts here,when calling `methodReturnsPOD` here,parameter `obj` of methodReturnsPOD,when calling `SomeObject.returnsPOD` here,parameter `self` of SomeObject.returnsPOD,invalid access occurs here]
codetoanalyze/objcpp/pulse/NPEBasic.mm, FP_testAccessPropertyAccessorOk, 2, NULLPTR_DEREFERENCE, no_bucket, ERROR, [invalidation part of the trace starts here,assigned,is the null pointer,use-after-lifetime part of the trace starts here,assigned,when calling `SomeObject.x` here,parameter `self` of SomeObject.x,invalid access occurs here]
codetoanalyze/objcpp/pulse/NPEBasic.mm, FP_testCallMethodReturnsPODOk, 2, NULLPTR_DEREFERENCE, no_bucket, ERROR, [invalidation part of the trace starts here,assigned,is the null pointer,use-after-lifetime part of the trace starts here,assigned,when calling `SomeObject.returnsPOD` here,parameter `self` of SomeObject.returnsPOD,invalid access occurs here]
codetoanalyze/objcpp/pulse/NPEBasic.mm, dereferenceNilBad, 2, NULLPTR_DEREFERENCE, no_bucket, ERROR, [invalidation part of the trace starts here,assigned,is the null pointer,use-after-lifetime part of the trace starts here,assigned,invalid access occurs here]
codetoanalyze/objcpp/pulse/NPEBasic.mm, testAccessPropertyAccessorBad, 2, NULLPTR_DEREFERENCE, no_bucket, ERROR, [invalidation part of the trace starts here,assigned,is the null pointer,use-after-lifetime part of the trace starts here,assigned,when calling `SomeObject.ptr` here,parameter `self` of SomeObject.ptr,invalid access occurs here]
codetoanalyze/objcpp/pulse/NPEBasic.mm, testCallMethodReturnsnonPODBad, 2, NULLPTR_DEREFERENCE, no_bucket, ERROR, [invalidation part of the trace starts here,assigned,is the null pointer,use-after-lifetime part of the trace starts here,assigned,when calling `SomeObject.returnsnonPOD` here,parameter `self` of SomeObject.returnsnonPOD,invalid access occurs here]
codetoanalyze/objcpp/pulse/use_after_delete.mm, PulseTest.deref_deleted_in_objc_method_bad, 3, USE_AFTER_DELETE, no_bucket, ERROR, [invalidation part of the trace starts here,passed as argument to `new` (modelled),return from call to `new` (modelled),assigned,was invalidated by `delete`,use-after-lifetime part of the trace starts here,passed as argument to `new` (modelled),return from call to `new` (modelled),assigned,when calling `Simple::Simple` here,parameter `__param_0` of Simple::Simple,invalid access occurs here] codetoanalyze/objcpp/pulse/use_after_delete.mm, PulseTest.deref_deleted_in_objc_method_bad, 3, USE_AFTER_DELETE, no_bucket, ERROR, [invalidation part of the trace starts here,passed as argument to `new` (modelled),return from call to `new` (modelled),assigned,was invalidated by `delete`,use-after-lifetime part of the trace starts here,passed as argument to `new` (modelled),return from call to `new` (modelled),assigned,when calling `Simple::Simple` here,parameter `__param_0` of Simple::Simple,invalid access occurs here]
codetoanalyze/objcpp/pulse/use_after_delete.mm, deref_deleted_bad, 3, USE_AFTER_DELETE, no_bucket, ERROR, [invalidation part of the trace starts here,passed as argument to `new` (modelled),return from call to `new` (modelled),assigned,was invalidated by `delete`,use-after-lifetime part of the trace starts here,passed as argument to `new` (modelled),return from call to `new` (modelled),assigned,when calling `Simple::Simple` here,parameter `__param_0` of Simple::Simple,invalid access occurs here] codetoanalyze/objcpp/pulse/use_after_delete.mm, deref_deleted_bad, 3, USE_AFTER_DELETE, no_bucket, ERROR, [invalidation part of the trace starts here,passed as argument to `new` (modelled),return from call to `new` (modelled),assigned,was invalidated by `delete`,use-after-lifetime part of the trace starts here,passed as argument to `new` (modelled),return from call to `new` (modelled),assigned,when calling `Simple::Simple` here,parameter `__param_0` of Simple::Simple,invalid access occurs here]

Loading…
Cancel
Save