// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -DI386 -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-config c++-inlining=constructors -Wno-null-dereference -std=c++11 -verify -analyzer-config eagerly-assume=false %s
// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -DI386 -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-config c++-inlining=constructors -Wno-null-dereference -std=c++11 -verify -DTEST_INLINABLE_ALLOCATORS -analyzer-config eagerly-assume=false %s
// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin12 -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-config c++-inlining=constructors -Wno-null-dereference -std=c++11 -verify -analyzer-config eagerly-assume=false %s
// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin12 -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-config c++-inlining=constructors -Wno-null-dereference -std=c++11 -verify -DTEST_INLINABLE_ALLOCATORS -analyzer-config eagerly-assume=false %s

#include "Inputs/system-header-simulator-cxx.h"

void clang_analyzer_eval(bool);
void clang_analyzer_checkInlined(bool);

// A simplified version of std::move.
template <typename T>
T &&move(T &obj) {
  return static_cast<T &&>(obj);
}


struct Wrapper {
  __strong id obj;
};

void test() {
  Wrapper w;
  // force a diagnostic
  *(char *)0 = 1; // expected-warning{{Dereference of null pointer}}
}


struct IntWrapper {
  int x;
};

void testCopyConstructor() {
  IntWrapper a;
  a.x = 42;

  IntWrapper b(a);
  clang_analyzer_eval(b.x == 42); // expected-warning{{TRUE}}
}

struct NonPODIntWrapper {
  int x;

  virtual int get();
};

void testNonPODCopyConstructor() {
  NonPODIntWrapper a;
  a.x = 42;

  NonPODIntWrapper b(a);
  clang_analyzer_eval(b.x == 42); // expected-warning{{TRUE}}
}


namespace ConstructorVirtualCalls {
  class A {
  public:
    int *out1, *out2, *out3;

    virtual int get() { return 1; }

    A(int *out1) {
      *out1 = get();
    }
  };

  class B : public A {
  public:
    virtual int get() { return 2; }

    B(int *out1, int *out2) : A(out1) {
      *out2 = get();
    }
  };

  class C : public B {
  public:
    virtual int get() { return 3; }

    C(int *out1, int *out2, int *out3) : B(out1, out2) {
      *out3 = get();
    }
  };

  void test() {
    int a, b, c;

    C obj(&a, &b, &c);
    clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
    clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}

    clang_analyzer_eval(obj.get() == 3); // expected-warning{{TRUE}}

    // Sanity check for devirtualization.
    A *base = &obj;
    clang_analyzer_eval(base->get() == 3); // expected-warning{{TRUE}}
  }
}

namespace TemporaryConstructor {
  class BoolWrapper {
  public:
    BoolWrapper() {
      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
      value = true;
    }
    bool value;
  };

  void test() {
    // PR13717 - Don't crash when a CXXTemporaryObjectExpr is inlined.
    if (BoolWrapper().value)
      return;
  }
}


namespace ConstructorUsedAsRValue {
  using TemporaryConstructor::BoolWrapper;

  bool extractValue(BoolWrapper b) {
    return b.value;
  }

  void test() {
    bool result = extractValue(BoolWrapper());
    clang_analyzer_eval(result); // expected-warning{{TRUE}}
  }
}

namespace PODUninitialized {
  class POD {
  public:
    int x, y;
  };

  class PODWrapper {
  public:
    POD p;
  };

  class NonPOD {
  public:
    int x, y;

    NonPOD() {}
    NonPOD(const NonPOD &Other)
      : x(Other.x), y(Other.y) // expected-warning {{undefined}}
    {
    }
    NonPOD(NonPOD &&Other)
    : x(Other.x), y(Other.y) // expected-warning {{undefined}}
    {
    }

    NonPOD &operator=(const NonPOD &Other)
    {
      x = Other.x;
      y = Other.y; // expected-warning {{undefined}}
      return *this;
    }
    NonPOD &operator=(NonPOD &&Other)
    {
      x = Other.x;
      y = Other.y; // expected-warning {{undefined}}
      return *this;
    }
  };

  class NonPODWrapper {
  public:
    class Inner {
    public:
      int x, y;

