// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config ipa=inlining -analyzer-config c++-allocator-inlining=true -verify %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) {
      // We don't want this constructor to be inlined unless we can actually
      // use the proper region for operator new.
      // See PR12014 and <rdar://problem/12180598>.
      clang_analyzer_checkInlined(false); // no-warning
    }
  };

  void test() {
    IntWrapper *obj = new IntWrapper(42);
    // should be TRUE
    clang_analyzer_eval(obj->value == 42); // expected-warning{{UNKNOWN}}
    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}}

    // should be TRUE
    clang_analyzer_eval(obj->value == 42); // expected-warning{{UNKNOWN}}
  }
}


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