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()17void 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()60void 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()101void 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