From c61b7b7b8ea5e3a55b4642dade4798e5c896df66 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 28 Mar 2023 20:25:26 +1030 Subject: [PATCH] Avoid undefined behaviour in m68hc11 md_begin Given p = A where p is a pointer to some type and A is an array of that type, then the expression p - 1 + 1 evokes undefined behaviour according to the C standard. gcc-13 -fsanitize=address,undefined complains about this, but not where the undefined behaviour actually occurs at tc-m68hc11.c:646. Instead you get an error: "tc-m68hc11.c:708:20: runtime error: store to address 0x62600000016c with insufficient space for an object of type 'int'". Which is a lie. There most definitely is space there. Oh well, diagnostics are sometimes hard to get right. The UB is easy to avoid. PR 30279 * config/tc-m68hc11.c (md_begin): Avoid undefined pointer decrement. Remove unnecessary cast. --- gas/config/tc-m68hc11.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/gas/config/tc-m68hc11.c b/gas/config/tc-m68hc11.c index 7438e0dd51d..270ddf999ce 100644 --- a/gas/config/tc-m68hc11.c +++ b/gas/config/tc-m68hc11.c @@ -643,7 +643,7 @@ md_begin (void) (int (*) (const void*, const void*)) cmp_opcode); opc = XNEWVEC (struct m68hc11_opcode_def, num_opcodes); - m68hc11_opcode_defs = opc--; + m68hc11_opcode_defs = opc; /* Insert unique names into hash table. The M6811 instruction set has several identical opcode names that have different opcodes based @@ -655,19 +655,18 @@ md_begin (void) if (strcmp (prev_name, opcodes->name)) { - prev_name = (char *) opcodes->name; - + prev_name = opcodes->name; opc++; - opc->format = 0; - opc->min_operands = 100; - opc->max_operands = 0; - opc->nb_modes = 0; - opc->opcode = opcodes; - opc->used = 0; - str_hash_insert (m68hc11_hash, opcodes->name, opc, 0); + (opc - 1)->format = 0; + (opc - 1)->min_operands = 100; + (opc - 1)->max_operands = 0; + (opc - 1)->nb_modes = 0; + (opc - 1)->opcode = opcodes; + (opc - 1)->used = 0; + str_hash_insert (m68hc11_hash, opcodes->name, opc - 1, 0); } - opc->nb_modes++; - opc->format |= opcodes->format; + (opc - 1)->nb_modes++; + (opc - 1)->format |= opcodes->format; /* See how many operands this opcode needs. */ expect = 0; @@ -700,14 +699,13 @@ md_begin (void) expect++; } - if (expect < opc->min_operands) - opc->min_operands = expect; + if (expect < (opc - 1)->min_operands) + (opc - 1)->min_operands = expect; if (IS_CALL_SYMBOL (opcodes->format)) expect++; - if (expect > opc->max_operands) - opc->max_operands = expect; + if (expect > (opc - 1)->max_operands) + (opc - 1)->max_operands = expect; } - opc++; m68hc11_nb_opcode_defs = opc - m68hc11_opcode_defs; if (flag_print_opcodes) -- 2.30.2