// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config ipa=inlining -analyzer-config c++-allocator-inlining=true -verify -analyzer-config eagerly-assume=false %s

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

typedef __typeof__(sizeof(int)) size_t;
extern "C" void *malloc(size_t);

// This is the standard placement new.
inline void* operator new(size_t, void* __p) throw()
{
  clang_analyzer_checkInlined(true);// expected-warning{{TRUE}}
  return __p;
}


class A {
public:
  int getZero() { return 0; }
  virtual int getNum() { return 0; }
};

void test(A &a) {
  clang_analyzer_eval(a.getZero() == 0); // expected-warning{{TRUE}}
  clang_analyzer_eval(a.getNum() == 0); // expected-warning{{UNKNOWN}}

  A copy(a);
  clang_analyzer_eval(copy.getZero() == 0); // expected-warning{{TRUE}}
  clang_analyzer_eval(copy.getNum() == 0); // expected-warning{{TRUE}}
}


class One : public A {
public:
  virtual int getNum() { return 1; }
};

void testPathSensitivity(int x) {
  A a;
  One b;

  A *ptr;
  switch (x) {
  case 0:
    ptr = &a;
    break;
  case 1:
    ptr = &b;
    break;
  default:
    return;
  }

  // This should be true on both branches.
  clang_analyzer_eval(ptr->getNum() == x); // expected-warning {{TRUE}}
}


namespace PureVirtualParent {
  class Parent {
  public:
    virtual int pureVirtual() const = 0;
    int callVirtual() const {
      return pureVirtual();
    }
  };

  class Child : public Parent {
  public:
    virtual int pureVirtual() const {
      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
      return 42;
    }
  };

  void testVirtual() {
    Child x;

    clang_analyzer_eval(x.pureVirtual() == 42); // expected-warning{{TRUE}}
    clang_analyzer_eval(x.callVirtual() == 42); // expected-warning{{TRUE}}
  }
}


namespace PR13569 {
  class Parent {
  protected:
    int m_parent;
    virtual int impl() const = 0;

    Parent() : m_parent(0) {}

  public:
    int interface() const {
      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
      return impl();
    }
  };

  class Child : public Parent {
  protected:
    virtual int impl() const {
      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
      return m_parent + m_child;
    }

  public:
    Child() : m_child(0) {}

    int m_child;
  };

  void testVirtual() {
    Child x;
    x.m_child = 42;

    // Don't crash when inlining and devirtualizing.
    x.interface();
  }


  class Grandchild : public Child {};

  void testDevirtualizeToMiddle() {
    Grandchild x;
    x.m_child = 42;

    // Don't crash when inlining and devirtualizing.
    x.interface();
  }
}

namespace PR13569_virtual {
  class Parent {
  protected:
    int m_parent;
    virtual int impl() const = 0;

    Parent() : m_parent(0) {}

  public:
    int interface() const {
      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
      return impl();
    }
  };

  class Child : virtual public Parent {
  protected:
    virtual int impl() const {
      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
      return m_parent + m_child;
    }

  public:
    Child() : m_child(0) {}

    int m_child;
  };

  void testVirtual() {
    Child x;
    x.m_child = 42;

    // Don't crash when inlining and devirtualizing.
    x.interface();
  }


  class Grandchild : virtual public Child {};

  void testDevirtualizeToMiddle() {
    Grandchild x;
    x.m_child = 42;

    // Don't crash when inlining and devirtualizing.
    x.interface();
  }
}

namespace Invalidation {
  struct X {
    void touch(int &x) const {
      x = 0;
    }

    void touch2(int &x) const;

    virtual void touchV(int &x) const {
      x = 0;
    }

    virtual void touchV2(int &x) const;

    int test() const {
      // We were accidentally not invalidating under inlining
      // at one point for virtual methods with visible definitions.
      int a, b, c, d;
      touch(a);
      touch2(b);
      touchV(c);
      touchV2(d);
      return a + b + c + d; // no-warning
    }
  };
}

namespace DefaultArgs {
  int takesDefaultArgs(int i = 42) {
    return -i;
  }

  void testFunction() {
    clang_analyzer_eval(takesDefaultArgs(1) == -1); // expected-warning{{TRUE}}
    clang_analyzer_eval(takesDefaultArgs() == -42); // expected-warning{{TRUE}}
  }

  class Secret {
  public:
    static const int value = 40 + 2;
    int get(int i = value) {
      return i;
    }
  };

