1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2019, Joyent, Inc. 14 */ 15 16 /* 17 * Check that we properly understand reference types and can walk through them 18 * as well as generate them. 19 */ 20 21 #include "check-common.h" 22 23 static check_number_t check_base[] = { 24 { "char", CTF_K_INTEGER, CTF_INT_SIGNED | CTF_INT_CHAR, 0, 8 }, 25 { "int", CTF_K_INTEGER, CTF_INT_SIGNED, 0, 32 }, 26 { "float", CTF_K_FLOAT, CTF_FP_SINGLE, 0, 32 }, 27 { NULL } 28 }; 29 30 static check_symbol_t check_syms[] = { 31 { "a", "int" }, 32 { "aa", "test_int_t" }, 33 { "b", "const short" }, 34 { "c", "volatile float" }, 35 { "d", "int *" }, 36 { "dd", "int **" }, 37 { "ddd", "int ***" }, 38 { "e", "test_int_t *" }, 39 { "ce", "const test_int_t *" }, 40 { "ve", "volatile test_int_t *" }, 41 { "cve", "const volatile test_int_t *" }, 42 { "f", "int *const *" }, 43 { "g", "const char *const" }, 44 { NULL }, 45 }; 46 47 static check_descent_t check_descent_aa[] = { 48 { "test_int_t", CTF_K_TYPEDEF }, 49 { "int", CTF_K_INTEGER }, 50 { NULL } 51 }; 52 53 static check_descent_t check_descent_b[] = { 54 { "const short", CTF_K_CONST }, 55 { "short", CTF_K_INTEGER }, 56 { NULL } 57 }; 58 59 static check_descent_t check_descent_c[] = { 60 { "volatile float", CTF_K_VOLATILE }, 61 { "float", CTF_K_FLOAT }, 62 { NULL } 63 }; 64 65 static check_descent_t check_descent_d[] = { 66 { "int *", CTF_K_POINTER }, 67 { "int", CTF_K_INTEGER }, 68 { NULL } 69 }; 70 71 static check_descent_t check_descent_dd[] = { 72 { "int **", CTF_K_POINTER }, 73 { "int *", CTF_K_POINTER }, 74 { "int", CTF_K_INTEGER }, 75 { NULL } 76 }; 77 78 static check_descent_t check_descent_ddd[] = { 79 { "int ***", CTF_K_POINTER }, 80 { "int **", CTF_K_POINTER }, 81 { "int *", CTF_K_POINTER }, 82 { "int", CTF_K_INTEGER }, 83 { NULL } 84 }; 85 86 static check_descent_t check_descent_e[] = { 87 { "test_int_t *", CTF_K_POINTER }, 88 { "test_int_t", CTF_K_TYPEDEF }, 89 { "int", CTF_K_INTEGER }, 90 { NULL }, 91 }; 92 93 static check_descent_t check_descent_ce[] = { 94 { "const test_int_t *", CTF_K_POINTER }, 95 { "const test_int_t", CTF_K_CONST }, 96 { "test_int_t", CTF_K_TYPEDEF }, 97 { "int", CTF_K_INTEGER }, 98 { NULL }, 99 }; 100 101 static check_descent_t check_descent_ve[] = { 102 { "volatile test_int_t *", CTF_K_POINTER}, 103 { "volatile test_int_t", CTF_K_VOLATILE }, 104 { "test_int_t", CTF_K_TYPEDEF }, 105 { "int", CTF_K_INTEGER }, 106 { NULL } 107 }; 108 109 static check_descent_t check_descent_cve[] = { 110 { "const volatile test_int_t *", CTF_K_POINTER }, 111 { "const volatile test_int_t", CTF_K_CONST }, 112 { "volatile test_int_t", CTF_K_VOLATILE }, 113 { "test_int_t", CTF_K_TYPEDEF }, 114 { "int", CTF_K_INTEGER }, 115 { NULL } 116 }; 117 118 static check_descent_t check_descent_f[] = { 119 { "int *const *", CTF_K_POINTER }, 120 { "int *const", CTF_K_CONST }, 121 { "int *", CTF_K_POINTER }, 122 { "int", CTF_K_INTEGER }, 123 { NULL } 124 }; 125 126 static check_descent_t check_descent_g[] = { 127 { "const char *const", CTF_K_CONST }, 128 { "const char *", CTF_K_POINTER }, 129 { "const char", CTF_K_CONST }, 130 { "char", CTF_K_INTEGER }, 131 { NULL } 132 }; 133 134 static check_descent_test_t descents[] = { 135 { "aa", check_descent_aa }, 136 { "b", check_descent_b }, 137 { "c", check_descent_c }, 138 { "d", check_descent_d }, 139 { "dd", check_descent_dd }, 140 { "ddd", check_descent_ddd }, 141 { "e", check_descent_e }, 142 { "ce", check_descent_ce }, 143 { "ve", check_descent_ve }, 144 { "cve", check_descent_cve }, 145 { "f", check_descent_f }, 146 { "g", check_descent_g }, 147 { NULL } 148 }; 149 150 static check_descent_t check_descent_cvh_gcc4[] = { 151 { "const volatile foo_t *", CTF_K_POINTER }, 152 { "const volatile foo_t", CTF_K_CONST }, 153 { "volatile foo_t", CTF_K_VOLATILE }, 154 { "foo_t", CTF_K_TYPEDEF }, 155 { "int *const *", CTF_K_POINTER }, 156 { "int *const", CTF_K_CONST }, 157 { "int *", CTF_K_POINTER }, 158 { "int", CTF_K_INTEGER }, 159 { NULL } 160 }; 161 162 static check_descent_t check_descent_cvh_gcc7[] = { 163 { "volatile const foo_t *", CTF_K_POINTER }, 164 { "volatile const foo_t", CTF_K_VOLATILE }, 165 { "const foo_t", CTF_K_CONST }, 166 { "foo_t", CTF_K_TYPEDEF }, 167 { "int *const *", CTF_K_POINTER }, 168 { "int *const", CTF_K_CONST }, 169 { "int *", CTF_K_POINTER }, 170 { "int", CTF_K_INTEGER }, 171 { NULL } 172 }; 173 174 /* 175 * GCC versions differ in how they order qualifiers, which is a shame for 176 * round-tripping; but as they're clearly both valid, we should cope. We'll 177 * just insist that at least one of these checks passes. 178 */ 179 static check_descent_test_t alt_descents[] = { 180 { "cvh", check_descent_cvh_gcc4 }, 181 { "cvh", check_descent_cvh_gcc7 }, 182 }; 183 184 int 185 main(int argc, char *argv[]) 186 { 187 int i, ret = 0; 188 189 if (argc < 2) { 190 errx(EXIT_FAILURE, "missing test files"); 191 } 192 193 for (i = 1; i < argc; i++) { 194 ctf_file_t *fp; 195 int alt_ok = 0; 196 uint_t d; 197 198 if ((fp = ctf_open(argv[i], &ret)) == NULL) { 199 warnx("failed to open %s: %s", argv[i], 200 ctf_errmsg(ret)); 201 ret = EXIT_FAILURE; 202 continue; 203 } 204 205 if (!ctftest_check_numbers(fp, check_base)) 206 ret = EXIT_FAILURE; 207 if (!ctftest_check_symbols(fp, check_syms)) 208 ret = EXIT_FAILURE; 209 for (d = 0; descents[d].cdt_sym != NULL; d++) { 210 if (!ctftest_check_descent(descents[d].cdt_sym, fp, 211 descents[d].cdt_tests, B_FALSE)) { 212 ret = EXIT_FAILURE; 213 } 214 } 215 216 for (d = 0; alt_descents[d].cdt_sym != NULL; d++) { 217 if (ctftest_check_descent(alt_descents[d].cdt_sym, fp, 218 alt_descents[d].cdt_tests, B_TRUE)) { 219 alt_ok = 1; 220 break; 221 } 222 } 223 224 if (!alt_ok) { 225 warnx("all descents failed for %s", 226 alt_descents[0].cdt_sym); 227 ret = EXIT_FAILURE; 228 } 229 230 ctf_close(fp); 231 } 232 233 return (ret); 234 } 235