xref: /llvm-project/clang/test/Analysis/retain-count-alloc.cpp (revision 68983321cc966018d2d0408f1abe920d332033df)
1*68983321SCsaba Dabis // RUN: %clang_analyze_cc1 \
2*68983321SCsaba Dabis // RUN:  -analyzer-checker=core,unix.Malloc \
3*68983321SCsaba Dabis // RUN:  -verify %s
4*68983321SCsaba Dabis 
5*68983321SCsaba Dabis // expected-no-diagnostics: We do not model Integer Set Library's retain-count
6*68983321SCsaba Dabis //                          based allocation. If any of the parameters has an
7*68983321SCsaba Dabis //                          '__isl_' prefixed macro definition we escape every
8*68983321SCsaba Dabis //                          of them when we are about to 'free()' something.
9*68983321SCsaba Dabis 
10*68983321SCsaba Dabis #define __isl_take
11*68983321SCsaba Dabis #define __isl_keep
12*68983321SCsaba Dabis 
13*68983321SCsaba Dabis struct Object { int Ref; };
14*68983321SCsaba Dabis void free(void *);
15*68983321SCsaba Dabis 
copyObj(__isl_keep Object * O)16*68983321SCsaba Dabis Object *copyObj(__isl_keep Object *O) {
17*68983321SCsaba Dabis   O->Ref++;
18*68983321SCsaba Dabis   return O;
19*68983321SCsaba Dabis }
20*68983321SCsaba Dabis 
freeObj(__isl_take Object * O)21*68983321SCsaba Dabis void freeObj(__isl_take Object *O) {
22*68983321SCsaba Dabis   if (--O->Ref > 0)
23*68983321SCsaba Dabis     return;
24*68983321SCsaba Dabis 
25*68983321SCsaba Dabis   free(O); // Here we notice that the parameter contains '__isl_', escape it.
26*68983321SCsaba Dabis }
27*68983321SCsaba Dabis 
useAfterFree(__isl_take Object * A)28*68983321SCsaba Dabis void useAfterFree(__isl_take Object *A) {
29*68983321SCsaba Dabis   if (!A)
30*68983321SCsaba Dabis     return;
31*68983321SCsaba Dabis 
32*68983321SCsaba Dabis   Object *B = copyObj(A);
33*68983321SCsaba Dabis   freeObj(B);
34*68983321SCsaba Dabis 
35*68983321SCsaba Dabis   A->Ref = 13;
36*68983321SCsaba Dabis   // no-warning: 'Use of memory after it is freed' was here.
37*68983321SCsaba Dabis }
38