1 | // RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s |
2 | // expected-no-diagnostics |
3 | |
4 | extern void __assert_fail (__const char *__assertion, __const char *__file, |
5 | unsigned int __line, __const char *__function) |
6 | __attribute__ ((__noreturn__)); |
7 | #define assert(expr) \ |
8 | ((expr) ? (void)(0) : __assert_fail (#expr, __FILE__, __LINE__, __func__)) |
9 | |
10 | class ButterFly { |
11 | private: |
12 | ButterFly() { } |
13 | public: |
14 | int triggerderef() { |
15 | return 0; |
16 | } |
17 | }; |
18 | ButterFly *getInP(); |
19 | class X{ |
20 | ButterFly *p; |
21 | void setP(ButterFly *inP) { |
22 | if(inP) |
23 | ; |
24 | p = inP; |
25 | }; |
26 | void subtest1() { |
27 | ButterFly *inP = getInP(); |
28 | setP(inP); |
29 | } |
30 | int subtest2() { |
31 | int c = p->triggerderef(); // no-warning |
32 | return c; |
33 | } |
34 | int test() { |
35 | subtest1(); |
36 | return subtest2(); |
37 | } |
38 | }; |
39 | |
40 | typedef const int *Ty; |
41 | extern |
42 | Ty notNullArg(Ty cf) __attribute__((nonnull)); |
43 | typedef const void *CFTypeRef; |
44 | extern Ty getTyVal(); |
45 | inline void radar13224271_callee(Ty def, Ty& result ) { |
46 | result = def; |
47 | // Clearly indicates that result cannot be 0 if def is not NULL. |
48 | assert( (result != 0) || (def == 0) ); |
49 | } |
50 | void radar13224271_caller() |
51 | { |
52 | Ty value; |
53 | radar13224271_callee(getTyVal(), value ); |
54 | notNullArg(value); // no-warning |
55 | } |
56 | |
57 | struct Foo { |
58 | int *ptr; |
59 | Foo(int *p) { |
60 | *p = 1; // no-warning |
61 | } |
62 | }; |
63 | void idc(int *p3) { |
64 | if (p3) |
65 | ; |
66 | } |
67 | int *retNull() { |
68 | return 0; |
69 | } |
70 | void test(int *p1, int *p2) { |
71 | idc(p1); |
72 | Foo f(p1); |
73 | } |
74 | |
75 | struct Bar { |
76 | int x; |
77 | }; |
78 | void idcBar(Bar *b) { |
79 | if (b) |
80 | ; |
81 | } |
82 | void testRefToField(Bar *b) { |
83 | idcBar(b); |
84 | int &x = b->x; // no-warning |
85 | x = 5; |
86 | } |
87 | |
88 | namespace get_deref_expr_with_cleanups { |
89 | struct S { |
90 | ~S(); |
91 | }; |
92 | S *conjure(); |
93 | // The argument won't be used, but it'll cause cleanups |
94 | // to appear around the call site. |
95 | S *get_conjured(S _) { |
96 | S *s = conjure(); |
97 | if (s) {} |
98 | return s; |
99 | } |
100 | void test_conjured() { |
101 | S &s = *get_conjured(S()); // no-warning |
102 | } |
103 | } // namespace get_deref_expr_with_cleanups |
104 | |