Dominic Chen | 184c624 | 2017-03-03 18:02:02 +0000 | [diff] [blame] | 1 | // RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s |
Anna Zaks | 5497d1a | 2013-03-09 03:23:19 +0000 | [diff] [blame] | 2 | // expected-no-diagnostics |
| 3 | |
Anna Zaks | 2672a4c | 2013-03-14 22:31:56 +0000 | [diff] [blame] | 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 | |
Anna Zaks | 5497d1a | 2013-03-09 03:23:19 +0000 | [diff] [blame] | 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 | } |
Anna Zaks | 2672a4c | 2013-03-14 22:31:56 +0000 | [diff] [blame] | 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 |
Anna Zaks | 94b48bd | 2013-04-05 23:50:11 +0000 | [diff] [blame] | 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); |
Artem Dergachev | 37de888 | 2017-04-24 19:30:33 +0000 | [diff] [blame] | 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 | } |
Artem Dergachev | 57790c5 | 2018-06-25 23:55:07 +0000 | [diff] [blame] | 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 |