1f08c3bdfSopenharmony_ci/* 2f08c3bdfSopenharmony_ci * sparse/evaluate.c 3f08c3bdfSopenharmony_ci * 4f08c3bdfSopenharmony_ci * Copyright (C) 2003 Transmeta Corp. 5f08c3bdfSopenharmony_ci * 2003-2004 Linus Torvalds 6f08c3bdfSopenharmony_ci * 7f08c3bdfSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 8f08c3bdfSopenharmony_ci * of this software and associated documentation files (the "Software"), to deal 9f08c3bdfSopenharmony_ci * in the Software without restriction, including without limitation the rights 10f08c3bdfSopenharmony_ci * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11f08c3bdfSopenharmony_ci * copies of the Software, and to permit persons to whom the Software is 12f08c3bdfSopenharmony_ci * furnished to do so, subject to the following conditions: 13f08c3bdfSopenharmony_ci * 14f08c3bdfSopenharmony_ci * The above copyright notice and this permission notice shall be included in 15f08c3bdfSopenharmony_ci * all copies or substantial portions of the Software. 16f08c3bdfSopenharmony_ci * 17f08c3bdfSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18f08c3bdfSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19f08c3bdfSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20f08c3bdfSopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21f08c3bdfSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22f08c3bdfSopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23f08c3bdfSopenharmony_ci * THE SOFTWARE. 24f08c3bdfSopenharmony_ci * 25f08c3bdfSopenharmony_ci * Evaluate constant expressions. 26f08c3bdfSopenharmony_ci */ 27f08c3bdfSopenharmony_ci#include <stdlib.h> 28f08c3bdfSopenharmony_ci#include <stdarg.h> 29f08c3bdfSopenharmony_ci#include <stddef.h> 30f08c3bdfSopenharmony_ci#include <stdio.h> 31f08c3bdfSopenharmony_ci#include <string.h> 32f08c3bdfSopenharmony_ci#include <ctype.h> 33f08c3bdfSopenharmony_ci#include <unistd.h> 34f08c3bdfSopenharmony_ci#include <fcntl.h> 35f08c3bdfSopenharmony_ci#include <limits.h> 36f08c3bdfSopenharmony_ci 37f08c3bdfSopenharmony_ci#include "evaluate.h" 38f08c3bdfSopenharmony_ci#include "lib.h" 39f08c3bdfSopenharmony_ci#include "allocate.h" 40f08c3bdfSopenharmony_ci#include "parse.h" 41f08c3bdfSopenharmony_ci#include "token.h" 42f08c3bdfSopenharmony_ci#include "symbol.h" 43f08c3bdfSopenharmony_ci#include "target.h" 44f08c3bdfSopenharmony_ci#include "expression.h" 45f08c3bdfSopenharmony_ci 46f08c3bdfSopenharmony_cistruct symbol *current_fn; 47f08c3bdfSopenharmony_ci 48f08c3bdfSopenharmony_cistruct ident bad_address_space = { .len = 6, .name = "bad AS", }; 49f08c3bdfSopenharmony_ci 50f08c3bdfSopenharmony_cistatic struct symbol *degenerate(struct expression *expr); 51f08c3bdfSopenharmony_cistatic struct symbol *evaluate_symbol(struct symbol *sym); 52f08c3bdfSopenharmony_ci 53f08c3bdfSopenharmony_cistatic inline int valid_expr_type(struct expression *expr) 54f08c3bdfSopenharmony_ci{ 55f08c3bdfSopenharmony_ci return expr && valid_type(expr->ctype); 56f08c3bdfSopenharmony_ci} 57f08c3bdfSopenharmony_ci 58f08c3bdfSopenharmony_cistatic inline int valid_subexpr_type(struct expression *expr) 59f08c3bdfSopenharmony_ci{ 60f08c3bdfSopenharmony_ci return valid_expr_type(expr->left) 61f08c3bdfSopenharmony_ci && valid_expr_type(expr->right); 62f08c3bdfSopenharmony_ci} 63f08c3bdfSopenharmony_ci 64f08c3bdfSopenharmony_cistatic struct symbol *unqualify_type(struct symbol *ctype) 65f08c3bdfSopenharmony_ci{ 66f08c3bdfSopenharmony_ci if (!ctype) 67f08c3bdfSopenharmony_ci return ctype; 68f08c3bdfSopenharmony_ci if (ctype->type == SYM_NODE && (ctype->ctype.modifiers & MOD_QUALIFIER)) { 69f08c3bdfSopenharmony_ci struct symbol *unqual = alloc_symbol(ctype->pos, 0); 70f08c3bdfSopenharmony_ci 71f08c3bdfSopenharmony_ci *unqual = *ctype; 72f08c3bdfSopenharmony_ci unqual->ctype.modifiers &= ~MOD_QUALIFIER; 73f08c3bdfSopenharmony_ci return unqual; 74f08c3bdfSopenharmony_ci } 75f08c3bdfSopenharmony_ci return ctype; 76f08c3bdfSopenharmony_ci} 77f08c3bdfSopenharmony_ci 78f08c3bdfSopenharmony_cistatic struct symbol *evaluate_symbol_expression(struct expression *expr) 79f08c3bdfSopenharmony_ci{ 80f08c3bdfSopenharmony_ci struct expression *addr; 81f08c3bdfSopenharmony_ci struct symbol *sym = expr->symbol; 82f08c3bdfSopenharmony_ci struct symbol *base_type; 83f08c3bdfSopenharmony_ci 84f08c3bdfSopenharmony_ci if (!sym) { 85f08c3bdfSopenharmony_ci expression_error(expr, "undefined identifier '%s'", show_ident(expr->symbol_name)); 86f08c3bdfSopenharmony_ci return NULL; 87f08c3bdfSopenharmony_ci } 88f08c3bdfSopenharmony_ci 89f08c3bdfSopenharmony_ci examine_symbol_type(sym); 90f08c3bdfSopenharmony_ci 91f08c3bdfSopenharmony_ci base_type = get_base_type(sym); 92f08c3bdfSopenharmony_ci if (!base_type) { 93f08c3bdfSopenharmony_ci expression_error(expr, "identifier '%s' has no type", show_ident(expr->symbol_name)); 94f08c3bdfSopenharmony_ci return NULL; 95f08c3bdfSopenharmony_ci } 96f08c3bdfSopenharmony_ci 97f08c3bdfSopenharmony_ci addr = alloc_expression(expr->pos, EXPR_SYMBOL); 98f08c3bdfSopenharmony_ci addr->symbol = sym; 99f08c3bdfSopenharmony_ci addr->symbol_name = expr->symbol_name; 100f08c3bdfSopenharmony_ci addr->ctype = &lazy_ptr_ctype; /* Lazy evaluation: we need to do a proper job if somebody does &sym */ 101f08c3bdfSopenharmony_ci addr->flags = expr->flags; 102f08c3bdfSopenharmony_ci expr->type = EXPR_PREOP; 103f08c3bdfSopenharmony_ci expr->op = '*'; 104f08c3bdfSopenharmony_ci expr->unop = addr; 105f08c3bdfSopenharmony_ci expr->flags = CEF_NONE; 106f08c3bdfSopenharmony_ci 107f08c3bdfSopenharmony_ci /* The type of a symbol is the symbol itself! */ 108f08c3bdfSopenharmony_ci expr->ctype = sym; 109f08c3bdfSopenharmony_ci return sym; 110f08c3bdfSopenharmony_ci} 111f08c3bdfSopenharmony_ci 112f08c3bdfSopenharmony_cistatic struct symbol *evaluate_string(struct expression *expr) 113f08c3bdfSopenharmony_ci{ 114f08c3bdfSopenharmony_ci struct symbol *sym = alloc_symbol(expr->pos, SYM_NODE); 115f08c3bdfSopenharmony_ci struct symbol *array = alloc_symbol(expr->pos, SYM_ARRAY); 116f08c3bdfSopenharmony_ci struct expression *addr = alloc_expression(expr->pos, EXPR_SYMBOL); 117f08c3bdfSopenharmony_ci struct expression *initstr = alloc_expression(expr->pos, EXPR_STRING); 118f08c3bdfSopenharmony_ci unsigned int length = expr->string->length; 119f08c3bdfSopenharmony_ci struct symbol *char_type = expr->wide ? wchar_ctype : &char_ctype; 120f08c3bdfSopenharmony_ci 121f08c3bdfSopenharmony_ci sym->array_size = alloc_const_expression(expr->pos, length); 122f08c3bdfSopenharmony_ci sym->bit_size = length * char_type->bit_size; 123f08c3bdfSopenharmony_ci sym->ctype.alignment = 1; 124f08c3bdfSopenharmony_ci sym->string = 1; 125f08c3bdfSopenharmony_ci sym->ctype.modifiers = MOD_STATIC; 126f08c3bdfSopenharmony_ci sym->ctype.base_type = array; 127f08c3bdfSopenharmony_ci sym->initializer = initstr; 128f08c3bdfSopenharmony_ci sym->examined = 1; 129f08c3bdfSopenharmony_ci sym->evaluated = 1; 130f08c3bdfSopenharmony_ci 131f08c3bdfSopenharmony_ci initstr->ctype = sym; 132f08c3bdfSopenharmony_ci initstr->string = expr->string; 133f08c3bdfSopenharmony_ci 134f08c3bdfSopenharmony_ci array->array_size = sym->array_size; 135f08c3bdfSopenharmony_ci array->bit_size = sym->bit_size; 136f08c3bdfSopenharmony_ci array->ctype.alignment = char_type->ctype.alignment; 137f08c3bdfSopenharmony_ci array->ctype.modifiers = MOD_STATIC; 138f08c3bdfSopenharmony_ci array->ctype.base_type = char_type; 139f08c3bdfSopenharmony_ci array->examined = 1; 140f08c3bdfSopenharmony_ci array->evaluated = 1; 141f08c3bdfSopenharmony_ci 142f08c3bdfSopenharmony_ci addr->symbol = sym; 143f08c3bdfSopenharmony_ci addr->ctype = &lazy_ptr_ctype; 144f08c3bdfSopenharmony_ci addr->flags = CEF_ADDR; 145f08c3bdfSopenharmony_ci 146f08c3bdfSopenharmony_ci expr->type = EXPR_PREOP; 147f08c3bdfSopenharmony_ci expr->op = '*'; 148f08c3bdfSopenharmony_ci expr->unop = addr; 149f08c3bdfSopenharmony_ci expr->ctype = sym; 150f08c3bdfSopenharmony_ci return sym; 151f08c3bdfSopenharmony_ci} 152f08c3bdfSopenharmony_ci 153f08c3bdfSopenharmony_ci/* type has come from classify_type and is an integer type */ 154f08c3bdfSopenharmony_cistatic inline struct symbol *integer_promotion(struct symbol *type) 155f08c3bdfSopenharmony_ci{ 156f08c3bdfSopenharmony_ci unsigned long mod = type->ctype.modifiers; 157f08c3bdfSopenharmony_ci int width = type->bit_size; 158f08c3bdfSopenharmony_ci 159f08c3bdfSopenharmony_ci /* 160f08c3bdfSopenharmony_ci * Bitfields always promote to the base type, 161f08c3bdfSopenharmony_ci * even if the bitfield might be bigger than 162f08c3bdfSopenharmony_ci * an "int". 163f08c3bdfSopenharmony_ci */ 164f08c3bdfSopenharmony_ci if (type->type == SYM_BITFIELD) { 165f08c3bdfSopenharmony_ci type = type->ctype.base_type; 166f08c3bdfSopenharmony_ci } 167f08c3bdfSopenharmony_ci mod = type->ctype.modifiers; 168f08c3bdfSopenharmony_ci if (width < bits_in_int) 169f08c3bdfSopenharmony_ci return &int_ctype; 170f08c3bdfSopenharmony_ci 171f08c3bdfSopenharmony_ci /* If char/short has as many bits as int, it still gets "promoted" */ 172f08c3bdfSopenharmony_ci if (type->rank < 0) { 173f08c3bdfSopenharmony_ci if (mod & MOD_UNSIGNED) 174f08c3bdfSopenharmony_ci return &uint_ctype; 175f08c3bdfSopenharmony_ci return &int_ctype; 176f08c3bdfSopenharmony_ci } 177f08c3bdfSopenharmony_ci return type; 178f08c3bdfSopenharmony_ci} 179f08c3bdfSopenharmony_ci 180f08c3bdfSopenharmony_ci/* 181f08c3bdfSopenharmony_ci * After integer promotons: 182f08c3bdfSopenharmony_ci * If both types are the same 183f08c3bdfSopenharmony_ci * -> no conversion needed 184f08c3bdfSopenharmony_ci * If the types have the same signedness (their rank must be different) 185f08c3bdfSopenharmony_ci * -> convert to the type of the highest rank 186f08c3bdfSopenharmony_ci * If rank(unsigned type) >= rank(signed type) 187f08c3bdfSopenharmony_ci * -> convert to the unsigned type 188f08c3bdfSopenharmony_ci * If size(signed type) > size(unsigned type) 189f08c3bdfSopenharmony_ci * -> convert to the signed type 190f08c3bdfSopenharmony_ci * Otherwise 191f08c3bdfSopenharmony_ci * -> convert to the unsigned type corresponding to the signed type. 192f08c3bdfSopenharmony_ci */ 193f08c3bdfSopenharmony_cistatic struct symbol *bigger_int_type(struct symbol *left, struct symbol *right) 194f08c3bdfSopenharmony_ci{ 195f08c3bdfSopenharmony_ci static struct symbol *unsigned_types[] = { 196f08c3bdfSopenharmony_ci [0] = &uint_ctype, 197f08c3bdfSopenharmony_ci [1] = &ulong_ctype, 198f08c3bdfSopenharmony_ci [2] = &ullong_ctype, 199f08c3bdfSopenharmony_ci [3] = &uint128_ctype, 200f08c3bdfSopenharmony_ci }; 201f08c3bdfSopenharmony_ci unsigned long lmod, rmod; 202f08c3bdfSopenharmony_ci struct symbol *stype, *utype; 203f08c3bdfSopenharmony_ci 204f08c3bdfSopenharmony_ci left = integer_promotion(left); 205f08c3bdfSopenharmony_ci right = integer_promotion(right); 206f08c3bdfSopenharmony_ci 207f08c3bdfSopenharmony_ci if (left == right) 208f08c3bdfSopenharmony_ci return left; 209f08c3bdfSopenharmony_ci 210f08c3bdfSopenharmony_ci lmod = left->ctype.modifiers; 211f08c3bdfSopenharmony_ci rmod = right->ctype.modifiers; 212f08c3bdfSopenharmony_ci if (((lmod ^ rmod) & MOD_UNSIGNED) == 0) 213f08c3bdfSopenharmony_ci return (left->rank > right->rank) ? left : right; 214f08c3bdfSopenharmony_ci if (lmod & MOD_UNSIGNED) { 215f08c3bdfSopenharmony_ci utype = left; 216f08c3bdfSopenharmony_ci stype = right; 217f08c3bdfSopenharmony_ci } else { 218f08c3bdfSopenharmony_ci stype = left; 219f08c3bdfSopenharmony_ci utype = right; 220f08c3bdfSopenharmony_ci } 221f08c3bdfSopenharmony_ci if (utype->rank >= stype->rank) 222f08c3bdfSopenharmony_ci return utype; 223f08c3bdfSopenharmony_ci if (stype->bit_size > utype->bit_size) 224f08c3bdfSopenharmony_ci return stype; 225f08c3bdfSopenharmony_ci utype = unsigned_types[stype->rank]; 226f08c3bdfSopenharmony_ci return utype; 227f08c3bdfSopenharmony_ci} 228f08c3bdfSopenharmony_ci 229f08c3bdfSopenharmony_cistatic struct symbol *base_type(struct symbol *node, unsigned long *modp, struct ident **asp) 230f08c3bdfSopenharmony_ci{ 231f08c3bdfSopenharmony_ci unsigned long mod = 0; 232f08c3bdfSopenharmony_ci struct ident *as = NULL; 233f08c3bdfSopenharmony_ci 234f08c3bdfSopenharmony_ci while (node) { 235f08c3bdfSopenharmony_ci mod |= node->ctype.modifiers; 236f08c3bdfSopenharmony_ci combine_address_space(node->pos, &as, node->ctype.as); 237f08c3bdfSopenharmony_ci if (node->type == SYM_NODE) { 238f08c3bdfSopenharmony_ci node = node->ctype.base_type; 239f08c3bdfSopenharmony_ci continue; 240f08c3bdfSopenharmony_ci } 241f08c3bdfSopenharmony_ci break; 242f08c3bdfSopenharmony_ci } 243f08c3bdfSopenharmony_ci *modp = mod & ~MOD_IGNORE; 244f08c3bdfSopenharmony_ci *asp = as; 245f08c3bdfSopenharmony_ci return node; 246f08c3bdfSopenharmony_ci} 247f08c3bdfSopenharmony_ci 248f08c3bdfSopenharmony_cistatic int is_same_type(struct expression *expr, struct symbol *new) 249f08c3bdfSopenharmony_ci{ 250f08c3bdfSopenharmony_ci struct symbol *old = expr->ctype; 251f08c3bdfSopenharmony_ci unsigned long oldmod, newmod; 252f08c3bdfSopenharmony_ci struct ident *oldas, *newas; 253f08c3bdfSopenharmony_ci 254f08c3bdfSopenharmony_ci old = base_type(old, &oldmod, &oldas); 255f08c3bdfSopenharmony_ci new = base_type(new, &newmod, &newas); 256f08c3bdfSopenharmony_ci 257f08c3bdfSopenharmony_ci /* Same base type, same address space? */ 258f08c3bdfSopenharmony_ci if (old == new && oldas == newas) { 259f08c3bdfSopenharmony_ci unsigned long difmod; 260f08c3bdfSopenharmony_ci 261f08c3bdfSopenharmony_ci /* Check the modifier bits. */ 262f08c3bdfSopenharmony_ci difmod = (oldmod ^ newmod) & ~MOD_NOCAST; 263f08c3bdfSopenharmony_ci 264f08c3bdfSopenharmony_ci /* Exact same type? */ 265f08c3bdfSopenharmony_ci if (!difmod) 266f08c3bdfSopenharmony_ci return 1; 267f08c3bdfSopenharmony_ci 268f08c3bdfSopenharmony_ci /* 269f08c3bdfSopenharmony_ci * Not the same type, but differs only in "const". 270f08c3bdfSopenharmony_ci * Don't warn about MOD_NOCAST. 271f08c3bdfSopenharmony_ci */ 272f08c3bdfSopenharmony_ci if (difmod == MOD_CONST) 273f08c3bdfSopenharmony_ci return 0; 274f08c3bdfSopenharmony_ci } 275f08c3bdfSopenharmony_ci if ((oldmod | newmod) & MOD_NOCAST) { 276f08c3bdfSopenharmony_ci const char *tofrom = "to/from"; 277f08c3bdfSopenharmony_ci if (!(newmod & MOD_NOCAST)) 278f08c3bdfSopenharmony_ci tofrom = "from"; 279f08c3bdfSopenharmony_ci if (!(oldmod & MOD_NOCAST)) 280f08c3bdfSopenharmony_ci tofrom = "to"; 281f08c3bdfSopenharmony_ci warning(expr->pos, "implicit cast %s nocast type", tofrom); 282f08c3bdfSopenharmony_ci } 283f08c3bdfSopenharmony_ci return 0; 284f08c3bdfSopenharmony_ci} 285f08c3bdfSopenharmony_ci 286f08c3bdfSopenharmony_cistatic void 287f08c3bdfSopenharmony_ciwarn_for_different_enum_types (struct position pos, 288f08c3bdfSopenharmony_ci struct symbol *typea, 289f08c3bdfSopenharmony_ci struct symbol *typeb) 290f08c3bdfSopenharmony_ci{ 291f08c3bdfSopenharmony_ci if (!Wenum_mismatch) 292f08c3bdfSopenharmony_ci return; 293f08c3bdfSopenharmony_ci if (typea->type == SYM_NODE) 294f08c3bdfSopenharmony_ci typea = typea->ctype.base_type; 295f08c3bdfSopenharmony_ci if (typeb->type == SYM_NODE) 296f08c3bdfSopenharmony_ci typeb = typeb->ctype.base_type; 297f08c3bdfSopenharmony_ci 298f08c3bdfSopenharmony_ci if (typea == typeb) 299f08c3bdfSopenharmony_ci return; 300f08c3bdfSopenharmony_ci 301f08c3bdfSopenharmony_ci if (typea->type == SYM_ENUM && typeb->type == SYM_ENUM) { 302f08c3bdfSopenharmony_ci warning(pos, "mixing different enum types:"); 303f08c3bdfSopenharmony_ci info(pos, " %s", show_typename(typea)); 304f08c3bdfSopenharmony_ci info(pos, " %s", show_typename(typeb)); 305f08c3bdfSopenharmony_ci } 306f08c3bdfSopenharmony_ci} 307f08c3bdfSopenharmony_ci 308f08c3bdfSopenharmony_cistatic int cast_flags(struct expression *expr, struct expression *target); 309f08c3bdfSopenharmony_cistatic struct symbol *cast_to_bool(struct expression *expr); 310f08c3bdfSopenharmony_ci 311f08c3bdfSopenharmony_ci/* 312f08c3bdfSopenharmony_ci * This gets called for implicit casts in assignments and 313f08c3bdfSopenharmony_ci * integer promotion. 314f08c3bdfSopenharmony_ci */ 315f08c3bdfSopenharmony_cistatic struct expression * cast_to(struct expression *old, struct symbol *type) 316f08c3bdfSopenharmony_ci{ 317f08c3bdfSopenharmony_ci struct expression *expr; 318f08c3bdfSopenharmony_ci 319f08c3bdfSopenharmony_ci warn_for_different_enum_types (old->pos, old->ctype, type); 320f08c3bdfSopenharmony_ci 321f08c3bdfSopenharmony_ci if (old->ctype != &null_ctype && is_same_type(old, type)) 322f08c3bdfSopenharmony_ci return old; 323f08c3bdfSopenharmony_ci 324f08c3bdfSopenharmony_ci expr = alloc_expression(old->pos, EXPR_IMPLIED_CAST); 325f08c3bdfSopenharmony_ci expr->ctype = type; 326f08c3bdfSopenharmony_ci expr->cast_type = type; 327f08c3bdfSopenharmony_ci expr->cast_expression = old; 328f08c3bdfSopenharmony_ci expr->flags = cast_flags(expr, old); 329f08c3bdfSopenharmony_ci 330f08c3bdfSopenharmony_ci if (is_bool_type(type)) 331f08c3bdfSopenharmony_ci cast_to_bool(expr); 332f08c3bdfSopenharmony_ci 333f08c3bdfSopenharmony_ci return expr; 334f08c3bdfSopenharmony_ci} 335f08c3bdfSopenharmony_ci 336f08c3bdfSopenharmony_cienum { 337f08c3bdfSopenharmony_ci TYPE_NUM = 1, 338f08c3bdfSopenharmony_ci TYPE_BITFIELD = 2, 339f08c3bdfSopenharmony_ci TYPE_RESTRICT = 4, 340f08c3bdfSopenharmony_ci TYPE_FLOAT = 8, 341f08c3bdfSopenharmony_ci TYPE_PTR = 16, 342f08c3bdfSopenharmony_ci TYPE_COMPOUND = 32, 343f08c3bdfSopenharmony_ci TYPE_FOULED = 64, 344f08c3bdfSopenharmony_ci TYPE_FN = 128, 345f08c3bdfSopenharmony_ci}; 346f08c3bdfSopenharmony_ci 347f08c3bdfSopenharmony_cistatic inline int classify_type(struct symbol *type, struct symbol **base) 348f08c3bdfSopenharmony_ci{ 349f08c3bdfSopenharmony_ci static int type_class[SYM_BAD + 1] = { 350f08c3bdfSopenharmony_ci [SYM_PTR] = TYPE_PTR, 351f08c3bdfSopenharmony_ci [SYM_FN] = TYPE_PTR | TYPE_FN, 352f08c3bdfSopenharmony_ci [SYM_ARRAY] = TYPE_PTR | TYPE_COMPOUND, 353f08c3bdfSopenharmony_ci [SYM_STRUCT] = TYPE_COMPOUND, 354f08c3bdfSopenharmony_ci [SYM_UNION] = TYPE_COMPOUND, 355f08c3bdfSopenharmony_ci [SYM_BITFIELD] = TYPE_NUM | TYPE_BITFIELD, 356f08c3bdfSopenharmony_ci [SYM_RESTRICT] = TYPE_NUM | TYPE_RESTRICT, 357f08c3bdfSopenharmony_ci [SYM_FOULED] = TYPE_NUM | TYPE_RESTRICT | TYPE_FOULED, 358f08c3bdfSopenharmony_ci }; 359f08c3bdfSopenharmony_ci if (type->type == SYM_NODE) 360f08c3bdfSopenharmony_ci type = type->ctype.base_type; 361f08c3bdfSopenharmony_ci if (type->type == SYM_TYPEOF) { 362f08c3bdfSopenharmony_ci type = examine_symbol_type(type); 363f08c3bdfSopenharmony_ci if (type->type == SYM_NODE) 364f08c3bdfSopenharmony_ci type = type->ctype.base_type; 365f08c3bdfSopenharmony_ci } 366f08c3bdfSopenharmony_ci if (type->type == SYM_ENUM) 367f08c3bdfSopenharmony_ci type = type->ctype.base_type; 368f08c3bdfSopenharmony_ci *base = type; 369f08c3bdfSopenharmony_ci if (type->type == SYM_BASETYPE) { 370f08c3bdfSopenharmony_ci if (type->ctype.base_type == &int_type) 371f08c3bdfSopenharmony_ci return TYPE_NUM; 372f08c3bdfSopenharmony_ci if (type->ctype.base_type == &fp_type) 373f08c3bdfSopenharmony_ci return TYPE_NUM | TYPE_FLOAT; 374f08c3bdfSopenharmony_ci } 375f08c3bdfSopenharmony_ci return type_class[type->type]; 376f08c3bdfSopenharmony_ci} 377f08c3bdfSopenharmony_ci 378f08c3bdfSopenharmony_ci#define is_int(class) ((class & (TYPE_NUM | TYPE_FLOAT)) == TYPE_NUM) 379f08c3bdfSopenharmony_ci 380f08c3bdfSopenharmony_cistatic inline int is_string_type(struct symbol *type) 381f08c3bdfSopenharmony_ci{ 382f08c3bdfSopenharmony_ci if (type->type == SYM_NODE) 383f08c3bdfSopenharmony_ci type = type->ctype.base_type; 384f08c3bdfSopenharmony_ci if (type->type != SYM_ARRAY) 385f08c3bdfSopenharmony_ci return 0; 386f08c3bdfSopenharmony_ci type = type->ctype.base_type; 387f08c3bdfSopenharmony_ci return is_byte_type(type) || is_wchar_type(type); 388f08c3bdfSopenharmony_ci} 389f08c3bdfSopenharmony_ci 390f08c3bdfSopenharmony_cistatic struct symbol *bad_expr_type(struct expression *expr) 391f08c3bdfSopenharmony_ci{ 392f08c3bdfSopenharmony_ci switch (expr->type) { 393f08c3bdfSopenharmony_ci case EXPR_BINOP: 394f08c3bdfSopenharmony_ci case EXPR_COMPARE: 395f08c3bdfSopenharmony_ci if (!valid_subexpr_type(expr)) 396f08c3bdfSopenharmony_ci break; 397f08c3bdfSopenharmony_ci sparse_error(expr->pos, "incompatible types for operation (%s):", show_special(expr->op)); 398f08c3bdfSopenharmony_ci info(expr->pos, " %s", show_typename(expr->left->ctype)); 399f08c3bdfSopenharmony_ci info(expr->pos, " %s", show_typename(expr->right->ctype)); 400f08c3bdfSopenharmony_ci break; 401f08c3bdfSopenharmony_ci case EXPR_PREOP: 402f08c3bdfSopenharmony_ci case EXPR_POSTOP: 403f08c3bdfSopenharmony_ci if (!valid_expr_type(expr->unop)) 404f08c3bdfSopenharmony_ci break; 405f08c3bdfSopenharmony_ci sparse_error(expr->pos, "incompatible type for operation (%s):", show_special(expr->op)); 406f08c3bdfSopenharmony_ci info(expr->pos, " %s", show_typename(expr->unop->ctype)); 407f08c3bdfSopenharmony_ci break; 408f08c3bdfSopenharmony_ci default: 409f08c3bdfSopenharmony_ci break; 410f08c3bdfSopenharmony_ci } 411f08c3bdfSopenharmony_ci 412f08c3bdfSopenharmony_ci expr->flags = CEF_NONE; 413f08c3bdfSopenharmony_ci return expr->ctype = &bad_ctype; 414f08c3bdfSopenharmony_ci} 415f08c3bdfSopenharmony_ci 416f08c3bdfSopenharmony_cistatic int restricted_value(struct expression *v, struct symbol *type) 417f08c3bdfSopenharmony_ci{ 418f08c3bdfSopenharmony_ci if (v->type != EXPR_VALUE) 419f08c3bdfSopenharmony_ci return 1; 420f08c3bdfSopenharmony_ci if (v->value != 0) 421f08c3bdfSopenharmony_ci return 1; 422f08c3bdfSopenharmony_ci return 0; 423f08c3bdfSopenharmony_ci} 424f08c3bdfSopenharmony_ci 425f08c3bdfSopenharmony_cistatic int restricted_binop(int op, struct symbol *type) 426f08c3bdfSopenharmony_ci{ 427f08c3bdfSopenharmony_ci switch (op) { 428f08c3bdfSopenharmony_ci case '&': 429f08c3bdfSopenharmony_ci case '=': 430f08c3bdfSopenharmony_ci case SPECIAL_AND_ASSIGN: 431f08c3bdfSopenharmony_ci case SPECIAL_OR_ASSIGN: 432f08c3bdfSopenharmony_ci case SPECIAL_XOR_ASSIGN: 433f08c3bdfSopenharmony_ci return 1; /* unfoul */ 434f08c3bdfSopenharmony_ci case '|': 435f08c3bdfSopenharmony_ci case '^': 436f08c3bdfSopenharmony_ci case '?': 437f08c3bdfSopenharmony_ci return 2; /* keep fouled */ 438f08c3bdfSopenharmony_ci case SPECIAL_EQUAL: 439f08c3bdfSopenharmony_ci case SPECIAL_NOTEQUAL: 440f08c3bdfSopenharmony_ci return 3; /* warn if fouled */ 441f08c3bdfSopenharmony_ci default: 442f08c3bdfSopenharmony_ci return 0; /* warn */ 443f08c3bdfSopenharmony_ci } 444f08c3bdfSopenharmony_ci} 445f08c3bdfSopenharmony_ci 446f08c3bdfSopenharmony_cistatic int restricted_unop(int op, struct symbol **type) 447f08c3bdfSopenharmony_ci{ 448f08c3bdfSopenharmony_ci if (op == '~') { 449f08c3bdfSopenharmony_ci if ((*type)->bit_size < bits_in_int) 450f08c3bdfSopenharmony_ci *type = befoul(*type); 451f08c3bdfSopenharmony_ci return 0; 452f08c3bdfSopenharmony_ci } if (op == '+') 453f08c3bdfSopenharmony_ci return 0; 454f08c3bdfSopenharmony_ci return 1; 455f08c3bdfSopenharmony_ci} 456f08c3bdfSopenharmony_ci 457f08c3bdfSopenharmony_ci/* type should be SYM_FOULED */ 458f08c3bdfSopenharmony_cistatic inline struct symbol *unfoul(struct symbol *type) 459f08c3bdfSopenharmony_ci{ 460f08c3bdfSopenharmony_ci return type->ctype.base_type; 461f08c3bdfSopenharmony_ci} 462f08c3bdfSopenharmony_ci 463f08c3bdfSopenharmony_cistatic struct symbol *restricted_binop_type(int op, 464f08c3bdfSopenharmony_ci struct expression *left, 465f08c3bdfSopenharmony_ci struct expression *right, 466f08c3bdfSopenharmony_ci int lclass, int rclass, 467f08c3bdfSopenharmony_ci struct symbol *ltype, 468f08c3bdfSopenharmony_ci struct symbol *rtype) 469f08c3bdfSopenharmony_ci{ 470f08c3bdfSopenharmony_ci struct symbol *ctype = NULL; 471f08c3bdfSopenharmony_ci if (lclass & TYPE_RESTRICT) { 472f08c3bdfSopenharmony_ci if (rclass & TYPE_RESTRICT) { 473f08c3bdfSopenharmony_ci if (ltype == rtype) { 474f08c3bdfSopenharmony_ci ctype = ltype; 475f08c3bdfSopenharmony_ci } else if (lclass & TYPE_FOULED) { 476f08c3bdfSopenharmony_ci if (unfoul(ltype) == rtype) 477f08c3bdfSopenharmony_ci ctype = ltype; 478f08c3bdfSopenharmony_ci } else if (rclass & TYPE_FOULED) { 479f08c3bdfSopenharmony_ci if (unfoul(rtype) == ltype) 480f08c3bdfSopenharmony_ci ctype = rtype; 481f08c3bdfSopenharmony_ci } 482f08c3bdfSopenharmony_ci } else { 483f08c3bdfSopenharmony_ci if (!restricted_value(right, ltype)) 484f08c3bdfSopenharmony_ci ctype = ltype; 485f08c3bdfSopenharmony_ci } 486f08c3bdfSopenharmony_ci } else if (!restricted_value(left, rtype)) 487f08c3bdfSopenharmony_ci ctype = rtype; 488f08c3bdfSopenharmony_ci 489f08c3bdfSopenharmony_ci if (ctype) { 490f08c3bdfSopenharmony_ci switch (restricted_binop(op, ctype)) { 491f08c3bdfSopenharmony_ci case 1: 492f08c3bdfSopenharmony_ci if ((lclass ^ rclass) & TYPE_FOULED) 493f08c3bdfSopenharmony_ci ctype = unfoul(ctype); 494f08c3bdfSopenharmony_ci break; 495f08c3bdfSopenharmony_ci case 3: 496f08c3bdfSopenharmony_ci if (!(lclass & rclass & TYPE_FOULED)) 497f08c3bdfSopenharmony_ci break; 498f08c3bdfSopenharmony_ci case 0: 499f08c3bdfSopenharmony_ci ctype = NULL; 500f08c3bdfSopenharmony_ci default: 501f08c3bdfSopenharmony_ci break; 502f08c3bdfSopenharmony_ci } 503f08c3bdfSopenharmony_ci } 504f08c3bdfSopenharmony_ci 505f08c3bdfSopenharmony_ci return ctype; 506f08c3bdfSopenharmony_ci} 507f08c3bdfSopenharmony_ci 508f08c3bdfSopenharmony_cistatic inline void unrestrict(struct expression *expr, 509f08c3bdfSopenharmony_ci int class, struct symbol **ctype) 510f08c3bdfSopenharmony_ci{ 511f08c3bdfSopenharmony_ci if (class & TYPE_RESTRICT) { 512f08c3bdfSopenharmony_ci if (class & TYPE_FOULED) 513f08c3bdfSopenharmony_ci *ctype = unfoul(*ctype); 514f08c3bdfSopenharmony_ci warning(expr->pos, "%s degrades to integer", 515f08c3bdfSopenharmony_ci show_typename(*ctype)); 516f08c3bdfSopenharmony_ci *ctype = (*ctype)->ctype.base_type; /* get to arithmetic type */ 517f08c3bdfSopenharmony_ci } 518f08c3bdfSopenharmony_ci} 519f08c3bdfSopenharmony_ci 520f08c3bdfSopenharmony_cistatic struct symbol *usual_conversions(int op, 521f08c3bdfSopenharmony_ci struct expression *left, 522f08c3bdfSopenharmony_ci struct expression *right, 523f08c3bdfSopenharmony_ci int lclass, int rclass, 524f08c3bdfSopenharmony_ci struct symbol *ltype, 525f08c3bdfSopenharmony_ci struct symbol *rtype) 526f08c3bdfSopenharmony_ci{ 527f08c3bdfSopenharmony_ci struct symbol *ctype; 528f08c3bdfSopenharmony_ci 529f08c3bdfSopenharmony_ci warn_for_different_enum_types(right->pos, left->ctype, right->ctype); 530f08c3bdfSopenharmony_ci 531f08c3bdfSopenharmony_ci if ((lclass | rclass) & TYPE_RESTRICT) 532f08c3bdfSopenharmony_ci goto Restr; 533f08c3bdfSopenharmony_ci 534f08c3bdfSopenharmony_ciNormal: 535f08c3bdfSopenharmony_ci if (!(lclass & TYPE_FLOAT)) { 536f08c3bdfSopenharmony_ci if (!(rclass & TYPE_FLOAT)) 537f08c3bdfSopenharmony_ci return bigger_int_type(ltype, rtype); 538f08c3bdfSopenharmony_ci else 539f08c3bdfSopenharmony_ci return rtype; 540f08c3bdfSopenharmony_ci } else if (rclass & TYPE_FLOAT) { 541f08c3bdfSopenharmony_ci if (rtype->rank > ltype->rank) 542f08c3bdfSopenharmony_ci return rtype; 543f08c3bdfSopenharmony_ci else 544f08c3bdfSopenharmony_ci return ltype; 545f08c3bdfSopenharmony_ci } else 546f08c3bdfSopenharmony_ci return ltype; 547f08c3bdfSopenharmony_ci 548f08c3bdfSopenharmony_ciRestr: 549f08c3bdfSopenharmony_ci ctype = restricted_binop_type(op, left, right, 550f08c3bdfSopenharmony_ci lclass, rclass, ltype, rtype); 551f08c3bdfSopenharmony_ci if (ctype) 552f08c3bdfSopenharmony_ci return ctype; 553f08c3bdfSopenharmony_ci 554f08c3bdfSopenharmony_ci unrestrict(left, lclass, <ype); 555f08c3bdfSopenharmony_ci unrestrict(right, rclass, &rtype); 556f08c3bdfSopenharmony_ci 557f08c3bdfSopenharmony_ci goto Normal; 558f08c3bdfSopenharmony_ci} 559f08c3bdfSopenharmony_ci 560f08c3bdfSopenharmony_cistatic inline int lvalue_expression(struct expression *expr) 561f08c3bdfSopenharmony_ci{ 562f08c3bdfSopenharmony_ci return expr->type == EXPR_PREOP && expr->op == '*'; 563f08c3bdfSopenharmony_ci} 564f08c3bdfSopenharmony_ci 565f08c3bdfSopenharmony_cistatic struct symbol *evaluate_ptr_add(struct expression *expr, struct symbol *itype) 566f08c3bdfSopenharmony_ci{ 567f08c3bdfSopenharmony_ci struct expression *index = expr->right; 568f08c3bdfSopenharmony_ci struct symbol *ctype, *base; 569f08c3bdfSopenharmony_ci int multiply; 570f08c3bdfSopenharmony_ci 571f08c3bdfSopenharmony_ci classify_type(degenerate(expr->left), &ctype); 572f08c3bdfSopenharmony_ci base = examine_pointer_target(ctype); 573f08c3bdfSopenharmony_ci 574f08c3bdfSopenharmony_ci /* 575f08c3bdfSopenharmony_ci * An address constant +/- an integer constant expression 576f08c3bdfSopenharmony_ci * yields an address constant again [6.6(7)]. 577f08c3bdfSopenharmony_ci */ 578f08c3bdfSopenharmony_ci if ((expr->left->flags & CEF_ADDR) && (expr->right->flags & CEF_ICE)) 579f08c3bdfSopenharmony_ci expr->flags = CEF_ADDR; 580f08c3bdfSopenharmony_ci 581f08c3bdfSopenharmony_ci if (!base) { 582f08c3bdfSopenharmony_ci expression_error(expr, "missing type information"); 583f08c3bdfSopenharmony_ci return NULL; 584f08c3bdfSopenharmony_ci } 585f08c3bdfSopenharmony_ci if (is_function(base)) { 586f08c3bdfSopenharmony_ci expression_error(expr, "arithmetics on pointers to functions"); 587f08c3bdfSopenharmony_ci return NULL; 588f08c3bdfSopenharmony_ci } 589f08c3bdfSopenharmony_ci 590f08c3bdfSopenharmony_ci /* Get the size of whatever the pointer points to */ 591f08c3bdfSopenharmony_ci multiply = is_void_type(base) ? 1 : bits_to_bytes(base->bit_size); 592f08c3bdfSopenharmony_ci 593f08c3bdfSopenharmony_ci if (ctype == &null_ctype) 594f08c3bdfSopenharmony_ci ctype = &ptr_ctype; 595f08c3bdfSopenharmony_ci expr->ctype = ctype; 596f08c3bdfSopenharmony_ci 597f08c3bdfSopenharmony_ci if (multiply == 1 && itype->bit_size == bits_in_pointer) 598f08c3bdfSopenharmony_ci return ctype; 599f08c3bdfSopenharmony_ci 600f08c3bdfSopenharmony_ci if (index->type == EXPR_VALUE) { 601f08c3bdfSopenharmony_ci struct expression *val = alloc_expression(expr->pos, EXPR_VALUE); 602f08c3bdfSopenharmony_ci unsigned long long v = index->value, mask; 603f08c3bdfSopenharmony_ci mask = 1ULL << (itype->bit_size - 1); 604f08c3bdfSopenharmony_ci if (v & mask) 605f08c3bdfSopenharmony_ci v |= -mask; 606f08c3bdfSopenharmony_ci else 607f08c3bdfSopenharmony_ci v &= mask - 1; 608f08c3bdfSopenharmony_ci v *= multiply; 609f08c3bdfSopenharmony_ci mask = 1ULL << (bits_in_pointer - 1); 610f08c3bdfSopenharmony_ci v &= mask | (mask - 1); 611f08c3bdfSopenharmony_ci val->value = v; 612f08c3bdfSopenharmony_ci val->ctype = ssize_t_ctype; 613f08c3bdfSopenharmony_ci expr->right = val; 614f08c3bdfSopenharmony_ci return ctype; 615f08c3bdfSopenharmony_ci } 616f08c3bdfSopenharmony_ci 617f08c3bdfSopenharmony_ci if (itype->bit_size != bits_in_pointer) 618f08c3bdfSopenharmony_ci index = cast_to(index, ssize_t_ctype); 619f08c3bdfSopenharmony_ci 620f08c3bdfSopenharmony_ci if (multiply > 1) { 621f08c3bdfSopenharmony_ci struct expression *val = alloc_expression(expr->pos, EXPR_VALUE); 622f08c3bdfSopenharmony_ci struct expression *mul = alloc_expression(expr->pos, EXPR_BINOP); 623f08c3bdfSopenharmony_ci 624f08c3bdfSopenharmony_ci val->ctype = ssize_t_ctype; 625f08c3bdfSopenharmony_ci val->value = multiply; 626f08c3bdfSopenharmony_ci 627f08c3bdfSopenharmony_ci mul->op = '*'; 628f08c3bdfSopenharmony_ci mul->ctype = ssize_t_ctype; 629f08c3bdfSopenharmony_ci mul->left = index; 630f08c3bdfSopenharmony_ci mul->right = val; 631f08c3bdfSopenharmony_ci index = mul; 632f08c3bdfSopenharmony_ci } 633f08c3bdfSopenharmony_ci 634f08c3bdfSopenharmony_ci expr->right = index; 635f08c3bdfSopenharmony_ci return ctype; 636f08c3bdfSopenharmony_ci} 637f08c3bdfSopenharmony_ci 638f08c3bdfSopenharmony_cistatic void examine_fn_arguments(struct symbol *fn); 639f08c3bdfSopenharmony_ci 640f08c3bdfSopenharmony_ci#define MOD_IGN (MOD_QUALIFIER | MOD_FUN_ATTR) 641f08c3bdfSopenharmony_ci 642f08c3bdfSopenharmony_ciconst char *type_difference(struct ctype *c1, struct ctype *c2, 643f08c3bdfSopenharmony_ci unsigned long mod1, unsigned long mod2) 644f08c3bdfSopenharmony_ci{ 645f08c3bdfSopenharmony_ci struct ident *as1 = c1->as, *as2 = c2->as; 646f08c3bdfSopenharmony_ci struct symbol *t1 = c1->base_type; 647f08c3bdfSopenharmony_ci struct symbol *t2 = c2->base_type; 648f08c3bdfSopenharmony_ci int move1 = 1, move2 = 1; 649f08c3bdfSopenharmony_ci mod1 |= c1->modifiers; 650f08c3bdfSopenharmony_ci mod2 |= c2->modifiers; 651f08c3bdfSopenharmony_ci for (;;) { 652f08c3bdfSopenharmony_ci unsigned long diff; 653f08c3bdfSopenharmony_ci int type; 654f08c3bdfSopenharmony_ci struct symbol *base1 = t1->ctype.base_type; 655f08c3bdfSopenharmony_ci struct symbol *base2 = t2->ctype.base_type; 656f08c3bdfSopenharmony_ci 657f08c3bdfSopenharmony_ci /* 658f08c3bdfSopenharmony_ci * FIXME! Collect alignment and context too here! 659f08c3bdfSopenharmony_ci */ 660f08c3bdfSopenharmony_ci if (move1) { 661f08c3bdfSopenharmony_ci if (t1 && t1->type != SYM_PTR) { 662f08c3bdfSopenharmony_ci mod1 |= t1->ctype.modifiers; 663f08c3bdfSopenharmony_ci combine_address_space(t1->pos, &as1, t1->ctype.as); 664f08c3bdfSopenharmony_ci } 665f08c3bdfSopenharmony_ci move1 = 0; 666f08c3bdfSopenharmony_ci } 667f08c3bdfSopenharmony_ci 668f08c3bdfSopenharmony_ci if (move2) { 669f08c3bdfSopenharmony_ci if (t2 && t2->type != SYM_PTR) { 670f08c3bdfSopenharmony_ci mod2 |= t2->ctype.modifiers; 671f08c3bdfSopenharmony_ci combine_address_space(t2->pos, &as2, t2->ctype.as); 672f08c3bdfSopenharmony_ci } 673f08c3bdfSopenharmony_ci move2 = 0; 674f08c3bdfSopenharmony_ci } 675f08c3bdfSopenharmony_ci 676f08c3bdfSopenharmony_ci if (t1 == t2) 677f08c3bdfSopenharmony_ci break; 678f08c3bdfSopenharmony_ci if (!t1 || !t2) 679f08c3bdfSopenharmony_ci return "different types"; 680f08c3bdfSopenharmony_ci 681f08c3bdfSopenharmony_ci if (t1->type == SYM_NODE || t1->type == SYM_ENUM) { 682f08c3bdfSopenharmony_ci t1 = base1; 683f08c3bdfSopenharmony_ci move1 = 1; 684f08c3bdfSopenharmony_ci if (!t1) 685f08c3bdfSopenharmony_ci return "bad types"; 686f08c3bdfSopenharmony_ci continue; 687f08c3bdfSopenharmony_ci } 688f08c3bdfSopenharmony_ci 689f08c3bdfSopenharmony_ci if (t2->type == SYM_NODE || t2->type == SYM_ENUM) { 690f08c3bdfSopenharmony_ci t2 = base2; 691f08c3bdfSopenharmony_ci move2 = 1; 692f08c3bdfSopenharmony_ci if (!t2) 693f08c3bdfSopenharmony_ci return "bad types"; 694f08c3bdfSopenharmony_ci continue; 695f08c3bdfSopenharmony_ci } 696f08c3bdfSopenharmony_ci 697f08c3bdfSopenharmony_ci move1 = move2 = 1; 698f08c3bdfSopenharmony_ci type = t1->type; 699f08c3bdfSopenharmony_ci if (type != t2->type) 700f08c3bdfSopenharmony_ci return "different base types"; 701f08c3bdfSopenharmony_ci 702f08c3bdfSopenharmony_ci switch (type) { 703f08c3bdfSopenharmony_ci default: 704f08c3bdfSopenharmony_ci sparse_error(t1->pos, 705f08c3bdfSopenharmony_ci "internal error: bad type in derived(%d)", 706f08c3bdfSopenharmony_ci type); 707f08c3bdfSopenharmony_ci return "bad types"; 708f08c3bdfSopenharmony_ci case SYM_RESTRICT: 709f08c3bdfSopenharmony_ci return "different base types"; 710f08c3bdfSopenharmony_ci case SYM_UNION: 711f08c3bdfSopenharmony_ci case SYM_STRUCT: 712f08c3bdfSopenharmony_ci /* allow definition of incomplete structs and unions */ 713f08c3bdfSopenharmony_ci if (t1->ident == t2->ident) 714f08c3bdfSopenharmony_ci return NULL; 715f08c3bdfSopenharmony_ci return "different base types"; 716f08c3bdfSopenharmony_ci case SYM_ARRAY: 717f08c3bdfSopenharmony_ci /* XXX: we ought to compare sizes */ 718f08c3bdfSopenharmony_ci break; 719f08c3bdfSopenharmony_ci case SYM_PTR: 720f08c3bdfSopenharmony_ci if (as1 != as2) 721f08c3bdfSopenharmony_ci return "different address spaces"; 722f08c3bdfSopenharmony_ci /* MOD_SPECIFIER is due to idiocy in parse.c */ 723f08c3bdfSopenharmony_ci if ((mod1 ^ mod2) & ~MOD_IGNORE & ~MOD_SPECIFIER) 724f08c3bdfSopenharmony_ci return "different modifiers"; 725f08c3bdfSopenharmony_ci /* we could be lazier here */ 726f08c3bdfSopenharmony_ci base1 = examine_pointer_target(t1); 727f08c3bdfSopenharmony_ci base2 = examine_pointer_target(t2); 728f08c3bdfSopenharmony_ci mod1 = t1->ctype.modifiers; 729f08c3bdfSopenharmony_ci as1 = t1->ctype.as; 730f08c3bdfSopenharmony_ci mod2 = t2->ctype.modifiers; 731f08c3bdfSopenharmony_ci as2 = t2->ctype.as; 732f08c3bdfSopenharmony_ci break; 733f08c3bdfSopenharmony_ci case SYM_FN: { 734f08c3bdfSopenharmony_ci struct symbol *arg1, *arg2; 735f08c3bdfSopenharmony_ci int i; 736f08c3bdfSopenharmony_ci 737f08c3bdfSopenharmony_ci if (as1 != as2) 738f08c3bdfSopenharmony_ci return "different address spaces"; 739f08c3bdfSopenharmony_ci if ((mod1 ^ mod2) & ~MOD_IGNORE & ~MOD_SIGNEDNESS) 740f08c3bdfSopenharmony_ci return "different modifiers"; 741f08c3bdfSopenharmony_ci mod1 = t1->ctype.modifiers; 742f08c3bdfSopenharmony_ci as1 = t1->ctype.as; 743f08c3bdfSopenharmony_ci mod2 = t2->ctype.modifiers; 744f08c3bdfSopenharmony_ci as2 = t2->ctype.as; 745f08c3bdfSopenharmony_ci 746f08c3bdfSopenharmony_ci if (t1->variadic != t2->variadic) 747f08c3bdfSopenharmony_ci return "incompatible variadic arguments"; 748f08c3bdfSopenharmony_ci examine_fn_arguments(t1); 749f08c3bdfSopenharmony_ci examine_fn_arguments(t2); 750f08c3bdfSopenharmony_ci PREPARE_PTR_LIST(t1->arguments, arg1); 751f08c3bdfSopenharmony_ci PREPARE_PTR_LIST(t2->arguments, arg2); 752f08c3bdfSopenharmony_ci i = 1; 753f08c3bdfSopenharmony_ci for (;;) { 754f08c3bdfSopenharmony_ci const char *diffstr; 755f08c3bdfSopenharmony_ci if (!arg1 && !arg2) 756f08c3bdfSopenharmony_ci break; 757f08c3bdfSopenharmony_ci if (!arg1 || !arg2) 758f08c3bdfSopenharmony_ci return "different argument counts"; 759f08c3bdfSopenharmony_ci diffstr = type_difference(&arg1->ctype, 760f08c3bdfSopenharmony_ci &arg2->ctype, 761f08c3bdfSopenharmony_ci MOD_IGN, MOD_IGN); 762f08c3bdfSopenharmony_ci if (diffstr) { 763f08c3bdfSopenharmony_ci static char argdiff[80]; 764f08c3bdfSopenharmony_ci sprintf(argdiff, "incompatible argument %d (%s)", i, diffstr); 765f08c3bdfSopenharmony_ci return argdiff; 766f08c3bdfSopenharmony_ci } 767f08c3bdfSopenharmony_ci NEXT_PTR_LIST(arg1); 768f08c3bdfSopenharmony_ci NEXT_PTR_LIST(arg2); 769f08c3bdfSopenharmony_ci i++; 770f08c3bdfSopenharmony_ci } 771f08c3bdfSopenharmony_ci FINISH_PTR_LIST(arg2); 772f08c3bdfSopenharmony_ci FINISH_PTR_LIST(arg1); 773f08c3bdfSopenharmony_ci break; 774f08c3bdfSopenharmony_ci } 775f08c3bdfSopenharmony_ci case SYM_BASETYPE: 776f08c3bdfSopenharmony_ci if (as1 != as2) 777f08c3bdfSopenharmony_ci return "different address spaces"; 778f08c3bdfSopenharmony_ci if (base1 != base2) 779f08c3bdfSopenharmony_ci return "different base types"; 780f08c3bdfSopenharmony_ci if (t1->rank != t2->rank) 781f08c3bdfSopenharmony_ci return "different type sizes"; 782f08c3bdfSopenharmony_ci diff = (mod1 ^ mod2) & ~MOD_IGNORE; 783f08c3bdfSopenharmony_ci if (!diff) 784f08c3bdfSopenharmony_ci return NULL; 785f08c3bdfSopenharmony_ci else if (diff & ~MOD_SIGNEDNESS) 786f08c3bdfSopenharmony_ci return "different modifiers"; 787f08c3bdfSopenharmony_ci else 788f08c3bdfSopenharmony_ci return "different signedness"; 789f08c3bdfSopenharmony_ci } 790f08c3bdfSopenharmony_ci t1 = base1; 791f08c3bdfSopenharmony_ci t2 = base2; 792f08c3bdfSopenharmony_ci } 793f08c3bdfSopenharmony_ci if (as1 != as2) 794f08c3bdfSopenharmony_ci return "different address spaces"; 795f08c3bdfSopenharmony_ci if ((mod1 ^ mod2) & ~MOD_IGNORE & ~MOD_SIGNEDNESS) 796f08c3bdfSopenharmony_ci return "different modifiers"; 797f08c3bdfSopenharmony_ci return NULL; 798f08c3bdfSopenharmony_ci} 799f08c3bdfSopenharmony_ci 800f08c3bdfSopenharmony_cistatic void bad_null(struct expression *expr) 801f08c3bdfSopenharmony_ci{ 802f08c3bdfSopenharmony_ci if (Wnon_pointer_null) 803f08c3bdfSopenharmony_ci warning(expr->pos, "Using plain integer as NULL pointer"); 804f08c3bdfSopenharmony_ci} 805f08c3bdfSopenharmony_ci 806f08c3bdfSopenharmony_cistatic unsigned long target_qualifiers(struct symbol *type) 807f08c3bdfSopenharmony_ci{ 808f08c3bdfSopenharmony_ci unsigned long mod = type->ctype.modifiers & MOD_IGN; 809f08c3bdfSopenharmony_ci if (type->ctype.base_type && type->ctype.base_type->type == SYM_ARRAY) 810f08c3bdfSopenharmony_ci mod = 0; 811f08c3bdfSopenharmony_ci return mod; 812f08c3bdfSopenharmony_ci} 813f08c3bdfSopenharmony_ci 814f08c3bdfSopenharmony_cistatic struct symbol *evaluate_ptr_sub(struct expression *expr) 815f08c3bdfSopenharmony_ci{ 816f08c3bdfSopenharmony_ci const char *typediff; 817f08c3bdfSopenharmony_ci struct symbol *ltype, *rtype; 818f08c3bdfSopenharmony_ci struct expression *l = expr->left; 819f08c3bdfSopenharmony_ci struct expression *r = expr->right; 820f08c3bdfSopenharmony_ci struct symbol *lbase; 821f08c3bdfSopenharmony_ci 822f08c3bdfSopenharmony_ci classify_type(degenerate(l), <ype); 823f08c3bdfSopenharmony_ci classify_type(degenerate(r), &rtype); 824f08c3bdfSopenharmony_ci 825f08c3bdfSopenharmony_ci lbase = examine_pointer_target(ltype); 826f08c3bdfSopenharmony_ci examine_pointer_target(rtype); 827f08c3bdfSopenharmony_ci typediff = type_difference(<ype->ctype, &rtype->ctype, 828f08c3bdfSopenharmony_ci target_qualifiers(rtype), 829f08c3bdfSopenharmony_ci target_qualifiers(ltype)); 830f08c3bdfSopenharmony_ci if (typediff) 831f08c3bdfSopenharmony_ci expression_error(expr, "subtraction of different types can't work (%s)", typediff); 832f08c3bdfSopenharmony_ci 833f08c3bdfSopenharmony_ci if (is_function(lbase)) { 834f08c3bdfSopenharmony_ci expression_error(expr, "subtraction of functions? Share your drugs"); 835f08c3bdfSopenharmony_ci return NULL; 836f08c3bdfSopenharmony_ci } 837f08c3bdfSopenharmony_ci 838f08c3bdfSopenharmony_ci expr->ctype = ssize_t_ctype; 839f08c3bdfSopenharmony_ci if (lbase->bit_size > bits_in_char) { 840f08c3bdfSopenharmony_ci struct expression *sub = alloc_expression(expr->pos, EXPR_BINOP); 841f08c3bdfSopenharmony_ci struct expression *div = expr; 842f08c3bdfSopenharmony_ci struct expression *val = alloc_expression(expr->pos, EXPR_VALUE); 843f08c3bdfSopenharmony_ci unsigned long value = bits_to_bytes(lbase->bit_size); 844f08c3bdfSopenharmony_ci 845f08c3bdfSopenharmony_ci val->ctype = size_t_ctype; 846f08c3bdfSopenharmony_ci val->value = value; 847f08c3bdfSopenharmony_ci 848f08c3bdfSopenharmony_ci if (value & (value-1)) { 849f08c3bdfSopenharmony_ci if (Wptr_subtraction_blows) { 850f08c3bdfSopenharmony_ci warning(expr->pos, "potentially expensive pointer subtraction"); 851f08c3bdfSopenharmony_ci info(expr->pos, " '%s' has a non-power-of-2 size: %lu", show_typename(lbase), value); 852f08c3bdfSopenharmony_ci } 853f08c3bdfSopenharmony_ci } 854f08c3bdfSopenharmony_ci 855f08c3bdfSopenharmony_ci sub->op = '-'; 856f08c3bdfSopenharmony_ci sub->ctype = ssize_t_ctype; 857f08c3bdfSopenharmony_ci sub->left = l; 858f08c3bdfSopenharmony_ci sub->right = r; 859f08c3bdfSopenharmony_ci 860f08c3bdfSopenharmony_ci div->op = '/'; 861f08c3bdfSopenharmony_ci div->left = sub; 862f08c3bdfSopenharmony_ci div->right = val; 863f08c3bdfSopenharmony_ci } 864f08c3bdfSopenharmony_ci 865f08c3bdfSopenharmony_ci return ssize_t_ctype; 866f08c3bdfSopenharmony_ci} 867f08c3bdfSopenharmony_ci 868f08c3bdfSopenharmony_ci#define is_safe_type(type) ((type)->ctype.modifiers & MOD_SAFE) 869f08c3bdfSopenharmony_ci 870f08c3bdfSopenharmony_cistatic struct symbol *evaluate_conditional(struct expression *expr, int iterator) 871f08c3bdfSopenharmony_ci{ 872f08c3bdfSopenharmony_ci struct symbol *ctype; 873f08c3bdfSopenharmony_ci 874f08c3bdfSopenharmony_ci if (!expr) 875f08c3bdfSopenharmony_ci return NULL; 876f08c3bdfSopenharmony_ci 877f08c3bdfSopenharmony_ci if (!iterator && expr->type == EXPR_ASSIGNMENT && expr->op == '=') 878f08c3bdfSopenharmony_ci warning(expr->pos, "assignment expression in conditional"); 879f08c3bdfSopenharmony_ci 880f08c3bdfSopenharmony_ci ctype = evaluate_expression(expr); 881f08c3bdfSopenharmony_ci if (!valid_type(ctype)) 882f08c3bdfSopenharmony_ci return NULL; 883f08c3bdfSopenharmony_ci if (is_safe_type(ctype)) 884f08c3bdfSopenharmony_ci warning(expr->pos, "testing a 'safe expression'"); 885f08c3bdfSopenharmony_ci if (is_func_type(ctype)) { 886f08c3bdfSopenharmony_ci if (Waddress) 887f08c3bdfSopenharmony_ci warning(expr->pos, "the address of %s will always evaluate as true", "a function"); 888f08c3bdfSopenharmony_ci } else if (is_array_type(ctype)) { 889f08c3bdfSopenharmony_ci if (Waddress) 890f08c3bdfSopenharmony_ci warning(expr->pos, "the address of %s will always evaluate as true", "an array"); 891f08c3bdfSopenharmony_ci } else if (!is_scalar_type(ctype)) { 892f08c3bdfSopenharmony_ci sparse_error(expr->pos, "non-scalar type in conditional:"); 893f08c3bdfSopenharmony_ci info(expr->pos, " %s", show_typename(ctype)); 894f08c3bdfSopenharmony_ci return NULL; 895f08c3bdfSopenharmony_ci } 896f08c3bdfSopenharmony_ci 897f08c3bdfSopenharmony_ci ctype = degenerate(expr); 898f08c3bdfSopenharmony_ci return ctype; 899f08c3bdfSopenharmony_ci} 900f08c3bdfSopenharmony_ci 901f08c3bdfSopenharmony_cistatic struct symbol *evaluate_logical(struct expression *expr) 902f08c3bdfSopenharmony_ci{ 903f08c3bdfSopenharmony_ci if (!evaluate_conditional(expr->left, 0)) 904f08c3bdfSopenharmony_ci return NULL; 905f08c3bdfSopenharmony_ci if (!evaluate_conditional(expr->right, 0)) 906f08c3bdfSopenharmony_ci return NULL; 907f08c3bdfSopenharmony_ci 908f08c3bdfSopenharmony_ci /* the result is int [6.5.13(3), 6.5.14(3)] */ 909f08c3bdfSopenharmony_ci expr->ctype = &int_ctype; 910f08c3bdfSopenharmony_ci expr->flags = expr->left->flags & expr->right->flags; 911f08c3bdfSopenharmony_ci expr->flags &= ~(CEF_CONST_MASK | CEF_ADDR); 912f08c3bdfSopenharmony_ci return &int_ctype; 913f08c3bdfSopenharmony_ci} 914f08c3bdfSopenharmony_ci 915f08c3bdfSopenharmony_cistatic struct symbol *evaluate_binop(struct expression *expr) 916f08c3bdfSopenharmony_ci{ 917f08c3bdfSopenharmony_ci struct symbol *ltype, *rtype, *ctype; 918f08c3bdfSopenharmony_ci int lclass = classify_type(expr->left->ctype, <ype); 919f08c3bdfSopenharmony_ci int rclass = classify_type(expr->right->ctype, &rtype); 920f08c3bdfSopenharmony_ci int op = expr->op; 921f08c3bdfSopenharmony_ci 922f08c3bdfSopenharmony_ci /* number op number */ 923f08c3bdfSopenharmony_ci if (lclass & rclass & TYPE_NUM) { 924f08c3bdfSopenharmony_ci expr->flags = expr->left->flags & expr->right->flags; 925f08c3bdfSopenharmony_ci expr->flags &= ~CEF_CONST_MASK; 926f08c3bdfSopenharmony_ci 927f08c3bdfSopenharmony_ci if ((lclass | rclass) & TYPE_FLOAT) { 928f08c3bdfSopenharmony_ci switch (op) { 929f08c3bdfSopenharmony_ci case '+': case '-': case '*': case '/': 930f08c3bdfSopenharmony_ci break; 931f08c3bdfSopenharmony_ci default: 932f08c3bdfSopenharmony_ci return bad_expr_type(expr); 933f08c3bdfSopenharmony_ci } 934f08c3bdfSopenharmony_ci } 935f08c3bdfSopenharmony_ci 936f08c3bdfSopenharmony_ci if (op == SPECIAL_LEFTSHIFT || op == SPECIAL_RIGHTSHIFT) { 937f08c3bdfSopenharmony_ci // shifts do integer promotions, but that's it. 938f08c3bdfSopenharmony_ci unrestrict(expr->left, lclass, <ype); 939f08c3bdfSopenharmony_ci unrestrict(expr->right, rclass, &rtype); 940f08c3bdfSopenharmony_ci ctype = ltype = integer_promotion(ltype); 941f08c3bdfSopenharmony_ci rtype = integer_promotion(rtype); 942f08c3bdfSopenharmony_ci } else { 943f08c3bdfSopenharmony_ci // The rest do usual conversions 944f08c3bdfSopenharmony_ci const unsigned left_not = expr->left->type == EXPR_PREOP 945f08c3bdfSopenharmony_ci && expr->left->op == '!'; 946f08c3bdfSopenharmony_ci const unsigned right_not = expr->right->type == EXPR_PREOP 947f08c3bdfSopenharmony_ci && expr->right->op == '!'; 948f08c3bdfSopenharmony_ci if ((op == '&' || op == '|') && (left_not || right_not)) 949f08c3bdfSopenharmony_ci warning(expr->pos, "dubious: %sx %c %sy", 950f08c3bdfSopenharmony_ci left_not ? "!" : "", 951f08c3bdfSopenharmony_ci op, 952f08c3bdfSopenharmony_ci right_not ? "!" : ""); 953f08c3bdfSopenharmony_ci 954f08c3bdfSopenharmony_ci ltype = usual_conversions(op, expr->left, expr->right, 955f08c3bdfSopenharmony_ci lclass, rclass, ltype, rtype); 956f08c3bdfSopenharmony_ci ctype = rtype = ltype; 957f08c3bdfSopenharmony_ci } 958f08c3bdfSopenharmony_ci 959f08c3bdfSopenharmony_ci expr->left = cast_to(expr->left, ltype); 960f08c3bdfSopenharmony_ci expr->right = cast_to(expr->right, rtype); 961f08c3bdfSopenharmony_ci expr->ctype = ctype; 962f08c3bdfSopenharmony_ci return ctype; 963f08c3bdfSopenharmony_ci } 964f08c3bdfSopenharmony_ci 965f08c3bdfSopenharmony_ci /* pointer (+|-) integer */ 966f08c3bdfSopenharmony_ci if (lclass & TYPE_PTR && is_int(rclass) && (op == '+' || op == '-')) { 967f08c3bdfSopenharmony_ci unrestrict(expr->right, rclass, &rtype); 968f08c3bdfSopenharmony_ci return evaluate_ptr_add(expr, rtype); 969f08c3bdfSopenharmony_ci } 970f08c3bdfSopenharmony_ci 971f08c3bdfSopenharmony_ci /* integer + pointer */ 972f08c3bdfSopenharmony_ci if (rclass & TYPE_PTR && is_int(lclass) && op == '+') { 973f08c3bdfSopenharmony_ci struct expression *index = expr->left; 974f08c3bdfSopenharmony_ci unrestrict(index, lclass, <ype); 975f08c3bdfSopenharmony_ci expr->left = expr->right; 976f08c3bdfSopenharmony_ci expr->right = index; 977f08c3bdfSopenharmony_ci return evaluate_ptr_add(expr, ltype); 978f08c3bdfSopenharmony_ci } 979f08c3bdfSopenharmony_ci 980f08c3bdfSopenharmony_ci /* pointer - pointer */ 981f08c3bdfSopenharmony_ci if (lclass & rclass & TYPE_PTR && expr->op == '-') 982f08c3bdfSopenharmony_ci return evaluate_ptr_sub(expr); 983f08c3bdfSopenharmony_ci 984f08c3bdfSopenharmony_ci return bad_expr_type(expr); 985f08c3bdfSopenharmony_ci} 986f08c3bdfSopenharmony_ci 987f08c3bdfSopenharmony_cistatic struct symbol *evaluate_comma(struct expression *expr) 988f08c3bdfSopenharmony_ci{ 989f08c3bdfSopenharmony_ci expr->ctype = unqualify_type(degenerate(expr->right)); 990f08c3bdfSopenharmony_ci if (expr->ctype == &null_ctype) 991f08c3bdfSopenharmony_ci expr->ctype = &ptr_ctype; 992f08c3bdfSopenharmony_ci expr->flags &= expr->left->flags & expr->right->flags; 993f08c3bdfSopenharmony_ci return expr->ctype; 994f08c3bdfSopenharmony_ci} 995f08c3bdfSopenharmony_ci 996f08c3bdfSopenharmony_cistatic int modify_for_unsigned(int op) 997f08c3bdfSopenharmony_ci{ 998f08c3bdfSopenharmony_ci if (op == '<') 999f08c3bdfSopenharmony_ci op = SPECIAL_UNSIGNED_LT; 1000f08c3bdfSopenharmony_ci else if (op == '>') 1001f08c3bdfSopenharmony_ci op = SPECIAL_UNSIGNED_GT; 1002f08c3bdfSopenharmony_ci else if (op == SPECIAL_LTE) 1003f08c3bdfSopenharmony_ci op = SPECIAL_UNSIGNED_LTE; 1004f08c3bdfSopenharmony_ci else if (op == SPECIAL_GTE) 1005f08c3bdfSopenharmony_ci op = SPECIAL_UNSIGNED_GTE; 1006f08c3bdfSopenharmony_ci return op; 1007f08c3bdfSopenharmony_ci} 1008f08c3bdfSopenharmony_ci 1009f08c3bdfSopenharmony_cienum null_constant_type { 1010f08c3bdfSopenharmony_ci NON_NULL, 1011f08c3bdfSopenharmony_ci NULL_PTR, 1012f08c3bdfSopenharmony_ci NULL_ZERO, 1013f08c3bdfSopenharmony_ci}; 1014f08c3bdfSopenharmony_ci 1015f08c3bdfSopenharmony_cistatic inline int is_null_pointer_constant(struct expression *e) 1016f08c3bdfSopenharmony_ci{ 1017f08c3bdfSopenharmony_ci if (e->ctype == &null_ctype) 1018f08c3bdfSopenharmony_ci return NULL_PTR; 1019f08c3bdfSopenharmony_ci if (!(e->flags & CEF_ICE)) 1020f08c3bdfSopenharmony_ci return NON_NULL; 1021f08c3bdfSopenharmony_ci return is_zero_constant(e) ? NULL_ZERO : NON_NULL; 1022f08c3bdfSopenharmony_ci} 1023f08c3bdfSopenharmony_ci 1024f08c3bdfSopenharmony_cistatic struct symbol *evaluate_compare(struct expression *expr) 1025f08c3bdfSopenharmony_ci{ 1026f08c3bdfSopenharmony_ci struct expression *left = expr->left, *right = expr->right; 1027f08c3bdfSopenharmony_ci struct symbol *ltype, *rtype, *lbase, *rbase; 1028f08c3bdfSopenharmony_ci int lclass = classify_type(degenerate(left), <ype); 1029f08c3bdfSopenharmony_ci int rclass = classify_type(degenerate(right), &rtype); 1030f08c3bdfSopenharmony_ci struct symbol *ctype; 1031f08c3bdfSopenharmony_ci const char *typediff; 1032f08c3bdfSopenharmony_ci 1033f08c3bdfSopenharmony_ci /* Type types? */ 1034f08c3bdfSopenharmony_ci if (is_type_type(ltype) && is_type_type(rtype)) { 1035f08c3bdfSopenharmony_ci /* 1036f08c3bdfSopenharmony_ci * __builtin_types_compatible_p() yields an integer 1037f08c3bdfSopenharmony_ci * constant expression 1038f08c3bdfSopenharmony_ci */ 1039f08c3bdfSopenharmony_ci expr->flags = CEF_SET_ICE; 1040f08c3bdfSopenharmony_ci goto OK; 1041f08c3bdfSopenharmony_ci } 1042f08c3bdfSopenharmony_ci 1043f08c3bdfSopenharmony_ci if (is_safe_type(left->ctype) || is_safe_type(right->ctype)) 1044f08c3bdfSopenharmony_ci warning(expr->pos, "testing a 'safe expression'"); 1045f08c3bdfSopenharmony_ci 1046f08c3bdfSopenharmony_ci expr->flags = left->flags & right->flags & ~CEF_CONST_MASK & ~CEF_ADDR; 1047f08c3bdfSopenharmony_ci 1048f08c3bdfSopenharmony_ci /* number on number */ 1049f08c3bdfSopenharmony_ci if (lclass & rclass & TYPE_NUM) { 1050f08c3bdfSopenharmony_ci ctype = usual_conversions(expr->op, expr->left, expr->right, 1051f08c3bdfSopenharmony_ci lclass, rclass, ltype, rtype); 1052f08c3bdfSopenharmony_ci expr->left = cast_to(expr->left, ctype); 1053f08c3bdfSopenharmony_ci expr->right = cast_to(expr->right, ctype); 1054f08c3bdfSopenharmony_ci if (ctype->ctype.modifiers & MOD_UNSIGNED) 1055f08c3bdfSopenharmony_ci expr->op = modify_for_unsigned(expr->op); 1056f08c3bdfSopenharmony_ci goto OK; 1057f08c3bdfSopenharmony_ci } 1058f08c3bdfSopenharmony_ci 1059f08c3bdfSopenharmony_ci /* at least one must be a pointer */ 1060f08c3bdfSopenharmony_ci if (!((lclass | rclass) & TYPE_PTR)) 1061f08c3bdfSopenharmony_ci return bad_expr_type(expr); 1062f08c3bdfSopenharmony_ci 1063f08c3bdfSopenharmony_ci /* equality comparisons can be with null pointer constants */ 1064f08c3bdfSopenharmony_ci if (expr->op == SPECIAL_EQUAL || expr->op == SPECIAL_NOTEQUAL) { 1065f08c3bdfSopenharmony_ci int is_null1 = is_null_pointer_constant(left); 1066f08c3bdfSopenharmony_ci int is_null2 = is_null_pointer_constant(right); 1067f08c3bdfSopenharmony_ci if (is_null1 == NULL_ZERO) 1068f08c3bdfSopenharmony_ci bad_null(left); 1069f08c3bdfSopenharmony_ci if (is_null2 == NULL_ZERO) 1070f08c3bdfSopenharmony_ci bad_null(right); 1071f08c3bdfSopenharmony_ci if (is_null1 && is_null2) { 1072f08c3bdfSopenharmony_ci int positive = expr->op == SPECIAL_EQUAL; 1073f08c3bdfSopenharmony_ci expr->type = EXPR_VALUE; 1074f08c3bdfSopenharmony_ci expr->value = positive; 1075f08c3bdfSopenharmony_ci goto OK; 1076f08c3bdfSopenharmony_ci } 1077f08c3bdfSopenharmony_ci if (is_null1 && (rclass & TYPE_PTR)) { 1078f08c3bdfSopenharmony_ci expr->left = cast_to(left, rtype); 1079f08c3bdfSopenharmony_ci goto OK; 1080f08c3bdfSopenharmony_ci } 1081f08c3bdfSopenharmony_ci if (is_null2 && (lclass & TYPE_PTR)) { 1082f08c3bdfSopenharmony_ci expr->right = cast_to(right, ltype); 1083f08c3bdfSopenharmony_ci goto OK; 1084f08c3bdfSopenharmony_ci } 1085f08c3bdfSopenharmony_ci } 1086f08c3bdfSopenharmony_ci /* both should be pointers */ 1087f08c3bdfSopenharmony_ci if (!(lclass & rclass & TYPE_PTR)) 1088f08c3bdfSopenharmony_ci return bad_expr_type(expr); 1089f08c3bdfSopenharmony_ci expr->op = modify_for_unsigned(expr->op); 1090f08c3bdfSopenharmony_ci 1091f08c3bdfSopenharmony_ci lbase = examine_pointer_target(ltype); 1092f08c3bdfSopenharmony_ci rbase = examine_pointer_target(rtype); 1093f08c3bdfSopenharmony_ci 1094f08c3bdfSopenharmony_ci /* they also have special treatment for pointers to void */ 1095f08c3bdfSopenharmony_ci if (expr->op == SPECIAL_EQUAL || expr->op == SPECIAL_NOTEQUAL) { 1096f08c3bdfSopenharmony_ci if (ltype->ctype.as == rtype->ctype.as) { 1097f08c3bdfSopenharmony_ci if (lbase == &void_ctype) { 1098f08c3bdfSopenharmony_ci expr->right = cast_to(right, ltype); 1099f08c3bdfSopenharmony_ci goto OK; 1100f08c3bdfSopenharmony_ci } 1101f08c3bdfSopenharmony_ci if (rbase == &void_ctype) { 1102f08c3bdfSopenharmony_ci expr->left = cast_to(left, rtype); 1103f08c3bdfSopenharmony_ci goto OK; 1104f08c3bdfSopenharmony_ci } 1105f08c3bdfSopenharmony_ci } 1106f08c3bdfSopenharmony_ci } 1107f08c3bdfSopenharmony_ci 1108f08c3bdfSopenharmony_ci typediff = type_difference(<ype->ctype, &rtype->ctype, 1109f08c3bdfSopenharmony_ci target_qualifiers(rtype), 1110f08c3bdfSopenharmony_ci target_qualifiers(ltype)); 1111f08c3bdfSopenharmony_ci if (!typediff) 1112f08c3bdfSopenharmony_ci goto OK; 1113f08c3bdfSopenharmony_ci 1114f08c3bdfSopenharmony_ci expression_error(expr, "incompatible types in comparison expression (%s):", typediff); 1115f08c3bdfSopenharmony_ci info(expr->pos, " %s", show_typename(ltype)); 1116f08c3bdfSopenharmony_ci info(expr->pos, " %s", show_typename(rtype)); 1117f08c3bdfSopenharmony_ci return NULL; 1118f08c3bdfSopenharmony_ci 1119f08c3bdfSopenharmony_ciOK: 1120f08c3bdfSopenharmony_ci /* the result is int [6.5.8(6), 6.5.9(3)]*/ 1121f08c3bdfSopenharmony_ci expr->ctype = &int_ctype; 1122f08c3bdfSopenharmony_ci return &int_ctype; 1123f08c3bdfSopenharmony_ci} 1124f08c3bdfSopenharmony_ci 1125f08c3bdfSopenharmony_ci/* 1126f08c3bdfSopenharmony_ci * NOTE! The degenerate case of "x ? : y", where we don't 1127f08c3bdfSopenharmony_ci * have a true case, this will possibly promote "x" to the 1128f08c3bdfSopenharmony_ci * same type as "y", and thus _change_ the conditional 1129f08c3bdfSopenharmony_ci * test in the expression. But since promotion is "safe" 1130f08c3bdfSopenharmony_ci * for testing, that's OK. 1131f08c3bdfSopenharmony_ci */ 1132f08c3bdfSopenharmony_cistatic struct symbol *evaluate_conditional_expression(struct expression *expr) 1133f08c3bdfSopenharmony_ci{ 1134f08c3bdfSopenharmony_ci struct expression **cond; 1135f08c3bdfSopenharmony_ci struct symbol *ctype, *ltype, *rtype, *lbase, *rbase; 1136f08c3bdfSopenharmony_ci int lclass, rclass; 1137f08c3bdfSopenharmony_ci const char * typediff; 1138f08c3bdfSopenharmony_ci int qual; 1139f08c3bdfSopenharmony_ci 1140f08c3bdfSopenharmony_ci if (!evaluate_conditional(expr->conditional, 0)) 1141f08c3bdfSopenharmony_ci return NULL; 1142f08c3bdfSopenharmony_ci if (!evaluate_expression(expr->cond_false)) 1143f08c3bdfSopenharmony_ci return NULL; 1144f08c3bdfSopenharmony_ci 1145f08c3bdfSopenharmony_ci ctype = degenerate(expr->conditional); 1146f08c3bdfSopenharmony_ci rtype = degenerate(expr->cond_false); 1147f08c3bdfSopenharmony_ci 1148f08c3bdfSopenharmony_ci cond = &expr->conditional; 1149f08c3bdfSopenharmony_ci ltype = ctype; 1150f08c3bdfSopenharmony_ci if (expr->cond_true) { 1151f08c3bdfSopenharmony_ci if (!evaluate_expression(expr->cond_true)) 1152f08c3bdfSopenharmony_ci return NULL; 1153f08c3bdfSopenharmony_ci ltype = degenerate(expr->cond_true); 1154f08c3bdfSopenharmony_ci cond = &expr->cond_true; 1155f08c3bdfSopenharmony_ci } 1156f08c3bdfSopenharmony_ci 1157f08c3bdfSopenharmony_ci expr->flags = (expr->conditional->flags & (*cond)->flags & 1158f08c3bdfSopenharmony_ci expr->cond_false->flags & ~CEF_CONST_MASK); 1159f08c3bdfSopenharmony_ci /* 1160f08c3bdfSopenharmony_ci * In the standard, it is defined that an integer constant expression 1161f08c3bdfSopenharmony_ci * shall only have operands that are themselves constant [6.6(6)]. 1162f08c3bdfSopenharmony_ci * While this definition is very clear for expressions that need all 1163f08c3bdfSopenharmony_ci * their operands to be evaluated, for conditional expressions with a 1164f08c3bdfSopenharmony_ci * constant condition things are much less obvious. 1165f08c3bdfSopenharmony_ci * So, as an extension, do the same as GCC seems to do: 1166f08c3bdfSopenharmony_ci * Consider a conditional expression with a constant condition 1167f08c3bdfSopenharmony_ci * as having the same constantness as the argument corresponding 1168f08c3bdfSopenharmony_ci * to the truth value (including in the case of address constants 1169f08c3bdfSopenharmony_ci * which are defined more stricly [6.6(9)]). 1170f08c3bdfSopenharmony_ci */ 1171f08c3bdfSopenharmony_ci if (expr->conditional->flags & (CEF_ACE | CEF_ADDR)) { 1172f08c3bdfSopenharmony_ci int is_true = expr_truth_value(expr->conditional); 1173f08c3bdfSopenharmony_ci struct expression *arg = is_true ? *cond : expr->cond_false; 1174f08c3bdfSopenharmony_ci expr->flags = arg->flags & ~CEF_CONST_MASK; 1175f08c3bdfSopenharmony_ci } 1176f08c3bdfSopenharmony_ci 1177f08c3bdfSopenharmony_ci lclass = classify_type(ltype, <ype); 1178f08c3bdfSopenharmony_ci rclass = classify_type(rtype, &rtype); 1179f08c3bdfSopenharmony_ci if (lclass & rclass & TYPE_NUM) { 1180f08c3bdfSopenharmony_ci ctype = usual_conversions('?', *cond, expr->cond_false, 1181f08c3bdfSopenharmony_ci lclass, rclass, ltype, rtype); 1182f08c3bdfSopenharmony_ci *cond = cast_to(*cond, ctype); 1183f08c3bdfSopenharmony_ci expr->cond_false = cast_to(expr->cond_false, ctype); 1184f08c3bdfSopenharmony_ci goto out; 1185f08c3bdfSopenharmony_ci } 1186f08c3bdfSopenharmony_ci 1187f08c3bdfSopenharmony_ci if ((lclass | rclass) & TYPE_PTR) { 1188f08c3bdfSopenharmony_ci int is_null1 = is_null_pointer_constant(*cond); 1189f08c3bdfSopenharmony_ci int is_null2 = is_null_pointer_constant(expr->cond_false); 1190f08c3bdfSopenharmony_ci 1191f08c3bdfSopenharmony_ci if (is_null1 && is_null2) { 1192f08c3bdfSopenharmony_ci *cond = cast_to(*cond, &ptr_ctype); 1193f08c3bdfSopenharmony_ci expr->cond_false = cast_to(expr->cond_false, &ptr_ctype); 1194f08c3bdfSopenharmony_ci ctype = &ptr_ctype; 1195f08c3bdfSopenharmony_ci goto out; 1196f08c3bdfSopenharmony_ci } 1197f08c3bdfSopenharmony_ci if (is_null1 && (rclass & TYPE_PTR)) { 1198f08c3bdfSopenharmony_ci if (is_null1 == NULL_ZERO) 1199f08c3bdfSopenharmony_ci bad_null(*cond); 1200f08c3bdfSopenharmony_ci *cond = cast_to(*cond, rtype); 1201f08c3bdfSopenharmony_ci ctype = rtype; 1202f08c3bdfSopenharmony_ci goto out; 1203f08c3bdfSopenharmony_ci } 1204f08c3bdfSopenharmony_ci if (is_null2 && (lclass & TYPE_PTR)) { 1205f08c3bdfSopenharmony_ci if (is_null2 == NULL_ZERO) 1206f08c3bdfSopenharmony_ci bad_null(expr->cond_false); 1207f08c3bdfSopenharmony_ci expr->cond_false = cast_to(expr->cond_false, ltype); 1208f08c3bdfSopenharmony_ci ctype = ltype; 1209f08c3bdfSopenharmony_ci goto out; 1210f08c3bdfSopenharmony_ci } 1211f08c3bdfSopenharmony_ci if (!(lclass & rclass & TYPE_PTR)) { 1212f08c3bdfSopenharmony_ci typediff = "different types"; 1213f08c3bdfSopenharmony_ci goto Err; 1214f08c3bdfSopenharmony_ci } 1215f08c3bdfSopenharmony_ci /* OK, it's pointer on pointer */ 1216f08c3bdfSopenharmony_ci if (ltype->ctype.as != rtype->ctype.as) { 1217f08c3bdfSopenharmony_ci typediff = "different address spaces"; 1218f08c3bdfSopenharmony_ci goto Err; 1219f08c3bdfSopenharmony_ci } 1220f08c3bdfSopenharmony_ci 1221f08c3bdfSopenharmony_ci /* need to be lazier here */ 1222f08c3bdfSopenharmony_ci lbase = examine_pointer_target(ltype); 1223f08c3bdfSopenharmony_ci rbase = examine_pointer_target(rtype); 1224f08c3bdfSopenharmony_ci qual = target_qualifiers(ltype) | target_qualifiers(rtype); 1225f08c3bdfSopenharmony_ci 1226f08c3bdfSopenharmony_ci if (lbase == &void_ctype) { 1227f08c3bdfSopenharmony_ci /* XXX: pointers to function should warn here */ 1228f08c3bdfSopenharmony_ci ctype = ltype; 1229f08c3bdfSopenharmony_ci goto Qual; 1230f08c3bdfSopenharmony_ci 1231f08c3bdfSopenharmony_ci } 1232f08c3bdfSopenharmony_ci if (rbase == &void_ctype) { 1233f08c3bdfSopenharmony_ci /* XXX: pointers to function should warn here */ 1234f08c3bdfSopenharmony_ci ctype = rtype; 1235f08c3bdfSopenharmony_ci goto Qual; 1236f08c3bdfSopenharmony_ci } 1237f08c3bdfSopenharmony_ci /* XXX: that should be pointer to composite */ 1238f08c3bdfSopenharmony_ci ctype = ltype; 1239f08c3bdfSopenharmony_ci typediff = type_difference(<ype->ctype, &rtype->ctype, 1240f08c3bdfSopenharmony_ci qual, qual); 1241f08c3bdfSopenharmony_ci if (!typediff) 1242f08c3bdfSopenharmony_ci goto Qual; 1243f08c3bdfSopenharmony_ci goto Err; 1244f08c3bdfSopenharmony_ci } 1245f08c3bdfSopenharmony_ci 1246f08c3bdfSopenharmony_ci /* void on void, struct on same struct, union on same union */ 1247f08c3bdfSopenharmony_ci if (ltype == rtype) { 1248f08c3bdfSopenharmony_ci ctype = ltype; 1249f08c3bdfSopenharmony_ci goto out; 1250f08c3bdfSopenharmony_ci } 1251f08c3bdfSopenharmony_ci typediff = "different base types"; 1252f08c3bdfSopenharmony_ci 1253f08c3bdfSopenharmony_ciErr: 1254f08c3bdfSopenharmony_ci expression_error(expr, "incompatible types in conditional expression (%s):", typediff); 1255f08c3bdfSopenharmony_ci info(expr->pos, " %s", show_typename(ltype)); 1256f08c3bdfSopenharmony_ci info(expr->pos, " %s", show_typename(rtype)); 1257f08c3bdfSopenharmony_ci /* 1258f08c3bdfSopenharmony_ci * if the condition is constant, the type is in fact known 1259f08c3bdfSopenharmony_ci * so use it, as gcc & clang do. 1260f08c3bdfSopenharmony_ci */ 1261f08c3bdfSopenharmony_ci switch (expr_truth_value(expr->conditional)) { 1262f08c3bdfSopenharmony_ci case 1: expr->ctype = ltype; 1263f08c3bdfSopenharmony_ci break; 1264f08c3bdfSopenharmony_ci case 0: expr->ctype = rtype; 1265f08c3bdfSopenharmony_ci break; 1266f08c3bdfSopenharmony_ci default: 1267f08c3bdfSopenharmony_ci break; 1268f08c3bdfSopenharmony_ci } 1269f08c3bdfSopenharmony_ci return NULL; 1270f08c3bdfSopenharmony_ci 1271f08c3bdfSopenharmony_ciout: 1272f08c3bdfSopenharmony_ci expr->ctype = ctype; 1273f08c3bdfSopenharmony_ci return ctype; 1274f08c3bdfSopenharmony_ci 1275f08c3bdfSopenharmony_ciQual: 1276f08c3bdfSopenharmony_ci if (qual & ~ctype->ctype.modifiers) { 1277f08c3bdfSopenharmony_ci struct symbol *sym = alloc_symbol(ctype->pos, SYM_PTR); 1278f08c3bdfSopenharmony_ci *sym = *ctype; 1279f08c3bdfSopenharmony_ci sym->ctype.modifiers |= qual; 1280f08c3bdfSopenharmony_ci ctype = sym; 1281f08c3bdfSopenharmony_ci } 1282f08c3bdfSopenharmony_ci *cond = cast_to(*cond, ctype); 1283f08c3bdfSopenharmony_ci expr->cond_false = cast_to(expr->cond_false, ctype); 1284f08c3bdfSopenharmony_ci goto out; 1285f08c3bdfSopenharmony_ci} 1286f08c3bdfSopenharmony_ci 1287f08c3bdfSopenharmony_ci/* FP assignments can not do modulo or bit operations */ 1288f08c3bdfSopenharmony_cistatic int compatible_float_op(int op) 1289f08c3bdfSopenharmony_ci{ 1290f08c3bdfSopenharmony_ci return op == SPECIAL_ADD_ASSIGN || 1291f08c3bdfSopenharmony_ci op == SPECIAL_SUB_ASSIGN || 1292f08c3bdfSopenharmony_ci op == SPECIAL_MUL_ASSIGN || 1293f08c3bdfSopenharmony_ci op == SPECIAL_DIV_ASSIGN; 1294f08c3bdfSopenharmony_ci} 1295f08c3bdfSopenharmony_ci 1296f08c3bdfSopenharmony_cistatic int evaluate_assign_op(struct expression *expr) 1297f08c3bdfSopenharmony_ci{ 1298f08c3bdfSopenharmony_ci struct symbol *target = expr->left->ctype; 1299f08c3bdfSopenharmony_ci struct symbol *source = expr->right->ctype; 1300f08c3bdfSopenharmony_ci struct symbol *t, *s; 1301f08c3bdfSopenharmony_ci int tclass = classify_type(target, &t); 1302f08c3bdfSopenharmony_ci int sclass = classify_type(source, &s); 1303f08c3bdfSopenharmony_ci int op = expr->op; 1304f08c3bdfSopenharmony_ci 1305f08c3bdfSopenharmony_ci if (tclass & sclass & TYPE_NUM) { 1306f08c3bdfSopenharmony_ci if (tclass & TYPE_FLOAT && !compatible_float_op(op)) { 1307f08c3bdfSopenharmony_ci expression_error(expr, "invalid assignment"); 1308f08c3bdfSopenharmony_ci return 0; 1309f08c3bdfSopenharmony_ci } 1310f08c3bdfSopenharmony_ci if (tclass & TYPE_RESTRICT) { 1311f08c3bdfSopenharmony_ci if (!restricted_binop(op, t)) { 1312f08c3bdfSopenharmony_ci warning(expr->pos, "bad assignment (%s) to %s", 1313f08c3bdfSopenharmony_ci show_special(op), show_typename(t)); 1314f08c3bdfSopenharmony_ci expr->right = cast_to(expr->right, target); 1315f08c3bdfSopenharmony_ci return 0; 1316f08c3bdfSopenharmony_ci } 1317f08c3bdfSopenharmony_ci /* allowed assignments unfoul */ 1318f08c3bdfSopenharmony_ci if (sclass & TYPE_FOULED && unfoul(s) == t) 1319f08c3bdfSopenharmony_ci goto Cast; 1320f08c3bdfSopenharmony_ci if (!restricted_value(expr->right, t)) 1321f08c3bdfSopenharmony_ci return 1; 1322f08c3bdfSopenharmony_ci } else if (op == SPECIAL_SHR_ASSIGN || op == SPECIAL_SHL_ASSIGN) { 1323f08c3bdfSopenharmony_ci // shifts do integer promotions, but that's it. 1324f08c3bdfSopenharmony_ci unrestrict(expr->left, tclass, &t); 1325f08c3bdfSopenharmony_ci target = integer_promotion(t); 1326f08c3bdfSopenharmony_ci 1327f08c3bdfSopenharmony_ci unrestrict(expr->right, sclass, &s); 1328f08c3bdfSopenharmony_ci source = integer_promotion(s); 1329f08c3bdfSopenharmony_ci expr->right = cast_to(expr->right, source); 1330f08c3bdfSopenharmony_ci 1331f08c3bdfSopenharmony_ci // both gcc & clang seems to do this, so ... 1332f08c3bdfSopenharmony_ci if (target->bit_size > source->bit_size) 1333f08c3bdfSopenharmony_ci expr->right = cast_to(expr->right, &uint_ctype); 1334f08c3bdfSopenharmony_ci 1335f08c3bdfSopenharmony_ci goto Cast; 1336f08c3bdfSopenharmony_ci } else if (!(sclass & TYPE_RESTRICT)) 1337f08c3bdfSopenharmony_ci goto usual; 1338f08c3bdfSopenharmony_ci /* source and target would better be identical restricted */ 1339f08c3bdfSopenharmony_ci if (t == s) 1340f08c3bdfSopenharmony_ci return 1; 1341f08c3bdfSopenharmony_ci warning(expr->pos, "invalid assignment: %s", show_special(op)); 1342f08c3bdfSopenharmony_ci info(expr->pos, " left side has type %s", show_typename(t)); 1343f08c3bdfSopenharmony_ci info(expr->pos, " right side has type %s", show_typename(s)); 1344f08c3bdfSopenharmony_ci expr->right = cast_to(expr->right, target); 1345f08c3bdfSopenharmony_ci return 0; 1346f08c3bdfSopenharmony_ci } 1347f08c3bdfSopenharmony_ci if (tclass == TYPE_PTR && is_int(sclass)) { 1348f08c3bdfSopenharmony_ci if (op == SPECIAL_ADD_ASSIGN || op == SPECIAL_SUB_ASSIGN) { 1349f08c3bdfSopenharmony_ci unrestrict(expr->right, sclass, &s); 1350f08c3bdfSopenharmony_ci evaluate_ptr_add(expr, s); 1351f08c3bdfSopenharmony_ci return 1; 1352f08c3bdfSopenharmony_ci } 1353f08c3bdfSopenharmony_ci expression_error(expr, "invalid pointer assignment"); 1354f08c3bdfSopenharmony_ci return 0; 1355f08c3bdfSopenharmony_ci } 1356f08c3bdfSopenharmony_ci 1357f08c3bdfSopenharmony_ci expression_error(expr, "invalid assignment"); 1358f08c3bdfSopenharmony_ci return 0; 1359f08c3bdfSopenharmony_ci 1360f08c3bdfSopenharmony_ciusual: 1361f08c3bdfSopenharmony_ci target = usual_conversions(op, expr->left, expr->right, 1362f08c3bdfSopenharmony_ci tclass, sclass, target, source); 1363f08c3bdfSopenharmony_ciCast: 1364f08c3bdfSopenharmony_ci expr->right = cast_to(expr->right, target); 1365f08c3bdfSopenharmony_ci return 1; 1366f08c3bdfSopenharmony_ci} 1367f08c3bdfSopenharmony_ci 1368f08c3bdfSopenharmony_cistatic int whitelist_pointers(struct symbol *t1, struct symbol *t2) 1369f08c3bdfSopenharmony_ci{ 1370f08c3bdfSopenharmony_ci if (t1 == t2) 1371f08c3bdfSopenharmony_ci return 0; /* yes, 0 - we don't want a cast_to here */ 1372f08c3bdfSopenharmony_ci if (t1 == &void_ctype) 1373f08c3bdfSopenharmony_ci return 1; 1374f08c3bdfSopenharmony_ci if (t2 == &void_ctype) 1375f08c3bdfSopenharmony_ci return 1; 1376f08c3bdfSopenharmony_ci if (classify_type(t1, &t1) != TYPE_NUM) 1377f08c3bdfSopenharmony_ci return 0; 1378f08c3bdfSopenharmony_ci if (classify_type(t2, &t2) != TYPE_NUM) 1379f08c3bdfSopenharmony_ci return 0; 1380f08c3bdfSopenharmony_ci if (t1 == t2) 1381f08c3bdfSopenharmony_ci return 1; 1382f08c3bdfSopenharmony_ci if (t1->rank == -2 && t2->rank == -2) 1383f08c3bdfSopenharmony_ci return 1; 1384f08c3bdfSopenharmony_ci if (t1->rank != t2->rank) 1385f08c3bdfSopenharmony_ci return 0; 1386f08c3bdfSopenharmony_ci return !Wtypesign; 1387f08c3bdfSopenharmony_ci} 1388f08c3bdfSopenharmony_ci 1389f08c3bdfSopenharmony_cistatic int check_assignment_types(struct symbol *target, struct expression **rp, 1390f08c3bdfSopenharmony_ci const char **typediff) 1391f08c3bdfSopenharmony_ci{ 1392f08c3bdfSopenharmony_ci struct symbol *source = degenerate(*rp); 1393f08c3bdfSopenharmony_ci struct symbol *t, *s; 1394f08c3bdfSopenharmony_ci int tclass = classify_type(target, &t); 1395f08c3bdfSopenharmony_ci int sclass = classify_type(source, &s); 1396f08c3bdfSopenharmony_ci 1397f08c3bdfSopenharmony_ci if (tclass & sclass & TYPE_NUM) { 1398f08c3bdfSopenharmony_ci if (tclass & TYPE_RESTRICT) { 1399f08c3bdfSopenharmony_ci /* allowed assignments unfoul */ 1400f08c3bdfSopenharmony_ci if (sclass & TYPE_FOULED && unfoul(s) == t) 1401f08c3bdfSopenharmony_ci goto Cast; 1402f08c3bdfSopenharmony_ci if (!restricted_value(*rp, target)) 1403f08c3bdfSopenharmony_ci goto Cast; 1404f08c3bdfSopenharmony_ci if (s == t) 1405f08c3bdfSopenharmony_ci return 1; 1406f08c3bdfSopenharmony_ci } else if (!(sclass & TYPE_RESTRICT)) 1407f08c3bdfSopenharmony_ci goto Cast; 1408f08c3bdfSopenharmony_ci if (t == &bool_ctype) { 1409f08c3bdfSopenharmony_ci if (is_fouled_type(s)) 1410f08c3bdfSopenharmony_ci warning((*rp)->pos, "%s degrades to integer", 1411f08c3bdfSopenharmony_ci show_typename(s->ctype.base_type)); 1412f08c3bdfSopenharmony_ci goto Cast; 1413f08c3bdfSopenharmony_ci } 1414f08c3bdfSopenharmony_ci *typediff = "different base types"; 1415f08c3bdfSopenharmony_ci return 0; 1416f08c3bdfSopenharmony_ci } 1417f08c3bdfSopenharmony_ci 1418f08c3bdfSopenharmony_ci if (tclass == TYPE_PTR) { 1419f08c3bdfSopenharmony_ci unsigned long mod1, mod2; 1420f08c3bdfSopenharmony_ci unsigned long modl, modr; 1421f08c3bdfSopenharmony_ci struct symbol *b1, *b2; 1422f08c3bdfSopenharmony_ci // NULL pointer is always OK 1423f08c3bdfSopenharmony_ci int is_null = is_null_pointer_constant(*rp); 1424f08c3bdfSopenharmony_ci if (is_null) { 1425f08c3bdfSopenharmony_ci if (is_null == NULL_ZERO) 1426f08c3bdfSopenharmony_ci bad_null(*rp); 1427f08c3bdfSopenharmony_ci goto Cast; 1428f08c3bdfSopenharmony_ci } 1429f08c3bdfSopenharmony_ci if (!(sclass & TYPE_PTR)) { 1430f08c3bdfSopenharmony_ci *typediff = "different base types"; 1431f08c3bdfSopenharmony_ci return 0; 1432f08c3bdfSopenharmony_ci } 1433f08c3bdfSopenharmony_ci b1 = examine_pointer_target(t); 1434f08c3bdfSopenharmony_ci b2 = examine_pointer_target(s); 1435f08c3bdfSopenharmony_ci mod1 = t->ctype.modifiers & MOD_IGN; 1436f08c3bdfSopenharmony_ci mod2 = s->ctype.modifiers & MOD_IGN; 1437f08c3bdfSopenharmony_ci if (whitelist_pointers(b1, b2)) { 1438f08c3bdfSopenharmony_ci /* 1439f08c3bdfSopenharmony_ci * assignments to/from void * are OK, provided that 1440f08c3bdfSopenharmony_ci * we do not remove qualifiers from pointed to [C] 1441f08c3bdfSopenharmony_ci * or mix address spaces [sparse]. 1442f08c3bdfSopenharmony_ci */ 1443f08c3bdfSopenharmony_ci if (t->ctype.as != s->ctype.as) { 1444f08c3bdfSopenharmony_ci *typediff = "different address spaces"; 1445f08c3bdfSopenharmony_ci return 0; 1446f08c3bdfSopenharmony_ci } 1447f08c3bdfSopenharmony_ci /* 1448f08c3bdfSopenharmony_ci * If this is a function pointer assignment, it is 1449f08c3bdfSopenharmony_ci * actually fine to assign a pointer to const data to 1450f08c3bdfSopenharmony_ci * it, as a function pointer points to const data 1451f08c3bdfSopenharmony_ci * implicitly, i.e., dereferencing it does not produce 1452f08c3bdfSopenharmony_ci * an lvalue. 1453f08c3bdfSopenharmony_ci */ 1454f08c3bdfSopenharmony_ci if (b1->type == SYM_FN) 1455f08c3bdfSopenharmony_ci mod1 |= MOD_CONST; 1456f08c3bdfSopenharmony_ci if (mod2 & ~mod1 & ~MOD_FUN_ATTR) { 1457f08c3bdfSopenharmony_ci *typediff = "different modifiers"; 1458f08c3bdfSopenharmony_ci return 0; 1459f08c3bdfSopenharmony_ci } 1460f08c3bdfSopenharmony_ci goto Cast; 1461f08c3bdfSopenharmony_ci } 1462f08c3bdfSopenharmony_ci /* It's OK if the target is more volatile or const than the source */ 1463f08c3bdfSopenharmony_ci /* It's OK if the source is more pure/noreturn than the target */ 1464f08c3bdfSopenharmony_ci modr = mod1 & ~MOD_REV_QUAL; 1465f08c3bdfSopenharmony_ci modl = mod2 & MOD_REV_QUAL; 1466f08c3bdfSopenharmony_ci *typediff = type_difference(&t->ctype, &s->ctype, modl, modr); 1467f08c3bdfSopenharmony_ci if (*typediff) 1468f08c3bdfSopenharmony_ci return 0; 1469f08c3bdfSopenharmony_ci return 1; 1470f08c3bdfSopenharmony_ci } 1471f08c3bdfSopenharmony_ci 1472f08c3bdfSopenharmony_ci if ((tclass & TYPE_COMPOUND) && s == t) 1473f08c3bdfSopenharmony_ci return 1; 1474f08c3bdfSopenharmony_ci 1475f08c3bdfSopenharmony_ci if (tclass & TYPE_NUM) { 1476f08c3bdfSopenharmony_ci /* XXX: need to turn into comparison with NULL */ 1477f08c3bdfSopenharmony_ci if (t == &bool_ctype && (sclass & TYPE_PTR)) 1478f08c3bdfSopenharmony_ci goto Cast; 1479f08c3bdfSopenharmony_ci *typediff = "different base types"; 1480f08c3bdfSopenharmony_ci return 0; 1481f08c3bdfSopenharmony_ci } 1482f08c3bdfSopenharmony_ci *typediff = "invalid types"; 1483f08c3bdfSopenharmony_ci return 0; 1484f08c3bdfSopenharmony_ci 1485f08c3bdfSopenharmony_ciCast: 1486f08c3bdfSopenharmony_ci *rp = cast_to(*rp, target); 1487f08c3bdfSopenharmony_ci return 1; 1488f08c3bdfSopenharmony_ci} 1489f08c3bdfSopenharmony_ci 1490f08c3bdfSopenharmony_cistatic int compatible_assignment_types(struct expression *expr, struct symbol *target, 1491f08c3bdfSopenharmony_ci struct expression **rp, const char *where) 1492f08c3bdfSopenharmony_ci{ 1493f08c3bdfSopenharmony_ci const char *typediff; 1494f08c3bdfSopenharmony_ci 1495f08c3bdfSopenharmony_ci if (!check_assignment_types(target, rp, &typediff)) { 1496f08c3bdfSopenharmony_ci struct symbol *source = *rp ? (*rp)->ctype : NULL; 1497f08c3bdfSopenharmony_ci warning(expr->pos, "incorrect type in %s (%s)", where, typediff); 1498f08c3bdfSopenharmony_ci info(expr->pos, " expected %s", show_typename(target)); 1499f08c3bdfSopenharmony_ci info(expr->pos, " got %s", show_typename(source)); 1500f08c3bdfSopenharmony_ci *rp = cast_to(*rp, target); 1501f08c3bdfSopenharmony_ci return 0; 1502f08c3bdfSopenharmony_ci } 1503f08c3bdfSopenharmony_ci 1504f08c3bdfSopenharmony_ci return 1; 1505f08c3bdfSopenharmony_ci} 1506f08c3bdfSopenharmony_ci 1507f08c3bdfSopenharmony_cistatic int compatible_transparent_union(struct symbol *target, 1508f08c3bdfSopenharmony_ci struct expression **rp) 1509f08c3bdfSopenharmony_ci{ 1510f08c3bdfSopenharmony_ci struct symbol *t, *member; 1511f08c3bdfSopenharmony_ci classify_type(target, &t); 1512f08c3bdfSopenharmony_ci if (t->type != SYM_UNION || !t->transparent_union) 1513f08c3bdfSopenharmony_ci return 0; 1514f08c3bdfSopenharmony_ci 1515f08c3bdfSopenharmony_ci FOR_EACH_PTR(t->symbol_list, member) { 1516f08c3bdfSopenharmony_ci const char *typediff; 1517f08c3bdfSopenharmony_ci if (check_assignment_types(member, rp, &typediff)) 1518f08c3bdfSopenharmony_ci return 1; 1519f08c3bdfSopenharmony_ci } END_FOR_EACH_PTR(member); 1520f08c3bdfSopenharmony_ci 1521f08c3bdfSopenharmony_ci return 0; 1522f08c3bdfSopenharmony_ci} 1523f08c3bdfSopenharmony_ci 1524f08c3bdfSopenharmony_cistatic int compatible_argument_type(struct expression *expr, struct symbol *target, 1525f08c3bdfSopenharmony_ci struct expression **rp, const char *where) 1526f08c3bdfSopenharmony_ci{ 1527f08c3bdfSopenharmony_ci if (compatible_transparent_union(target, rp)) 1528f08c3bdfSopenharmony_ci return 1; 1529f08c3bdfSopenharmony_ci 1530f08c3bdfSopenharmony_ci return compatible_assignment_types(expr, target, rp, where); 1531f08c3bdfSopenharmony_ci} 1532f08c3bdfSopenharmony_ci 1533f08c3bdfSopenharmony_cistatic void mark_addressable(struct expression *expr) 1534f08c3bdfSopenharmony_ci{ 1535f08c3bdfSopenharmony_ci while (expr->type == EXPR_BINOP && expr->op == '+') 1536f08c3bdfSopenharmony_ci expr = expr->left; 1537f08c3bdfSopenharmony_ci if (expr->type == EXPR_SYMBOL) { 1538f08c3bdfSopenharmony_ci struct symbol *sym = expr->symbol; 1539f08c3bdfSopenharmony_ci sym->ctype.modifiers |= MOD_ADDRESSABLE; 1540f08c3bdfSopenharmony_ci } 1541f08c3bdfSopenharmony_ci} 1542f08c3bdfSopenharmony_ci 1543f08c3bdfSopenharmony_cistatic void mark_assigned(struct expression *expr) 1544f08c3bdfSopenharmony_ci{ 1545f08c3bdfSopenharmony_ci struct symbol *sym; 1546f08c3bdfSopenharmony_ci 1547f08c3bdfSopenharmony_ci if (!expr) 1548f08c3bdfSopenharmony_ci return; 1549f08c3bdfSopenharmony_ci switch (expr->type) { 1550f08c3bdfSopenharmony_ci case EXPR_SYMBOL: 1551f08c3bdfSopenharmony_ci sym = expr->symbol; 1552f08c3bdfSopenharmony_ci if (!sym) 1553f08c3bdfSopenharmony_ci return; 1554f08c3bdfSopenharmony_ci if (sym->type != SYM_NODE) 1555f08c3bdfSopenharmony_ci return; 1556f08c3bdfSopenharmony_ci sym->ctype.modifiers |= MOD_ASSIGNED; 1557f08c3bdfSopenharmony_ci return; 1558f08c3bdfSopenharmony_ci 1559f08c3bdfSopenharmony_ci case EXPR_BINOP: 1560f08c3bdfSopenharmony_ci mark_assigned(expr->left); 1561f08c3bdfSopenharmony_ci mark_assigned(expr->right); 1562f08c3bdfSopenharmony_ci return; 1563f08c3bdfSopenharmony_ci case EXPR_CAST: 1564f08c3bdfSopenharmony_ci case EXPR_FORCE_CAST: 1565f08c3bdfSopenharmony_ci mark_assigned(expr->cast_expression); 1566f08c3bdfSopenharmony_ci return; 1567f08c3bdfSopenharmony_ci case EXPR_SLICE: 1568f08c3bdfSopenharmony_ci mark_assigned(expr->base); 1569f08c3bdfSopenharmony_ci return; 1570f08c3bdfSopenharmony_ci default: 1571f08c3bdfSopenharmony_ci /* Hmm? */ 1572f08c3bdfSopenharmony_ci return; 1573f08c3bdfSopenharmony_ci } 1574f08c3bdfSopenharmony_ci} 1575f08c3bdfSopenharmony_ci 1576f08c3bdfSopenharmony_cistatic void evaluate_assign_to(struct expression *left, struct symbol *type) 1577f08c3bdfSopenharmony_ci{ 1578f08c3bdfSopenharmony_ci if (type->ctype.modifiers & MOD_CONST) 1579f08c3bdfSopenharmony_ci expression_error(left, "assignment to const expression"); 1580f08c3bdfSopenharmony_ci 1581f08c3bdfSopenharmony_ci /* We know left is an lvalue, so it's a "preop-*" */ 1582f08c3bdfSopenharmony_ci mark_assigned(left->unop); 1583f08c3bdfSopenharmony_ci} 1584f08c3bdfSopenharmony_ci 1585f08c3bdfSopenharmony_cistatic struct symbol *evaluate_assignment(struct expression *expr) 1586f08c3bdfSopenharmony_ci{ 1587f08c3bdfSopenharmony_ci struct expression *left = expr->left; 1588f08c3bdfSopenharmony_ci struct symbol *ltype; 1589f08c3bdfSopenharmony_ci 1590f08c3bdfSopenharmony_ci if (!lvalue_expression(left)) { 1591f08c3bdfSopenharmony_ci expression_error(expr, "not an lvalue"); 1592f08c3bdfSopenharmony_ci return NULL; 1593f08c3bdfSopenharmony_ci } 1594f08c3bdfSopenharmony_ci 1595f08c3bdfSopenharmony_ci ltype = left->ctype; 1596f08c3bdfSopenharmony_ci 1597f08c3bdfSopenharmony_ci if (expr->op != '=') { 1598f08c3bdfSopenharmony_ci if (!evaluate_assign_op(expr)) 1599f08c3bdfSopenharmony_ci return NULL; 1600f08c3bdfSopenharmony_ci } else { 1601f08c3bdfSopenharmony_ci if (!compatible_assignment_types(expr, ltype, &expr->right, "assignment")) 1602f08c3bdfSopenharmony_ci return NULL; 1603f08c3bdfSopenharmony_ci } 1604f08c3bdfSopenharmony_ci 1605f08c3bdfSopenharmony_ci evaluate_assign_to(left, ltype); 1606f08c3bdfSopenharmony_ci 1607f08c3bdfSopenharmony_ci expr->ctype = ltype; 1608f08c3bdfSopenharmony_ci return ltype; 1609f08c3bdfSopenharmony_ci} 1610f08c3bdfSopenharmony_ci 1611f08c3bdfSopenharmony_cistatic void examine_fn_arguments(struct symbol *fn) 1612f08c3bdfSopenharmony_ci{ 1613f08c3bdfSopenharmony_ci struct symbol *s; 1614f08c3bdfSopenharmony_ci 1615f08c3bdfSopenharmony_ci FOR_EACH_PTR(fn->arguments, s) { 1616f08c3bdfSopenharmony_ci struct symbol *arg = evaluate_symbol(s); 1617f08c3bdfSopenharmony_ci /* Array/function arguments silently degenerate into pointers */ 1618f08c3bdfSopenharmony_ci if (arg) { 1619f08c3bdfSopenharmony_ci struct symbol *ptr; 1620f08c3bdfSopenharmony_ci switch(arg->type) { 1621f08c3bdfSopenharmony_ci case SYM_ARRAY: 1622f08c3bdfSopenharmony_ci case SYM_FN: 1623f08c3bdfSopenharmony_ci ptr = alloc_symbol(s->pos, SYM_PTR); 1624f08c3bdfSopenharmony_ci if (arg->type == SYM_ARRAY) 1625f08c3bdfSopenharmony_ci ptr->ctype = arg->ctype; 1626f08c3bdfSopenharmony_ci else 1627f08c3bdfSopenharmony_ci ptr->ctype.base_type = arg; 1628f08c3bdfSopenharmony_ci combine_address_space(s->pos, &ptr->ctype.as, s->ctype.as); 1629f08c3bdfSopenharmony_ci ptr->ctype.modifiers |= s->ctype.modifiers & MOD_PTRINHERIT; 1630f08c3bdfSopenharmony_ci 1631f08c3bdfSopenharmony_ci s->ctype.base_type = ptr; 1632f08c3bdfSopenharmony_ci s->ctype.as = NULL; 1633f08c3bdfSopenharmony_ci s->ctype.modifiers &= ~MOD_PTRINHERIT; 1634f08c3bdfSopenharmony_ci s->bit_size = 0; 1635f08c3bdfSopenharmony_ci s->examined = 0; 1636f08c3bdfSopenharmony_ci examine_symbol_type(s); 1637f08c3bdfSopenharmony_ci break; 1638f08c3bdfSopenharmony_ci default: 1639f08c3bdfSopenharmony_ci /* nothing */ 1640f08c3bdfSopenharmony_ci break; 1641f08c3bdfSopenharmony_ci } 1642f08c3bdfSopenharmony_ci } 1643f08c3bdfSopenharmony_ci } END_FOR_EACH_PTR(s); 1644f08c3bdfSopenharmony_ci} 1645f08c3bdfSopenharmony_ci 1646f08c3bdfSopenharmony_cistatic struct symbol *convert_to_as_mod(struct symbol *sym, struct ident *as, int mod) 1647f08c3bdfSopenharmony_ci{ 1648f08c3bdfSopenharmony_ci /* Take the modifiers of the pointer, and apply them to the member */ 1649f08c3bdfSopenharmony_ci mod |= sym->ctype.modifiers; 1650f08c3bdfSopenharmony_ci if (sym->ctype.as != as || sym->ctype.modifiers != mod) { 1651f08c3bdfSopenharmony_ci struct symbol *newsym = alloc_symbol(sym->pos, SYM_NODE); 1652f08c3bdfSopenharmony_ci *newsym = *sym; 1653f08c3bdfSopenharmony_ci newsym->ctype.as = as; 1654f08c3bdfSopenharmony_ci newsym->ctype.modifiers = mod; 1655f08c3bdfSopenharmony_ci sym = newsym; 1656f08c3bdfSopenharmony_ci } 1657f08c3bdfSopenharmony_ci return sym; 1658f08c3bdfSopenharmony_ci} 1659f08c3bdfSopenharmony_ci 1660f08c3bdfSopenharmony_cistatic struct symbol *create_pointer(struct expression *expr, struct symbol *sym, int degenerate) 1661f08c3bdfSopenharmony_ci{ 1662f08c3bdfSopenharmony_ci struct symbol *node = alloc_symbol(expr->pos, SYM_NODE); 1663f08c3bdfSopenharmony_ci struct symbol *ptr = alloc_symbol(expr->pos, SYM_PTR); 1664f08c3bdfSopenharmony_ci 1665f08c3bdfSopenharmony_ci node->ctype.base_type = ptr; 1666f08c3bdfSopenharmony_ci ptr->bit_size = bits_in_pointer; 1667f08c3bdfSopenharmony_ci ptr->ctype.alignment = pointer_alignment; 1668f08c3bdfSopenharmony_ci 1669f08c3bdfSopenharmony_ci node->bit_size = bits_in_pointer; 1670f08c3bdfSopenharmony_ci node->ctype.alignment = pointer_alignment; 1671f08c3bdfSopenharmony_ci 1672f08c3bdfSopenharmony_ci access_symbol(sym); 1673f08c3bdfSopenharmony_ci if (sym->ctype.modifiers & MOD_REGISTER) { 1674f08c3bdfSopenharmony_ci warning(expr->pos, "taking address of 'register' variable '%s'", show_ident(sym->ident)); 1675f08c3bdfSopenharmony_ci sym->ctype.modifiers &= ~MOD_REGISTER; 1676f08c3bdfSopenharmony_ci } 1677f08c3bdfSopenharmony_ci if (sym->type == SYM_NODE) { 1678f08c3bdfSopenharmony_ci combine_address_space(sym->pos, &ptr->ctype.as, sym->ctype.as); 1679f08c3bdfSopenharmony_ci ptr->ctype.modifiers |= sym->ctype.modifiers & MOD_PTRINHERIT; 1680f08c3bdfSopenharmony_ci sym = sym->ctype.base_type; 1681f08c3bdfSopenharmony_ci } 1682f08c3bdfSopenharmony_ci if (degenerate && sym->type == SYM_ARRAY) { 1683f08c3bdfSopenharmony_ci combine_address_space(sym->pos, &ptr->ctype.as, sym->ctype.as); 1684f08c3bdfSopenharmony_ci ptr->ctype.modifiers |= sym->ctype.modifiers & MOD_PTRINHERIT; 1685f08c3bdfSopenharmony_ci sym = sym->ctype.base_type; 1686f08c3bdfSopenharmony_ci } 1687f08c3bdfSopenharmony_ci ptr->ctype.base_type = sym; 1688f08c3bdfSopenharmony_ci 1689f08c3bdfSopenharmony_ci return node; 1690f08c3bdfSopenharmony_ci} 1691f08c3bdfSopenharmony_ci 1692f08c3bdfSopenharmony_ci/* Arrays degenerate into pointers on pointer arithmetic */ 1693f08c3bdfSopenharmony_cistatic struct symbol *degenerate(struct expression *expr) 1694f08c3bdfSopenharmony_ci{ 1695f08c3bdfSopenharmony_ci struct symbol *ctype, *base; 1696f08c3bdfSopenharmony_ci 1697f08c3bdfSopenharmony_ci if (!expr) 1698f08c3bdfSopenharmony_ci return NULL; 1699f08c3bdfSopenharmony_ci ctype = expr->ctype; 1700f08c3bdfSopenharmony_ci if (!ctype) 1701f08c3bdfSopenharmony_ci return NULL; 1702f08c3bdfSopenharmony_ci base = examine_symbol_type(ctype); 1703f08c3bdfSopenharmony_ci if (ctype->type == SYM_NODE) 1704f08c3bdfSopenharmony_ci base = ctype->ctype.base_type; 1705f08c3bdfSopenharmony_ci /* 1706f08c3bdfSopenharmony_ci * Arrays degenerate into pointers to the entries, while 1707f08c3bdfSopenharmony_ci * functions degenerate into pointers to themselves. 1708f08c3bdfSopenharmony_ci * If array was part of non-lvalue compound, we create a copy 1709f08c3bdfSopenharmony_ci * of that compound first and then act as if we were dealing with 1710f08c3bdfSopenharmony_ci * the corresponding field in there. 1711f08c3bdfSopenharmony_ci */ 1712f08c3bdfSopenharmony_ci switch (base->type) { 1713f08c3bdfSopenharmony_ci case SYM_ARRAY: 1714f08c3bdfSopenharmony_ci if (expr->type == EXPR_SLICE) { 1715f08c3bdfSopenharmony_ci struct symbol *a = alloc_symbol(expr->pos, SYM_NODE); 1716f08c3bdfSopenharmony_ci struct expression *e0, *e1, *e2, *e3, *e4; 1717f08c3bdfSopenharmony_ci 1718f08c3bdfSopenharmony_ci a->ctype.base_type = expr->base->ctype; 1719f08c3bdfSopenharmony_ci a->bit_size = expr->base->ctype->bit_size; 1720f08c3bdfSopenharmony_ci a->array_size = expr->base->ctype->array_size; 1721f08c3bdfSopenharmony_ci 1722f08c3bdfSopenharmony_ci e0 = alloc_expression(expr->pos, EXPR_SYMBOL); 1723f08c3bdfSopenharmony_ci e0->symbol = a; 1724f08c3bdfSopenharmony_ci e0->ctype = &lazy_ptr_ctype; 1725f08c3bdfSopenharmony_ci 1726f08c3bdfSopenharmony_ci e1 = alloc_expression(expr->pos, EXPR_PREOP); 1727f08c3bdfSopenharmony_ci e1->unop = e0; 1728f08c3bdfSopenharmony_ci e1->op = '*'; 1729f08c3bdfSopenharmony_ci e1->ctype = expr->base->ctype; /* XXX */ 1730f08c3bdfSopenharmony_ci 1731f08c3bdfSopenharmony_ci e2 = alloc_expression(expr->pos, EXPR_ASSIGNMENT); 1732f08c3bdfSopenharmony_ci e2->left = e1; 1733f08c3bdfSopenharmony_ci e2->right = expr->base; 1734f08c3bdfSopenharmony_ci e2->op = '='; 1735f08c3bdfSopenharmony_ci e2->ctype = expr->base->ctype; 1736f08c3bdfSopenharmony_ci 1737f08c3bdfSopenharmony_ci if (expr->r_bitpos) { 1738f08c3bdfSopenharmony_ci e3 = alloc_expression(expr->pos, EXPR_BINOP); 1739f08c3bdfSopenharmony_ci e3->op = '+'; 1740f08c3bdfSopenharmony_ci e3->left = e0; 1741f08c3bdfSopenharmony_ci e3->right = alloc_const_expression(expr->pos, 1742f08c3bdfSopenharmony_ci bits_to_bytes(expr->r_bitpos)); 1743f08c3bdfSopenharmony_ci e3->ctype = &lazy_ptr_ctype; 1744f08c3bdfSopenharmony_ci } else { 1745f08c3bdfSopenharmony_ci e3 = e0; 1746f08c3bdfSopenharmony_ci } 1747f08c3bdfSopenharmony_ci 1748f08c3bdfSopenharmony_ci e4 = alloc_expression(expr->pos, EXPR_COMMA); 1749f08c3bdfSopenharmony_ci e4->left = e2; 1750f08c3bdfSopenharmony_ci e4->right = e3; 1751f08c3bdfSopenharmony_ci e4->ctype = &lazy_ptr_ctype; 1752f08c3bdfSopenharmony_ci 1753f08c3bdfSopenharmony_ci expr->unop = e4; 1754f08c3bdfSopenharmony_ci expr->type = EXPR_PREOP; 1755f08c3bdfSopenharmony_ci expr->op = '*'; 1756f08c3bdfSopenharmony_ci } 1757f08c3bdfSopenharmony_ci case SYM_FN: 1758f08c3bdfSopenharmony_ci if (expr->op != '*' || expr->type != EXPR_PREOP) { 1759f08c3bdfSopenharmony_ci expression_error(expr, "strange non-value function or array"); 1760f08c3bdfSopenharmony_ci return &bad_ctype; 1761f08c3bdfSopenharmony_ci } 1762f08c3bdfSopenharmony_ci if (ctype->builtin) 1763f08c3bdfSopenharmony_ci sparse_error(expr->pos, "taking the address of built-in function '%s'", show_ident(ctype->ident)); 1764f08c3bdfSopenharmony_ci *expr = *expr->unop; 1765f08c3bdfSopenharmony_ci ctype = create_pointer(expr, ctype, 1); 1766f08c3bdfSopenharmony_ci expr->ctype = ctype; 1767f08c3bdfSopenharmony_ci mark_addressable(expr); 1768f08c3bdfSopenharmony_ci default: 1769f08c3bdfSopenharmony_ci /* nothing */; 1770f08c3bdfSopenharmony_ci } 1771f08c3bdfSopenharmony_ci return ctype; 1772f08c3bdfSopenharmony_ci} 1773f08c3bdfSopenharmony_ci 1774f08c3bdfSopenharmony_cistatic struct symbol *evaluate_addressof(struct expression *expr) 1775f08c3bdfSopenharmony_ci{ 1776f08c3bdfSopenharmony_ci struct expression *op = expr->unop; 1777f08c3bdfSopenharmony_ci struct symbol *ctype; 1778f08c3bdfSopenharmony_ci 1779f08c3bdfSopenharmony_ci if (op->op != '*' || op->type != EXPR_PREOP) { 1780f08c3bdfSopenharmony_ci expression_error(expr, "not addressable"); 1781f08c3bdfSopenharmony_ci return NULL; 1782f08c3bdfSopenharmony_ci } 1783f08c3bdfSopenharmony_ci ctype = op->ctype; 1784f08c3bdfSopenharmony_ci if (ctype->builtin) 1785f08c3bdfSopenharmony_ci sparse_error(expr->pos, "taking the address of built-in function '%s'", show_ident(ctype->ident)); 1786f08c3bdfSopenharmony_ci *expr = *op->unop; 1787f08c3bdfSopenharmony_ci 1788f08c3bdfSopenharmony_ci mark_addressable(expr); 1789f08c3bdfSopenharmony_ci 1790f08c3bdfSopenharmony_ci /* 1791f08c3bdfSopenharmony_ci * symbol expression evaluation is lazy about the type 1792f08c3bdfSopenharmony_ci * of the sub-expression, so we may have to generate 1793f08c3bdfSopenharmony_ci * the type here if so.. 1794f08c3bdfSopenharmony_ci */ 1795f08c3bdfSopenharmony_ci if (expr->ctype == &lazy_ptr_ctype) { 1796f08c3bdfSopenharmony_ci ctype = create_pointer(expr, ctype, 0); 1797f08c3bdfSopenharmony_ci expr->ctype = ctype; 1798f08c3bdfSopenharmony_ci } 1799f08c3bdfSopenharmony_ci return expr->ctype; 1800f08c3bdfSopenharmony_ci} 1801f08c3bdfSopenharmony_ci 1802f08c3bdfSopenharmony_ci 1803f08c3bdfSopenharmony_cistatic struct symbol *evaluate_dereference(struct expression *expr) 1804f08c3bdfSopenharmony_ci{ 1805f08c3bdfSopenharmony_ci struct expression *op = expr->unop; 1806f08c3bdfSopenharmony_ci struct symbol *ctype = op->ctype, *node, *target; 1807f08c3bdfSopenharmony_ci 1808f08c3bdfSopenharmony_ci /* Simplify: *&(expr) => (expr) */ 1809f08c3bdfSopenharmony_ci if (op->type == EXPR_PREOP && op->op == '&') { 1810f08c3bdfSopenharmony_ci *expr = *op->unop; 1811f08c3bdfSopenharmony_ci expr->flags = CEF_NONE; 1812f08c3bdfSopenharmony_ci return expr->ctype; 1813f08c3bdfSopenharmony_ci } 1814f08c3bdfSopenharmony_ci 1815f08c3bdfSopenharmony_ci examine_symbol_type(ctype); 1816f08c3bdfSopenharmony_ci 1817f08c3bdfSopenharmony_ci /* Dereferencing a node drops all the node information. */ 1818f08c3bdfSopenharmony_ci if (ctype->type == SYM_NODE) 1819f08c3bdfSopenharmony_ci ctype = ctype->ctype.base_type; 1820f08c3bdfSopenharmony_ci 1821f08c3bdfSopenharmony_ci target = ctype->ctype.base_type; 1822f08c3bdfSopenharmony_ci 1823f08c3bdfSopenharmony_ci switch (ctype->type) { 1824f08c3bdfSopenharmony_ci default: 1825f08c3bdfSopenharmony_ci expression_error(expr, "cannot dereference this type"); 1826f08c3bdfSopenharmony_ci return NULL; 1827f08c3bdfSopenharmony_ci case SYM_FN: 1828f08c3bdfSopenharmony_ci *expr = *op; 1829f08c3bdfSopenharmony_ci return expr->ctype; 1830f08c3bdfSopenharmony_ci case SYM_PTR: 1831f08c3bdfSopenharmony_ci examine_symbol_type(target); 1832f08c3bdfSopenharmony_ci node = alloc_symbol(expr->pos, SYM_NODE); 1833f08c3bdfSopenharmony_ci node->ctype.modifiers = target->ctype.modifiers & MOD_SPECIFIER; 1834f08c3bdfSopenharmony_ci merge_type(node, ctype); 1835f08c3bdfSopenharmony_ci break; 1836f08c3bdfSopenharmony_ci 1837f08c3bdfSopenharmony_ci case SYM_ARRAY: 1838f08c3bdfSopenharmony_ci if (!lvalue_expression(op)) { 1839f08c3bdfSopenharmony_ci expression_error(op, "non-lvalue array??"); 1840f08c3bdfSopenharmony_ci return NULL; 1841f08c3bdfSopenharmony_ci } 1842f08c3bdfSopenharmony_ci 1843f08c3bdfSopenharmony_ci /* Do the implied "addressof" on the array */ 1844f08c3bdfSopenharmony_ci *op = *op->unop; 1845f08c3bdfSopenharmony_ci 1846f08c3bdfSopenharmony_ci /* 1847f08c3bdfSopenharmony_ci * When an array is dereferenced, we need to pick 1848f08c3bdfSopenharmony_ci * up the attributes of the original node too.. 1849f08c3bdfSopenharmony_ci */ 1850f08c3bdfSopenharmony_ci node = alloc_symbol(expr->pos, SYM_NODE); 1851f08c3bdfSopenharmony_ci merge_type(node, op->ctype); 1852f08c3bdfSopenharmony_ci merge_type(node, ctype); 1853f08c3bdfSopenharmony_ci break; 1854f08c3bdfSopenharmony_ci } 1855f08c3bdfSopenharmony_ci 1856f08c3bdfSopenharmony_ci node->bit_size = target->bit_size; 1857f08c3bdfSopenharmony_ci node->array_size = target->array_size; 1858f08c3bdfSopenharmony_ci 1859f08c3bdfSopenharmony_ci expr->ctype = node; 1860f08c3bdfSopenharmony_ci return node; 1861f08c3bdfSopenharmony_ci} 1862f08c3bdfSopenharmony_ci 1863f08c3bdfSopenharmony_ci/* 1864f08c3bdfSopenharmony_ci * Unary post-ops: x++ and x-- 1865f08c3bdfSopenharmony_ci */ 1866f08c3bdfSopenharmony_cistatic struct symbol *evaluate_postop(struct expression *expr) 1867f08c3bdfSopenharmony_ci{ 1868f08c3bdfSopenharmony_ci struct expression *op = expr->unop; 1869f08c3bdfSopenharmony_ci struct symbol *ctype = op->ctype; 1870f08c3bdfSopenharmony_ci int class = classify_type(ctype, &ctype); 1871f08c3bdfSopenharmony_ci int multiply = 0; 1872f08c3bdfSopenharmony_ci 1873f08c3bdfSopenharmony_ci if (!class || class & TYPE_COMPOUND) { 1874f08c3bdfSopenharmony_ci expression_error(expr, "need scalar for ++/--"); 1875f08c3bdfSopenharmony_ci return NULL; 1876f08c3bdfSopenharmony_ci } 1877f08c3bdfSopenharmony_ci if (!lvalue_expression(expr->unop)) { 1878f08c3bdfSopenharmony_ci expression_error(expr, "need lvalue expression for ++/--"); 1879f08c3bdfSopenharmony_ci return NULL; 1880f08c3bdfSopenharmony_ci } 1881f08c3bdfSopenharmony_ci 1882f08c3bdfSopenharmony_ci unrestrict(expr, class, &ctype); 1883f08c3bdfSopenharmony_ci 1884f08c3bdfSopenharmony_ci if (class & TYPE_NUM) { 1885f08c3bdfSopenharmony_ci multiply = 1; 1886f08c3bdfSopenharmony_ci } else if (class == TYPE_PTR) { 1887f08c3bdfSopenharmony_ci struct symbol *target = examine_pointer_target(ctype); 1888f08c3bdfSopenharmony_ci if (!is_function(target)) 1889f08c3bdfSopenharmony_ci multiply = bits_to_bytes(target->bit_size); 1890f08c3bdfSopenharmony_ci } 1891f08c3bdfSopenharmony_ci 1892f08c3bdfSopenharmony_ci if (multiply) { 1893f08c3bdfSopenharmony_ci evaluate_assign_to(op, op->ctype); 1894f08c3bdfSopenharmony_ci expr->op_value = multiply; 1895f08c3bdfSopenharmony_ci expr->ctype = ctype; 1896f08c3bdfSopenharmony_ci return ctype; 1897f08c3bdfSopenharmony_ci } 1898f08c3bdfSopenharmony_ci 1899f08c3bdfSopenharmony_ci expression_error(expr, "bad argument type for ++/--"); 1900f08c3bdfSopenharmony_ci return NULL; 1901f08c3bdfSopenharmony_ci} 1902f08c3bdfSopenharmony_ci 1903f08c3bdfSopenharmony_cistatic struct symbol *evaluate_sign(struct expression *expr) 1904f08c3bdfSopenharmony_ci{ 1905f08c3bdfSopenharmony_ci struct symbol *ctype = expr->unop->ctype; 1906f08c3bdfSopenharmony_ci int class = classify_type(ctype, &ctype); 1907f08c3bdfSopenharmony_ci unsigned char flags = expr->unop->flags & ~CEF_CONST_MASK; 1908f08c3bdfSopenharmony_ci 1909f08c3bdfSopenharmony_ci /* should be an arithmetic type */ 1910f08c3bdfSopenharmony_ci if (!(class & TYPE_NUM)) 1911f08c3bdfSopenharmony_ci return bad_expr_type(expr); 1912f08c3bdfSopenharmony_ci if (class & TYPE_RESTRICT) 1913f08c3bdfSopenharmony_ci goto Restr; 1914f08c3bdfSopenharmony_ciNormal: 1915f08c3bdfSopenharmony_ci if (!(class & TYPE_FLOAT)) { 1916f08c3bdfSopenharmony_ci ctype = integer_promotion(ctype); 1917f08c3bdfSopenharmony_ci expr->unop = cast_to(expr->unop, ctype); 1918f08c3bdfSopenharmony_ci } else if (expr->op != '~') { 1919f08c3bdfSopenharmony_ci /* no conversions needed */ 1920f08c3bdfSopenharmony_ci } else { 1921f08c3bdfSopenharmony_ci return bad_expr_type(expr); 1922f08c3bdfSopenharmony_ci } 1923f08c3bdfSopenharmony_ci if (expr->op == '+') 1924f08c3bdfSopenharmony_ci *expr = *expr->unop; 1925f08c3bdfSopenharmony_ci expr->flags = flags; 1926f08c3bdfSopenharmony_ci expr->ctype = ctype; 1927f08c3bdfSopenharmony_ci return ctype; 1928f08c3bdfSopenharmony_ciRestr: 1929f08c3bdfSopenharmony_ci if (restricted_unop(expr->op, &ctype)) 1930f08c3bdfSopenharmony_ci unrestrict(expr, class, &ctype); 1931f08c3bdfSopenharmony_ci goto Normal; 1932f08c3bdfSopenharmony_ci} 1933f08c3bdfSopenharmony_ci 1934f08c3bdfSopenharmony_cistatic struct symbol *evaluate_preop(struct expression *expr) 1935f08c3bdfSopenharmony_ci{ 1936f08c3bdfSopenharmony_ci struct symbol *ctype = expr->unop->ctype; 1937f08c3bdfSopenharmony_ci 1938f08c3bdfSopenharmony_ci switch (expr->op) { 1939f08c3bdfSopenharmony_ci case '(': 1940f08c3bdfSopenharmony_ci *expr = *expr->unop; 1941f08c3bdfSopenharmony_ci return ctype; 1942f08c3bdfSopenharmony_ci 1943f08c3bdfSopenharmony_ci case '+': 1944f08c3bdfSopenharmony_ci case '-': 1945f08c3bdfSopenharmony_ci case '~': 1946f08c3bdfSopenharmony_ci return evaluate_sign(expr); 1947f08c3bdfSopenharmony_ci 1948f08c3bdfSopenharmony_ci case '*': 1949f08c3bdfSopenharmony_ci return evaluate_dereference(expr); 1950f08c3bdfSopenharmony_ci 1951f08c3bdfSopenharmony_ci case '&': 1952f08c3bdfSopenharmony_ci return evaluate_addressof(expr); 1953f08c3bdfSopenharmony_ci 1954f08c3bdfSopenharmony_ci case SPECIAL_INCREMENT: 1955f08c3bdfSopenharmony_ci case SPECIAL_DECREMENT: 1956f08c3bdfSopenharmony_ci /* 1957f08c3bdfSopenharmony_ci * From a type evaluation standpoint the preops are 1958f08c3bdfSopenharmony_ci * the same as the postops 1959f08c3bdfSopenharmony_ci */ 1960f08c3bdfSopenharmony_ci return evaluate_postop(expr); 1961f08c3bdfSopenharmony_ci 1962f08c3bdfSopenharmony_ci case '!': 1963f08c3bdfSopenharmony_ci ctype = degenerate(expr->unop); 1964f08c3bdfSopenharmony_ci expr->flags = expr->unop->flags & ~CEF_CONST_MASK; 1965f08c3bdfSopenharmony_ci /* 1966f08c3bdfSopenharmony_ci * A logical negation never yields an address constant 1967f08c3bdfSopenharmony_ci * [6.6(9)]. 1968f08c3bdfSopenharmony_ci */ 1969f08c3bdfSopenharmony_ci expr->flags &= ~CEF_ADDR; 1970f08c3bdfSopenharmony_ci 1971f08c3bdfSopenharmony_ci if (is_safe_type(ctype)) 1972f08c3bdfSopenharmony_ci warning(expr->pos, "testing a 'safe expression'"); 1973f08c3bdfSopenharmony_ci if (is_float_type(ctype)) { 1974f08c3bdfSopenharmony_ci struct expression *arg = expr->unop; 1975f08c3bdfSopenharmony_ci expr->type = EXPR_COMPARE; 1976f08c3bdfSopenharmony_ci expr->op = SPECIAL_EQUAL; 1977f08c3bdfSopenharmony_ci expr->left = arg; 1978f08c3bdfSopenharmony_ci expr->right = alloc_expression(expr->pos, EXPR_FVALUE); 1979f08c3bdfSopenharmony_ci expr->right->ctype = ctype; 1980f08c3bdfSopenharmony_ci expr->right->fvalue = 0; 1981f08c3bdfSopenharmony_ci } else if (is_fouled_type(ctype)) { 1982f08c3bdfSopenharmony_ci warning(expr->pos, "%s degrades to integer", 1983f08c3bdfSopenharmony_ci show_typename(ctype->ctype.base_type)); 1984f08c3bdfSopenharmony_ci } 1985f08c3bdfSopenharmony_ci /* the result is int [6.5.3.3(5)]*/ 1986f08c3bdfSopenharmony_ci ctype = &int_ctype; 1987f08c3bdfSopenharmony_ci break; 1988f08c3bdfSopenharmony_ci 1989f08c3bdfSopenharmony_ci default: 1990f08c3bdfSopenharmony_ci break; 1991f08c3bdfSopenharmony_ci } 1992f08c3bdfSopenharmony_ci expr->ctype = ctype; 1993f08c3bdfSopenharmony_ci return ctype; 1994f08c3bdfSopenharmony_ci} 1995f08c3bdfSopenharmony_ci 1996f08c3bdfSopenharmony_cistatic struct symbol *find_identifier(struct ident *ident, struct symbol_list *_list, int *offset) 1997f08c3bdfSopenharmony_ci{ 1998f08c3bdfSopenharmony_ci struct ptr_list *head = (struct ptr_list *)_list; 1999f08c3bdfSopenharmony_ci struct ptr_list *list = head; 2000f08c3bdfSopenharmony_ci 2001f08c3bdfSopenharmony_ci if (!head) 2002f08c3bdfSopenharmony_ci return NULL; 2003f08c3bdfSopenharmony_ci do { 2004f08c3bdfSopenharmony_ci int i; 2005f08c3bdfSopenharmony_ci for (i = 0; i < list->nr; i++) { 2006f08c3bdfSopenharmony_ci struct symbol *sym = (struct symbol *) list->list[i]; 2007f08c3bdfSopenharmony_ci if (sym->ident) { 2008f08c3bdfSopenharmony_ci if (sym->ident != ident) 2009f08c3bdfSopenharmony_ci continue; 2010f08c3bdfSopenharmony_ci *offset = sym->offset; 2011f08c3bdfSopenharmony_ci return sym; 2012f08c3bdfSopenharmony_ci } else { 2013f08c3bdfSopenharmony_ci struct symbol *ctype = sym->ctype.base_type; 2014f08c3bdfSopenharmony_ci struct symbol *sub; 2015f08c3bdfSopenharmony_ci if (!ctype) 2016f08c3bdfSopenharmony_ci continue; 2017f08c3bdfSopenharmony_ci if (ctype->type != SYM_UNION && ctype->type != SYM_STRUCT) 2018f08c3bdfSopenharmony_ci continue; 2019f08c3bdfSopenharmony_ci sub = find_identifier(ident, ctype->symbol_list, offset); 2020f08c3bdfSopenharmony_ci if (!sub) 2021f08c3bdfSopenharmony_ci continue; 2022f08c3bdfSopenharmony_ci *offset += sym->offset; 2023f08c3bdfSopenharmony_ci return sub; 2024f08c3bdfSopenharmony_ci } 2025f08c3bdfSopenharmony_ci } 2026f08c3bdfSopenharmony_ci } while ((list = list->next) != head); 2027f08c3bdfSopenharmony_ci return NULL; 2028f08c3bdfSopenharmony_ci} 2029f08c3bdfSopenharmony_ci 2030f08c3bdfSopenharmony_cistatic struct expression *evaluate_offset(struct expression *expr, unsigned long offset) 2031f08c3bdfSopenharmony_ci{ 2032f08c3bdfSopenharmony_ci struct expression *add; 2033f08c3bdfSopenharmony_ci 2034f08c3bdfSopenharmony_ci /* 2035f08c3bdfSopenharmony_ci * Create a new add-expression 2036f08c3bdfSopenharmony_ci * 2037f08c3bdfSopenharmony_ci * NOTE! Even if we just add zero, we need a new node 2038f08c3bdfSopenharmony_ci * for the member pointer, since it has a different 2039f08c3bdfSopenharmony_ci * type than the original pointer. We could make that 2040f08c3bdfSopenharmony_ci * be just a cast, but the fact is, a node is a node, 2041f08c3bdfSopenharmony_ci * so we might as well just do the "add zero" here. 2042f08c3bdfSopenharmony_ci */ 2043f08c3bdfSopenharmony_ci add = alloc_expression(expr->pos, EXPR_BINOP); 2044f08c3bdfSopenharmony_ci add->op = '+'; 2045f08c3bdfSopenharmony_ci add->left = expr; 2046f08c3bdfSopenharmony_ci add->right = alloc_expression(expr->pos, EXPR_VALUE); 2047f08c3bdfSopenharmony_ci add->right->ctype = &int_ctype; 2048f08c3bdfSopenharmony_ci add->right->value = offset; 2049f08c3bdfSopenharmony_ci 2050f08c3bdfSopenharmony_ci /* 2051f08c3bdfSopenharmony_ci * The ctype of the pointer will be lazily evaluated if 2052f08c3bdfSopenharmony_ci * we ever take the address of this member dereference.. 2053f08c3bdfSopenharmony_ci */ 2054f08c3bdfSopenharmony_ci add->ctype = &lazy_ptr_ctype; 2055f08c3bdfSopenharmony_ci /* 2056f08c3bdfSopenharmony_ci * The resulting address of a member access through an address 2057f08c3bdfSopenharmony_ci * constant is an address constant again [6.6(9)]. 2058f08c3bdfSopenharmony_ci */ 2059f08c3bdfSopenharmony_ci add->flags = expr->flags; 2060f08c3bdfSopenharmony_ci 2061f08c3bdfSopenharmony_ci return add; 2062f08c3bdfSopenharmony_ci} 2063f08c3bdfSopenharmony_ci 2064f08c3bdfSopenharmony_ci/* structure/union dereference */ 2065f08c3bdfSopenharmony_cistatic struct symbol *evaluate_member_dereference(struct expression *expr) 2066f08c3bdfSopenharmony_ci{ 2067f08c3bdfSopenharmony_ci int offset; 2068f08c3bdfSopenharmony_ci struct symbol *ctype, *member; 2069f08c3bdfSopenharmony_ci struct expression *deref = expr->deref, *add; 2070f08c3bdfSopenharmony_ci struct ident *ident = expr->member; 2071f08c3bdfSopenharmony_ci struct ident *address_space; 2072f08c3bdfSopenharmony_ci unsigned int mod; 2073f08c3bdfSopenharmony_ci 2074f08c3bdfSopenharmony_ci if (!evaluate_expression(deref)) 2075f08c3bdfSopenharmony_ci return NULL; 2076f08c3bdfSopenharmony_ci if (!ident) { 2077f08c3bdfSopenharmony_ci expression_error(expr, "bad member name"); 2078f08c3bdfSopenharmony_ci return NULL; 2079f08c3bdfSopenharmony_ci } 2080f08c3bdfSopenharmony_ci 2081f08c3bdfSopenharmony_ci ctype = deref->ctype; 2082f08c3bdfSopenharmony_ci examine_symbol_type(ctype); 2083f08c3bdfSopenharmony_ci address_space = ctype->ctype.as; 2084f08c3bdfSopenharmony_ci mod = ctype->ctype.modifiers; 2085f08c3bdfSopenharmony_ci if (ctype->type == SYM_NODE) { 2086f08c3bdfSopenharmony_ci ctype = ctype->ctype.base_type; 2087f08c3bdfSopenharmony_ci combine_address_space(deref->pos, &address_space, ctype->ctype.as); 2088f08c3bdfSopenharmony_ci mod |= ctype->ctype.modifiers; 2089f08c3bdfSopenharmony_ci } 2090f08c3bdfSopenharmony_ci if (!ctype || (ctype->type != SYM_STRUCT && ctype->type != SYM_UNION)) { 2091f08c3bdfSopenharmony_ci expression_error(expr, "expected structure or union"); 2092f08c3bdfSopenharmony_ci return NULL; 2093f08c3bdfSopenharmony_ci } 2094f08c3bdfSopenharmony_ci offset = 0; 2095f08c3bdfSopenharmony_ci member = find_identifier(ident, ctype->symbol_list, &offset); 2096f08c3bdfSopenharmony_ci if (!member) { 2097f08c3bdfSopenharmony_ci const char *type = ctype->type == SYM_STRUCT ? "struct" : "union"; 2098f08c3bdfSopenharmony_ci const char *name = "<unnamed>"; 2099f08c3bdfSopenharmony_ci int namelen = 9; 2100f08c3bdfSopenharmony_ci if (ctype->ident) { 2101f08c3bdfSopenharmony_ci name = ctype->ident->name; 2102f08c3bdfSopenharmony_ci namelen = ctype->ident->len; 2103f08c3bdfSopenharmony_ci } 2104f08c3bdfSopenharmony_ci if (ctype->symbol_list) 2105f08c3bdfSopenharmony_ci expression_error(expr, "no member '%s' in %s %.*s", 2106f08c3bdfSopenharmony_ci show_ident(ident), type, namelen, name); 2107f08c3bdfSopenharmony_ci else 2108f08c3bdfSopenharmony_ci expression_error(expr, "using member '%s' in " 2109f08c3bdfSopenharmony_ci "incomplete %s %.*s", show_ident(ident), 2110f08c3bdfSopenharmony_ci type, namelen, name); 2111f08c3bdfSopenharmony_ci return NULL; 2112f08c3bdfSopenharmony_ci } 2113f08c3bdfSopenharmony_ci 2114f08c3bdfSopenharmony_ci /* 2115f08c3bdfSopenharmony_ci * The member needs to take on the address space and modifiers of 2116f08c3bdfSopenharmony_ci * the "parent" type. 2117f08c3bdfSopenharmony_ci */ 2118f08c3bdfSopenharmony_ci member = convert_to_as_mod(member, address_space, mod); 2119f08c3bdfSopenharmony_ci ctype = get_base_type(member); 2120f08c3bdfSopenharmony_ci 2121f08c3bdfSopenharmony_ci if (!lvalue_expression(deref)) { 2122f08c3bdfSopenharmony_ci if (deref->type != EXPR_SLICE) { 2123f08c3bdfSopenharmony_ci expr->base = deref; 2124f08c3bdfSopenharmony_ci expr->r_bitpos = 0; 2125f08c3bdfSopenharmony_ci } else { 2126f08c3bdfSopenharmony_ci expr->base = deref->base; 2127f08c3bdfSopenharmony_ci expr->r_bitpos = deref->r_bitpos; 2128f08c3bdfSopenharmony_ci } 2129f08c3bdfSopenharmony_ci expr->r_bitpos += bytes_to_bits(offset); 2130f08c3bdfSopenharmony_ci expr->type = EXPR_SLICE; 2131f08c3bdfSopenharmony_ci expr->r_bitpos += member->bit_offset; 2132f08c3bdfSopenharmony_ci expr->ctype = member; 2133f08c3bdfSopenharmony_ci return member; 2134f08c3bdfSopenharmony_ci } 2135f08c3bdfSopenharmony_ci 2136f08c3bdfSopenharmony_ci deref = deref->unop; 2137f08c3bdfSopenharmony_ci expr->deref = deref; 2138f08c3bdfSopenharmony_ci 2139f08c3bdfSopenharmony_ci add = evaluate_offset(deref, offset); 2140f08c3bdfSopenharmony_ci expr->type = EXPR_PREOP; 2141f08c3bdfSopenharmony_ci expr->op = '*'; 2142f08c3bdfSopenharmony_ci expr->unop = add; 2143f08c3bdfSopenharmony_ci 2144f08c3bdfSopenharmony_ci expr->ctype = member; 2145f08c3bdfSopenharmony_ci return member; 2146f08c3bdfSopenharmony_ci} 2147f08c3bdfSopenharmony_ci 2148f08c3bdfSopenharmony_cistatic int is_promoted(struct expression *expr) 2149f08c3bdfSopenharmony_ci{ 2150f08c3bdfSopenharmony_ci while (1) { 2151f08c3bdfSopenharmony_ci switch (expr->type) { 2152f08c3bdfSopenharmony_ci case EXPR_BINOP: 2153f08c3bdfSopenharmony_ci case EXPR_SELECT: 2154f08c3bdfSopenharmony_ci case EXPR_CONDITIONAL: 2155f08c3bdfSopenharmony_ci return 1; 2156f08c3bdfSopenharmony_ci case EXPR_COMMA: 2157f08c3bdfSopenharmony_ci expr = expr->right; 2158f08c3bdfSopenharmony_ci continue; 2159f08c3bdfSopenharmony_ci case EXPR_PREOP: 2160f08c3bdfSopenharmony_ci switch (expr->op) { 2161f08c3bdfSopenharmony_ci case '(': 2162f08c3bdfSopenharmony_ci expr = expr->unop; 2163f08c3bdfSopenharmony_ci continue; 2164f08c3bdfSopenharmony_ci case '+': 2165f08c3bdfSopenharmony_ci case '-': 2166f08c3bdfSopenharmony_ci case '~': 2167f08c3bdfSopenharmony_ci return 1; 2168f08c3bdfSopenharmony_ci default: 2169f08c3bdfSopenharmony_ci return 0; 2170f08c3bdfSopenharmony_ci } 2171f08c3bdfSopenharmony_ci default: 2172f08c3bdfSopenharmony_ci return 0; 2173f08c3bdfSopenharmony_ci } 2174f08c3bdfSopenharmony_ci } 2175f08c3bdfSopenharmony_ci} 2176f08c3bdfSopenharmony_ci 2177f08c3bdfSopenharmony_ci 2178f08c3bdfSopenharmony_cistatic struct symbol *evaluate_type_information(struct expression *expr) 2179f08c3bdfSopenharmony_ci{ 2180f08c3bdfSopenharmony_ci struct symbol *sym = expr->cast_type; 2181f08c3bdfSopenharmony_ci if (!sym) { 2182f08c3bdfSopenharmony_ci sym = evaluate_expression(expr->cast_expression); 2183f08c3bdfSopenharmony_ci if (!sym) 2184f08c3bdfSopenharmony_ci return NULL; 2185f08c3bdfSopenharmony_ci /* 2186f08c3bdfSopenharmony_ci * Expressions of restricted types will possibly get 2187f08c3bdfSopenharmony_ci * promoted - check that here 2188f08c3bdfSopenharmony_ci */ 2189f08c3bdfSopenharmony_ci if (is_restricted_type(sym)) { 2190f08c3bdfSopenharmony_ci if (sym->bit_size < bits_in_int && is_promoted(expr)) 2191f08c3bdfSopenharmony_ci sym = &int_ctype; 2192f08c3bdfSopenharmony_ci } else if (is_fouled_type(sym)) { 2193f08c3bdfSopenharmony_ci sym = &int_ctype; 2194f08c3bdfSopenharmony_ci } 2195f08c3bdfSopenharmony_ci } 2196f08c3bdfSopenharmony_ci examine_symbol_type(sym); 2197f08c3bdfSopenharmony_ci if (is_bitfield_type(sym)) { 2198f08c3bdfSopenharmony_ci expression_error(expr, "trying to examine bitfield type"); 2199f08c3bdfSopenharmony_ci return NULL; 2200f08c3bdfSopenharmony_ci } 2201f08c3bdfSopenharmony_ci return sym; 2202f08c3bdfSopenharmony_ci} 2203f08c3bdfSopenharmony_ci 2204f08c3bdfSopenharmony_cistatic struct symbol *evaluate_sizeof(struct expression *expr) 2205f08c3bdfSopenharmony_ci{ 2206f08c3bdfSopenharmony_ci struct symbol *type; 2207f08c3bdfSopenharmony_ci int size; 2208f08c3bdfSopenharmony_ci 2209f08c3bdfSopenharmony_ci type = evaluate_type_information(expr); 2210f08c3bdfSopenharmony_ci if (!type) 2211f08c3bdfSopenharmony_ci return NULL; 2212f08c3bdfSopenharmony_ci 2213f08c3bdfSopenharmony_ci size = type->bit_size; 2214f08c3bdfSopenharmony_ci 2215f08c3bdfSopenharmony_ci if (size < 0 && is_void_type(type)) { 2216f08c3bdfSopenharmony_ci if (Wpointer_arith) 2217f08c3bdfSopenharmony_ci warning(expr->pos, "expression using sizeof(void)"); 2218f08c3bdfSopenharmony_ci size = bits_in_char; 2219f08c3bdfSopenharmony_ci } 2220f08c3bdfSopenharmony_ci 2221f08c3bdfSopenharmony_ci if (is_bool_type(type)) { 2222f08c3bdfSopenharmony_ci if (Wsizeof_bool) 2223f08c3bdfSopenharmony_ci warning(expr->pos, "expression using sizeof _Bool"); 2224f08c3bdfSopenharmony_ci size = bits_to_bytes(bits_in_bool) * bits_in_char; 2225f08c3bdfSopenharmony_ci } 2226f08c3bdfSopenharmony_ci 2227f08c3bdfSopenharmony_ci if (is_function(type->ctype.base_type)) { 2228f08c3bdfSopenharmony_ci if (Wpointer_arith) 2229f08c3bdfSopenharmony_ci warning(expr->pos, "expression using sizeof on a function"); 2230f08c3bdfSopenharmony_ci size = bits_in_char; 2231f08c3bdfSopenharmony_ci } 2232f08c3bdfSopenharmony_ci 2233f08c3bdfSopenharmony_ci if (has_flexible_array(type) && Wflexible_array_sizeof) 2234f08c3bdfSopenharmony_ci warning(expr->pos, "using sizeof on a flexible structure"); 2235f08c3bdfSopenharmony_ci 2236f08c3bdfSopenharmony_ci if (is_array_type(type) && size < 0) { // VLA, 1-dimension only 2237f08c3bdfSopenharmony_ci struct expression *base, *size; 2238f08c3bdfSopenharmony_ci struct symbol *base_type; 2239f08c3bdfSopenharmony_ci 2240f08c3bdfSopenharmony_ci if (type->type == SYM_NODE) 2241f08c3bdfSopenharmony_ci type = type->ctype.base_type; // strip the SYM_NODE 2242f08c3bdfSopenharmony_ci base_type = get_base_type(type); 2243f08c3bdfSopenharmony_ci if (!base_type) 2244f08c3bdfSopenharmony_ci goto error; 2245f08c3bdfSopenharmony_ci if (base_type->bit_size <= 0) { 2246f08c3bdfSopenharmony_ci base = alloc_expression(expr->pos, EXPR_SIZEOF); 2247f08c3bdfSopenharmony_ci base->cast_type = base_type; 2248f08c3bdfSopenharmony_ci if (!evaluate_sizeof(base)) 2249f08c3bdfSopenharmony_ci goto error; 2250f08c3bdfSopenharmony_ci } else { 2251f08c3bdfSopenharmony_ci base = alloc_expression(expr->pos, EXPR_VALUE); 2252f08c3bdfSopenharmony_ci base->value = bits_to_bytes(base_type->bit_size); 2253f08c3bdfSopenharmony_ci base->ctype = size_t_ctype; 2254f08c3bdfSopenharmony_ci } 2255f08c3bdfSopenharmony_ci size = alloc_expression(expr->pos, EXPR_CAST); 2256f08c3bdfSopenharmony_ci size->cast_type = size_t_ctype; 2257f08c3bdfSopenharmony_ci size->cast_expression = type->array_size; 2258f08c3bdfSopenharmony_ci if (!evaluate_expression(size)) 2259f08c3bdfSopenharmony_ci goto error; 2260f08c3bdfSopenharmony_ci expr->left = size; 2261f08c3bdfSopenharmony_ci expr->right = base; 2262f08c3bdfSopenharmony_ci expr->type = EXPR_BINOP; 2263f08c3bdfSopenharmony_ci expr->op = '*'; 2264f08c3bdfSopenharmony_ci return expr->ctype = size_t_ctype; 2265f08c3bdfSopenharmony_ci } 2266f08c3bdfSopenharmony_ci 2267f08c3bdfSopenharmony_cierror: 2268f08c3bdfSopenharmony_ci if ((size < 0) || (size & (bits_in_char - 1))) 2269f08c3bdfSopenharmony_ci expression_error(expr, "cannot size expression"); 2270f08c3bdfSopenharmony_ci 2271f08c3bdfSopenharmony_ci expr->type = EXPR_VALUE; 2272f08c3bdfSopenharmony_ci expr->value = bits_to_bytes(size); 2273f08c3bdfSopenharmony_ci expr->taint = 0; 2274f08c3bdfSopenharmony_ci expr->ctype = size_t_ctype; 2275f08c3bdfSopenharmony_ci return size_t_ctype; 2276f08c3bdfSopenharmony_ci} 2277f08c3bdfSopenharmony_ci 2278f08c3bdfSopenharmony_cistatic struct symbol *evaluate_ptrsizeof(struct expression *expr) 2279f08c3bdfSopenharmony_ci{ 2280f08c3bdfSopenharmony_ci struct symbol *type; 2281f08c3bdfSopenharmony_ci int size; 2282f08c3bdfSopenharmony_ci 2283f08c3bdfSopenharmony_ci type = evaluate_type_information(expr); 2284f08c3bdfSopenharmony_ci if (!type) 2285f08c3bdfSopenharmony_ci return NULL; 2286f08c3bdfSopenharmony_ci 2287f08c3bdfSopenharmony_ci if (type->type == SYM_NODE) 2288f08c3bdfSopenharmony_ci type = type->ctype.base_type; 2289f08c3bdfSopenharmony_ci if (!type) 2290f08c3bdfSopenharmony_ci return NULL; 2291f08c3bdfSopenharmony_ci switch (type->type) { 2292f08c3bdfSopenharmony_ci case SYM_ARRAY: 2293f08c3bdfSopenharmony_ci break; 2294f08c3bdfSopenharmony_ci case SYM_PTR: 2295f08c3bdfSopenharmony_ci type = get_base_type(type); 2296f08c3bdfSopenharmony_ci if (type) 2297f08c3bdfSopenharmony_ci break; 2298f08c3bdfSopenharmony_ci default: 2299f08c3bdfSopenharmony_ci expression_error(expr, "expected pointer expression"); 2300f08c3bdfSopenharmony_ci return NULL; 2301f08c3bdfSopenharmony_ci } 2302f08c3bdfSopenharmony_ci size = type->bit_size; 2303f08c3bdfSopenharmony_ci if (size & (bits_in_char-1)) 2304f08c3bdfSopenharmony_ci size = 0; 2305f08c3bdfSopenharmony_ci expr->type = EXPR_VALUE; 2306f08c3bdfSopenharmony_ci expr->value = bits_to_bytes(size); 2307f08c3bdfSopenharmony_ci expr->taint = 0; 2308f08c3bdfSopenharmony_ci expr->ctype = size_t_ctype; 2309f08c3bdfSopenharmony_ci return size_t_ctype; 2310f08c3bdfSopenharmony_ci} 2311f08c3bdfSopenharmony_ci 2312f08c3bdfSopenharmony_cistatic struct symbol *evaluate_alignof(struct expression *expr) 2313f08c3bdfSopenharmony_ci{ 2314f08c3bdfSopenharmony_ci struct symbol *type; 2315f08c3bdfSopenharmony_ci 2316f08c3bdfSopenharmony_ci type = evaluate_type_information(expr); 2317f08c3bdfSopenharmony_ci if (!type) 2318f08c3bdfSopenharmony_ci return NULL; 2319f08c3bdfSopenharmony_ci 2320f08c3bdfSopenharmony_ci expr->type = EXPR_VALUE; 2321f08c3bdfSopenharmony_ci expr->value = type->ctype.alignment; 2322f08c3bdfSopenharmony_ci expr->taint = 0; 2323f08c3bdfSopenharmony_ci expr->ctype = size_t_ctype; 2324f08c3bdfSopenharmony_ci return size_t_ctype; 2325f08c3bdfSopenharmony_ci} 2326f08c3bdfSopenharmony_ci 2327f08c3bdfSopenharmony_ciint evaluate_arguments(struct symbol_list *argtypes, struct expression_list *head) 2328f08c3bdfSopenharmony_ci{ 2329f08c3bdfSopenharmony_ci struct expression *expr; 2330f08c3bdfSopenharmony_ci struct symbol *argtype; 2331f08c3bdfSopenharmony_ci int i = 1; 2332f08c3bdfSopenharmony_ci 2333f08c3bdfSopenharmony_ci PREPARE_PTR_LIST(argtypes, argtype); 2334f08c3bdfSopenharmony_ci FOR_EACH_PTR (head, expr) { 2335f08c3bdfSopenharmony_ci struct expression **p = THIS_ADDRESS(expr); 2336f08c3bdfSopenharmony_ci struct symbol *ctype, *target; 2337f08c3bdfSopenharmony_ci ctype = evaluate_expression(expr); 2338f08c3bdfSopenharmony_ci 2339f08c3bdfSopenharmony_ci if (!ctype) 2340f08c3bdfSopenharmony_ci return 0; 2341f08c3bdfSopenharmony_ci 2342f08c3bdfSopenharmony_ci target = argtype; 2343f08c3bdfSopenharmony_ci if (!target) { 2344f08c3bdfSopenharmony_ci struct symbol *type; 2345f08c3bdfSopenharmony_ci int class = classify_type(ctype, &type); 2346f08c3bdfSopenharmony_ci if (is_int(class)) { 2347f08c3bdfSopenharmony_ci *p = cast_to(expr, integer_promotion(type)); 2348f08c3bdfSopenharmony_ci } else if (class & TYPE_FLOAT) { 2349f08c3bdfSopenharmony_ci if (type->rank < 0) 2350f08c3bdfSopenharmony_ci *p = cast_to(expr, &double_ctype); 2351f08c3bdfSopenharmony_ci } else if (class & TYPE_PTR) { 2352f08c3bdfSopenharmony_ci if (expr->ctype == &null_ctype) 2353f08c3bdfSopenharmony_ci *p = cast_to(expr, &ptr_ctype); 2354f08c3bdfSopenharmony_ci else 2355f08c3bdfSopenharmony_ci degenerate(expr); 2356f08c3bdfSopenharmony_ci } 2357f08c3bdfSopenharmony_ci } else if (!target->forced_arg){ 2358f08c3bdfSopenharmony_ci static char where[30]; 2359f08c3bdfSopenharmony_ci examine_symbol_type(target); 2360f08c3bdfSopenharmony_ci sprintf(where, "argument %d", i); 2361f08c3bdfSopenharmony_ci compatible_argument_type(expr, target, p, where); 2362f08c3bdfSopenharmony_ci } 2363f08c3bdfSopenharmony_ci 2364f08c3bdfSopenharmony_ci i++; 2365f08c3bdfSopenharmony_ci NEXT_PTR_LIST(argtype); 2366f08c3bdfSopenharmony_ci } END_FOR_EACH_PTR(expr); 2367f08c3bdfSopenharmony_ci FINISH_PTR_LIST(argtype); 2368f08c3bdfSopenharmony_ci return 1; 2369f08c3bdfSopenharmony_ci} 2370f08c3bdfSopenharmony_ci 2371f08c3bdfSopenharmony_cistatic void convert_index(struct expression *e) 2372f08c3bdfSopenharmony_ci{ 2373f08c3bdfSopenharmony_ci struct expression *child = e->idx_expression; 2374f08c3bdfSopenharmony_ci unsigned from = e->idx_from; 2375f08c3bdfSopenharmony_ci unsigned to = e->idx_to + 1; 2376f08c3bdfSopenharmony_ci e->type = EXPR_POS; 2377f08c3bdfSopenharmony_ci e->init_offset = from * bits_to_bytes(e->ctype->bit_size); 2378f08c3bdfSopenharmony_ci e->init_nr = to - from; 2379f08c3bdfSopenharmony_ci e->init_expr = child; 2380f08c3bdfSopenharmony_ci} 2381f08c3bdfSopenharmony_ci 2382f08c3bdfSopenharmony_cistatic void convert_ident(struct expression *e) 2383f08c3bdfSopenharmony_ci{ 2384f08c3bdfSopenharmony_ci struct expression *child = e->ident_expression; 2385f08c3bdfSopenharmony_ci int offset = e->offset; 2386f08c3bdfSopenharmony_ci 2387f08c3bdfSopenharmony_ci e->type = EXPR_POS; 2388f08c3bdfSopenharmony_ci e->init_offset = offset; 2389f08c3bdfSopenharmony_ci e->init_nr = 1; 2390f08c3bdfSopenharmony_ci e->init_expr = child; 2391f08c3bdfSopenharmony_ci} 2392f08c3bdfSopenharmony_ci 2393f08c3bdfSopenharmony_cistatic void convert_designators(struct expression *e) 2394f08c3bdfSopenharmony_ci{ 2395f08c3bdfSopenharmony_ci while (e) { 2396f08c3bdfSopenharmony_ci if (e->type == EXPR_INDEX) 2397f08c3bdfSopenharmony_ci convert_index(e); 2398f08c3bdfSopenharmony_ci else if (e->type == EXPR_IDENTIFIER) 2399f08c3bdfSopenharmony_ci convert_ident(e); 2400f08c3bdfSopenharmony_ci else 2401f08c3bdfSopenharmony_ci break; 2402f08c3bdfSopenharmony_ci e = e->init_expr; 2403f08c3bdfSopenharmony_ci } 2404f08c3bdfSopenharmony_ci} 2405f08c3bdfSopenharmony_ci 2406f08c3bdfSopenharmony_cistatic void excess(struct expression *e, const char *s) 2407f08c3bdfSopenharmony_ci{ 2408f08c3bdfSopenharmony_ci warning(e->pos, "excessive elements in %s initializer", s); 2409f08c3bdfSopenharmony_ci} 2410f08c3bdfSopenharmony_ci 2411f08c3bdfSopenharmony_ci/* 2412f08c3bdfSopenharmony_ci * implicit designator for the first element 2413f08c3bdfSopenharmony_ci */ 2414f08c3bdfSopenharmony_cistatic struct expression *first_subobject(struct symbol *ctype, int class, 2415f08c3bdfSopenharmony_ci struct expression **v) 2416f08c3bdfSopenharmony_ci{ 2417f08c3bdfSopenharmony_ci struct expression *e = *v, *new; 2418f08c3bdfSopenharmony_ci 2419f08c3bdfSopenharmony_ci if (ctype->type == SYM_NODE) 2420f08c3bdfSopenharmony_ci ctype = ctype->ctype.base_type; 2421f08c3bdfSopenharmony_ci 2422f08c3bdfSopenharmony_ci if (class & TYPE_PTR) { /* array */ 2423f08c3bdfSopenharmony_ci if (!ctype->bit_size) 2424f08c3bdfSopenharmony_ci return NULL; 2425f08c3bdfSopenharmony_ci new = alloc_expression(e->pos, EXPR_INDEX); 2426f08c3bdfSopenharmony_ci new->idx_expression = e; 2427f08c3bdfSopenharmony_ci new->ctype = ctype->ctype.base_type; 2428f08c3bdfSopenharmony_ci } else { 2429f08c3bdfSopenharmony_ci struct symbol *field, *p; 2430f08c3bdfSopenharmony_ci PREPARE_PTR_LIST(ctype->symbol_list, p); 2431f08c3bdfSopenharmony_ci while (p && !p->ident && is_bitfield_type(p)) 2432f08c3bdfSopenharmony_ci NEXT_PTR_LIST(p); 2433f08c3bdfSopenharmony_ci field = p; 2434f08c3bdfSopenharmony_ci FINISH_PTR_LIST(p); 2435f08c3bdfSopenharmony_ci if (!field) 2436f08c3bdfSopenharmony_ci return NULL; 2437f08c3bdfSopenharmony_ci new = alloc_expression(e->pos, EXPR_IDENTIFIER); 2438f08c3bdfSopenharmony_ci new->ident_expression = e; 2439f08c3bdfSopenharmony_ci new->field = new->ctype = field; 2440f08c3bdfSopenharmony_ci new->offset = field->offset; 2441f08c3bdfSopenharmony_ci } 2442f08c3bdfSopenharmony_ci *v = new; 2443f08c3bdfSopenharmony_ci return new; 2444f08c3bdfSopenharmony_ci} 2445f08c3bdfSopenharmony_ci 2446f08c3bdfSopenharmony_ci/* 2447f08c3bdfSopenharmony_ci * sanity-check explicit designators; return the innermost one or NULL 2448f08c3bdfSopenharmony_ci * in case of error. Assign types. 2449f08c3bdfSopenharmony_ci */ 2450f08c3bdfSopenharmony_cistatic struct expression *check_designators(struct expression *e, 2451f08c3bdfSopenharmony_ci struct symbol *ctype) 2452f08c3bdfSopenharmony_ci{ 2453f08c3bdfSopenharmony_ci struct expression *last = NULL; 2454f08c3bdfSopenharmony_ci const char *err; 2455f08c3bdfSopenharmony_ci while (1) { 2456f08c3bdfSopenharmony_ci if (ctype->type == SYM_NODE) 2457f08c3bdfSopenharmony_ci ctype = ctype->ctype.base_type; 2458f08c3bdfSopenharmony_ci if (e->type == EXPR_INDEX) { 2459f08c3bdfSopenharmony_ci struct symbol *type; 2460f08c3bdfSopenharmony_ci if (ctype->type != SYM_ARRAY) { 2461f08c3bdfSopenharmony_ci err = "array index in non-array"; 2462f08c3bdfSopenharmony_ci break; 2463f08c3bdfSopenharmony_ci } 2464f08c3bdfSopenharmony_ci type = ctype->ctype.base_type; 2465f08c3bdfSopenharmony_ci if (ctype->bit_size >= 0 && type->bit_size >= 0) { 2466f08c3bdfSopenharmony_ci unsigned offset = array_element_offset(type->bit_size, e->idx_to); 2467f08c3bdfSopenharmony_ci if (offset >= ctype->bit_size) { 2468f08c3bdfSopenharmony_ci err = "index out of bounds in"; 2469f08c3bdfSopenharmony_ci break; 2470f08c3bdfSopenharmony_ci } 2471f08c3bdfSopenharmony_ci } 2472f08c3bdfSopenharmony_ci e->ctype = ctype = type; 2473f08c3bdfSopenharmony_ci ctype = type; 2474f08c3bdfSopenharmony_ci last = e; 2475f08c3bdfSopenharmony_ci if (!e->idx_expression) { 2476f08c3bdfSopenharmony_ci err = "invalid"; 2477f08c3bdfSopenharmony_ci break; 2478f08c3bdfSopenharmony_ci } 2479f08c3bdfSopenharmony_ci e = e->idx_expression; 2480f08c3bdfSopenharmony_ci } else if (e->type == EXPR_IDENTIFIER) { 2481f08c3bdfSopenharmony_ci int offset = 0; 2482f08c3bdfSopenharmony_ci if (ctype->type != SYM_STRUCT && ctype->type != SYM_UNION) { 2483f08c3bdfSopenharmony_ci err = "field name not in struct or union"; 2484f08c3bdfSopenharmony_ci break; 2485f08c3bdfSopenharmony_ci } 2486f08c3bdfSopenharmony_ci ctype = find_identifier(e->expr_ident, ctype->symbol_list, &offset); 2487f08c3bdfSopenharmony_ci if (!ctype) { 2488f08c3bdfSopenharmony_ci err = "unknown field name in"; 2489f08c3bdfSopenharmony_ci break; 2490f08c3bdfSopenharmony_ci } 2491f08c3bdfSopenharmony_ci e->offset = offset; 2492f08c3bdfSopenharmony_ci e->field = e->ctype = ctype; 2493f08c3bdfSopenharmony_ci last = e; 2494f08c3bdfSopenharmony_ci if (!e->ident_expression) { 2495f08c3bdfSopenharmony_ci err = "invalid"; 2496f08c3bdfSopenharmony_ci break; 2497f08c3bdfSopenharmony_ci } 2498f08c3bdfSopenharmony_ci e = e->ident_expression; 2499f08c3bdfSopenharmony_ci } else if (e->type == EXPR_POS) { 2500f08c3bdfSopenharmony_ci err = "internal front-end error: EXPR_POS in"; 2501f08c3bdfSopenharmony_ci break; 2502f08c3bdfSopenharmony_ci } else 2503f08c3bdfSopenharmony_ci return last; 2504f08c3bdfSopenharmony_ci } 2505f08c3bdfSopenharmony_ci expression_error(e, "%s initializer", err); 2506f08c3bdfSopenharmony_ci return NULL; 2507f08c3bdfSopenharmony_ci} 2508f08c3bdfSopenharmony_ci 2509f08c3bdfSopenharmony_ci/* 2510f08c3bdfSopenharmony_ci * choose the next subobject to initialize. 2511f08c3bdfSopenharmony_ci * 2512f08c3bdfSopenharmony_ci * Get designators for next element, switch old ones to EXPR_POS. 2513f08c3bdfSopenharmony_ci * Return the resulting expression or NULL if we'd run out of subobjects. 2514f08c3bdfSopenharmony_ci * The innermost designator is returned in *v. Designators in old 2515f08c3bdfSopenharmony_ci * are assumed to be already sanity-checked. 2516f08c3bdfSopenharmony_ci */ 2517f08c3bdfSopenharmony_cistatic struct expression *next_designators(struct expression *old, 2518f08c3bdfSopenharmony_ci struct symbol *ctype, 2519f08c3bdfSopenharmony_ci struct expression *e, struct expression **v) 2520f08c3bdfSopenharmony_ci{ 2521f08c3bdfSopenharmony_ci struct expression *new = NULL; 2522f08c3bdfSopenharmony_ci 2523f08c3bdfSopenharmony_ci if (!old) 2524f08c3bdfSopenharmony_ci return NULL; 2525f08c3bdfSopenharmony_ci if (old->type == EXPR_INDEX) { 2526f08c3bdfSopenharmony_ci struct expression *copy; 2527f08c3bdfSopenharmony_ci unsigned n; 2528f08c3bdfSopenharmony_ci 2529f08c3bdfSopenharmony_ci copy = next_designators(old->idx_expression, 2530f08c3bdfSopenharmony_ci old->ctype, e, v); 2531f08c3bdfSopenharmony_ci if (!copy) { 2532f08c3bdfSopenharmony_ci n = old->idx_to + 1; 2533f08c3bdfSopenharmony_ci if (array_element_offset(old->ctype->bit_size, n) == ctype->bit_size) { 2534f08c3bdfSopenharmony_ci convert_index(old); 2535f08c3bdfSopenharmony_ci return NULL; 2536f08c3bdfSopenharmony_ci } 2537f08c3bdfSopenharmony_ci copy = e; 2538f08c3bdfSopenharmony_ci *v = new = alloc_expression(e->pos, EXPR_INDEX); 2539f08c3bdfSopenharmony_ci } else { 2540f08c3bdfSopenharmony_ci n = old->idx_to; 2541f08c3bdfSopenharmony_ci new = alloc_expression(e->pos, EXPR_INDEX); 2542f08c3bdfSopenharmony_ci } 2543f08c3bdfSopenharmony_ci 2544f08c3bdfSopenharmony_ci new->idx_from = new->idx_to = n; 2545f08c3bdfSopenharmony_ci new->idx_expression = copy; 2546f08c3bdfSopenharmony_ci new->ctype = old->ctype; 2547f08c3bdfSopenharmony_ci convert_index(old); 2548f08c3bdfSopenharmony_ci } else if (old->type == EXPR_IDENTIFIER) { 2549f08c3bdfSopenharmony_ci struct expression *copy; 2550f08c3bdfSopenharmony_ci struct symbol *field; 2551f08c3bdfSopenharmony_ci int offset = 0; 2552f08c3bdfSopenharmony_ci 2553f08c3bdfSopenharmony_ci copy = next_designators(old->ident_expression, 2554f08c3bdfSopenharmony_ci old->ctype, e, v); 2555f08c3bdfSopenharmony_ci if (!copy) { 2556f08c3bdfSopenharmony_ci field = old->field->next_subobject; 2557f08c3bdfSopenharmony_ci if (!field) { 2558f08c3bdfSopenharmony_ci convert_ident(old); 2559f08c3bdfSopenharmony_ci return NULL; 2560f08c3bdfSopenharmony_ci } 2561f08c3bdfSopenharmony_ci copy = e; 2562f08c3bdfSopenharmony_ci *v = new = alloc_expression(e->pos, EXPR_IDENTIFIER); 2563f08c3bdfSopenharmony_ci /* 2564f08c3bdfSopenharmony_ci * We can't necessarily trust "field->offset", 2565f08c3bdfSopenharmony_ci * because the field might be in an anonymous 2566f08c3bdfSopenharmony_ci * union, and the field offset is then the offset 2567f08c3bdfSopenharmony_ci * within that union. 2568f08c3bdfSopenharmony_ci * 2569f08c3bdfSopenharmony_ci * The "old->offset - old->field->offset" 2570f08c3bdfSopenharmony_ci * would be the offset of such an anonymous 2571f08c3bdfSopenharmony_ci * union. 2572f08c3bdfSopenharmony_ci */ 2573f08c3bdfSopenharmony_ci offset = old->offset - old->field->offset; 2574f08c3bdfSopenharmony_ci } else { 2575f08c3bdfSopenharmony_ci field = old->field; 2576f08c3bdfSopenharmony_ci new = alloc_expression(e->pos, EXPR_IDENTIFIER); 2577f08c3bdfSopenharmony_ci } 2578f08c3bdfSopenharmony_ci 2579f08c3bdfSopenharmony_ci new->field = field; 2580f08c3bdfSopenharmony_ci new->expr_ident = field->ident; 2581f08c3bdfSopenharmony_ci new->ident_expression = copy; 2582f08c3bdfSopenharmony_ci new->ctype = field; 2583f08c3bdfSopenharmony_ci new->offset = field->offset + offset; 2584f08c3bdfSopenharmony_ci convert_ident(old); 2585f08c3bdfSopenharmony_ci } 2586f08c3bdfSopenharmony_ci return new; 2587f08c3bdfSopenharmony_ci} 2588f08c3bdfSopenharmony_ci 2589f08c3bdfSopenharmony_cistatic int handle_initializer(struct expression **ep, int nested, 2590f08c3bdfSopenharmony_ci int class, struct symbol *ctype, unsigned long mods); 2591f08c3bdfSopenharmony_ci 2592f08c3bdfSopenharmony_ci/* 2593f08c3bdfSopenharmony_ci * deal with traversing subobjects [6.7.8(17,18,20)] 2594f08c3bdfSopenharmony_ci */ 2595f08c3bdfSopenharmony_cistatic void handle_list_initializer(struct expression *expr, 2596f08c3bdfSopenharmony_ci int class, struct symbol *ctype, unsigned long mods) 2597f08c3bdfSopenharmony_ci{ 2598f08c3bdfSopenharmony_ci struct expression *e, *last = NULL, *top = NULL, *next; 2599f08c3bdfSopenharmony_ci int jumped = 0; // has the last designator multiple levels? 2600f08c3bdfSopenharmony_ci 2601f08c3bdfSopenharmony_ci if (expr->zero_init) 2602f08c3bdfSopenharmony_ci free_ptr_list(&expr->expr_list); 2603f08c3bdfSopenharmony_ci 2604f08c3bdfSopenharmony_ci FOR_EACH_PTR(expr->expr_list, e) { 2605f08c3bdfSopenharmony_ci struct expression **v; 2606f08c3bdfSopenharmony_ci struct symbol *type; 2607f08c3bdfSopenharmony_ci int lclass; 2608f08c3bdfSopenharmony_ci 2609f08c3bdfSopenharmony_ci if (e->type != EXPR_INDEX && e->type != EXPR_IDENTIFIER) { 2610f08c3bdfSopenharmony_ci struct symbol *struct_sym; 2611f08c3bdfSopenharmony_ci if (!top) { 2612f08c3bdfSopenharmony_ci top = e; 2613f08c3bdfSopenharmony_ci last = first_subobject(ctype, class, &top); 2614f08c3bdfSopenharmony_ci } else { 2615f08c3bdfSopenharmony_ci last = next_designators(last, ctype, e, &top); 2616f08c3bdfSopenharmony_ci } 2617f08c3bdfSopenharmony_ci if (!last) { 2618f08c3bdfSopenharmony_ci excess(e, class & TYPE_PTR ? "array" : 2619f08c3bdfSopenharmony_ci "struct or union"); 2620f08c3bdfSopenharmony_ci DELETE_CURRENT_PTR(e); 2621f08c3bdfSopenharmony_ci continue; 2622f08c3bdfSopenharmony_ci } 2623f08c3bdfSopenharmony_ci struct_sym = ctype->type == SYM_NODE ? ctype->ctype.base_type : ctype; 2624f08c3bdfSopenharmony_ci if (Wdesignated_init && struct_sym->designated_init) 2625f08c3bdfSopenharmony_ci warning(e->pos, "%s%.*s%spositional init of field in %s %s, declared with attribute designated_init", 2626f08c3bdfSopenharmony_ci ctype->ident ? "in initializer for " : "", 2627f08c3bdfSopenharmony_ci ctype->ident ? ctype->ident->len : 0, 2628f08c3bdfSopenharmony_ci ctype->ident ? ctype->ident->name : "", 2629f08c3bdfSopenharmony_ci ctype->ident ? ": " : "", 2630f08c3bdfSopenharmony_ci get_type_name(struct_sym->type), 2631f08c3bdfSopenharmony_ci show_ident(struct_sym->ident)); 2632f08c3bdfSopenharmony_ci if (jumped && Wpast_deep_designator) { 2633f08c3bdfSopenharmony_ci warning(e->pos, "advancing past deep designator"); 2634f08c3bdfSopenharmony_ci jumped = 0; 2635f08c3bdfSopenharmony_ci } 2636f08c3bdfSopenharmony_ci REPLACE_CURRENT_PTR(e, last); 2637f08c3bdfSopenharmony_ci } else { 2638f08c3bdfSopenharmony_ci next = check_designators(e, ctype); 2639f08c3bdfSopenharmony_ci if (!next) { 2640f08c3bdfSopenharmony_ci DELETE_CURRENT_PTR(e); 2641f08c3bdfSopenharmony_ci continue; 2642f08c3bdfSopenharmony_ci } 2643f08c3bdfSopenharmony_ci top = next; 2644f08c3bdfSopenharmony_ci /* deeper than one designator? */ 2645f08c3bdfSopenharmony_ci jumped = top != e; 2646f08c3bdfSopenharmony_ci convert_designators(last); 2647f08c3bdfSopenharmony_ci last = e; 2648f08c3bdfSopenharmony_ci } 2649f08c3bdfSopenharmony_ci 2650f08c3bdfSopenharmony_cifound: 2651f08c3bdfSopenharmony_ci lclass = classify_type(top->ctype, &type); 2652f08c3bdfSopenharmony_ci if (top->type == EXPR_INDEX) 2653f08c3bdfSopenharmony_ci v = &top->idx_expression; 2654f08c3bdfSopenharmony_ci else 2655f08c3bdfSopenharmony_ci v = &top->ident_expression; 2656f08c3bdfSopenharmony_ci 2657f08c3bdfSopenharmony_ci mods |= ctype->ctype.modifiers & MOD_STORAGE; 2658f08c3bdfSopenharmony_ci if (handle_initializer(v, 1, lclass, top->ctype, mods)) 2659f08c3bdfSopenharmony_ci continue; 2660f08c3bdfSopenharmony_ci 2661f08c3bdfSopenharmony_ci if (!(lclass & TYPE_COMPOUND)) { 2662f08c3bdfSopenharmony_ci warning(e->pos, "bogus scalar initializer"); 2663f08c3bdfSopenharmony_ci DELETE_CURRENT_PTR(e); 2664f08c3bdfSopenharmony_ci continue; 2665f08c3bdfSopenharmony_ci } 2666f08c3bdfSopenharmony_ci 2667f08c3bdfSopenharmony_ci next = first_subobject(type, lclass, v); 2668f08c3bdfSopenharmony_ci if (next) { 2669f08c3bdfSopenharmony_ci warning(e->pos, "missing braces around initializer"); 2670f08c3bdfSopenharmony_ci top = next; 2671f08c3bdfSopenharmony_ci goto found; 2672f08c3bdfSopenharmony_ci } 2673f08c3bdfSopenharmony_ci 2674f08c3bdfSopenharmony_ci DELETE_CURRENT_PTR(e); 2675f08c3bdfSopenharmony_ci excess(e, lclass & TYPE_PTR ? "array" : "struct or union"); 2676f08c3bdfSopenharmony_ci 2677f08c3bdfSopenharmony_ci } END_FOR_EACH_PTR(e); 2678f08c3bdfSopenharmony_ci 2679f08c3bdfSopenharmony_ci convert_designators(last); 2680f08c3bdfSopenharmony_ci expr->ctype = ctype; 2681f08c3bdfSopenharmony_ci} 2682f08c3bdfSopenharmony_ci 2683f08c3bdfSopenharmony_cistatic int is_string_literal(struct expression **v) 2684f08c3bdfSopenharmony_ci{ 2685f08c3bdfSopenharmony_ci struct expression *e = *v; 2686f08c3bdfSopenharmony_ci while (e && e->type == EXPR_PREOP && e->op == '(') 2687f08c3bdfSopenharmony_ci e = e->unop; 2688f08c3bdfSopenharmony_ci if (!e || e->type != EXPR_STRING) 2689f08c3bdfSopenharmony_ci return 0; 2690f08c3bdfSopenharmony_ci if (e != *v && Wparen_string) 2691f08c3bdfSopenharmony_ci warning(e->pos, 2692f08c3bdfSopenharmony_ci "array initialized from parenthesized string constant"); 2693f08c3bdfSopenharmony_ci *v = e; 2694f08c3bdfSopenharmony_ci return 1; 2695f08c3bdfSopenharmony_ci} 2696f08c3bdfSopenharmony_ci 2697f08c3bdfSopenharmony_ci/* 2698f08c3bdfSopenharmony_ci * We want a normal expression, possibly in one layer of braces. Warn 2699f08c3bdfSopenharmony_ci * if the latter happens inside a list (it's legal, but likely to be 2700f08c3bdfSopenharmony_ci * an effect of screwup). In case of anything not legal, we are definitely 2701f08c3bdfSopenharmony_ci * having an effect of screwup, so just fail and let the caller warn. 2702f08c3bdfSopenharmony_ci */ 2703f08c3bdfSopenharmony_cistatic struct expression *handle_scalar(struct expression *e, int nested) 2704f08c3bdfSopenharmony_ci{ 2705f08c3bdfSopenharmony_ci struct expression *v = NULL, *p; 2706f08c3bdfSopenharmony_ci int count = 0; 2707f08c3bdfSopenharmony_ci 2708f08c3bdfSopenharmony_ci /* normal case */ 2709f08c3bdfSopenharmony_ci if (e->type != EXPR_INITIALIZER) 2710f08c3bdfSopenharmony_ci return e; 2711f08c3bdfSopenharmony_ci 2712f08c3bdfSopenharmony_ci FOR_EACH_PTR(e->expr_list, p) { 2713f08c3bdfSopenharmony_ci if (!v) 2714f08c3bdfSopenharmony_ci v = p; 2715f08c3bdfSopenharmony_ci count++; 2716f08c3bdfSopenharmony_ci } END_FOR_EACH_PTR(p); 2717f08c3bdfSopenharmony_ci if (count != 1) 2718f08c3bdfSopenharmony_ci return NULL; 2719f08c3bdfSopenharmony_ci switch(v->type) { 2720f08c3bdfSopenharmony_ci case EXPR_INITIALIZER: 2721f08c3bdfSopenharmony_ci case EXPR_INDEX: 2722f08c3bdfSopenharmony_ci case EXPR_IDENTIFIER: 2723f08c3bdfSopenharmony_ci return NULL; 2724f08c3bdfSopenharmony_ci default: 2725f08c3bdfSopenharmony_ci break; 2726f08c3bdfSopenharmony_ci } 2727f08c3bdfSopenharmony_ci if (nested) 2728f08c3bdfSopenharmony_ci warning(e->pos, "braces around scalar initializer"); 2729f08c3bdfSopenharmony_ci return v; 2730f08c3bdfSopenharmony_ci} 2731f08c3bdfSopenharmony_ci 2732f08c3bdfSopenharmony_ci/* 2733f08c3bdfSopenharmony_ci * deal with the cases that don't care about subobjects: 2734f08c3bdfSopenharmony_ci * scalar <- assignment expression, possibly in braces [6.7.8(11)] 2735f08c3bdfSopenharmony_ci * character array <- string literal, possibly in braces [6.7.8(14)] 2736f08c3bdfSopenharmony_ci * struct or union <- assignment expression of compatible type [6.7.8(13)] 2737f08c3bdfSopenharmony_ci * compound type <- initializer list in braces [6.7.8(16)] 2738f08c3bdfSopenharmony_ci * The last one punts to handle_list_initializer() which, in turn will call 2739f08c3bdfSopenharmony_ci * us for individual elements of the list. 2740f08c3bdfSopenharmony_ci * 2741f08c3bdfSopenharmony_ci * We do not handle 6.7.8(15) (wide char array <- wide string literal) for 2742f08c3bdfSopenharmony_ci * the lack of support of wide char stuff in general. 2743f08c3bdfSopenharmony_ci * 2744f08c3bdfSopenharmony_ci * One note: we need to take care not to evaluate a string literal until 2745f08c3bdfSopenharmony_ci * we know that we *will* handle it right here. Otherwise we would screw 2746f08c3bdfSopenharmony_ci * the cases like struct { struct {char s[10]; ...} ...} initialized with 2747f08c3bdfSopenharmony_ci * { "string", ...} - we need to preserve that string literal recognizable 2748f08c3bdfSopenharmony_ci * until we dig into the inner struct. 2749f08c3bdfSopenharmony_ci */ 2750f08c3bdfSopenharmony_cistatic int handle_initializer(struct expression **ep, int nested, 2751f08c3bdfSopenharmony_ci int class, struct symbol *ctype, unsigned long mods) 2752f08c3bdfSopenharmony_ci{ 2753f08c3bdfSopenharmony_ci struct expression *e = *ep, *p; 2754f08c3bdfSopenharmony_ci struct symbol *type; 2755f08c3bdfSopenharmony_ci 2756f08c3bdfSopenharmony_ci if (!e) 2757f08c3bdfSopenharmony_ci return 0; 2758f08c3bdfSopenharmony_ci 2759f08c3bdfSopenharmony_ci /* scalar */ 2760f08c3bdfSopenharmony_ci if (!(class & TYPE_COMPOUND)) { 2761f08c3bdfSopenharmony_ci e = handle_scalar(e, nested); 2762f08c3bdfSopenharmony_ci if (!e) 2763f08c3bdfSopenharmony_ci return 0; 2764f08c3bdfSopenharmony_ci *ep = e; 2765f08c3bdfSopenharmony_ci if (!evaluate_expression(e)) 2766f08c3bdfSopenharmony_ci return 1; 2767f08c3bdfSopenharmony_ci compatible_assignment_types(e, ctype, ep, "initializer"); 2768f08c3bdfSopenharmony_ci /* 2769f08c3bdfSopenharmony_ci * Initializers for static storage duration objects 2770f08c3bdfSopenharmony_ci * shall be constant expressions or a string literal [6.7.8(4)]. 2771f08c3bdfSopenharmony_ci */ 2772f08c3bdfSopenharmony_ci mods |= ctype->ctype.modifiers; 2773f08c3bdfSopenharmony_ci mods &= (MOD_TOPLEVEL | MOD_STATIC); 2774f08c3bdfSopenharmony_ci if (mods && !(e->flags & (CEF_ACE | CEF_ADDR))) 2775f08c3bdfSopenharmony_ci if (Wconstexpr_not_const) 2776f08c3bdfSopenharmony_ci warning(e->pos, "non-constant initializer for static object"); 2777f08c3bdfSopenharmony_ci 2778f08c3bdfSopenharmony_ci return 1; 2779f08c3bdfSopenharmony_ci } 2780f08c3bdfSopenharmony_ci 2781f08c3bdfSopenharmony_ci /* 2782f08c3bdfSopenharmony_ci * sublist; either a string, or we dig in; the latter will deal with 2783f08c3bdfSopenharmony_ci * pathologies, so we don't need anything fancy here. 2784f08c3bdfSopenharmony_ci */ 2785f08c3bdfSopenharmony_ci if (e->type == EXPR_INITIALIZER) { 2786f08c3bdfSopenharmony_ci if (is_string_type(ctype)) { 2787f08c3bdfSopenharmony_ci struct expression *v = NULL; 2788f08c3bdfSopenharmony_ci int count = 0; 2789f08c3bdfSopenharmony_ci 2790f08c3bdfSopenharmony_ci FOR_EACH_PTR(e->expr_list, p) { 2791f08c3bdfSopenharmony_ci if (!v) 2792f08c3bdfSopenharmony_ci v = p; 2793f08c3bdfSopenharmony_ci count++; 2794f08c3bdfSopenharmony_ci } END_FOR_EACH_PTR(p); 2795f08c3bdfSopenharmony_ci if (count == 1 && is_string_literal(&v)) { 2796f08c3bdfSopenharmony_ci *ep = e = v; 2797f08c3bdfSopenharmony_ci goto String; 2798f08c3bdfSopenharmony_ci } 2799f08c3bdfSopenharmony_ci } 2800f08c3bdfSopenharmony_ci handle_list_initializer(e, class, ctype, mods); 2801f08c3bdfSopenharmony_ci return 1; 2802f08c3bdfSopenharmony_ci } 2803f08c3bdfSopenharmony_ci 2804f08c3bdfSopenharmony_ci /* string */ 2805f08c3bdfSopenharmony_ci if (is_string_literal(&e)) { 2806f08c3bdfSopenharmony_ci /* either we are doing array of char, or we'll have to dig in */ 2807f08c3bdfSopenharmony_ci if (is_string_type(ctype)) { 2808f08c3bdfSopenharmony_ci *ep = e; 2809f08c3bdfSopenharmony_ci goto String; 2810f08c3bdfSopenharmony_ci } 2811f08c3bdfSopenharmony_ci return 0; 2812f08c3bdfSopenharmony_ci } 2813f08c3bdfSopenharmony_ci /* struct or union can be initialized by compatible */ 2814f08c3bdfSopenharmony_ci if (class != TYPE_COMPOUND) 2815f08c3bdfSopenharmony_ci return 0; 2816f08c3bdfSopenharmony_ci type = evaluate_expression(e); 2817f08c3bdfSopenharmony_ci if (!type) 2818f08c3bdfSopenharmony_ci return 0; 2819f08c3bdfSopenharmony_ci if (ctype->type == SYM_NODE) 2820f08c3bdfSopenharmony_ci ctype = ctype->ctype.base_type; 2821f08c3bdfSopenharmony_ci if (type->type == SYM_NODE) 2822f08c3bdfSopenharmony_ci type = type->ctype.base_type; 2823f08c3bdfSopenharmony_ci if (ctype == type) 2824f08c3bdfSopenharmony_ci return 1; 2825f08c3bdfSopenharmony_ci return 0; 2826f08c3bdfSopenharmony_ci 2827f08c3bdfSopenharmony_ciString: 2828f08c3bdfSopenharmony_ci p = alloc_expression(e->pos, EXPR_STRING); 2829f08c3bdfSopenharmony_ci *p = *e; 2830f08c3bdfSopenharmony_ci type = evaluate_expression(p); 2831f08c3bdfSopenharmony_ci if (ctype->bit_size != -1) { 2832f08c3bdfSopenharmony_ci struct symbol *char_type = e->wide ? wchar_ctype : &char_ctype; 2833f08c3bdfSopenharmony_ci unsigned int size_with_null = ctype->bit_size + char_type->bit_size; 2834f08c3bdfSopenharmony_ci if (size_with_null < type->bit_size) 2835f08c3bdfSopenharmony_ci warning(e->pos, 2836f08c3bdfSopenharmony_ci "too long initializer-string for array of char"); 2837f08c3bdfSopenharmony_ci else if (Winit_cstring && size_with_null == type->bit_size) { 2838f08c3bdfSopenharmony_ci warning(e->pos, 2839f08c3bdfSopenharmony_ci "too long initializer-string for array of char(no space for nul char)"); 2840f08c3bdfSopenharmony_ci } 2841f08c3bdfSopenharmony_ci } 2842f08c3bdfSopenharmony_ci *ep = p; 2843f08c3bdfSopenharmony_ci return 1; 2844f08c3bdfSopenharmony_ci} 2845f08c3bdfSopenharmony_ci 2846f08c3bdfSopenharmony_cistatic void evaluate_initializer(struct symbol *ctype, struct expression **ep) 2847f08c3bdfSopenharmony_ci{ 2848f08c3bdfSopenharmony_ci struct symbol *type; 2849f08c3bdfSopenharmony_ci int class = classify_type(ctype, &type); 2850f08c3bdfSopenharmony_ci if (!handle_initializer(ep, 0, class, ctype, 0)) 2851f08c3bdfSopenharmony_ci expression_error(*ep, "invalid initializer"); 2852f08c3bdfSopenharmony_ci} 2853f08c3bdfSopenharmony_ci 2854f08c3bdfSopenharmony_cistatic struct symbol *cast_to_bool(struct expression *expr) 2855f08c3bdfSopenharmony_ci{ 2856f08c3bdfSopenharmony_ci struct expression *old = expr->cast_expression; 2857f08c3bdfSopenharmony_ci struct expression *zero; 2858f08c3bdfSopenharmony_ci struct symbol *otype; 2859f08c3bdfSopenharmony_ci int oclass = classify_type(degenerate(old), &otype); 2860f08c3bdfSopenharmony_ci struct symbol *ctype; 2861f08c3bdfSopenharmony_ci 2862f08c3bdfSopenharmony_ci if (oclass & TYPE_COMPOUND) 2863f08c3bdfSopenharmony_ci return NULL; 2864f08c3bdfSopenharmony_ci 2865f08c3bdfSopenharmony_ci zero = alloc_const_expression(expr->pos, 0); 2866f08c3bdfSopenharmony_ci if (oclass & TYPE_PTR) 2867f08c3bdfSopenharmony_ci zero->ctype = otype; 2868f08c3bdfSopenharmony_ci expr->op = SPECIAL_NOTEQUAL; 2869f08c3bdfSopenharmony_ci ctype = usual_conversions(expr->op, old, zero, 2870f08c3bdfSopenharmony_ci oclass, TYPE_NUM, otype, zero->ctype); 2871f08c3bdfSopenharmony_ci expr->type = EXPR_COMPARE; 2872f08c3bdfSopenharmony_ci expr->left = cast_to(old, ctype); 2873f08c3bdfSopenharmony_ci expr->right = cast_to(zero, ctype); 2874f08c3bdfSopenharmony_ci 2875f08c3bdfSopenharmony_ci return expr->ctype; 2876f08c3bdfSopenharmony_ci} 2877f08c3bdfSopenharmony_ci 2878f08c3bdfSopenharmony_cistatic int cast_flags(struct expression *expr, struct expression *old) 2879f08c3bdfSopenharmony_ci{ 2880f08c3bdfSopenharmony_ci struct symbol *t; 2881f08c3bdfSopenharmony_ci int class; 2882f08c3bdfSopenharmony_ci int flags = CEF_NONE; 2883f08c3bdfSopenharmony_ci 2884f08c3bdfSopenharmony_ci class = classify_type(expr->ctype, &t); 2885f08c3bdfSopenharmony_ci if (class & TYPE_NUM) { 2886f08c3bdfSopenharmony_ci flags = old->flags & ~CEF_CONST_MASK; 2887f08c3bdfSopenharmony_ci /* 2888f08c3bdfSopenharmony_ci * Casts to numeric types never result in address 2889f08c3bdfSopenharmony_ci * constants [6.6(9)]. 2890f08c3bdfSopenharmony_ci */ 2891f08c3bdfSopenharmony_ci flags &= ~CEF_ADDR; 2892f08c3bdfSopenharmony_ci 2893f08c3bdfSopenharmony_ci /* 2894f08c3bdfSopenharmony_ci * As an extension, treat address constants cast to 2895f08c3bdfSopenharmony_ci * integer type as an arithmetic constant. 2896f08c3bdfSopenharmony_ci */ 2897f08c3bdfSopenharmony_ci if (old->flags & CEF_ADDR) 2898f08c3bdfSopenharmony_ci flags = CEF_ACE; 2899f08c3bdfSopenharmony_ci 2900f08c3bdfSopenharmony_ci /* 2901f08c3bdfSopenharmony_ci * Cast to float type -> not an integer constant 2902f08c3bdfSopenharmony_ci * expression [6.6(6)]. 2903f08c3bdfSopenharmony_ci */ 2904f08c3bdfSopenharmony_ci if (class & TYPE_FLOAT) 2905f08c3bdfSopenharmony_ci flags &= ~CEF_CLR_ICE; 2906f08c3bdfSopenharmony_ci /* 2907f08c3bdfSopenharmony_ci * Casts of float literals to integer type results in 2908f08c3bdfSopenharmony_ci * a constant integer expression [6.6(6)]. 2909f08c3bdfSopenharmony_ci */ 2910f08c3bdfSopenharmony_ci else if (old->flags & CEF_FLOAT) 2911f08c3bdfSopenharmony_ci flags = CEF_SET_ICE; 2912f08c3bdfSopenharmony_ci } else if (class & TYPE_PTR) { 2913f08c3bdfSopenharmony_ci /* 2914f08c3bdfSopenharmony_ci * Casts of integer literals to pointer type yield 2915f08c3bdfSopenharmony_ci * address constants [6.6(9)]. 2916f08c3bdfSopenharmony_ci * 2917f08c3bdfSopenharmony_ci * As an extension, treat address constants cast to a 2918f08c3bdfSopenharmony_ci * different pointer type as address constants again. 2919f08c3bdfSopenharmony_ci * 2920f08c3bdfSopenharmony_ci * As another extension, treat integer constant 2921f08c3bdfSopenharmony_ci * expressions (in contrast to literals) cast to 2922f08c3bdfSopenharmony_ci * pointer type as address constants. 2923f08c3bdfSopenharmony_ci */ 2924f08c3bdfSopenharmony_ci if (old->flags & (CEF_ICE | CEF_ADDR)) 2925f08c3bdfSopenharmony_ci flags = CEF_ADDR; 2926f08c3bdfSopenharmony_ci } 2927f08c3bdfSopenharmony_ci 2928f08c3bdfSopenharmony_ci return flags; 2929f08c3bdfSopenharmony_ci} 2930f08c3bdfSopenharmony_ci 2931f08c3bdfSopenharmony_ci/// 2932f08c3bdfSopenharmony_ci// check if a type matches one of the members of a union type 2933f08c3bdfSopenharmony_ci// @utype: the union type 2934f08c3bdfSopenharmony_ci// @type: to type to check 2935f08c3bdfSopenharmony_ci// @return: to identifier of the matching type in the union. 2936f08c3bdfSopenharmony_cistatic struct symbol *find_member_type(struct symbol *utype, struct symbol *type) 2937f08c3bdfSopenharmony_ci{ 2938f08c3bdfSopenharmony_ci struct symbol *t, *member; 2939f08c3bdfSopenharmony_ci 2940f08c3bdfSopenharmony_ci if (utype->type != SYM_UNION) 2941f08c3bdfSopenharmony_ci return NULL; 2942f08c3bdfSopenharmony_ci 2943f08c3bdfSopenharmony_ci FOR_EACH_PTR(utype->symbol_list, member) { 2944f08c3bdfSopenharmony_ci classify_type(member, &t); 2945f08c3bdfSopenharmony_ci if (type == t) 2946f08c3bdfSopenharmony_ci return member; 2947f08c3bdfSopenharmony_ci } END_FOR_EACH_PTR(member); 2948f08c3bdfSopenharmony_ci return NULL; 2949f08c3bdfSopenharmony_ci} 2950f08c3bdfSopenharmony_ci 2951f08c3bdfSopenharmony_cistatic struct symbol *evaluate_compound_literal(struct expression *expr, struct expression *source) 2952f08c3bdfSopenharmony_ci{ 2953f08c3bdfSopenharmony_ci struct expression *addr = alloc_expression(expr->pos, EXPR_SYMBOL); 2954f08c3bdfSopenharmony_ci struct symbol *sym = expr->cast_type; 2955f08c3bdfSopenharmony_ci 2956f08c3bdfSopenharmony_ci sym->initializer = source; 2957f08c3bdfSopenharmony_ci evaluate_symbol(sym); 2958f08c3bdfSopenharmony_ci 2959f08c3bdfSopenharmony_ci addr->ctype = &lazy_ptr_ctype; /* Lazy eval */ 2960f08c3bdfSopenharmony_ci addr->symbol = sym; 2961f08c3bdfSopenharmony_ci if (sym->ctype.modifiers & MOD_TOPLEVEL) 2962f08c3bdfSopenharmony_ci addr->flags |= CEF_ADDR; 2963f08c3bdfSopenharmony_ci 2964f08c3bdfSopenharmony_ci expr->type = EXPR_PREOP; 2965f08c3bdfSopenharmony_ci expr->op = '*'; 2966f08c3bdfSopenharmony_ci expr->deref = addr; 2967f08c3bdfSopenharmony_ci expr->ctype = sym; 2968f08c3bdfSopenharmony_ci return sym; 2969f08c3bdfSopenharmony_ci} 2970f08c3bdfSopenharmony_ci 2971f08c3bdfSopenharmony_cistatic struct symbol *evaluate_cast(struct expression *expr) 2972f08c3bdfSopenharmony_ci{ 2973f08c3bdfSopenharmony_ci struct expression *source = expr->cast_expression; 2974f08c3bdfSopenharmony_ci struct symbol *ctype; 2975f08c3bdfSopenharmony_ci struct symbol *ttype, *stype; 2976f08c3bdfSopenharmony_ci struct symbol *member; 2977f08c3bdfSopenharmony_ci int tclass, sclass; 2978f08c3bdfSopenharmony_ci struct ident *tas = NULL, *sas = NULL; 2979f08c3bdfSopenharmony_ci 2980f08c3bdfSopenharmony_ci if (!source) 2981f08c3bdfSopenharmony_ci return NULL; 2982f08c3bdfSopenharmony_ci 2983f08c3bdfSopenharmony_ci /* 2984f08c3bdfSopenharmony_ci * Special case: a cast can be followed by an 2985f08c3bdfSopenharmony_ci * initializer, in which case we need to pass 2986f08c3bdfSopenharmony_ci * the type value down to that initializer rather 2987f08c3bdfSopenharmony_ci * than trying to evaluate it as an expression 2988f08c3bdfSopenharmony_ci * (cfr. compound literals: C99 & C11 6.5.2.5). 2989f08c3bdfSopenharmony_ci * 2990f08c3bdfSopenharmony_ci * A more complex case is when the initializer is 2991f08c3bdfSopenharmony_ci * dereferenced as part of a post-fix expression. 2992f08c3bdfSopenharmony_ci * We need to produce an expression that can be dereferenced. 2993f08c3bdfSopenharmony_ci */ 2994f08c3bdfSopenharmony_ci if (source->type == EXPR_INITIALIZER) 2995f08c3bdfSopenharmony_ci return evaluate_compound_literal(expr, source); 2996f08c3bdfSopenharmony_ci 2997f08c3bdfSopenharmony_ci ctype = examine_symbol_type(expr->cast_type); 2998f08c3bdfSopenharmony_ci ctype = unqualify_type(ctype); 2999f08c3bdfSopenharmony_ci expr->ctype = ctype; 3000f08c3bdfSopenharmony_ci expr->cast_type = ctype; 3001f08c3bdfSopenharmony_ci 3002f08c3bdfSopenharmony_ci evaluate_expression(source); 3003f08c3bdfSopenharmony_ci degenerate(source); 3004f08c3bdfSopenharmony_ci 3005f08c3bdfSopenharmony_ci tclass = classify_type(ctype, &ttype); 3006f08c3bdfSopenharmony_ci 3007f08c3bdfSopenharmony_ci expr->flags = cast_flags(expr, source); 3008f08c3bdfSopenharmony_ci 3009f08c3bdfSopenharmony_ci /* 3010f08c3bdfSopenharmony_ci * You can always throw a value away by casting to 3011f08c3bdfSopenharmony_ci * "void" - that's an implicit "force". Note that 3012f08c3bdfSopenharmony_ci * the same is _not_ true of "void *". 3013f08c3bdfSopenharmony_ci */ 3014f08c3bdfSopenharmony_ci if (ttype == &void_ctype) 3015f08c3bdfSopenharmony_ci goto out; 3016f08c3bdfSopenharmony_ci 3017f08c3bdfSopenharmony_ci stype = source->ctype; 3018f08c3bdfSopenharmony_ci if (!stype) { 3019f08c3bdfSopenharmony_ci expression_error(expr, "cast from unknown type"); 3020f08c3bdfSopenharmony_ci goto out; 3021f08c3bdfSopenharmony_ci } 3022f08c3bdfSopenharmony_ci sclass = classify_type(stype, &stype); 3023f08c3bdfSopenharmony_ci 3024f08c3bdfSopenharmony_ci if (expr->type == EXPR_FORCE_CAST) 3025f08c3bdfSopenharmony_ci goto out; 3026f08c3bdfSopenharmony_ci 3027f08c3bdfSopenharmony_ci if (tclass & (TYPE_COMPOUND | TYPE_FN)) { 3028f08c3bdfSopenharmony_ci /* 3029f08c3bdfSopenharmony_ci * Special case: cast to union type (GCC extension) 3030f08c3bdfSopenharmony_ci * The effect is similar to a compound literal except 3031f08c3bdfSopenharmony_ci * that the result is a rvalue. 3032f08c3bdfSopenharmony_ci */ 3033f08c3bdfSopenharmony_ci if ((member = find_member_type(ttype, stype))) { 3034f08c3bdfSopenharmony_ci struct expression *item, *init; 3035f08c3bdfSopenharmony_ci 3036f08c3bdfSopenharmony_ci if (Wunion_cast) 3037f08c3bdfSopenharmony_ci warning(expr->pos, "cast to union type"); 3038f08c3bdfSopenharmony_ci 3039f08c3bdfSopenharmony_ci item = alloc_expression(source->pos, EXPR_IDENTIFIER); 3040f08c3bdfSopenharmony_ci item->expr_ident = member->ident; 3041f08c3bdfSopenharmony_ci item->ident_expression = source; 3042f08c3bdfSopenharmony_ci 3043f08c3bdfSopenharmony_ci init = alloc_expression(source->pos, EXPR_INITIALIZER); 3044f08c3bdfSopenharmony_ci add_expression(&init->expr_list, item); 3045f08c3bdfSopenharmony_ci 3046f08c3bdfSopenharmony_ci // FIXME: this should be a rvalue 3047f08c3bdfSopenharmony_ci evaluate_compound_literal(expr, init); 3048f08c3bdfSopenharmony_ci return ctype; 3049f08c3bdfSopenharmony_ci } 3050f08c3bdfSopenharmony_ci 3051f08c3bdfSopenharmony_ci warning(expr->pos, "cast to non-scalar"); 3052f08c3bdfSopenharmony_ci } 3053f08c3bdfSopenharmony_ci 3054f08c3bdfSopenharmony_ci if (sclass & TYPE_COMPOUND) 3055f08c3bdfSopenharmony_ci warning(expr->pos, "cast from non-scalar"); 3056f08c3bdfSopenharmony_ci 3057f08c3bdfSopenharmony_ci /* allowed cast unfouls */ 3058f08c3bdfSopenharmony_ci if (sclass & TYPE_FOULED) 3059f08c3bdfSopenharmony_ci stype = unfoul(stype); 3060f08c3bdfSopenharmony_ci 3061f08c3bdfSopenharmony_ci if (ttype != stype) { 3062f08c3bdfSopenharmony_ci if ((tclass & TYPE_RESTRICT) && restricted_value(source, ttype)) 3063f08c3bdfSopenharmony_ci warning(expr->pos, "cast to %s", 3064f08c3bdfSopenharmony_ci show_typename(ttype)); 3065f08c3bdfSopenharmony_ci if (sclass & TYPE_RESTRICT) { 3066f08c3bdfSopenharmony_ci if (ttype == &bool_ctype) { 3067f08c3bdfSopenharmony_ci if (sclass & TYPE_FOULED) 3068f08c3bdfSopenharmony_ci warning(expr->pos, "%s degrades to integer", 3069f08c3bdfSopenharmony_ci show_typename(stype)); 3070f08c3bdfSopenharmony_ci } else { 3071f08c3bdfSopenharmony_ci warning(expr->pos, "cast from %s", 3072f08c3bdfSopenharmony_ci show_typename(stype)); 3073f08c3bdfSopenharmony_ci } 3074f08c3bdfSopenharmony_ci } 3075f08c3bdfSopenharmony_ci } 3076f08c3bdfSopenharmony_ci 3077f08c3bdfSopenharmony_ci if ((ttype == &ulong_ctype || ttype == uintptr_ctype) && !Wcast_from_as) 3078f08c3bdfSopenharmony_ci tas = &bad_address_space; 3079f08c3bdfSopenharmony_ci else if (tclass == TYPE_PTR) { 3080f08c3bdfSopenharmony_ci examine_pointer_target(ttype); 3081f08c3bdfSopenharmony_ci tas = ttype->ctype.as; 3082f08c3bdfSopenharmony_ci } 3083f08c3bdfSopenharmony_ci 3084f08c3bdfSopenharmony_ci if ((stype == &ulong_ctype || stype == uintptr_ctype)) 3085f08c3bdfSopenharmony_ci sas = &bad_address_space; 3086f08c3bdfSopenharmony_ci else if (sclass == TYPE_PTR) { 3087f08c3bdfSopenharmony_ci examine_pointer_target(stype); 3088f08c3bdfSopenharmony_ci sas = stype->ctype.as; 3089f08c3bdfSopenharmony_ci } 3090f08c3bdfSopenharmony_ci 3091f08c3bdfSopenharmony_ci if (!tas && valid_as(sas)) 3092f08c3bdfSopenharmony_ci warning(expr->pos, "cast removes address space '%s' of expression", show_as(sas)); 3093f08c3bdfSopenharmony_ci if (valid_as(tas) && valid_as(sas) && tas != sas) 3094f08c3bdfSopenharmony_ci warning(expr->pos, "cast between address spaces (%s -> %s)", show_as(sas), show_as(tas)); 3095f08c3bdfSopenharmony_ci if (valid_as(tas) && !sas && 3096f08c3bdfSopenharmony_ci !is_null_pointer_constant(source) && Wcast_to_as) 3097f08c3bdfSopenharmony_ci warning(expr->pos, 3098f08c3bdfSopenharmony_ci "cast adds address space '%s' to expression", show_as(tas)); 3099f08c3bdfSopenharmony_ci 3100f08c3bdfSopenharmony_ci if (!(ttype->ctype.modifiers & MOD_PTRINHERIT) && tclass == TYPE_PTR && 3101f08c3bdfSopenharmony_ci !tas && (source->flags & CEF_ICE)) { 3102f08c3bdfSopenharmony_ci if (ttype->ctype.base_type == &void_ctype) { 3103f08c3bdfSopenharmony_ci if (is_zero_constant(source)) { 3104f08c3bdfSopenharmony_ci /* NULL */ 3105f08c3bdfSopenharmony_ci expr->type = EXPR_VALUE; 3106f08c3bdfSopenharmony_ci expr->ctype = &null_ctype; 3107f08c3bdfSopenharmony_ci expr->value = 0; 3108f08c3bdfSopenharmony_ci return expr->ctype; 3109f08c3bdfSopenharmony_ci } 3110f08c3bdfSopenharmony_ci } 3111f08c3bdfSopenharmony_ci } 3112f08c3bdfSopenharmony_ci 3113f08c3bdfSopenharmony_ci if (ttype == &bool_ctype) 3114f08c3bdfSopenharmony_ci cast_to_bool(expr); 3115f08c3bdfSopenharmony_ci 3116f08c3bdfSopenharmony_ci // checks pointers to restricted 3117f08c3bdfSopenharmony_ci while (Wbitwise_pointer && tclass == TYPE_PTR && sclass == TYPE_PTR) { 3118f08c3bdfSopenharmony_ci tclass = classify_type(ttype->ctype.base_type, &ttype); 3119f08c3bdfSopenharmony_ci sclass = classify_type(stype->ctype.base_type, &stype); 3120f08c3bdfSopenharmony_ci if (ttype == stype) 3121f08c3bdfSopenharmony_ci break; 3122f08c3bdfSopenharmony_ci if (!ttype || !stype) 3123f08c3bdfSopenharmony_ci break; 3124f08c3bdfSopenharmony_ci if (ttype == &void_ctype || stype == &void_ctype) 3125f08c3bdfSopenharmony_ci break; 3126f08c3bdfSopenharmony_ci if (tclass & TYPE_RESTRICT) { 3127f08c3bdfSopenharmony_ci warning(expr->pos, "cast to %s", show_typename(ctype)); 3128f08c3bdfSopenharmony_ci break; 3129f08c3bdfSopenharmony_ci } 3130f08c3bdfSopenharmony_ci if (sclass & TYPE_RESTRICT) { 3131f08c3bdfSopenharmony_ci warning(expr->pos, "cast from %s", show_typename(source->ctype)); 3132f08c3bdfSopenharmony_ci break; 3133f08c3bdfSopenharmony_ci } 3134f08c3bdfSopenharmony_ci } 3135f08c3bdfSopenharmony_ciout: 3136f08c3bdfSopenharmony_ci return ctype; 3137f08c3bdfSopenharmony_ci} 3138f08c3bdfSopenharmony_ci 3139f08c3bdfSopenharmony_ci/* 3140f08c3bdfSopenharmony_ci * Evaluate a call expression with a symbol. This 3141f08c3bdfSopenharmony_ci * should expand inline functions, and evaluate 3142f08c3bdfSopenharmony_ci * builtins. 3143f08c3bdfSopenharmony_ci */ 3144f08c3bdfSopenharmony_cistatic int evaluate_symbol_call(struct expression *expr) 3145f08c3bdfSopenharmony_ci{ 3146f08c3bdfSopenharmony_ci struct expression *fn = expr->fn; 3147f08c3bdfSopenharmony_ci struct symbol *ctype = fn->ctype; 3148f08c3bdfSopenharmony_ci 3149f08c3bdfSopenharmony_ci if (fn->type != EXPR_PREOP) 3150f08c3bdfSopenharmony_ci return 0; 3151f08c3bdfSopenharmony_ci 3152f08c3bdfSopenharmony_ci if (ctype->op && ctype->op->evaluate) 3153f08c3bdfSopenharmony_ci return ctype->op->evaluate(expr); 3154f08c3bdfSopenharmony_ci 3155f08c3bdfSopenharmony_ci return 0; 3156f08c3bdfSopenharmony_ci} 3157f08c3bdfSopenharmony_ci 3158f08c3bdfSopenharmony_cistatic struct symbol *evaluate_call(struct expression *expr) 3159f08c3bdfSopenharmony_ci{ 3160f08c3bdfSopenharmony_ci int args, fnargs; 3161f08c3bdfSopenharmony_ci struct symbol *ctype, *sym; 3162f08c3bdfSopenharmony_ci struct expression *fn = expr->fn; 3163f08c3bdfSopenharmony_ci struct expression_list *arglist = expr->args; 3164f08c3bdfSopenharmony_ci 3165f08c3bdfSopenharmony_ci if (!evaluate_expression(fn)) 3166f08c3bdfSopenharmony_ci return NULL; 3167f08c3bdfSopenharmony_ci sym = ctype = fn->ctype; 3168f08c3bdfSopenharmony_ci if (ctype->type == SYM_NODE) 3169f08c3bdfSopenharmony_ci ctype = ctype->ctype.base_type; 3170f08c3bdfSopenharmony_ci if (ctype->type == SYM_PTR) 3171f08c3bdfSopenharmony_ci ctype = get_base_type(ctype); 3172f08c3bdfSopenharmony_ci 3173f08c3bdfSopenharmony_ci if (ctype->type != SYM_FN) { 3174f08c3bdfSopenharmony_ci struct expression *arg; 3175f08c3bdfSopenharmony_ci 3176f08c3bdfSopenharmony_ci if (fn->ctype == &bad_ctype) 3177f08c3bdfSopenharmony_ci return NULL; 3178f08c3bdfSopenharmony_ci 3179f08c3bdfSopenharmony_ci expression_error(expr, "not a function %s", 3180f08c3bdfSopenharmony_ci show_ident(sym->ident)); 3181f08c3bdfSopenharmony_ci /* do typechecking in arguments */ 3182f08c3bdfSopenharmony_ci FOR_EACH_PTR (arglist, arg) { 3183f08c3bdfSopenharmony_ci evaluate_expression(arg); 3184f08c3bdfSopenharmony_ci } END_FOR_EACH_PTR(arg); 3185f08c3bdfSopenharmony_ci return NULL; 3186f08c3bdfSopenharmony_ci } 3187f08c3bdfSopenharmony_ci 3188f08c3bdfSopenharmony_ci examine_fn_arguments(ctype); 3189f08c3bdfSopenharmony_ci if (sym->type == SYM_NODE && fn->type == EXPR_PREOP && 3190f08c3bdfSopenharmony_ci sym->op && sym->op->args) { 3191f08c3bdfSopenharmony_ci if (!sym->op->args(expr)) 3192f08c3bdfSopenharmony_ci return NULL; 3193f08c3bdfSopenharmony_ci } else { 3194f08c3bdfSopenharmony_ci if (!evaluate_arguments(ctype->arguments, arglist)) 3195f08c3bdfSopenharmony_ci return NULL; 3196f08c3bdfSopenharmony_ci args = expression_list_size(expr->args); 3197f08c3bdfSopenharmony_ci fnargs = symbol_list_size(ctype->arguments); 3198f08c3bdfSopenharmony_ci if (args < fnargs) { 3199f08c3bdfSopenharmony_ci expression_error(expr, 3200f08c3bdfSopenharmony_ci "not enough arguments for function %s", 3201f08c3bdfSopenharmony_ci show_ident(sym->ident)); 3202f08c3bdfSopenharmony_ci return NULL; 3203f08c3bdfSopenharmony_ci } 3204f08c3bdfSopenharmony_ci if (args > fnargs && !ctype->variadic) 3205f08c3bdfSopenharmony_ci expression_error(expr, 3206f08c3bdfSopenharmony_ci "too many arguments for function %s", 3207f08c3bdfSopenharmony_ci show_ident(sym->ident)); 3208f08c3bdfSopenharmony_ci } 3209f08c3bdfSopenharmony_ci expr->ctype = ctype->ctype.base_type; 3210f08c3bdfSopenharmony_ci if (sym->type == SYM_NODE) { 3211f08c3bdfSopenharmony_ci if (evaluate_symbol_call(expr)) 3212f08c3bdfSopenharmony_ci return expr->ctype; 3213f08c3bdfSopenharmony_ci } 3214f08c3bdfSopenharmony_ci return expr->ctype; 3215f08c3bdfSopenharmony_ci} 3216f08c3bdfSopenharmony_ci 3217f08c3bdfSopenharmony_cistatic struct symbol *evaluate_offsetof(struct expression *expr) 3218f08c3bdfSopenharmony_ci{ 3219f08c3bdfSopenharmony_ci struct expression *e = expr->down; 3220f08c3bdfSopenharmony_ci struct symbol *ctype = expr->in; 3221f08c3bdfSopenharmony_ci int class; 3222f08c3bdfSopenharmony_ci 3223f08c3bdfSopenharmony_ci if (expr->op == '.') { 3224f08c3bdfSopenharmony_ci struct symbol *field; 3225f08c3bdfSopenharmony_ci int offset = 0; 3226f08c3bdfSopenharmony_ci if (!ctype) { 3227f08c3bdfSopenharmony_ci expression_error(expr, "expected structure or union"); 3228f08c3bdfSopenharmony_ci return NULL; 3229f08c3bdfSopenharmony_ci } 3230f08c3bdfSopenharmony_ci examine_symbol_type(ctype); 3231f08c3bdfSopenharmony_ci class = classify_type(ctype, &ctype); 3232f08c3bdfSopenharmony_ci if (class != TYPE_COMPOUND) { 3233f08c3bdfSopenharmony_ci expression_error(expr, "expected structure or union"); 3234f08c3bdfSopenharmony_ci return NULL; 3235f08c3bdfSopenharmony_ci } 3236f08c3bdfSopenharmony_ci 3237f08c3bdfSopenharmony_ci field = find_identifier(expr->ident, ctype->symbol_list, &offset); 3238f08c3bdfSopenharmony_ci if (!field) { 3239f08c3bdfSopenharmony_ci expression_error(expr, "unknown member"); 3240f08c3bdfSopenharmony_ci return NULL; 3241f08c3bdfSopenharmony_ci } 3242f08c3bdfSopenharmony_ci ctype = field; 3243f08c3bdfSopenharmony_ci expr->type = EXPR_VALUE; 3244f08c3bdfSopenharmony_ci expr->flags = CEF_SET_ICE; 3245f08c3bdfSopenharmony_ci expr->value = offset; 3246f08c3bdfSopenharmony_ci expr->taint = 0; 3247f08c3bdfSopenharmony_ci expr->ctype = size_t_ctype; 3248f08c3bdfSopenharmony_ci } else { 3249f08c3bdfSopenharmony_ci if (!ctype) { 3250f08c3bdfSopenharmony_ci expression_error(expr, "expected structure or union"); 3251f08c3bdfSopenharmony_ci return NULL; 3252f08c3bdfSopenharmony_ci } 3253f08c3bdfSopenharmony_ci examine_symbol_type(ctype); 3254f08c3bdfSopenharmony_ci class = classify_type(ctype, &ctype); 3255f08c3bdfSopenharmony_ci if (class != (TYPE_COMPOUND | TYPE_PTR)) { 3256f08c3bdfSopenharmony_ci expression_error(expr, "expected array"); 3257f08c3bdfSopenharmony_ci return NULL; 3258f08c3bdfSopenharmony_ci } 3259f08c3bdfSopenharmony_ci ctype = ctype->ctype.base_type; 3260f08c3bdfSopenharmony_ci if (!expr->index) { 3261f08c3bdfSopenharmony_ci expr->type = EXPR_VALUE; 3262f08c3bdfSopenharmony_ci expr->flags = CEF_SET_ICE; 3263f08c3bdfSopenharmony_ci expr->value = 0; 3264f08c3bdfSopenharmony_ci expr->taint = 0; 3265f08c3bdfSopenharmony_ci expr->ctype = size_t_ctype; 3266f08c3bdfSopenharmony_ci } else { 3267f08c3bdfSopenharmony_ci struct expression *idx = expr->index, *m; 3268f08c3bdfSopenharmony_ci struct symbol *i_type = evaluate_expression(idx); 3269f08c3bdfSopenharmony_ci unsigned old_idx_flags; 3270f08c3bdfSopenharmony_ci int i_class = classify_type(i_type, &i_type); 3271f08c3bdfSopenharmony_ci 3272f08c3bdfSopenharmony_ci if (!is_int(i_class)) { 3273f08c3bdfSopenharmony_ci expression_error(expr, "non-integer index"); 3274f08c3bdfSopenharmony_ci return NULL; 3275f08c3bdfSopenharmony_ci } 3276f08c3bdfSopenharmony_ci unrestrict(idx, i_class, &i_type); 3277f08c3bdfSopenharmony_ci old_idx_flags = idx->flags; 3278f08c3bdfSopenharmony_ci idx = cast_to(idx, size_t_ctype); 3279f08c3bdfSopenharmony_ci idx->flags = old_idx_flags; 3280f08c3bdfSopenharmony_ci m = alloc_const_expression(expr->pos, 3281f08c3bdfSopenharmony_ci bits_to_bytes(ctype->bit_size)); 3282f08c3bdfSopenharmony_ci m->ctype = size_t_ctype; 3283f08c3bdfSopenharmony_ci m->flags = CEF_SET_INT; 3284f08c3bdfSopenharmony_ci expr->type = EXPR_BINOP; 3285f08c3bdfSopenharmony_ci expr->left = idx; 3286f08c3bdfSopenharmony_ci expr->right = m; 3287f08c3bdfSopenharmony_ci expr->op = '*'; 3288f08c3bdfSopenharmony_ci expr->ctype = size_t_ctype; 3289f08c3bdfSopenharmony_ci expr->flags = m->flags & idx->flags & ~CEF_CONST_MASK; 3290f08c3bdfSopenharmony_ci } 3291f08c3bdfSopenharmony_ci } 3292f08c3bdfSopenharmony_ci if (e) { 3293f08c3bdfSopenharmony_ci struct expression *copy = __alloc_expression(0); 3294f08c3bdfSopenharmony_ci *copy = *expr; 3295f08c3bdfSopenharmony_ci if (e->type == EXPR_OFFSETOF) 3296f08c3bdfSopenharmony_ci e->in = ctype; 3297f08c3bdfSopenharmony_ci if (!evaluate_expression(e)) 3298f08c3bdfSopenharmony_ci return NULL; 3299f08c3bdfSopenharmony_ci expr->type = EXPR_BINOP; 3300f08c3bdfSopenharmony_ci expr->flags = e->flags & copy->flags & ~CEF_CONST_MASK; 3301f08c3bdfSopenharmony_ci expr->op = '+'; 3302f08c3bdfSopenharmony_ci expr->ctype = size_t_ctype; 3303f08c3bdfSopenharmony_ci expr->left = copy; 3304f08c3bdfSopenharmony_ci expr->right = e; 3305f08c3bdfSopenharmony_ci } 3306f08c3bdfSopenharmony_ci return size_t_ctype; 3307f08c3bdfSopenharmony_ci} 3308f08c3bdfSopenharmony_ci 3309f08c3bdfSopenharmony_cistatic void check_label_declaration(struct position pos, struct symbol *label) 3310f08c3bdfSopenharmony_ci{ 3311f08c3bdfSopenharmony_ci switch (label->namespace) { 3312f08c3bdfSopenharmony_ci case NS_LABEL: 3313f08c3bdfSopenharmony_ci if (label->stmt) 3314f08c3bdfSopenharmony_ci break; 3315f08c3bdfSopenharmony_ci sparse_error(pos, "label '%s' was not declared", show_ident(label->ident)); 3316f08c3bdfSopenharmony_ci /* fallthrough */ 3317f08c3bdfSopenharmony_ci case NS_NONE: 3318f08c3bdfSopenharmony_ci current_fn->bogus_linear = 1; 3319f08c3bdfSopenharmony_ci default: 3320f08c3bdfSopenharmony_ci break; 3321f08c3bdfSopenharmony_ci } 3322f08c3bdfSopenharmony_ci} 3323f08c3bdfSopenharmony_ci 3324f08c3bdfSopenharmony_cistatic int type_selection(struct symbol *ctrl, struct symbol *type) 3325f08c3bdfSopenharmony_ci{ 3326f08c3bdfSopenharmony_ci struct ctype c = { .base_type = ctrl }; 3327f08c3bdfSopenharmony_ci struct ctype t = { .base_type = type }; 3328f08c3bdfSopenharmony_ci 3329f08c3bdfSopenharmony_ci return !type_difference(&c, &t, 0, 0); 3330f08c3bdfSopenharmony_ci} 3331f08c3bdfSopenharmony_ci 3332f08c3bdfSopenharmony_cistatic struct symbol *evaluate_generic_selection(struct expression *expr) 3333f08c3bdfSopenharmony_ci{ 3334f08c3bdfSopenharmony_ci struct type_expression *map; 3335f08c3bdfSopenharmony_ci struct expression *res; 3336f08c3bdfSopenharmony_ci struct symbol source; 3337f08c3bdfSopenharmony_ci struct symbol *ctrl; 3338f08c3bdfSopenharmony_ci 3339f08c3bdfSopenharmony_ci if (!evaluate_expression(expr->control)) 3340f08c3bdfSopenharmony_ci return NULL; 3341f08c3bdfSopenharmony_ci if (!(ctrl = degenerate(expr->control))) 3342f08c3bdfSopenharmony_ci return NULL; 3343f08c3bdfSopenharmony_ci 3344f08c3bdfSopenharmony_ci source = *ctrl; 3345f08c3bdfSopenharmony_ci source.ctype.modifiers &= ~(MOD_QUALIFIER|MOD_ATOMIC); 3346f08c3bdfSopenharmony_ci for (map = expr->map; map; map = map->next) { 3347f08c3bdfSopenharmony_ci struct symbol *stype = map->type; 3348f08c3bdfSopenharmony_ci struct symbol *base; 3349f08c3bdfSopenharmony_ci 3350f08c3bdfSopenharmony_ci if (!evaluate_symbol(stype)) 3351f08c3bdfSopenharmony_ci continue; 3352f08c3bdfSopenharmony_ci 3353f08c3bdfSopenharmony_ci base = stype->ctype.base_type; 3354f08c3bdfSopenharmony_ci if (base->type == SYM_ARRAY && base->array_size) { 3355f08c3bdfSopenharmony_ci get_expression_value_silent(base->array_size); 3356f08c3bdfSopenharmony_ci if (base->array_size->type == EXPR_VALUE) 3357f08c3bdfSopenharmony_ci continue; 3358f08c3bdfSopenharmony_ci sparse_error(stype->pos, "variable length array type in generic selection"); 3359f08c3bdfSopenharmony_ci continue; 3360f08c3bdfSopenharmony_ci } 3361f08c3bdfSopenharmony_ci if (is_func_type(stype)) { 3362f08c3bdfSopenharmony_ci sparse_error(stype->pos, "function type in generic selection"); 3363f08c3bdfSopenharmony_ci continue; 3364f08c3bdfSopenharmony_ci } 3365f08c3bdfSopenharmony_ci if (stype->bit_size <= 0 || is_void_type(stype)) { 3366f08c3bdfSopenharmony_ci sparse_error(stype->pos, "incomplete type in generic selection"); 3367f08c3bdfSopenharmony_ci continue; 3368f08c3bdfSopenharmony_ci } 3369f08c3bdfSopenharmony_ci if (!type_selection(&source, stype)) 3370f08c3bdfSopenharmony_ci continue; 3371f08c3bdfSopenharmony_ci 3372f08c3bdfSopenharmony_ci res = map->expr; 3373f08c3bdfSopenharmony_ci goto found; 3374f08c3bdfSopenharmony_ci } 3375f08c3bdfSopenharmony_ci res = expr->def; 3376f08c3bdfSopenharmony_ci if (!res) { 3377f08c3bdfSopenharmony_ci sparse_error(expr->pos, "no generic selection for '%s'", show_typename(ctrl)); 3378f08c3bdfSopenharmony_ci return NULL; 3379f08c3bdfSopenharmony_ci } 3380f08c3bdfSopenharmony_ci 3381f08c3bdfSopenharmony_cifound: 3382f08c3bdfSopenharmony_ci *expr = *res; 3383f08c3bdfSopenharmony_ci return evaluate_expression(expr); 3384f08c3bdfSopenharmony_ci} 3385f08c3bdfSopenharmony_ci 3386f08c3bdfSopenharmony_cistruct symbol *evaluate_expression(struct expression *expr) 3387f08c3bdfSopenharmony_ci{ 3388f08c3bdfSopenharmony_ci if (!expr) 3389f08c3bdfSopenharmony_ci return NULL; 3390f08c3bdfSopenharmony_ci if (expr->ctype) 3391f08c3bdfSopenharmony_ci return expr->ctype; 3392f08c3bdfSopenharmony_ci 3393f08c3bdfSopenharmony_ci switch (expr->type) { 3394f08c3bdfSopenharmony_ci case EXPR_VALUE: 3395f08c3bdfSopenharmony_ci case EXPR_FVALUE: 3396f08c3bdfSopenharmony_ci expression_error(expr, "value expression without a type"); 3397f08c3bdfSopenharmony_ci return NULL; 3398f08c3bdfSopenharmony_ci case EXPR_STRING: 3399f08c3bdfSopenharmony_ci return evaluate_string(expr); 3400f08c3bdfSopenharmony_ci case EXPR_SYMBOL: 3401f08c3bdfSopenharmony_ci return evaluate_symbol_expression(expr); 3402f08c3bdfSopenharmony_ci case EXPR_BINOP: 3403f08c3bdfSopenharmony_ci evaluate_expression(expr->left); 3404f08c3bdfSopenharmony_ci evaluate_expression(expr->right); 3405f08c3bdfSopenharmony_ci if (!valid_subexpr_type(expr)) 3406f08c3bdfSopenharmony_ci return NULL; 3407f08c3bdfSopenharmony_ci return evaluate_binop(expr); 3408f08c3bdfSopenharmony_ci case EXPR_LOGICAL: 3409f08c3bdfSopenharmony_ci return evaluate_logical(expr); 3410f08c3bdfSopenharmony_ci case EXPR_COMMA: 3411f08c3bdfSopenharmony_ci evaluate_expression(expr->left); 3412f08c3bdfSopenharmony_ci if (!evaluate_expression(expr->right)) 3413f08c3bdfSopenharmony_ci return NULL; 3414f08c3bdfSopenharmony_ci return evaluate_comma(expr); 3415f08c3bdfSopenharmony_ci case EXPR_COMPARE: 3416f08c3bdfSopenharmony_ci evaluate_expression(expr->left); 3417f08c3bdfSopenharmony_ci evaluate_expression(expr->right); 3418f08c3bdfSopenharmony_ci if (!valid_subexpr_type(expr)) 3419f08c3bdfSopenharmony_ci return NULL; 3420f08c3bdfSopenharmony_ci return evaluate_compare(expr); 3421f08c3bdfSopenharmony_ci case EXPR_ASSIGNMENT: 3422f08c3bdfSopenharmony_ci evaluate_expression(expr->left); 3423f08c3bdfSopenharmony_ci evaluate_expression(expr->right); 3424f08c3bdfSopenharmony_ci if (!valid_subexpr_type(expr)) 3425f08c3bdfSopenharmony_ci return NULL; 3426f08c3bdfSopenharmony_ci return evaluate_assignment(expr); 3427f08c3bdfSopenharmony_ci case EXPR_PREOP: 3428f08c3bdfSopenharmony_ci if (!evaluate_expression(expr->unop)) 3429f08c3bdfSopenharmony_ci return NULL; 3430f08c3bdfSopenharmony_ci return evaluate_preop(expr); 3431f08c3bdfSopenharmony_ci case EXPR_POSTOP: 3432f08c3bdfSopenharmony_ci if (!evaluate_expression(expr->unop)) 3433f08c3bdfSopenharmony_ci return NULL; 3434f08c3bdfSopenharmony_ci return evaluate_postop(expr); 3435f08c3bdfSopenharmony_ci case EXPR_CAST: 3436f08c3bdfSopenharmony_ci case EXPR_FORCE_CAST: 3437f08c3bdfSopenharmony_ci case EXPR_IMPLIED_CAST: 3438f08c3bdfSopenharmony_ci return evaluate_cast(expr); 3439f08c3bdfSopenharmony_ci case EXPR_SIZEOF: 3440f08c3bdfSopenharmony_ci return evaluate_sizeof(expr); 3441f08c3bdfSopenharmony_ci case EXPR_PTRSIZEOF: 3442f08c3bdfSopenharmony_ci return evaluate_ptrsizeof(expr); 3443f08c3bdfSopenharmony_ci case EXPR_ALIGNOF: 3444f08c3bdfSopenharmony_ci return evaluate_alignof(expr); 3445f08c3bdfSopenharmony_ci case EXPR_DEREF: 3446f08c3bdfSopenharmony_ci return evaluate_member_dereference(expr); 3447f08c3bdfSopenharmony_ci case EXPR_CALL: 3448f08c3bdfSopenharmony_ci return evaluate_call(expr); 3449f08c3bdfSopenharmony_ci case EXPR_SELECT: 3450f08c3bdfSopenharmony_ci case EXPR_CONDITIONAL: 3451f08c3bdfSopenharmony_ci return evaluate_conditional_expression(expr); 3452f08c3bdfSopenharmony_ci case EXPR_STATEMENT: 3453f08c3bdfSopenharmony_ci expr->ctype = evaluate_statement(expr->statement); 3454f08c3bdfSopenharmony_ci return expr->ctype; 3455f08c3bdfSopenharmony_ci 3456f08c3bdfSopenharmony_ci case EXPR_LABEL: 3457f08c3bdfSopenharmony_ci expr->ctype = &ptr_ctype; 3458f08c3bdfSopenharmony_ci check_label_declaration(expr->pos, expr->label_symbol); 3459f08c3bdfSopenharmony_ci return &ptr_ctype; 3460f08c3bdfSopenharmony_ci 3461f08c3bdfSopenharmony_ci case EXPR_TYPE: 3462f08c3bdfSopenharmony_ci /* Evaluate the type of the symbol .. */ 3463f08c3bdfSopenharmony_ci evaluate_symbol(expr->symbol); 3464f08c3bdfSopenharmony_ci /* .. but the type of the _expression_ is a "type" */ 3465f08c3bdfSopenharmony_ci expr->ctype = &type_ctype; 3466f08c3bdfSopenharmony_ci return &type_ctype; 3467f08c3bdfSopenharmony_ci 3468f08c3bdfSopenharmony_ci case EXPR_OFFSETOF: 3469f08c3bdfSopenharmony_ci return evaluate_offsetof(expr); 3470f08c3bdfSopenharmony_ci 3471f08c3bdfSopenharmony_ci case EXPR_GENERIC: 3472f08c3bdfSopenharmony_ci return evaluate_generic_selection(expr); 3473f08c3bdfSopenharmony_ci 3474f08c3bdfSopenharmony_ci /* These can not exist as stand-alone expressions */ 3475f08c3bdfSopenharmony_ci case EXPR_INITIALIZER: 3476f08c3bdfSopenharmony_ci case EXPR_IDENTIFIER: 3477f08c3bdfSopenharmony_ci case EXPR_INDEX: 3478f08c3bdfSopenharmony_ci case EXPR_POS: 3479f08c3bdfSopenharmony_ci expression_error(expr, "internal front-end error: initializer in expression"); 3480f08c3bdfSopenharmony_ci return NULL; 3481f08c3bdfSopenharmony_ci case EXPR_SLICE: 3482f08c3bdfSopenharmony_ci expression_error(expr, "internal front-end error: SLICE re-evaluated"); 3483f08c3bdfSopenharmony_ci return NULL; 3484f08c3bdfSopenharmony_ci } 3485f08c3bdfSopenharmony_ci return NULL; 3486f08c3bdfSopenharmony_ci} 3487f08c3bdfSopenharmony_ci 3488f08c3bdfSopenharmony_civoid check_duplicates(struct symbol *sym) 3489f08c3bdfSopenharmony_ci{ 3490f08c3bdfSopenharmony_ci int declared = 0; 3491f08c3bdfSopenharmony_ci struct symbol *next = sym; 3492f08c3bdfSopenharmony_ci int initialized = sym->initializer != NULL; 3493f08c3bdfSopenharmony_ci 3494f08c3bdfSopenharmony_ci while ((next = next->same_symbol) != NULL) { 3495f08c3bdfSopenharmony_ci const char *typediff; 3496f08c3bdfSopenharmony_ci evaluate_symbol(next); 3497f08c3bdfSopenharmony_ci if (initialized && next->initializer) { 3498f08c3bdfSopenharmony_ci sparse_error(sym->pos, "symbol '%s' has multiple initializers (originally initialized at %s:%d)", 3499f08c3bdfSopenharmony_ci show_ident(sym->ident), 3500f08c3bdfSopenharmony_ci stream_name(next->pos.stream), next->pos.line); 3501f08c3bdfSopenharmony_ci /* Only warn once */ 3502f08c3bdfSopenharmony_ci initialized = 0; 3503f08c3bdfSopenharmony_ci } 3504f08c3bdfSopenharmony_ci declared++; 3505f08c3bdfSopenharmony_ci typediff = type_difference(&sym->ctype, &next->ctype, 0, 0); 3506f08c3bdfSopenharmony_ci if (typediff) { 3507f08c3bdfSopenharmony_ci sparse_error(sym->pos, "symbol '%s' redeclared with different type (%s):", 3508f08c3bdfSopenharmony_ci show_ident(sym->ident), typediff); 3509f08c3bdfSopenharmony_ci info(sym->pos, " %s", show_typename(sym)); 3510f08c3bdfSopenharmony_ci info(next->pos, "note: previously declared as:"); 3511f08c3bdfSopenharmony_ci info(next->pos, " %s", show_typename(next)); 3512f08c3bdfSopenharmony_ci return; 3513f08c3bdfSopenharmony_ci } 3514f08c3bdfSopenharmony_ci } 3515f08c3bdfSopenharmony_ci if (!declared) { 3516f08c3bdfSopenharmony_ci unsigned long mod = sym->ctype.modifiers; 3517f08c3bdfSopenharmony_ci if (mod & (MOD_STATIC | MOD_REGISTER | MOD_EXT_VISIBLE)) 3518f08c3bdfSopenharmony_ci return; 3519f08c3bdfSopenharmony_ci if (!(mod & MOD_TOPLEVEL)) 3520f08c3bdfSopenharmony_ci return; 3521f08c3bdfSopenharmony_ci if (!Wdecl) 3522f08c3bdfSopenharmony_ci return; 3523f08c3bdfSopenharmony_ci if (sym->ident == &main_ident) 3524f08c3bdfSopenharmony_ci return; 3525f08c3bdfSopenharmony_ci warning(sym->pos, "symbol '%s' was not declared. Should it be static?", show_ident(sym->ident)); 3526f08c3bdfSopenharmony_ci } 3527f08c3bdfSopenharmony_ci} 3528f08c3bdfSopenharmony_ci 3529f08c3bdfSopenharmony_cistatic struct symbol *evaluate_symbol(struct symbol *sym) 3530f08c3bdfSopenharmony_ci{ 3531f08c3bdfSopenharmony_ci struct symbol *base_type; 3532f08c3bdfSopenharmony_ci 3533f08c3bdfSopenharmony_ci if (!sym) 3534f08c3bdfSopenharmony_ci return sym; 3535f08c3bdfSopenharmony_ci if (sym->evaluated) 3536f08c3bdfSopenharmony_ci return sym; 3537f08c3bdfSopenharmony_ci sym->evaluated = 1; 3538f08c3bdfSopenharmony_ci 3539f08c3bdfSopenharmony_ci sym = examine_symbol_type(sym); 3540f08c3bdfSopenharmony_ci base_type = get_base_type(sym); 3541f08c3bdfSopenharmony_ci if (!base_type) 3542f08c3bdfSopenharmony_ci return NULL; 3543f08c3bdfSopenharmony_ci 3544f08c3bdfSopenharmony_ci /* Evaluate the initializers */ 3545f08c3bdfSopenharmony_ci if (sym->initializer) 3546f08c3bdfSopenharmony_ci evaluate_initializer(sym, &sym->initializer); 3547f08c3bdfSopenharmony_ci 3548f08c3bdfSopenharmony_ci /* And finally, evaluate the body of the symbol too */ 3549f08c3bdfSopenharmony_ci if (base_type->type == SYM_FN) { 3550f08c3bdfSopenharmony_ci struct symbol *curr = current_fn; 3551f08c3bdfSopenharmony_ci 3552f08c3bdfSopenharmony_ci if (sym->definition && sym->definition != sym) 3553f08c3bdfSopenharmony_ci return evaluate_symbol(sym->definition); 3554f08c3bdfSopenharmony_ci 3555f08c3bdfSopenharmony_ci current_fn = sym; 3556f08c3bdfSopenharmony_ci 3557f08c3bdfSopenharmony_ci examine_fn_arguments(base_type); 3558f08c3bdfSopenharmony_ci if (!base_type->stmt && base_type->inline_stmt) 3559f08c3bdfSopenharmony_ci uninline(sym); 3560f08c3bdfSopenharmony_ci if (base_type->stmt) 3561f08c3bdfSopenharmony_ci evaluate_statement(base_type->stmt); 3562f08c3bdfSopenharmony_ci 3563f08c3bdfSopenharmony_ci current_fn = curr; 3564f08c3bdfSopenharmony_ci } 3565f08c3bdfSopenharmony_ci 3566f08c3bdfSopenharmony_ci return base_type; 3567f08c3bdfSopenharmony_ci} 3568f08c3bdfSopenharmony_ci 3569f08c3bdfSopenharmony_civoid evaluate_symbol_list(struct symbol_list *list) 3570f08c3bdfSopenharmony_ci{ 3571f08c3bdfSopenharmony_ci struct symbol *sym; 3572f08c3bdfSopenharmony_ci 3573f08c3bdfSopenharmony_ci FOR_EACH_PTR(list, sym) { 3574f08c3bdfSopenharmony_ci has_error &= ~ERROR_CURR_PHASE; 3575f08c3bdfSopenharmony_ci evaluate_symbol(sym); 3576f08c3bdfSopenharmony_ci check_duplicates(sym); 3577f08c3bdfSopenharmony_ci } END_FOR_EACH_PTR(sym); 3578f08c3bdfSopenharmony_ci} 3579f08c3bdfSopenharmony_ci 3580f08c3bdfSopenharmony_cistatic struct symbol *evaluate_return_expression(struct statement *stmt) 3581f08c3bdfSopenharmony_ci{ 3582f08c3bdfSopenharmony_ci struct expression *expr = stmt->expression; 3583f08c3bdfSopenharmony_ci struct symbol *fntype, *rettype; 3584f08c3bdfSopenharmony_ci 3585f08c3bdfSopenharmony_ci evaluate_expression(expr); 3586f08c3bdfSopenharmony_ci fntype = current_fn->ctype.base_type; 3587f08c3bdfSopenharmony_ci rettype = fntype->ctype.base_type; 3588f08c3bdfSopenharmony_ci if (!rettype || rettype == &void_ctype) { 3589f08c3bdfSopenharmony_ci if (expr && expr->ctype && !is_void_type(expr->ctype)) 3590f08c3bdfSopenharmony_ci expression_error(expr, "return expression in %s function", rettype?"void":"typeless"); 3591f08c3bdfSopenharmony_ci if (expr && Wreturn_void) 3592f08c3bdfSopenharmony_ci warning(stmt->pos, "returning void-valued expression"); 3593f08c3bdfSopenharmony_ci return NULL; 3594f08c3bdfSopenharmony_ci } 3595f08c3bdfSopenharmony_ci 3596f08c3bdfSopenharmony_ci if (!expr) { 3597f08c3bdfSopenharmony_ci sparse_error(stmt->pos, "return with no return value"); 3598f08c3bdfSopenharmony_ci return NULL; 3599f08c3bdfSopenharmony_ci } 3600f08c3bdfSopenharmony_ci if (!expr->ctype) 3601f08c3bdfSopenharmony_ci return NULL; 3602f08c3bdfSopenharmony_ci compatible_assignment_types(expr, rettype, &stmt->expression, "return expression"); 3603f08c3bdfSopenharmony_ci return NULL; 3604f08c3bdfSopenharmony_ci} 3605f08c3bdfSopenharmony_ci 3606f08c3bdfSopenharmony_cistatic void evaluate_if_statement(struct statement *stmt) 3607f08c3bdfSopenharmony_ci{ 3608f08c3bdfSopenharmony_ci if (!stmt->if_conditional) 3609f08c3bdfSopenharmony_ci return; 3610f08c3bdfSopenharmony_ci 3611f08c3bdfSopenharmony_ci evaluate_conditional(stmt->if_conditional, 0); 3612f08c3bdfSopenharmony_ci evaluate_statement(stmt->if_true); 3613f08c3bdfSopenharmony_ci evaluate_statement(stmt->if_false); 3614f08c3bdfSopenharmony_ci} 3615f08c3bdfSopenharmony_ci 3616f08c3bdfSopenharmony_cistatic void evaluate_iterator(struct statement *stmt) 3617f08c3bdfSopenharmony_ci{ 3618f08c3bdfSopenharmony_ci evaluate_symbol_list(stmt->iterator_syms); 3619f08c3bdfSopenharmony_ci evaluate_conditional(stmt->iterator_pre_condition, 1); 3620f08c3bdfSopenharmony_ci evaluate_conditional(stmt->iterator_post_condition,1); 3621f08c3bdfSopenharmony_ci evaluate_statement(stmt->iterator_pre_statement); 3622f08c3bdfSopenharmony_ci evaluate_statement(stmt->iterator_statement); 3623f08c3bdfSopenharmony_ci evaluate_statement(stmt->iterator_post_statement); 3624f08c3bdfSopenharmony_ci} 3625f08c3bdfSopenharmony_ci 3626f08c3bdfSopenharmony_ci 3627f08c3bdfSopenharmony_cistatic void parse_asm_constraint(struct asm_operand *op) 3628f08c3bdfSopenharmony_ci{ 3629f08c3bdfSopenharmony_ci struct expression *constraint = op->constraint; 3630f08c3bdfSopenharmony_ci const char *str = constraint->string->data; 3631f08c3bdfSopenharmony_ci int c; 3632f08c3bdfSopenharmony_ci 3633f08c3bdfSopenharmony_ci switch (str[0]) { 3634f08c3bdfSopenharmony_ci case '\0': 3635f08c3bdfSopenharmony_ci sparse_error(constraint->pos, "invalid ASM constraint (\"\")"); 3636f08c3bdfSopenharmony_ci break; 3637f08c3bdfSopenharmony_ci case '+': 3638f08c3bdfSopenharmony_ci op->is_modify = true; 3639f08c3bdfSopenharmony_ci /* fall-through */ 3640f08c3bdfSopenharmony_ci case '=': 3641f08c3bdfSopenharmony_ci op->is_assign = true; 3642f08c3bdfSopenharmony_ci str++; 3643f08c3bdfSopenharmony_ci break; 3644f08c3bdfSopenharmony_ci } 3645f08c3bdfSopenharmony_ci 3646f08c3bdfSopenharmony_ci while ((c = *str++)) { 3647f08c3bdfSopenharmony_ci switch (c) { 3648f08c3bdfSopenharmony_ci case '=': 3649f08c3bdfSopenharmony_ci case '+': 3650f08c3bdfSopenharmony_ci sparse_error(constraint->pos, "invalid ASM constraint '%c'", c); 3651f08c3bdfSopenharmony_ci break; 3652f08c3bdfSopenharmony_ci 3653f08c3bdfSopenharmony_ci case '&': 3654f08c3bdfSopenharmony_ci op->is_earlyclobber = true; 3655f08c3bdfSopenharmony_ci break; 3656f08c3bdfSopenharmony_ci case '%': 3657f08c3bdfSopenharmony_ci op->is_commutative = true; 3658f08c3bdfSopenharmony_ci break; 3659f08c3bdfSopenharmony_ci case 'r': 3660f08c3bdfSopenharmony_ci op->is_register = true; 3661f08c3bdfSopenharmony_ci break; 3662f08c3bdfSopenharmony_ci 3663f08c3bdfSopenharmony_ci case 'm': 3664f08c3bdfSopenharmony_ci case 'o': 3665f08c3bdfSopenharmony_ci case 'V': 3666f08c3bdfSopenharmony_ci case 'Q': 3667f08c3bdfSopenharmony_ci op->is_memory = true; 3668f08c3bdfSopenharmony_ci break; 3669f08c3bdfSopenharmony_ci 3670f08c3bdfSopenharmony_ci case '<': 3671f08c3bdfSopenharmony_ci case '>': 3672f08c3bdfSopenharmony_ci // FIXME: ignored for now 3673f08c3bdfSopenharmony_ci break; 3674f08c3bdfSopenharmony_ci 3675f08c3bdfSopenharmony_ci case ',': 3676f08c3bdfSopenharmony_ci // FIXME: multiple alternative constraints 3677f08c3bdfSopenharmony_ci break; 3678f08c3bdfSopenharmony_ci 3679f08c3bdfSopenharmony_ci case '0' ... '9': 3680f08c3bdfSopenharmony_ci // FIXME: numeric matching constraint? 3681f08c3bdfSopenharmony_ci break; 3682f08c3bdfSopenharmony_ci case '[': 3683f08c3bdfSopenharmony_ci // FIXME: symbolic matching constraint 3684f08c3bdfSopenharmony_ci return; 3685f08c3bdfSopenharmony_ci 3686f08c3bdfSopenharmony_ci default: 3687f08c3bdfSopenharmony_ci if (arch_target->asm_constraint) 3688f08c3bdfSopenharmony_ci str = arch_target->asm_constraint(op, c, str); 3689f08c3bdfSopenharmony_ci 3690f08c3bdfSopenharmony_ci // FIXME: multi-letter constraints 3691f08c3bdfSopenharmony_ci break; 3692f08c3bdfSopenharmony_ci } 3693f08c3bdfSopenharmony_ci } 3694f08c3bdfSopenharmony_ci 3695f08c3bdfSopenharmony_ci // FIXME: how to deal with multi-constraint? 3696f08c3bdfSopenharmony_ci if (op->is_register) 3697f08c3bdfSopenharmony_ci op->is_memory = 0; 3698f08c3bdfSopenharmony_ci} 3699f08c3bdfSopenharmony_ci 3700f08c3bdfSopenharmony_cistatic void verify_output_constraint(struct asm_operand *op) 3701f08c3bdfSopenharmony_ci{ 3702f08c3bdfSopenharmony_ci struct expression *expr = op->constraint; 3703f08c3bdfSopenharmony_ci const char *constraint = expr->string->data; 3704f08c3bdfSopenharmony_ci 3705f08c3bdfSopenharmony_ci if (!op->is_assign) 3706f08c3bdfSopenharmony_ci expression_error(expr, "output constraint is not an assignment constraint (\"%s\")", constraint); 3707f08c3bdfSopenharmony_ci} 3708f08c3bdfSopenharmony_ci 3709f08c3bdfSopenharmony_cistatic void verify_input_constraint(struct asm_operand *op) 3710f08c3bdfSopenharmony_ci{ 3711f08c3bdfSopenharmony_ci struct expression *expr = op->constraint; 3712f08c3bdfSopenharmony_ci const char *constraint = expr->string->data; 3713f08c3bdfSopenharmony_ci 3714f08c3bdfSopenharmony_ci if (op->is_assign) 3715f08c3bdfSopenharmony_ci expression_error(expr, "input constraint with assignment (\"%s\")", constraint); 3716f08c3bdfSopenharmony_ci} 3717f08c3bdfSopenharmony_ci 3718f08c3bdfSopenharmony_cistatic void evaluate_asm_memop(struct asm_operand *op) 3719f08c3bdfSopenharmony_ci{ 3720f08c3bdfSopenharmony_ci if (op->is_memory) { 3721f08c3bdfSopenharmony_ci struct expression *expr = op->expr; 3722f08c3bdfSopenharmony_ci struct expression *addr; 3723f08c3bdfSopenharmony_ci 3724f08c3bdfSopenharmony_ci // implicit addressof 3725f08c3bdfSopenharmony_ci addr = alloc_expression(expr->pos, EXPR_PREOP); 3726f08c3bdfSopenharmony_ci addr->op = '&'; 3727f08c3bdfSopenharmony_ci addr->unop = expr; 3728f08c3bdfSopenharmony_ci 3729f08c3bdfSopenharmony_ci evaluate_addressof(addr); 3730f08c3bdfSopenharmony_ci op->expr = addr; 3731f08c3bdfSopenharmony_ci } else { 3732f08c3bdfSopenharmony_ci evaluate_expression(op->expr); 3733f08c3bdfSopenharmony_ci degenerate(op->expr); 3734f08c3bdfSopenharmony_ci } 3735f08c3bdfSopenharmony_ci} 3736f08c3bdfSopenharmony_ci 3737f08c3bdfSopenharmony_cistatic void evaluate_asm_statement(struct statement *stmt) 3738f08c3bdfSopenharmony_ci{ 3739f08c3bdfSopenharmony_ci struct expression *expr; 3740f08c3bdfSopenharmony_ci struct asm_operand *op; 3741f08c3bdfSopenharmony_ci struct symbol *sym; 3742f08c3bdfSopenharmony_ci 3743f08c3bdfSopenharmony_ci if (!stmt->asm_string) 3744f08c3bdfSopenharmony_ci return; 3745f08c3bdfSopenharmony_ci 3746f08c3bdfSopenharmony_ci FOR_EACH_PTR(stmt->asm_outputs, op) { 3747f08c3bdfSopenharmony_ci /* Identifier */ 3748f08c3bdfSopenharmony_ci 3749f08c3bdfSopenharmony_ci /* Constraint */ 3750f08c3bdfSopenharmony_ci if (op->constraint) { 3751f08c3bdfSopenharmony_ci parse_asm_constraint(op); 3752f08c3bdfSopenharmony_ci verify_output_constraint(op); 3753f08c3bdfSopenharmony_ci } 3754f08c3bdfSopenharmony_ci 3755f08c3bdfSopenharmony_ci /* Expression */ 3756f08c3bdfSopenharmony_ci expr = op->expr; 3757f08c3bdfSopenharmony_ci if (!evaluate_expression(expr)) 3758f08c3bdfSopenharmony_ci return; 3759f08c3bdfSopenharmony_ci if (!lvalue_expression(expr)) 3760f08c3bdfSopenharmony_ci warning(expr->pos, "asm output is not an lvalue"); 3761f08c3bdfSopenharmony_ci evaluate_assign_to(expr, expr->ctype); 3762f08c3bdfSopenharmony_ci evaluate_asm_memop(op); 3763f08c3bdfSopenharmony_ci } END_FOR_EACH_PTR(op); 3764f08c3bdfSopenharmony_ci 3765f08c3bdfSopenharmony_ci FOR_EACH_PTR(stmt->asm_inputs, op) { 3766f08c3bdfSopenharmony_ci /* Identifier */ 3767f08c3bdfSopenharmony_ci 3768f08c3bdfSopenharmony_ci /* Constraint */ 3769f08c3bdfSopenharmony_ci if (op->constraint) { 3770f08c3bdfSopenharmony_ci parse_asm_constraint(op); 3771f08c3bdfSopenharmony_ci verify_input_constraint(op); 3772f08c3bdfSopenharmony_ci } 3773f08c3bdfSopenharmony_ci 3774f08c3bdfSopenharmony_ci /* Expression */ 3775f08c3bdfSopenharmony_ci if (!evaluate_expression(op->expr)) 3776f08c3bdfSopenharmony_ci return; 3777f08c3bdfSopenharmony_ci evaluate_asm_memop(op); 3778f08c3bdfSopenharmony_ci } END_FOR_EACH_PTR(op); 3779f08c3bdfSopenharmony_ci 3780f08c3bdfSopenharmony_ci FOR_EACH_PTR(stmt->asm_clobbers, expr) { 3781f08c3bdfSopenharmony_ci if (!expr) { 3782f08c3bdfSopenharmony_ci sparse_error(stmt->pos, "bad asm clobbers"); 3783f08c3bdfSopenharmony_ci return; 3784f08c3bdfSopenharmony_ci } 3785f08c3bdfSopenharmony_ci if (expr->type == EXPR_STRING) 3786f08c3bdfSopenharmony_ci continue; 3787f08c3bdfSopenharmony_ci expression_error(expr, "asm clobber is not a string"); 3788f08c3bdfSopenharmony_ci } END_FOR_EACH_PTR(expr); 3789f08c3bdfSopenharmony_ci 3790f08c3bdfSopenharmony_ci FOR_EACH_PTR(stmt->asm_labels, sym) { 3791f08c3bdfSopenharmony_ci if (!sym || sym->type != SYM_LABEL) { 3792f08c3bdfSopenharmony_ci sparse_error(stmt->pos, "bad asm label"); 3793f08c3bdfSopenharmony_ci return; 3794f08c3bdfSopenharmony_ci } 3795f08c3bdfSopenharmony_ci } END_FOR_EACH_PTR(sym); 3796f08c3bdfSopenharmony_ci} 3797f08c3bdfSopenharmony_ci 3798f08c3bdfSopenharmony_cistatic void evaluate_case_statement(struct statement *stmt) 3799f08c3bdfSopenharmony_ci{ 3800f08c3bdfSopenharmony_ci evaluate_expression(stmt->case_expression); 3801f08c3bdfSopenharmony_ci evaluate_expression(stmt->case_to); 3802f08c3bdfSopenharmony_ci evaluate_statement(stmt->case_statement); 3803f08c3bdfSopenharmony_ci} 3804f08c3bdfSopenharmony_ci 3805f08c3bdfSopenharmony_cistatic void check_case_type(struct expression *switch_expr, 3806f08c3bdfSopenharmony_ci struct expression *case_expr, 3807f08c3bdfSopenharmony_ci struct expression **enumcase) 3808f08c3bdfSopenharmony_ci{ 3809f08c3bdfSopenharmony_ci struct symbol *switch_type, *case_type; 3810f08c3bdfSopenharmony_ci int sclass, cclass; 3811f08c3bdfSopenharmony_ci 3812f08c3bdfSopenharmony_ci if (!case_expr) 3813f08c3bdfSopenharmony_ci return; 3814f08c3bdfSopenharmony_ci 3815f08c3bdfSopenharmony_ci switch_type = switch_expr->ctype; 3816f08c3bdfSopenharmony_ci case_type = evaluate_expression(case_expr); 3817f08c3bdfSopenharmony_ci 3818f08c3bdfSopenharmony_ci if (!switch_type || !case_type) 3819f08c3bdfSopenharmony_ci goto Bad; 3820f08c3bdfSopenharmony_ci if (enumcase) { 3821f08c3bdfSopenharmony_ci if (*enumcase) 3822f08c3bdfSopenharmony_ci warn_for_different_enum_types(case_expr->pos, case_type, (*enumcase)->ctype); 3823f08c3bdfSopenharmony_ci else if (is_enum_type(case_type)) 3824f08c3bdfSopenharmony_ci *enumcase = case_expr; 3825f08c3bdfSopenharmony_ci } 3826f08c3bdfSopenharmony_ci 3827f08c3bdfSopenharmony_ci sclass = classify_type(switch_type, &switch_type); 3828f08c3bdfSopenharmony_ci cclass = classify_type(case_type, &case_type); 3829f08c3bdfSopenharmony_ci 3830f08c3bdfSopenharmony_ci /* both should be arithmetic */ 3831f08c3bdfSopenharmony_ci if (!(sclass & cclass & TYPE_NUM)) 3832f08c3bdfSopenharmony_ci goto Bad; 3833f08c3bdfSopenharmony_ci 3834f08c3bdfSopenharmony_ci /* neither should be floating */ 3835f08c3bdfSopenharmony_ci if ((sclass | cclass) & TYPE_FLOAT) 3836f08c3bdfSopenharmony_ci goto Bad; 3837f08c3bdfSopenharmony_ci 3838f08c3bdfSopenharmony_ci /* if neither is restricted, we are OK */ 3839f08c3bdfSopenharmony_ci if (!((sclass | cclass) & TYPE_RESTRICT)) 3840f08c3bdfSopenharmony_ci return; 3841f08c3bdfSopenharmony_ci 3842f08c3bdfSopenharmony_ci if (!restricted_binop_type(SPECIAL_EQUAL, case_expr, switch_expr, 3843f08c3bdfSopenharmony_ci cclass, sclass, case_type, switch_type)) { 3844f08c3bdfSopenharmony_ci unrestrict(case_expr, cclass, &case_type); 3845f08c3bdfSopenharmony_ci unrestrict(switch_expr, sclass, &switch_type); 3846f08c3bdfSopenharmony_ci } 3847f08c3bdfSopenharmony_ci return; 3848f08c3bdfSopenharmony_ci 3849f08c3bdfSopenharmony_ciBad: 3850f08c3bdfSopenharmony_ci expression_error(case_expr, "incompatible types for 'case' statement"); 3851f08c3bdfSopenharmony_ci} 3852f08c3bdfSopenharmony_ci 3853f08c3bdfSopenharmony_cistatic void evaluate_switch_statement(struct statement *stmt) 3854f08c3bdfSopenharmony_ci{ 3855f08c3bdfSopenharmony_ci struct symbol *sym; 3856f08c3bdfSopenharmony_ci struct expression *enumcase = NULL; 3857f08c3bdfSopenharmony_ci struct expression **enumcase_holder = &enumcase; 3858f08c3bdfSopenharmony_ci struct expression *sel = stmt->switch_expression; 3859f08c3bdfSopenharmony_ci 3860f08c3bdfSopenharmony_ci evaluate_expression(sel); 3861f08c3bdfSopenharmony_ci evaluate_statement(stmt->switch_statement); 3862f08c3bdfSopenharmony_ci if (!sel) 3863f08c3bdfSopenharmony_ci return; 3864f08c3bdfSopenharmony_ci if (sel->ctype && is_enum_type(sel->ctype)) 3865f08c3bdfSopenharmony_ci enumcase_holder = NULL; /* Only check cases against switch */ 3866f08c3bdfSopenharmony_ci 3867f08c3bdfSopenharmony_ci FOR_EACH_PTR(stmt->switch_case->symbol_list, sym) { 3868f08c3bdfSopenharmony_ci struct statement *case_stmt = sym->stmt; 3869f08c3bdfSopenharmony_ci check_case_type(sel, case_stmt->case_expression, enumcase_holder); 3870f08c3bdfSopenharmony_ci check_case_type(sel, case_stmt->case_to, enumcase_holder); 3871f08c3bdfSopenharmony_ci } END_FOR_EACH_PTR(sym); 3872f08c3bdfSopenharmony_ci} 3873f08c3bdfSopenharmony_ci 3874f08c3bdfSopenharmony_cistatic void evaluate_goto_statement(struct statement *stmt) 3875f08c3bdfSopenharmony_ci{ 3876f08c3bdfSopenharmony_ci struct symbol *label = stmt->goto_label; 3877f08c3bdfSopenharmony_ci 3878f08c3bdfSopenharmony_ci if (!label) { 3879f08c3bdfSopenharmony_ci // no label associated, may be a computed goto 3880f08c3bdfSopenharmony_ci evaluate_expression(stmt->goto_expression); 3881f08c3bdfSopenharmony_ci return; 3882f08c3bdfSopenharmony_ci } 3883f08c3bdfSopenharmony_ci 3884f08c3bdfSopenharmony_ci check_label_declaration(stmt->pos, label); 3885f08c3bdfSopenharmony_ci} 3886f08c3bdfSopenharmony_ci 3887f08c3bdfSopenharmony_cistruct symbol *evaluate_statement(struct statement *stmt) 3888f08c3bdfSopenharmony_ci{ 3889f08c3bdfSopenharmony_ci if (!stmt) 3890f08c3bdfSopenharmony_ci return NULL; 3891f08c3bdfSopenharmony_ci 3892f08c3bdfSopenharmony_ci switch (stmt->type) { 3893f08c3bdfSopenharmony_ci case STMT_DECLARATION: { 3894f08c3bdfSopenharmony_ci struct symbol *s; 3895f08c3bdfSopenharmony_ci FOR_EACH_PTR(stmt->declaration, s) { 3896f08c3bdfSopenharmony_ci evaluate_symbol(s); 3897f08c3bdfSopenharmony_ci } END_FOR_EACH_PTR(s); 3898f08c3bdfSopenharmony_ci return NULL; 3899f08c3bdfSopenharmony_ci } 3900f08c3bdfSopenharmony_ci 3901f08c3bdfSopenharmony_ci case STMT_RETURN: 3902f08c3bdfSopenharmony_ci return evaluate_return_expression(stmt); 3903f08c3bdfSopenharmony_ci 3904f08c3bdfSopenharmony_ci case STMT_EXPRESSION: 3905f08c3bdfSopenharmony_ci if (!evaluate_expression(stmt->expression)) 3906f08c3bdfSopenharmony_ci return NULL; 3907f08c3bdfSopenharmony_ci if (stmt->expression->ctype == &null_ctype) 3908f08c3bdfSopenharmony_ci stmt->expression = cast_to(stmt->expression, &ptr_ctype); 3909f08c3bdfSopenharmony_ci return unqualify_type(degenerate(stmt->expression)); 3910f08c3bdfSopenharmony_ci 3911f08c3bdfSopenharmony_ci case STMT_COMPOUND: { 3912f08c3bdfSopenharmony_ci struct statement *s; 3913f08c3bdfSopenharmony_ci struct symbol *type = NULL; 3914f08c3bdfSopenharmony_ci 3915f08c3bdfSopenharmony_ci /* Evaluate the return symbol in the compound statement */ 3916f08c3bdfSopenharmony_ci evaluate_symbol(stmt->ret); 3917f08c3bdfSopenharmony_ci 3918f08c3bdfSopenharmony_ci /* 3919f08c3bdfSopenharmony_ci * Then, evaluate each statement, making the type of the 3920f08c3bdfSopenharmony_ci * compound statement be the type of the last statement 3921f08c3bdfSopenharmony_ci */ 3922f08c3bdfSopenharmony_ci type = evaluate_statement(stmt->args); 3923f08c3bdfSopenharmony_ci FOR_EACH_PTR(stmt->stmts, s) { 3924f08c3bdfSopenharmony_ci type = evaluate_statement(s); 3925f08c3bdfSopenharmony_ci } END_FOR_EACH_PTR(s); 3926f08c3bdfSopenharmony_ci if (!type) 3927f08c3bdfSopenharmony_ci type = &void_ctype; 3928f08c3bdfSopenharmony_ci return type; 3929f08c3bdfSopenharmony_ci } 3930f08c3bdfSopenharmony_ci case STMT_IF: 3931f08c3bdfSopenharmony_ci evaluate_if_statement(stmt); 3932f08c3bdfSopenharmony_ci return NULL; 3933f08c3bdfSopenharmony_ci case STMT_ITERATOR: 3934f08c3bdfSopenharmony_ci evaluate_iterator(stmt); 3935f08c3bdfSopenharmony_ci return NULL; 3936f08c3bdfSopenharmony_ci case STMT_SWITCH: 3937f08c3bdfSopenharmony_ci evaluate_switch_statement(stmt); 3938f08c3bdfSopenharmony_ci return NULL; 3939f08c3bdfSopenharmony_ci case STMT_CASE: 3940f08c3bdfSopenharmony_ci evaluate_case_statement(stmt); 3941f08c3bdfSopenharmony_ci return NULL; 3942f08c3bdfSopenharmony_ci case STMT_LABEL: 3943f08c3bdfSopenharmony_ci return evaluate_statement(stmt->label_statement); 3944f08c3bdfSopenharmony_ci case STMT_GOTO: 3945f08c3bdfSopenharmony_ci evaluate_goto_statement(stmt); 3946f08c3bdfSopenharmony_ci return NULL; 3947f08c3bdfSopenharmony_ci case STMT_NONE: 3948f08c3bdfSopenharmony_ci break; 3949f08c3bdfSopenharmony_ci case STMT_ASM: 3950f08c3bdfSopenharmony_ci evaluate_asm_statement(stmt); 3951f08c3bdfSopenharmony_ci return NULL; 3952f08c3bdfSopenharmony_ci case STMT_CONTEXT: 3953f08c3bdfSopenharmony_ci evaluate_expression(stmt->expression); 3954f08c3bdfSopenharmony_ci return NULL; 3955f08c3bdfSopenharmony_ci case STMT_RANGE: 3956f08c3bdfSopenharmony_ci evaluate_expression(stmt->range_expression); 3957f08c3bdfSopenharmony_ci evaluate_expression(stmt->range_low); 3958f08c3bdfSopenharmony_ci evaluate_expression(stmt->range_high); 3959f08c3bdfSopenharmony_ci return NULL; 3960f08c3bdfSopenharmony_ci } 3961f08c3bdfSopenharmony_ci return NULL; 3962f08c3bdfSopenharmony_ci} 3963