aboutsummaryrefslogtreecommitdiff
path: root/test/Analysis/operator-calls.cpp
blob: 7461d75f673b011841d891cb3581a7ba5f3b70ce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify %s
void clang_analyzer_eval(bool);

struct X0 { };
bool operator==(const X0&, const X0&);

// PR7287
struct test { int a[2]; };

void t2() {
  test p = {{1,2}};
  test q;
  q = p;
}

bool PR7287(X0 a, X0 b) {
  return operator==(a, b);
}


// Inlining non-static member operators mistakenly treated 'this' as the first
// argument for a while.

struct IntComparable {
  bool operator==(int x) const {
    return x == 0;
  }
};

void testMemberOperator(IntComparable B) {
  clang_analyzer_eval(B == 0); // expected-warning{{TRUE}}
}



namespace UserDefinedConversions {
  class Convertible {
  public:
    operator int() const {
      return 42;
    }
    operator bool() const {
      return true;
    }
  };

  void test(const Convertible &obj) {
    clang_analyzer_eval((int)obj == 42); // expected-warning{{TRUE}}
    clang_analyzer_eval(obj); // expected-warning{{TRUE}}
  }
}


namespace RValues {
  struct SmallOpaque {
    float x;
    int operator +() const {
      return (int)x;
    }
  };

  struct LargeOpaque {
    float x[4];
    int operator +() const {
      return (int)x[0];
    }
  };

  SmallOpaque getSmallOpaque() {
    SmallOpaque obj;
    obj.x = 1.0;
    return obj;
  }

  LargeOpaque getLargeOpaque() {
    LargeOpaque obj = LargeOpaque();
    obj.x[0] = 1.0;
    return obj;
  }

  void test(int coin) {
    // Force a cache-out when we try to conjure a temporary region for the operator call.
    // ...then, don't crash.
    clang_analyzer_eval(+(coin ? getSmallOpaque() : getSmallOpaque())); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(+(coin ? getLargeOpaque() : getLargeOpaque())); // expected-warning{{UNKNOWN}}
  }
}