xref: /llvm-project/clang/test/Analysis/retain-release-cpp-classes.cpp (revision bbc6d68297c8b0641eb8226dea7746a0d97ae33b)
1*bbc6d682SArtem Dergachev // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -analyzer-output=text -verify %s
2*bbc6d682SArtem Dergachev 
3*bbc6d682SArtem Dergachev // expected-no-diagnostics
4*bbc6d682SArtem Dergachev 
5*bbc6d682SArtem Dergachev typedef void *CFTypeRef;
6*bbc6d682SArtem Dergachev typedef struct _CFURLCacheRef *CFURLCacheRef;
7*bbc6d682SArtem Dergachev 
8*bbc6d682SArtem Dergachev CFTypeRef CustomCFRetain(CFTypeRef);
9*bbc6d682SArtem Dergachev void invalidate(void *);
10*bbc6d682SArtem Dergachev struct S1 {
11*bbc6d682SArtem Dergachev   CFTypeRef s;
returnFieldAtPlus0S112*bbc6d682SArtem Dergachev   CFTypeRef returnFieldAtPlus0() {
13*bbc6d682SArtem Dergachev     return s;
14*bbc6d682SArtem Dergachev   }
15*bbc6d682SArtem Dergachev };
16*bbc6d682SArtem Dergachev struct S2 {
17*bbc6d682SArtem Dergachev   S1 *s1;
18*bbc6d682SArtem Dergachev };
foo(S1 * s1)19*bbc6d682SArtem Dergachev void foo(S1 *s1) {
20*bbc6d682SArtem Dergachev   invalidate(s1);
21*bbc6d682SArtem Dergachev   S2 s2;
22*bbc6d682SArtem Dergachev   s2.s1 = s1;
23*bbc6d682SArtem Dergachev   CustomCFRetain(s1->returnFieldAtPlus0());
24*bbc6d682SArtem Dergachev 
25*bbc6d682SArtem Dergachev   // Definitely no leak end-of-path note here. The retained pointer
26*bbc6d682SArtem Dergachev   // is still accessible through s1 and s2.
27*bbc6d682SArtem Dergachev   ((void) 0); // no-warning
28*bbc6d682SArtem Dergachev 
29*bbc6d682SArtem Dergachev   // FIXME: Ideally we need to warn after this invalidate(). The per-function
30*bbc6d682SArtem Dergachev   // retain-release contract is violated: the programmer should release
31*bbc6d682SArtem Dergachev   // the symbol after it was retained, within the same function.
32*bbc6d682SArtem Dergachev   invalidate(&s2);
33*bbc6d682SArtem Dergachev }
34