Skip to content

Commit 9abf6d3

Browse files
authored
[analyzer] [MallocChecker] Assume functions with ownership_returns return unknown memory (#110115)
There is no good way to tell CSA if function with `ownership_returns` attribute returns initialized or not initialized memory. To make FP rate lower, let's assume that memory returned from such functions is unknown and do not reason about it. In future it would be great to add a way to annotate such behavior
1 parent 439dcfa commit 9abf6d3

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,9 +1811,9 @@ MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallEvent &Call,
18111811
if (!Att->args().empty()) {
18121812
return MallocMemAux(C, Call,
18131813
Call.getArgExpr(Att->args_begin()->getASTIndex()),
1814-
UndefinedVal(), State, Family);
1814+
UnknownVal(), State, Family);
18151815
}
1816-
return MallocMemAux(C, Call, UnknownVal(), UndefinedVal(), State, Family);
1816+
return MallocMemAux(C, Call, UnknownVal(), UnknownVal(), State, Family);
18171817
}
18181818

18191819
ProgramStateRef MallocChecker::MallocBindRetVal(CheckerContext &C,

clang/test/Analysis/malloc-annotations.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// RUN: -analyzer-checker=alpha.deadcode.UnreachableCode \
44
// RUN: -analyzer-checker=alpha.core.CastSize \
55
// RUN: -analyzer-checker=unix.Malloc \
6+
// RUN: -analyzer-checker=debug.ExprInspection \
67
// RUN: -analyzer-config unix.DynamicMemoryModeling:Optimistic=true %s
78

89
typedef __typeof(sizeof(int)) size_t;
@@ -23,6 +24,12 @@ void __attribute((ownership_holds(malloc, 1))) my_hold(void *);
2324
void __attribute((ownership_holds(malloc, 1)))
2425
__attribute((ownership_holds(malloc, 1)))
2526
__attribute((ownership_holds(malloc, 3))) my_hold2(void *, void *, void *);
27+
28+
__attribute((ownership_returns(user_malloc, 1))) void *user_malloc(size_t);
29+
__attribute((ownership_takes(user_malloc, 1))) void user_free(void *);
30+
31+
void clang_analyzer_dump(int);
32+
2633
void *my_malloc3(size_t);
2734
void *myglobalpointer;
2835
struct stuff {
@@ -273,3 +280,10 @@ void testMultipleFreeAnnotations(void) {
273280
my_freeBoth(p, q);
274281
}
275282

283+
void testNoUninitAttr(void) {
284+
int *p = user_malloc(sizeof(int));
285+
int read = p[0]; // no-warning
286+
clang_analyzer_dump(p[0]); // expected-warning{{Unknown}}
287+
user_free(p);
288+
}
289+

0 commit comments

Comments
 (0)