      Inner() {}
      Inner(const Inner &Other)
        : x(Other.x), y(Other.y) // expected-warning {{undefined}}
      {
      }
      Inner(Inner &&Other)
      : x(Other.x), y(Other.y) // expected-warning {{undefined}}
      {
      }

      Inner &operator=(const Inner &Other)
      {
        x = Other.x; // expected-warning {{undefined}}
        y = Other.y;
        return *this;
      }
      Inner &operator=(Inner &&Other)
      {
        x = Other.x; // expected-warning {{undefined}}
        y = Other.y;
        return *this;
      }
    };

    Inner p;
  };

  void testPOD(const POD &pp) {
    POD p;
    p.x = 1;
    POD p2 = p; // no-warning
    clang_analyzer_eval(p2.x == 1); // expected-warning{{TRUE}}
    POD p3 = move(p); // no-warning
    clang_analyzer_eval(p3.x == 1); // expected-warning{{TRUE}}

    // Use rvalues as well.
    clang_analyzer_eval(POD(p3).x == 1); // expected-warning{{TRUE}}

    // Copy from symbolic references correctly.
    POD p4 = pp;
    // Make sure that p4.x contains a symbol after copy.
    if (p4.x > 0)
      clang_analyzer_eval(p4.x > 0); // expected-warning{{TRUE}}
    // FIXME: Element region gets in the way, so these aren't the same symbols
    // as they should be.
    clang_analyzer_eval(pp.x == p4.x); // expected-warning{{UNKNOWN}}

    PODWrapper w;
    w.p.y = 1;
    PODWrapper w2 = w; // no-warning
    clang_analyzer_eval(w2.p.y == 1); // expected-warning{{TRUE}}
    PODWrapper w3 = move(w); // no-warning
    clang_analyzer_eval(w3.p.y == 1); // expected-warning{{TRUE}}

    // Use rvalues as well.
    clang_analyzer_eval(PODWrapper(w3).p.y == 1); // expected-warning{{TRUE}}
  }

  void testNonPOD() {
    NonPOD p;
    p.x = 1;
    NonPOD p2 = p;
  }

  void testNonPODMove() {
    NonPOD p;
    p.x = 1;
    NonPOD p2 = move(p);
  }

  void testNonPODWrapper() {
    NonPODWrapper w;
    w.p.y = 1;
    NonPODWrapper w2 = w;
  }

  void testNonPODWrapperMove() {
    NonPODWrapper w;
    w.p.y = 1;
    NonPODWrapper w2 = move(w);
  }

  // Not strictly about constructors, but trivial assignment operators should
  // essentially work the same way.
  namespace AssignmentOperator {
    void testPOD() {
      POD p;
      p.x = 1;
      POD p2;
      p2 = p; // no-warning
      clang_analyzer_eval(p2.x == 1); // expected-warning{{TRUE}}
      POD p3;
      p3 = move(p); // no-warning
      clang_analyzer_eval(p3.x == 1); // expected-warning{{TRUE}}

      PODWrapper w;
      w.p.y = 1;
      PODWrapper w2;
      w2 = w; // no-warning
      clang_analyzer_eval(w2.p.y == 1); // expected-warning{{TRUE}}
      PODWrapper w3;
      w3 = move(w); // no-warning
      clang_analyzer_eval(w3.p.y == 1); // expected-warning{{TRUE}}
    }

    void testReturnValue() {
      POD p;
      p.x = 1;
      POD p2;
      clang_analyzer_eval(&(p2 = p) == &p2); // expected-warning{{TRUE}}

      PODWrapper w;
      w.p.y = 1;
      PODWrapper w2;
      clang_analyzer_eval(&(w2 = w) == &w2); // expected-warning{{TRUE}}
    }

    void testNonPOD() {
      NonPOD p;
      p.x = 1;
      NonPOD p2;
      p2 = p;
    }

    void testNonPODMove() {
      NonPOD p;
      p.x = 1;
      NonPOD p2;
      p2 = move(p);
    }

    void testNonPODWrapper() {
      NonPODWrapper w;
      w.p.y = 1;
      NonPODWrapper w2;
      w2 = w;
    }

    void testNonPODWrapperMove() {
      NonPODWrapper w;
      w.p.y = 1;
      NonPODWrapper w2;
      w2 = move(w);
    }
  }
}

namespace ArrayMembers {
  struct Primitive {
    int values[3];
  };

