1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -verify %s
4 typedef __SIZE_TYPE__
size_t;
6 typedef enum memory_order
{
7 memory_order_relaxed
= __ATOMIC_RELAXED
,
10 void *calloc(size_t, size_t);
18 static struct SomeData
*alloc_data(void)
20 struct SomeData
*data
= calloc(sizeof(*data
), 1);
22 __c11_atomic_store(&data
->ref
, 2, memory_order_relaxed
);
26 static void put_data(struct SomeData
*data
)
28 if (__c11_atomic_fetch_sub(&data
->ref
, 1, memory_order_relaxed
) == 1)
32 static int dec_refcounter(struct SomeData
*data
)
34 return __c11_atomic_fetch_sub(&data
->ref
, 1, memory_order_relaxed
) == 1;
37 static void put_data_nested(struct SomeData
*data
)
39 if (dec_refcounter(data
))
43 static void put_data_uncond(struct SomeData
*data
)
48 static void put_data_unrelated_atomic(struct SomeData
*data
)
51 __c11_atomic_fetch_sub(&data
->ref
, 1, memory_order_relaxed
);
54 void test_no_uaf(void)
56 struct SomeData
*data
= alloc_data();
58 data
->i
+= 1; // no warning
61 void test_no_uaf_nested(void)
63 struct SomeData
*data
= alloc_data();
64 put_data_nested(data
);
65 data
->i
+= 1; // no warning
70 struct SomeData
*data
= alloc_data();
71 put_data_uncond(data
);
72 data
->i
+= 1; // expected-warning{{Use of memory after it is freed}}
75 void test_no_uaf_atomic_after(void)
77 struct SomeData
*data
= alloc_data();
78 put_data_unrelated_atomic(data
);
79 data
->i
+= 1; // expected-warning{{Use of memory after it is freed}}