| // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.CastToStruct,core -verify %s | 
 |  | 
 | struct AB { | 
 |   int A; | 
 |   int B; | 
 | }; | 
 |  | 
 | struct ABC { | 
 |   int A; | 
 |   int B; | 
 |   int C; | 
 | }; | 
 |  | 
 | struct Base { | 
 |   Base() : A(0), B(0) {} | 
 |   virtual ~Base() {} | 
 |  | 
 |   int A; | 
 |   int B; | 
 | }; | 
 |  | 
 | struct Derived : public Base { | 
 |   Derived() : Base(), C(0) {} | 
 |   int C; | 
 | }; | 
 |  | 
 | void structToStruct(struct AB *P) { | 
 |   struct AB Ab; | 
 |   struct ABC *Abc; | 
 |   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}} | 
 |   Abc = (struct ABC *)P; // No warning; It is not known what data P points at. | 
 |   Abc = (struct ABC *)&*P; | 
 |  | 
 |   // Don't warn when the cast is not widening. | 
 |   P = (struct AB *)&Ab; // struct AB * => struct AB * | 
 |   struct ABC Abc2; | 
 |   P = (struct AB *)&Abc2; // struct ABC * => struct AB * | 
 |  | 
 |   // True negatives when casting from Base to Derived. | 
 |   Derived D1, *D2; | 
 |   Base &B1 = D1; | 
 |   D2 = (Derived *)&B1; | 
 |   D2 = dynamic_cast<Derived *>(&B1); | 
 |   D2 = static_cast<Derived *>(&B1); | 
 |  | 
 |   // True positives when casting from Base to Derived. | 
 |   Base B2; | 
 |   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}} | 
 |   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}} | 
 |   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}} | 
 |  | 
 |   // False negatives, cast from Base to Derived. With path sensitive analysis | 
 |   // these false negatives could be fixed. | 
 |   Base *B3 = &B2; | 
 |   D2 = (Derived *)B3; | 
 |   D2 = dynamic_cast<Derived *>(B3); | 
 |   D2 = static_cast<Derived *>(B3); | 
 | } | 
 |  | 
 | void intToStruct(int *P) { | 
 |   struct ABC *Abc; | 
 |   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}} | 
 |  | 
 |   // Cast from void *. | 
 |   void *VP = P; | 
 |   Abc = (struct ABC *)VP; | 
 | } | 
 |  | 
 | // https://llvm.org/bugs/show_bug.cgi?id=31173 | 
 | void dontCrash1(struct AB X) { | 
 |   struct UndefS *S = (struct UndefS *)&X; | 
 | } | 
 |  | 
 | struct S; | 
 | struct T { | 
 |   struct S *P; | 
 | }; | 
 | extern struct S Var1, Var2; | 
 | void dontCrash2() { | 
 |   ((struct T *) &Var1)->P = &Var2; | 
 | } |