// RUN: %clang_analyze_cc1  -analyzer-checker=alpha.security.taint,core,alpha.security.ArrayBoundV2 -analyzer-config alpha.security.taint.TaintPropagation:Config=%S/Inputs/taint-generic-config.yaml -Wno-format-security -verify -std=c++11 %s

#define BUFSIZE 10
int Buffer[BUFSIZE];

int scanf(const char*, ...);
int mySource1();
int mySource3();

bool isOutOfRange2(const int*);

void mySink2(int);

// Test configuration
namespace myNamespace {
  void scanf(const char*, ...);
  void myScanf(const char*, ...);
  int mySource3();

  bool isOutOfRange(const int*);
  bool isOutOfRange2(const int*);

  void mySink(int, int, int);
  void mySink2(int);
}

namespace myAnotherNamespace {
  int mySource3();

  bool isOutOfRange2(const int*);

  void mySink2(int);
}

void testConfigurationNamespacePropagation1() {
  int x;
  // The built-in functions should be matched only for functions in
  // the global namespace
  myNamespace::scanf("%d", &x);
  Buffer[x] = 1; // no-warning

  scanf("%d", &x);
  Buffer[x] = 1; // expected-warning {{Out of bound memory access }}
}

void testConfigurationNamespacePropagation2() {
  int x = mySource3();
  Buffer[x] = 1; // no-warning

  int y = myNamespace::mySource3();
  Buffer[y] = 1; // expected-warning {{Out of bound memory access }}
}

void testConfigurationNamespacePropagation3() {
  int x = myAnotherNamespace::mySource3();
  Buffer[x] = 1; // expected-warning {{Out of bound memory access }}
}

void testConfigurationNamespacePropagation4() {
  int x;
  // Configured functions without scope should match for all function.
  myNamespace::myScanf("%d", &x);
  Buffer[x] = 1; // expected-warning {{Out of bound memory access }}
}

void testConfigurationNamespaceFilter1() {
  int x = mySource1();
  if (myNamespace::isOutOfRange2(&x))
    return;
  Buffer[x] = 1; // no-warning

  int y = mySource1();
  if (isOutOfRange2(&y))
    return;
  Buffer[y] = 1; // expected-warning {{Out of bound memory access }}
}

void testConfigurationNamespaceFilter2() {
  int x = mySource1();
  if (myAnotherNamespace::isOutOfRange2(&x))
    return;
  Buffer[x] = 1; // no-warning
}

void testConfigurationNamespaceFilter3() {
  int x = mySource1();
  if (myNamespace::isOutOfRange(&x))
    return;
  Buffer[x] = 1; // no-warning
}

void testConfigurationNamespaceSink1() {
  int x = mySource1();
  mySink2(x); // no-warning

  int y = mySource1();
  myNamespace::mySink2(y);
  // expected-warning@-1 {{Untrusted data is passed to a user-defined sink}}
}

void testConfigurationNamespaceSink2() {
  int x = mySource1();
  myAnotherNamespace::mySink2(x);
  // expected-warning@-1 {{Untrusted data is passed to a user-defined sink}}
}

void testConfigurationNamespaceSink3() {
  int x = mySource1();
  myNamespace::mySink(x, 0, 1);
  // expected-warning@-1 {{Untrusted data is passed to a user-defined sink}}
}

struct Foo {
    void scanf(const char*, int*);
    void myMemberScanf(const char*, int*);
};

void testConfigurationMemberFunc() {
  int x;
  Foo foo;
  foo.scanf("%d", &x);
  Buffer[x] = 1; // no-warning

  foo.myMemberScanf("%d", &x);
  Buffer[x] = 1; // expected-warning {{Out of bound memory access }}
}