  void testPrimitive() {
    Primitive a = { { 1, 2, 3 } };

    clang_analyzer_eval(a.values[0] == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(a.values[1] == 2); // expected-warning{{TRUE}}
    clang_analyzer_eval(a.values[2] == 3); // expected-warning{{TRUE}}

    Primitive b = a;

    clang_analyzer_eval(b.values[0] == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(b.values[1] == 2); // expected-warning{{TRUE}}
    clang_analyzer_eval(b.values[2] == 3); // expected-warning{{TRUE}}

    Primitive c;
    c = b;

    clang_analyzer_eval(c.values[0] == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(c.values[1] == 2); // expected-warning{{TRUE}}
    clang_analyzer_eval(c.values[2] == 3); // expected-warning{{TRUE}}
  }

  struct NestedPrimitive {
    int values[2][3];
  };

  void testNestedPrimitive() {
    NestedPrimitive a = { { { 0, 0, 0 }, { 1, 2, 3 } } };

    clang_analyzer_eval(a.values[1][0] == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(a.values[1][1] == 2); // expected-warning{{TRUE}}
    clang_analyzer_eval(a.values[1][2] == 3); // expected-warning{{TRUE}}

    NestedPrimitive b = a;

    clang_analyzer_eval(b.values[1][0] == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(b.values[1][1] == 2); // expected-warning{{TRUE}}
    clang_analyzer_eval(b.values[1][2] == 3); // expected-warning{{TRUE}}

    NestedPrimitive c;
    c = b;

    clang_analyzer_eval(c.values[1][0] == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(c.values[1][1] == 2); // expected-warning{{TRUE}}
    clang_analyzer_eval(c.values[1][2] == 3); // expected-warning{{TRUE}}
  }

  struct POD {
    IntWrapper values[3];
  };

  void testPOD() {
    POD a = { { { 1 }, { 2 }, { 3 } } };

    clang_analyzer_eval(a.values[0].x == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(a.values[1].x == 2); // expected-warning{{TRUE}}
    clang_analyzer_eval(a.values[2].x == 3); // expected-warning{{TRUE}}

    POD b = a;

    clang_analyzer_eval(b.values[0].x == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(b.values[1].x == 2); // expected-warning{{TRUE}}
    clang_analyzer_eval(b.values[2].x == 3); // expected-warning{{TRUE}}

    POD c;
    c = b;

    clang_analyzer_eval(c.values[0].x == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(c.values[1].x == 2); // expected-warning{{TRUE}}
    clang_analyzer_eval(c.values[2].x == 3); // expected-warning{{TRUE}}
  }

  struct NestedPOD {
    IntWrapper values[2][3];
  };

  void testNestedPOD() {
    NestedPOD a = { { { { 0 }, { 0 }, { 0 } }, { { 1 }, { 2 }, { 3 } } } };

    clang_analyzer_eval(a.values[1][0].x == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(a.values[1][1].x == 2); // expected-warning{{TRUE}}
    clang_analyzer_eval(a.values[1][2].x == 3); // expected-warning{{TRUE}}

    NestedPOD b = a;

    clang_analyzer_eval(b.values[1][0].x == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(b.values[1][1].x == 2); // expected-warning{{TRUE}}
    clang_analyzer_eval(b.values[1][2].x == 3); // expected-warning{{TRUE}}

    NestedPOD c;
    c = b;

    clang_analyzer_eval(c.values[1][0].x == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(c.values[1][1].x == 2); // expected-warning{{TRUE}}
    clang_analyzer_eval(c.values[1][2].x == 3); // expected-warning{{TRUE}}
  }

  struct NonPOD {
    NonPODIntWrapper values[3];
  };

  void testNonPOD() {
    NonPOD a;
    a.values[0].x = 1;
    a.values[1].x = 2;
    a.values[2].x = 3;

    clang_analyzer_eval(a.values[0].x == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(a.values[1].x == 2); // expected-warning{{TRUE}}
    clang_analyzer_eval(a.values[2].x == 3); // expected-warning{{TRUE}}

    NonPOD b = a;

    clang_analyzer_eval(b.values[0].x == 1); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(b.values[1].x == 2); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(b.values[2].x == 3); // expected-warning{{UNKNOWN}}

    NonPOD c;
    c = b;

    clang_analyzer_eval(c.values[0].x == 1); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(c.values[1].x == 2); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(c.values[2].x == 3); // expected-warning{{UNKNOWN}}
  }

  struct NestedNonPOD {
    NonPODIntWrapper values[2][3];
  };

  void testNestedNonPOD() {
    NestedNonPOD a;
    a.values[0][0].x = 0;
    a.values[0][1].x = 0;
    a.values[0][2].x = 0;
    a.values[1][0].x = 1;
    a.values[1][1].x = 2;
    a.values[1][2].x = 3;

    clang_analyzer_eval(a.values[1][0].x == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(a.values[1][1].x == 2); // expected-warning{{TRUE}}
    clang_analyzer_eval(a.values[1][2].x == 3); // expected-warning{{TRUE}}

    NestedNonPOD b = a;

    clang_analyzer_eval(b.values[1][0].x == 1); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(b.values[1][1].x == 2); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(b.values[1][2].x == 3); // expected-warning{{UNKNOWN}}

    NestedNonPOD c;
    c = b;

    clang_analyzer_eval(c.values[1][0].x == 1); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(c.values[1][1].x == 2); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(c.values[1][2].x == 3); // expected-warning{{UNKNOWN}}
  }
  
  struct NonPODDefaulted {
    NonPODIntWrapper values[3];

    NonPODDefaulted() = default;
    NonPODDefaulted(const NonPODDefaulted &) = default;
    NonPODDefaulted &operator=(const NonPODDefaulted &) = default;
  };

  void testNonPODDefaulted() {
    NonPODDefaulted a;
    a.values[0].x = 1;
    a.values[1].x = 2;
    a.values[2].x = 3;

    clang_analyzer_eval(a.values[0].x == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(a.values[1].x == 2); // expected-warning{{TRUE}}
    clang_analyzer_eval(a.values[2].x == 3); // expected-warning{{TRUE}}

    NonPODDefaulted b = a;

    clang_analyzer_eval(b.values[0].x == 1); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(b.values[1].x == 2); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(b.values[2].x == 3); // expected-warning{{UNKNOWN}}

    NonPODDefaulted c;
    c = b;

    clang_analyzer_eval(c.values[0].x == 1); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(c.values[1].x == 2); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(c.values[2].x == 3); // expected-warning{{UNKNOWN}}
  }
};

namespace VirtualInheritance {
  int counter;

  struct base {
    base() {
      ++counter;
    }
  };

  struct virtual_subclass : public virtual base {
    virtual_subclass() {}
  };

  struct double_subclass : public virtual_subclass {
    double_subclass() {}
  };

  void test() {
    counter = 0;
    double_subclass obj;
    clang_analyzer_eval(counter == 1); // expected-warning{{TRUE}}
  }

  struct double_virtual_subclass : public virtual virtual_subclass {
    double_virtual_subclass() {}
  };

  void testVirtual() {
    counter = 0;
    double_virtual_subclass obj;
    clang_analyzer_eval(counter == 1); // expected-warning{{TRUE}}
  }
}

namespace ZeroInitialization {
  struct raw_pair {
    int p1;
    int p2;
  };

  void testVarDecl() {
    raw_pair p{};
    clang_analyzer_eval(p.p1 == 0); // expected-warning{{TRUE}}
    clang_analyzer_eval(p.p2 == 0); // expected-warning{{TRUE}}
  }

  void testTemporary() {
    clang_analyzer_eval(raw_pair().p1 == 0); // expected-warning{{TRUE}}
    clang_analyzer_eval(raw_pair().p2 == 0); // expected-warning{{TRUE}}
  }

  void testArray() {
    raw_pair p[2] = {};
    clang_analyzer_eval(p[0].p1 == 0); // expected-warning{{TRUE}}
    clang_analyzer_eval(p[0].p2 == 0); // expected-warning{{TRUE}}
    clang_analyzer_eval(p[1].p1 == 0); // expected-warning{{TRUE}}
    clang_analyzer_eval(p[1].p2 == 0); // expected-warning{{TRUE}}
  }

  void testNew() {
    raw_pair *pp = new raw_pair();
    clang_analyzer_eval(pp->p1 == 0); // expected-warning{{TRUE}}
    clang_analyzer_eval(pp->p2 == 0); // expected-warning{{TRUE}}
  }

  void testArrayNew() {
    // FIXME: Pending proper implementation of constructors for 'new[]'.
    raw_pair *p = new raw_pair[2]();
    clang_analyzer_eval(p[0].p1 == 0); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(p[0].p2 == 0); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(p[1].p1 == 0); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(p[1].p2 == 0); // expected-warning{{UNKNOWN}}
  }

  struct initializing_pair {
  public:
    int x;
    raw_pair y;
    initializing_pair() : x(), y() {}
  };
  
  void testFieldInitializers() {
    initializing_pair p;
    clang_analyzer_eval(p.x == 0); // expected-warning{{TRUE}}
    clang_analyzer_eval(p.y.p1 == 0); // expected-warning{{TRUE}}
    clang_analyzer_eval(p.y.p2 == 0); // expected-warning{{TRUE}}
  }

  struct subclass : public raw_pair {
    subclass() = default;
  };

  void testSubclass() {
    subclass p;
    clang_analyzer_eval(p.p1 == 0); // expected-warning{{garbage}}
  }

  struct initializing_subclass : public raw_pair {
    initializing_subclass() : raw_pair() {}
  };

  void testInitializingSubclass() {
    initializing_subclass p;
    clang_analyzer_eval(p.p1 == 0); // expected-warning{{TRUE}}
    clang_analyzer_eval(p.p2 == 0); // expected-warning{{TRUE}}
  }

  struct pair_wrapper {
    pair_wrapper() : p() {}
    raw_pair p;
  };

  struct virtual_subclass : public virtual pair_wrapper {
    virtual_subclass() {}
  };

  struct double_virtual_subclass : public virtual_subclass {
    double_virtual_subclass() {
      // This previously caused a crash because the pair_wrapper subobject was
      // initialized twice.
    }
  };

  class Empty {
  public:
    static int glob;
    Empty(); // No body.
    Empty(int x); // Body below.
  };

  class PairContainer : public Empty {
  public:
    raw_pair p;
    int q;
    PairContainer() : Empty(), p() {
      // This previously caused a crash because the empty base class looked
      // like an initialization of 'p'.
    }
    PairContainer(int) : Empty(), p() {
      // Test inlining something else here.
    }
    PairContainer(double): Empty(1), p() {
      clang_analyzer_eval(p.p1 == 0); // expected-warning{{TRUE}}
      clang_analyzer_eval(p.p2 == 0); // expected-warning{{TRUE}}

      clang_analyzer_eval(q == 1); // expected-warning{{TRUE}}

      // This one's indeed UNKNOWN. Definitely not TRUE.
      clang_analyzer_eval(p.p2 == glob); // expected-warning{{UNKNOWN}}
    }
  };

  Empty::Empty(int x) {
    static_cast<PairContainer *>(this)->p.p1 = x;
    static_cast<PairContainer *>(this)->q = x;
    // Our static member will store the old garbage values of fields that aren't
    // yet initialized. It's not certainly garbage though (i.e. the constructor
    // could have been called on an initialized piece of memory), so no
    // uninitialized value warning here, and it should be a symbol, not
    // undefined value, for later comparison.
    glob = static_cast<PairContainer *>(this)->p.p2;
  }

	class Empty2 {
	public:
		static int glob_p1, glob_p2;
		Empty2(); // Body below.
	};

	class PairDoubleEmptyContainer: public Empty, public Empty2 {
	public:
    raw_pair p;
		PairDoubleEmptyContainer(): Empty(), Empty2(), p() {
      clang_analyzer_eval(p.p1 == 0); // expected-warning{{TRUE}}
      clang_analyzer_eval(p.p2 == 0); // expected-warning{{TRUE}}

      // This is indeed UNKNOWN.
      clang_analyzer_eval(p.p1 == glob_p1); // expected-warning{{UNKNOWN}}
      clang_analyzer_eval(p.p2 == glob_p2); // expected-warning{{UNKNOWN}}
		}
	};

	Empty2::Empty2() {
    glob_p1 = static_cast<PairDoubleEmptyContainer *>(this)->p.p1;
    glob_p2 = static_cast<PairDoubleEmptyContainer *>(this)->p.p2;
	}

  class PairContainerContainer {
    int padding;
    PairContainer pc;
  public:
    PairContainerContainer() : pc(1) {}
  };
}

namespace InitializerList {
  struct List {
    bool usedInitializerList;

    List() : usedInitializerList(false) {}
    List(std::initializer_list<int>) : usedInitializerList(true) {}
  };

  void testStatic() {
    List defaultCtor;
    clang_analyzer_eval(!defaultCtor.usedInitializerList); // expected-warning{{TRUE}}

    List list{1, 2};
    clang_analyzer_eval(list.usedInitializerList); // expected-warning{{TRUE}}
  }

  void testDynamic() {
    List *list = new List{1, 2};
    clang_analyzer_eval(list->usedInitializerList); // expected-warning{{TRUE}}
  }
}

namespace PR19579 {
  class C {};

  void f() {
    C();
    int a;

    extern void use(int);
    use(a); // expected-warning{{uninitialized}}
  }

  void g() {
    struct S {
      C c;
      int i;
    };
    
    // This order triggers the initialization of the inner "a" after the
    // constructor for "C" is run, which used to confuse the analyzer
    // (is "C()" the initialization of "a"?).
    struct S s = {
      C(),
      ({
        int a, b = 0;
        0;
      })
    };
  }
}

namespace NoCrashOnEmptyBaseOptimization {
  struct NonEmptyBase {
    int X;
    explicit NonEmptyBase(int X) : X(X) {}
  };

  struct EmptyBase {};

  struct S : NonEmptyBase, EmptyBase {
    S() : NonEmptyBase(0), EmptyBase() {}
  };

  void testSCtorNoCrash() {
    S s;
  }
}

namespace EmptyBaseAssign {
struct B1 {};
struct B2 { int x; };
struct D: public B1, public B2 {
const D &operator=(const D &d) {
  *((B2 *)this) = d;
  *((B1 *)this) = d;
  return *this;
}
};

void test() {
  D d1;
  d1.x = 1;
  D d2;
  d2 = d1;
  clang_analyzer_eval(d2.x == 1); // expected-warning{{TRUE}}
}
}

namespace vbase_zero_init {
class A {
  virtual void foo();
};

class B {
  virtual void bar();
public:
  static int glob_y, glob_z, glob_w;
  int x;
  B(); // Body below.
};

class C : virtual public A {
public:
  int y;
};

class D : public B, public C {
public:
  // 'z', unlike 'w', resides in an area that would have been within padding of
  // base class 'C' if it wasn't part of 'D', but only on 64-bit systems.
  int z, w;
  // Initialization order: A(), B(), C().
  D() : A(), C() {
    clang_analyzer_eval(x == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(y == 0); // expected-warning{{TRUE}}
#ifdef I386
    clang_analyzer_eval(z == 3); // expected-warning{{TRUE}}
#else
    // FIXME: Should be TRUE. Initialized in B().
    clang_analyzer_eval(z == 3); // expected-warning{{UNKNOWN}}
#endif
    clang_analyzer_eval(w == 4); // expected-warning{{TRUE}}

    // FIXME: Should be UNKNOWN. Changed in B() since glob_y was assigned.
    clang_analyzer_eval(y == glob_y); // expected-warning{{TRUE}}

#ifdef I386
    clang_analyzer_eval(z == glob_z); // expected-warning{{UNKNOWN}}
#else
    // FIXME: Should be UNKNOWN. Changed in B() since glob_z was assigned.
    clang_analyzer_eval(z == glob_z); // expected-warning{{TRUE}}
#endif

    clang_analyzer_eval(w == glob_w); // expected-warning{{UNKNOWN}}
  } // no-crash
};

B::B() : x(1) {
  // Our static members will store the old garbage values of fields that aren't
  // yet initialized. These aren't certainly garbage though (i.e. the
  // constructor could have been called on an initialized piece of memory),
  // so no uninitialized value warning here, and these should be symbols, not
  // undefined values, for later comparison.
  glob_y = static_cast<D *>(this)->y;
  glob_z = static_cast<D *>(this)->z;
  glob_w = static_cast<D *>(this)->w;
  static_cast<D *>(this)->y = 2;
  static_cast<D *>(this)->z = 3;
  static_cast<D *>(this)->w = 4;
}
}
