[PATCH] D35216: [analyzer] Escape symbols when creating std::initializer_list.
Artem Dergachev via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 2 08:02:14 PDT 2017
NoQ added inline comments.
================
Comment at: lib/StaticAnalyzer/Core/ExprEngine.cpp:1127
+ // only consist of ObjC objects, and escapes of ObjC objects
+ // aren't so important (eg., retain count checker ignores them).
+ if (isa<CXXStdInitializerListExpr>(Ex) ||
----------------
dcoughlin wrote:
> Note that we do have other ObjC checkers that rely on escaping of ObjC objects, such as the ObjCLoopChecker and ObjCDeallocChecker. I think having the TODO is great, but I'd like you to remove the the bit about "escapes of ObjC objects aren't so important".
Hmm, should have double-checked. Will fix.
================
Comment at: test/Analysis/objc-boxing.m:66
+ BoxableStruct bs;
+ bs.str = strdup("dynamic string"); // The duped string shall be owned by val.
+ NSValue *val = @(bs); // no-warning
----------------
dcoughlin wrote:
> In this case the duped string is not owned by `val`. NSValue doesn't take ownership of the string, so this *will* leak and we should warn about it.
I mean, the pointer to the raw string is stored inside the `NSValue`, and can be used or freed from there. The caller can free this string by looking into the `val`, even though `val` itself won't release the pointer (i guess i messed up the comment again). From MallocChecker's perspective, this is an escape and no-warning. If we free the string in this function, it'd most likely cause use-after-free in the caller.
I tested that the string is indeed not strduped during boxing:
**`$ cat test.m`**
```
#import <Foundation/Foundation.h>
typedef struct __attribute__((objc_boxable)) {
const char *str;
} BoxableStruct;
int main() {
BoxableStruct bs;
bs.str = strdup("dynamic string");
NSLog(@"%p\n", bs.str);
NSValue *val = @(bs);
BoxableStruct bs2;
[val getValue:&bs2];
NSLog(@"%p\n", bs2.str);
return 0;
}
```
**`$ clang test.m -framework Foundation`**
**`$ ./a.out`**
```
2017-10-02 17:56:00.004 a.out[17933:1083757] 0x7ffd23407380
2017-10-02 17:56:00.004 a.out[17933:1083757] 0x7ffd23407380
```
So it's possible to retrieve the exact same pointer from the boxed value. So if `val` is returned to the caller, like in the test, it shouldn't be freed.
If the `NSValue` itself dies and never escapes, then of course it's a leak, but in order to see that we'd need to model contents of `NSValue`.
https://reviews.llvm.org/D35216
More information about the cfe-commits
mailing list