1 // Verify the correctness of folding relational expressions involving
2 // pointers to array elements and struct data members and null pointers.
3 // Although the C semantics of relational expressions are only defined
4 // for pointers to objects, C++ makes them well-defined when
5 // (nullptr < p) yields true.  See the discussion of the patch for
6 // c++/67376 on gcc-patches for additional background.
7 
8 // { dg-do compile { target c++11 } }
9 // { dg-options "-O1 -fdelete-null-pointer-checks -fdump-tree-optimized" }
10 
11 // Runtime assert.  Used for potentially invalid expressions.
12 #define RA(e)  ((e) ? (void)0 : __builtin_abort ())
13 
14 // Static assert.  Used for valid core constant expressions.
15 #define SA(e)  static_assert ((e), #e)
16 
test_first_array_element()17 void test_first_array_element ()
18 {
19   static constexpr int a[] = { 0 };
20   constexpr const int *null = 0;
21   constexpr const int *pi = a;
22 
23   // The following are valid constant expressions since in &*pi
24   // the '&*' "cancel each other out."
25   SA (!(null == &*pi));
26   SA ( (null != &*pi));
27 
28   // The validity of the relational expressions involving null
29   // pointers in a constexpr context is questionable.  Use a run
30   // time assertion to verify these.
31   RA ( (null <  &*pi));
32   RA ( (null <= &*pi));
33   RA (!(null >  &*pi));
34   RA (!(null >= &*pi));
35 
36   SA (!(&*pi == null));
37   SA ( (&*pi != null));
38   RA (!(&*pi <  null));
39   RA (!(&*pi <= null));
40   RA ( (&*pi >  null));
41   RA ( (&*pi >= null));
42 
43   // The following are valid constant expressions since &pi [0] is
44   // equivalent to &*pi.
45   SA (!(null == &pi [0]));
46   SA ( (null != &pi [0]));
47   RA ( (null <  &pi [0]));
48   RA ( (null <= &pi [0]));
49   RA (!(null >  &pi [0]));
50   RA (!(null >= &pi [0]));
51 
52   SA (!(&pi [0] == null));
53   SA ( (&pi [0] != null));
54   RA (!(&pi [0] <  null));
55   RA (!(&pi [0] <= null));
56   RA ( (&pi [0] >  null));
57   RA ( (&pi [0] >= null));
58 }
59 
test_first_null_array_element()60 void test_first_null_array_element ()
61 {
62   constexpr const int *pi = 0;
63   constexpr const int *qi = 0;
64 
65   // The following are valid constant expressions since in &*qi
66   // the '&*' "cancel each other out."
67   SA ( (pi == &*qi));
68   SA (!(pi != &*qi));
69 
70   // The validity of the relational expressions involving null
71   // pointers in a constexpr context is questionable.
72   RA (!(pi <  &*qi));
73   RA ( (pi <= &*qi));
74   RA (!(pi >  &*qi));
75   RA ( (pi >= &*qi));
76 
77   SA ( (&*qi == pi));
78   SA (!(&*qi != pi));
79   RA (!(&*qi <  pi));
80   RA ( (&*qi <= pi));
81   RA (!(&*qi >  pi));
82   RA ( (&*qi >= pi));
83 
84   // The following are valid constant expressions since &qi [0] is
85   // equivalent to &*qi.
86   SA ( (pi == &qi [0]));
87   SA (!(pi != &qi [0]));
88   RA (!(pi <  &qi [0]));
89   RA ( (pi <= &qi [0]));
90   RA (!(pi >  &qi [0]));
91   RA ( (pi >= &qi [0]));
92 
93   SA ( (&qi [0] == pi));
94   SA (!(&qi [0] != pi));
95   RA (!(&qi [0] <  pi));
96   RA ( (&qi [0] <= pi));
97   RA (!(&qi [0] >  pi));
98   RA ( (&qi [0] >= pi));
99 }
100 
test_first_struct_member()101 void test_first_struct_member ()
102 {
103   static struct S { int a, b; } s = { 0, 0 };
104 
105   constexpr const int *p = 0;
106   constexpr const S   *q = &s;
107 
108   SA (!(p == &q->b));
109   SA ( (p != &q->b));
110   RA ( (p <  &q->b));
111   RA ( (p <= &q->b));
112   RA (!(p >  &q->b));
113   RA (!(p >= &q->b));
114 
115   SA (!(&q->b == p));
116   SA ( (&q->b != p));
117   RA (!(&q->b <  p));
118   RA (!(&q->b <= p));
119   RA ( (&q->b >  p));
120   RA ( (&q->b >= p));
121 }
122 
123 // Expect all runtime asserts to have been eliminated as a result
124 // of the tested expressions constant folded into true.
125 // { dg-final { scan-assembler-not "abort" } }
126