  void testMethod() {
    Secret obj;
    clang_analyzer_eval(obj.get(1) == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(obj.get() == 42); // expected-warning{{TRUE}}
    clang_analyzer_eval(Secret::value == 42); // expected-warning{{TRUE}}
  }

  enum ABC {
    A = 0,
    B = 1,
    C = 2
  };

  int enumUser(ABC input = B) {
    return static_cast<int>(input);
  }

  void testEnum() {
    clang_analyzer_eval(enumUser(C) == 2); // expected-warning{{TRUE}}
    clang_analyzer_eval(enumUser() == 1); // expected-warning{{TRUE}}
  }


  int exprUser(int input = 2 * 4) {
    return input;
  }

  int complicatedExprUser(int input = 2 * Secret::value) {
    return input;
  }

  void testExprs() {
    clang_analyzer_eval(exprUser(1) == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(exprUser() == 8); // expected-warning{{TRUE}}

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

  int defaultReference(const int &input = 42) {
    return -input;
  }
  int defaultReferenceZero(const int &input = 0) {
    return -input;
  }

  void testReference() {
    clang_analyzer_eval(defaultReference(1) == -1); // expected-warning{{TRUE}}
    clang_analyzer_eval(defaultReference() == -42); // expected-warning{{TRUE}}

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

  double defaultFloatReference(const double &i = 42) {
    return -i;
  }
  double defaultFloatReferenceZero(const double &i = 0) {
    return -i;
  }

  void testFloatReference() {
    clang_analyzer_eval(defaultFloatReference(1) == -1); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(defaultFloatReference() == -42); // expected-warning{{UNKNOWN}}

    clang_analyzer_eval(defaultFloatReferenceZero(1) == -1); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(defaultFloatReferenceZero() == 0); // expected-warning{{UNKNOWN}}
  }

  char defaultString(const char *s = "abc") {
    return s[1];
  }

  void testString() {
    clang_analyzer_eval(defaultString("xyz") == 'y'); // expected-warning{{TRUE}}
    clang_analyzer_eval(defaultString() == 'b'); // expected-warning{{TRUE}}
  }

  const void * const void_string = "abc";

  void testBitcastedString() {
    clang_analyzer_eval(0 != void_string); // expected-warning{{TRUE}}
    clang_analyzer_eval('b' == ((char *)void_string)[1]); // expected-warning{{TRUE}}
  }
}

namespace OperatorNew {
  class IntWrapper {
  public:
    int value;

    IntWrapper(int input) : value(input) {
      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
    }
  };

  void test() {
    IntWrapper *obj = new IntWrapper(42);
    clang_analyzer_eval(obj->value == 42); // expected-warning{{TRUE}}
    delete obj;
  }

  void testPlacement() {
    IntWrapper *obj = static_cast<IntWrapper *>(malloc(sizeof(IntWrapper)));
    IntWrapper *alias = new (obj) IntWrapper(42);

    clang_analyzer_eval(alias == obj); // expected-warning{{TRUE}}

    clang_analyzer_eval(obj->value == 42); // expected-warning{{TRUE}}
    // Because malloc() was never free()d:
    // expected-warning@-2{{Potential leak of memory pointed to by 'alias'}}
  }
}


namespace VirtualWithSisterCasts {
  // This entire set of tests exercises casts from sister classes and
  // from classes outside the hierarchy, which can very much confuse
  // code that uses DynamicTypeInfo or needs to construct CXXBaseObjectRegions.
  // These examples used to cause crashes in +Asserts builds.
  struct Parent {
    virtual int foo();
    int x;
  };

  struct A : Parent {
    virtual int foo() { return 42; }
  };

  struct B : Parent {
    virtual int foo();
  };

  struct Grandchild : public A {};

  struct Unrelated {};

  void testDowncast(Parent *b) {
    A *a = (A *)(void *)b;
    clang_analyzer_eval(a->foo() == 42); // expected-warning{{UNKNOWN}}

    a->x = 42;
    clang_analyzer_eval(a->x == 42); // expected-warning{{TRUE}}
  }

  void testRelated(B *b) {
    A *a = (A *)(void *)b;
    clang_analyzer_eval(a->foo() == 42); // expected-warning{{UNKNOWN}}

    a->x = 42;
    clang_analyzer_eval(a->x == 42); // expected-warning{{TRUE}}
  }

  void testUnrelated(Unrelated *b) {
    A *a = (A *)(void *)b;
    clang_analyzer_eval(a->foo() == 42); // expected-warning{{UNKNOWN}}

    a->x = 42;
    clang_analyzer_eval(a->x == 42); // expected-warning{{TRUE}}
  }

  void testCastViaNew(B *b) {
    Grandchild *g = new (b) Grandchild();
    clang_analyzer_eval(g->foo() == 42); // expected-warning{{TRUE}}

    g->x = 42;
    clang_analyzer_eval(g->x == 42); // expected-warning{{TRUE}}
  }
}


namespace QualifiedCalls {
  void test(One *object) {
    // This uses the One class from the top of the file.
    clang_analyzer_eval(object->getNum() == 1); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(object->One::getNum() == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(object->A::getNum() == 0); // expected-warning{{TRUE}}

    // getZero is non-virtual.
    clang_analyzer_eval(object->getZero() == 0); // expected-warning{{TRUE}}
    clang_analyzer_eval(object->One::getZero() == 0); // expected-warning{{TRUE}}
    clang_analyzer_eval(object->A::getZero() == 0); // expected-warning{{TRUE}}
}
}


namespace rdar12409977  {
  struct Base {
    int x;
  };

  struct Parent : public Base {
    virtual Parent *vGetThis();
    Parent *getThis() { return vGetThis(); }
  };

  struct Child : public Parent {
    virtual Child *vGetThis() { return this; }
  };

  void test() {
    Child obj;
    obj.x = 42;

    // Originally, calling a devirtualized method with a covariant return type
    // caused a crash because the return value had the wrong type. When we then
    // go to layer a CXXBaseObjectRegion on it, the base isn't a direct base of
    // the object region and we get an assertion failure.
    clang_analyzer_eval(obj.getThis()->x == 42); // expected-warning{{TRUE}}
  }
}

namespace bug16307 {
  void one_argument(int a) { }
  void call_with_less() {
    reinterpret_cast<void (*)()>(one_argument)(); // expected-warning{{Function taking 1 argument is called with fewer (0)}}
  }
}
