// RUN: %clang_analyze_cc1 -std=c++14 \
// RUN:  -analyzer-checker=core,apiModeling.llvm.CastValue,debug.ExprInspection\
// RUN:  -verify %s

#include "Inputs/llvm.h"

void clang_analyzer_numTimesReached();
void clang_analyzer_warnIfReached();
void clang_analyzer_eval(bool);

namespace clang {
struct Shape {
  template <typename T>
  const T *castAs() const;

  template <typename T>
  const T *getAs() const;

  virtual double area();
};
class Triangle : public Shape {};
class Rectangle : public Shape {};
class Hexagon : public Shape {};
class Circle : public Shape {
public:
  ~Circle();
};
class SuspiciouslySpecificCircle : public Circle {};
} // namespace clang

using namespace llvm;
using namespace clang;

void test_regions_dyn_cast(const Shape *A, const Shape *B) {
  if (dyn_cast<Circle>(A) && !dyn_cast<Circle>(B))
    clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
}

void test_regions_isa(const Shape *A, const Shape *B) {
  if (isa<Circle>(A) && !isa<Circle>(B))
    clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
}

void test_regions_isa_variadic(const Shape *A, const Shape *B) {
  if (isa<Triangle, Rectangle, Hexagon>(A) &&
      !isa<Rectangle, Hexagon, Circle>(B))
    clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
}

void test_regions_isa_and_nonnull(const Shape *A, const Shape *B) {
  if (isa_and_nonnull<Circle>(A) && !isa_and_nonnull<Circle>(B))
    clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
}

void test_regions_isa_and_nonnull_variadic(const Shape *A, const Shape *B) {
  if (isa_and_nonnull<Triangle, Rectangle, Hexagon>(A) &&
      !isa_and_nonnull<Rectangle, Hexagon, Circle>(B))
    clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
}

namespace test_cast {
void evalLogic(const Shape *S) {
  const Circle *C = cast<Circle>(S);
  clang_analyzer_numTimesReached(); // expected-warning {{1}}

  if (S && C)
    clang_analyzer_eval(C == S); // expected-warning {{TRUE}}

  if (S && !C)
    clang_analyzer_warnIfReached(); // no-warning

  if (!S)
    clang_analyzer_warnIfReached(); // no-warning
}
} // namespace test_cast

namespace test_dyn_cast {
void evalLogic(const Shape *S) {
  const Circle *C = dyn_cast<Circle>(S);
  clang_analyzer_numTimesReached(); // expected-warning {{2}}

  if (S && C)
    clang_analyzer_eval(C == S); // expected-warning {{TRUE}}

  if (S && !C)
    clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}

  if (!S)
    clang_analyzer_warnIfReached(); // no-warning
}
} // namespace test_dyn_cast

namespace test_cast_or_null {
void evalLogic(const Shape *S) {
  const Circle *C = cast_or_null<Circle>(S);
  clang_analyzer_numTimesReached(); // expected-warning {{2}}

  if (S && C)
    clang_analyzer_eval(C == S); // expected-warning {{TRUE}}

  if (S && !C)
    clang_analyzer_warnIfReached(); // no-warning

  if (!S)
    clang_analyzer_eval(!C); // expected-warning {{TRUE}}
}
} // namespace test_cast_or_null

namespace test_dyn_cast_or_null {
void evalLogic(const Shape *S) {
  const Circle *C = dyn_cast_or_null<Circle>(S);
  clang_analyzer_numTimesReached(); // expected-warning {{3}}

  if (S && C)
    clang_analyzer_eval(C == S); // expected-warning {{TRUE}}

  if (S && !C)
    clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}

  if (!S)
    clang_analyzer_eval(!C); // expected-warning {{TRUE}}
}
} // namespace test_dyn_cast_or_null

namespace test_cast_as {
void evalLogic(const Shape *S) {
  const Circle *C = S->castAs<Circle>();
  clang_analyzer_numTimesReached(); // expected-warning {{1}}

  if (S && C)
    clang_analyzer_eval(C == S);
  // expected-warning@-1 {{TRUE}}

  if (S && !C)
    clang_analyzer_warnIfReached(); // no-warning

  if (!S)
    clang_analyzer_warnIfReached(); // no-warning
}
} // namespace test_cast_as

namespace test_get_as {
void evalLogic(const Shape *S) {
  const Circle *C = S->getAs<Circle>();
  clang_analyzer_numTimesReached(); // expected-warning {{2}}

  if (S && C)
    clang_analyzer_eval(C == S);
  // expected-warning@-1 {{TRUE}}

  if (S && !C)
    clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}

  if (!S)
    clang_analyzer_warnIfReached(); // no-warning
}
} // namespace test_get_as

namespace crashes {
void test_non_reference_null_region_crash(Shape s) {
  cast<Circle>(s); // no-crash
}

void test_non_reference_temporary_crash() {
  extern std::unique_ptr<Shape> foo();
  auto P = foo();
  auto Q = cast<Circle>(std::move(P)); // no-crash
}

double test_virtual_method_after_call(Shape *S) {
  if (isa<Circle>(S))
    return S->area();
  return S->area() / 2;
}

void test_delete_crash() {
  extern Circle *makeCircle();
  Shape *S = makeCircle();
  delete cast<SuspiciouslySpecificCircle>(S);
}
} // namespace crashes
