Dominic Chen | 4a90bf8 | 2017-03-02 22:58:06 +0000 | [diff] [blame^] | 1 | // RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.CastToStruct,core -verify %s |
Daniel Marjamaki | 13264eb | 2016-09-26 15:17:18 +0000 | [diff] [blame] | 2 | |
| 3 | struct AB { |
| 4 | int A; |
| 5 | int B; |
| 6 | }; |
| 7 | |
| 8 | struct ABC { |
| 9 | int A; |
| 10 | int B; |
| 11 | int C; |
| 12 | }; |
| 13 | |
| 14 | struct Base { |
| 15 | Base() : A(0), B(0) {} |
| 16 | virtual ~Base() {} |
| 17 | |
| 18 | int A; |
| 19 | int B; |
| 20 | }; |
| 21 | |
| 22 | struct Derived : public Base { |
| 23 | Derived() : Base(), C(0) {} |
| 24 | int C; |
| 25 | }; |
| 26 | |
| 27 | void structToStruct(struct AB *P) { |
| 28 | struct AB Ab; |
| 29 | struct ABC *Abc; |
| 30 | Abc = (struct ABC *)&Ab; // expected-warning {{Casting data to a larger structure type and accessing a field can lead to memory access errors or data corruption}} |
| 31 | Abc = (struct ABC *)P; // No warning; It is not known what data P points at. |
| 32 | Abc = (struct ABC *)&*P; |
| 33 | |
| 34 | // Don't warn when the cast is not widening. |
| 35 | P = (struct AB *)&Ab; // struct AB * => struct AB * |
| 36 | struct ABC Abc2; |
| 37 | P = (struct AB *)&Abc2; // struct ABC * => struct AB * |
| 38 | |
| 39 | // True negatives when casting from Base to Derived. |
| 40 | Derived D1, *D2; |
| 41 | Base &B1 = D1; |
| 42 | D2 = (Derived *)&B1; |
| 43 | D2 = dynamic_cast<Derived *>(&B1); |
| 44 | D2 = static_cast<Derived *>(&B1); |
| 45 | |
| 46 | // True positives when casting from Base to Derived. |
| 47 | Base B2; |
| 48 | D2 = (Derived *)&B2;// expected-warning {{Casting data to a larger structure type and accessing a field can lead to memory access errors or data corruption}} |
| 49 | D2 = dynamic_cast<Derived *>(&B2);// expected-warning {{Casting data to a larger structure type and accessing a field can lead to memory access errors or data corruption}} |
| 50 | D2 = static_cast<Derived *>(&B2);// expected-warning {{Casting data to a larger structure type and accessing a field can lead to memory access errors or data corruption}} |
| 51 | |
| 52 | // False negatives, cast from Base to Derived. With path sensitive analysis |
| 53 | // these false negatives could be fixed. |
| 54 | Base *B3 = &B2; |
| 55 | D2 = (Derived *)B3; |
| 56 | D2 = dynamic_cast<Derived *>(B3); |
| 57 | D2 = static_cast<Derived *>(B3); |
| 58 | } |
| 59 | |
| 60 | void intToStruct(int *P) { |
| 61 | struct ABC *Abc; |
| 62 | Abc = (struct ABC *)P; // expected-warning {{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption}} |
| 63 | |
| 64 | // Cast from void *. |
| 65 | void *VP = P; |
| 66 | Abc = (struct ABC *)VP; |
| 67 | } |