1// RUN: %clang_cc1 -fsyntax-only -verify %s
2
3class Base { };
4class Derived1 : public Base { };
5class Derived2 : public Base { };
6
7void f0(volatile Base *b, Derived1 *d1, const Derived2 *d2) {
8  if (b > d1)
9    return;
10  if (d1 <= b)
11    return;
12  if (b > d2)
13    return;
14  if (d1 >= d2) // expected-error{{comparison of distinct}}
15    return;
16}
17
18void f1(volatile Base *b, Derived1 *d1, const Derived2 *d2) {
19  if (b == d1)
20    return;
21  if (d1 == b)
22    return;
23  if (b != d2)
24    return;
25  if (d1 == d2) // expected-error{{comparison of distinct}}
26    return;
27}
28
29// PR4691
30int ptrcmp1(void *a, int *b) {
31  return a < b;
32}
33int ptrcmp2(long *a, int *b) {
34  return a < b; // expected-error{{distinct}}
35}
36
37// PR5509 - Multi-level pointers
38int f2() {
39  typedef int *IntPtr;
40  typedef IntPtr *IntPtrPtr;
41  typedef IntPtr const *IntPtrConstPtr;
42  IntPtrConstPtr i = 0;
43  IntPtrPtr j = 0;
44  return i != j;
45}
46
47// PR5763
48typedef double Matrix4[4][4];
49
50bool f(Matrix4 m1, const Matrix4 m2) {
51  return m1 != m2;
52}
53
54// PR6346
55bool f1(bool b, void **p, const void **q) {
56  if (p == q) // expected-warning{{comparison of distinct pointer types ('void **' and 'const void **') uses non-standard composite pointer type 'const void *const *'}}
57    return false;
58
59  return b? p : q; // expected-warning{{incompatible operand types ('void **' and 'const void **') use non-standard composite pointer type 'const void *const *'}}
60}
61