summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h2
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp3
-rw-r--r--clang/lib/StaticAnalyzer/Core/CallEvent.cpp11
-rw-r--r--clang/test/Analysis/Inputs/system-header-simulator-objc.h7
-rw-r--r--clang/test/Analysis/malloc.m5
5 files changed, 25 insertions, 3 deletions
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index d69f50a9a2f..e2baf38e0be 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -885,6 +885,8 @@ public:
virtual RuntimeDefinition getRuntimeDefinition() const;
+ virtual bool argumentsMayEscape() const;
+
virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
BindingsTy &Bindings) const;
diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 82a1aa22579..87d7e89e52e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -1907,7 +1907,8 @@ bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly(
// that the pointers get freed by following the container itself.
if (FirstSlot.startswith("addPointer") ||
FirstSlot.startswith("insertPointer") ||
- FirstSlot.startswith("replacePointer")) {
+ FirstSlot.startswith("replacePointer") ||
+ FirstSlot.equals("valueWithPointer")) {
return true;
}
diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
index e0392bd1473..838d273cc0a 100644
--- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -886,6 +886,17 @@ RuntimeDefinition ObjCMethodCall::getRuntimeDefinition() const {
return RuntimeDefinition();
}
+bool ObjCMethodCall::argumentsMayEscape() const {
+ if (isInSystemHeader() && !isInstanceMessage()) {
+ Selector Sel = getSelector();
+ if (Sel.getNumArgs() == 1 &&
+ Sel.getIdentifierInfoForSlot(0)->isStr("valueWithPointer"))
+ return true;
+ }
+
+ return CallEvent::argumentsMayEscape();
+}
+
void ObjCMethodCall::getInitialStackFrameContents(
const StackFrameContext *CalleeCtx,
BindingsTy &Bindings) const {
diff --git a/clang/test/Analysis/Inputs/system-header-simulator-objc.h b/clang/test/Analysis/Inputs/system-header-simulator-objc.h
index 3e1d9555bbd..8a5d3b6403c 100644
--- a/clang/test/Analysis/Inputs/system-header-simulator-objc.h
+++ b/clang/test/Analysis/Inputs/system-header-simulator-objc.h
@@ -66,8 +66,11 @@ typedef struct {
NSFastEnumerationState;
@protocol NSFastEnumeration - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
@end @class NSString, NSDictionary;
-@interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value;
-@end @interface NSNumber : NSValue - (char)charValue;
+@interface NSValue : NSObject <NSCopying, NSCoding>
++ (NSValue *)valueWithPointer:(const void *)p;
+- (void)getValue:(void *)value;
+@end
+@interface NSNumber : NSValue - (char)charValue;
- (id)initWithInt:(int)value;
@end @class NSString;
@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count;
diff --git a/clang/test/Analysis/malloc.m b/clang/test/Analysis/malloc.m
index ad16db52dff..9201c2b75fe 100644
--- a/clang/test/Analysis/malloc.m
+++ b/clang/test/Analysis/malloc.m
@@ -49,4 +49,9 @@ void _ArrayCreate() {
void testNSDataTruePositiveLeak() {
char *b = (char *)malloc(12);
NSData *d = [[NSData alloc] initWithBytes: b length: 12]; // expected-warning {{Potential leak of memory pointed to by 'b'}}
+}
+
+id wrapInNSValue() {
+ void *buffer = malloc(4);
+ return [NSValue valueWithPointer:buffer]; // no-warning
} \ No newline at end of file
OpenPOWER on IntegriCloud