brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.7 KiB · 97fde38 Raw
99 lines · cpp
1// RUN: %clang_analyze_cc1 -verify \2// RUN:   -analyzer-checker=core \3// RUN:   -analyzer-checker=alpha.deadcode.UnreachableCode \4// RUN:   -analyzer-checker=unix.Malloc \5// RUN:   -analyzer-config unix.DynamicMemoryModeling:Optimistic=true %s6 7typedef __typeof(sizeof(int)) size_t;8void *malloc(size_t);9void free(void *);10 11struct MemoryAllocator {12  void __attribute((ownership_returns(malloc))) * my_malloc(size_t);13  void __attribute((ownership_takes(malloc, 2))) my_free(void *);14  void __attribute((ownership_holds(malloc, 2))) my_hold(void *);15};16 17void *myglobalpointer;18 19struct stuff {20  void *somefield;21};22 23struct stuff myglobalstuff;24 25void af1(MemoryAllocator &Alloc) {26  void *p = Alloc.my_malloc(12);27  return; // expected-warning{{Potential leak of memory pointed to by}}28}29 30void af1_b(MemoryAllocator &Alloc) {31  void *p = Alloc.my_malloc(12);32} // expected-warning{{Potential leak of memory pointed to by}}33 34void af1_c(MemoryAllocator &Alloc) {35  myglobalpointer = Alloc.my_malloc(12); // no-warning36}37 38// Test that we can pass out allocated memory via pointer-to-pointer.39void af1_e(MemoryAllocator &Alloc, void **pp) {40  *pp = Alloc.my_malloc(42); // no-warning41}42 43void af1_f(MemoryAllocator &Alloc, struct stuff *somestuff) {44  somestuff->somefield = Alloc.my_malloc(12); // no-warning45}46 47// Allocating memory for a field via multiple indirections to our arguments is OK.48void af1_g(MemoryAllocator &Alloc, struct stuff **pps) {49  *pps = (struct stuff *)Alloc.my_malloc(sizeof(struct stuff)); // no-warning50  (*pps)->somefield = Alloc.my_malloc(42); // no-warning51}52 53void af2(MemoryAllocator &Alloc) {54  void *p = Alloc.my_malloc(12);55  Alloc.my_free(p);56  free(p); // expected-warning{{Attempt to release already released memory}}57}58 59void af2b(MemoryAllocator &Alloc) {60  void *p = Alloc.my_malloc(12);61  free(p);62  Alloc.my_free(p); // expected-warning{{Attempt to release already released memory}}63}64 65void af2c(MemoryAllocator &Alloc) {66  void *p = Alloc.my_malloc(12);67  free(p);68  Alloc.my_hold(p); // expected-warning{{Attempt to release already released memory}}69}70 71// No leak if malloc returns null.72void af2e(MemoryAllocator &Alloc) {73  void *p = Alloc.my_malloc(12);74  if (!p)75    return; // no-warning76  free(p); // no-warning77}78 79// This case inflicts a possible double-free.80void af3(MemoryAllocator &Alloc) {81  void *p = Alloc.my_malloc(12);82  Alloc.my_hold(p);83  free(p); // expected-warning{{Attempt to release non-owned memory}}84}85 86void * af4(MemoryAllocator &Alloc) {87  void *p = Alloc.my_malloc(12);88  Alloc.my_free(p);89  return p; // expected-warning{{Use of memory after it is released}}90}91 92// This case is (possibly) ok, be conservative93void * af5(MemoryAllocator &Alloc) {94  void *p = Alloc.my_malloc(12);95  Alloc.my_hold(p);96  return p; // no-warning97}98 99