1/* Self tests for offset types for GDB, the GNU debugger. 2 3 Copyright (C) 2017-2020 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20#include "defs.h" 21#include "gdbsupport/selftest.h" 22#include "gdbsupport/offset-type.h" 23#include "gdbsupport/underlying.h" 24#include "gdbsupport/valid-expr.h" 25 26namespace selftests { 27namespace offset_type { 28 29DEFINE_OFFSET_TYPE (off_A, unsigned int); 30DEFINE_OFFSET_TYPE (off_B, unsigned int); 31 32/* First, compile-time tests that: 33 34 - make sure that incorrect operations with mismatching types are 35 caught at compile time. 36 37 - make sure that the same operations but involving the right types 38 do compile and that they return the correct type. 39*/ 40 41#define CHECK_VALID(VALID, EXPR_TYPE, EXPR) \ 42 CHECK_VALID_EXPR_2 (off_A, off_B, VALID, EXPR_TYPE, EXPR) 43 44off_A lval_a {}; 45off_B lval_b {}; 46 47using undrl = std::underlying_type<off_A>::type; 48 49/* Offset +/- underlying. */ 50 51CHECK_VALID (true, off_A, off_A {} + undrl {}); 52CHECK_VALID (true, off_A, off_A {} - undrl {}); 53CHECK_VALID (true, off_A, undrl {} + off_A {}); 54CHECK_VALID (true, off_A, undrl {} - off_A {}); 55 56/* Add offset types. Both same and different. */ 57 58CHECK_VALID (false, void, off_A {} + off_A {}); 59CHECK_VALID (false, void, off_A {} + off_B {}); 60 61/* Subtract offset types. Both same and different. */ 62 63CHECK_VALID (false, void, off_B {} - off_A {}); 64CHECK_VALID (true, undrl, off_A {} - off_A {}); 65 66/* Add/assign offset types. Both same and different. */ 67 68CHECK_VALID (false, void, lval_a += off_A {}); 69CHECK_VALID (false, void, lval_a += off_B {}); 70CHECK_VALID (false, void, lval_a -= off_A {}); 71CHECK_VALID (false, void, lval_a -= off_B {}); 72 73/* operator OP+= (offset, underlying), lvalue ref on the lhs. */ 74 75CHECK_VALID (true, off_A&, lval_a += undrl {}); 76CHECK_VALID (true, off_A&, lval_a -= undrl {}); 77 78/* operator OP+= (offset, underlying), rvalue ref on the lhs. */ 79 80CHECK_VALID (false, void, off_A {} += undrl {}); 81CHECK_VALID (false, void, off_A {} -= undrl {}); 82 83/* Rel ops, with same type. */ 84 85CHECK_VALID (true, bool, off_A {} < off_A {}); 86CHECK_VALID (true, bool, off_A {} > off_A {}); 87CHECK_VALID (true, bool, off_A {} <= off_A {}); 88CHECK_VALID (true, bool, off_A {} >= off_A {}); 89 90/* Rel ops, with unrelated offset types. */ 91 92CHECK_VALID (false, void, off_A {} < off_B {}); 93CHECK_VALID (false, void, off_A {} > off_B {}); 94CHECK_VALID (false, void, off_A {} <= off_B {}); 95CHECK_VALID (false, void, off_A {} >= off_B {}); 96 97/* Rel ops, with unrelated types. */ 98 99CHECK_VALID (false, void, off_A {} < undrl {}); 100CHECK_VALID (false, void, off_A {} > undrl {}); 101CHECK_VALID (false, void, off_A {} <= undrl {}); 102CHECK_VALID (false, void, off_A {} >= undrl {}); 103 104static void 105run_tests () 106{ 107 /* Test op+ and op-. */ 108 { 109 constexpr off_A a {}; 110 static_assert (to_underlying (a) == 0, ""); 111 112 { 113 constexpr off_A res1 = a + 2; 114 static_assert (to_underlying (res1) == 2, ""); 115 116 constexpr off_A res2 = res1 - 1; 117 static_assert (to_underlying (res2) == 1, ""); 118 } 119 120 { 121 constexpr off_A res1 = 2 + a; 122 static_assert (to_underlying (res1) == 2, ""); 123 124 constexpr off_A res2 = 3 - res1; 125 static_assert (to_underlying (res2) == 1, ""); 126 } 127 } 128 129 /* Test op+= and op-=. */ 130 { 131 off_A o {}; 132 133 o += 10; 134 SELF_CHECK (to_underlying (o) == 10); 135 o -= 5; 136 SELF_CHECK (to_underlying (o) == 5); 137 } 138 139 /* Test op-. */ 140 { 141 constexpr off_A o1 = (off_A) 10; 142 constexpr off_A o2 = (off_A) 20; 143 144 constexpr unsigned int delta = o2 - o1; 145 146 static_assert (delta == 10, ""); 147 } 148 149 /* Test <, <=, >, >=. */ 150 { 151 constexpr off_A o1 = (off_A) 10; 152 constexpr off_A o2 = (off_A) 20; 153 154 static_assert (o1 < o2, ""); 155 static_assert (!(o2 < o1), ""); 156 157 static_assert (o2 > o1, ""); 158 static_assert (!(o1 > o2), ""); 159 160 static_assert (o1 <= o2, ""); 161 static_assert (!(o2 <= o1), ""); 162 163 static_assert (o2 >= o1, ""); 164 static_assert (!(o1 >= o2), ""); 165 166 static_assert (o1 <= o1, ""); 167 static_assert (o1 >= o1, ""); 168 } 169} 170 171} /* namespace offset_type */ 172} /* namespace selftests */ 173 174void _initialize_offset_type_selftests (); 175void 176_initialize_offset_type_selftests () 177{ 178 selftests::register_test ("offset_type", selftests::offset_type::run_tests); 179} 180