// 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}}

    // Correctness 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;
}
}
