PR 33229 nds32 gas segfaults on gcc output

Commit 1ac26e9f7a replaced ISSPACE with is_whitespace, but the
former returns true on EOL while the latter does not.  Sprinkle
is_end_of_stmt tests to fix this bug.

The same segfault can be triggered by a ".relax_hint" with no
following instructions.  Fix that too.

	* config/tc-nds32.c (nds32_lookup_pseudo_opcode): Use
	is_end_of_stmt along with is_whitespace.
	(nds32_relax_relocs, nds32_relax_hint, nds32_flag),
	(ict_model: Likewise.
	(nds32_elf_append_relax_relocs): Return on no opcode.
	* testsuite/gas/nds32/nds32.exp: Find .d files automatically.
	* testsuite/gas/nds32/pr33229.d,
	* testsuite/gas/nds32/pr33229.s: New test.

(cherry picked from commit 303045d953)
This commit is contained in:
Alan Modra
2025-07-30 08:18:19 +09:30
parent 8ed80d4abd
commit 72d7cfff26
4 changed files with 25 additions and 19 deletions

View File

@@ -3452,8 +3452,9 @@ nds32_lookup_pseudo_opcode (const char *str)
for (i = 0; i < maxlen; i++)
{
if (is_whitespace (op[i] = str[i]))
if (is_end_of_stmt (str[i]) || is_whitespace (str[i]))
break;
op[i] = str[i];
}
op[i] = '\0';
@@ -4093,7 +4094,8 @@ nds32_relax_relocs (int relax)
{"", "",};
name = input_line_pointer;
while (*input_line_pointer && !is_whitespace (*input_line_pointer))
while (!is_end_of_stmt (*input_line_pointer)
&& !is_whitespace (*input_line_pointer))
input_line_pointer++;
saved_char = *input_line_pointer;
*input_line_pointer = 0;
@@ -4228,7 +4230,8 @@ nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
struct relax_hint_id *record_id;
name = input_line_pointer;
while (*input_line_pointer && !is_whitespace (*input_line_pointer))
while (!is_end_of_stmt (*input_line_pointer)
&& !is_whitespace (*input_line_pointer))
input_line_pointer++;
saved_char = *input_line_pointer;
*input_line_pointer = 0;
@@ -4361,7 +4364,8 @@ nds32_flag (int ignore ATTRIBUTE_UNUSED)
/* Skip whitespaces. */
name = input_line_pointer;
while (*input_line_pointer && !is_whitespace (*input_line_pointer))
while (!is_end_of_stmt (*input_line_pointer)
&& !is_whitespace (*input_line_pointer))
input_line_pointer++;
saved_char = *input_line_pointer;
*input_line_pointer = 0;
@@ -4398,7 +4402,8 @@ ict_model (int ignore ATTRIBUTE_UNUSED)
/* Skip whitespaces. */
name = input_line_pointer;
while (*input_line_pointer && !is_whitespace (*input_line_pointer))
while (!is_end_of_stmt (*input_line_pointer)
&& !is_whitespace (*input_line_pointer))
input_line_pointer++;
saved_char = *input_line_pointer;
*input_line_pointer = 0;
@@ -5944,7 +5949,7 @@ nds32_elf_append_relax_relocs (const char *key, const void *value)
char *where;
int pcrel;
if (!relocs_pattern)
if (!relocs_pattern || !relocs_pattern->opcode)
return;
if (!nds32_find_reloc_table (relocs_pattern, &hint_info))

View File

@@ -16,17 +16,13 @@
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
# MA 02110-1301, USA.
if { [istarget nds32*] } {
run_dump_test "alu-1"
run_dump_test "alu-2"
run_dump_test "lsi"
run_dump_test "ls"
run_dump_test "br-1"
run_dump_test "br-2"
run_dump_test "ji-jr"
run_dump_test "to-16bit-v1"
run_dump_test "to-16bit-v2"
run_dump_test "to-16bit-v3"
run_dump_test "usr-spe-reg"
run_dump_test "sys-reg"
if { ![istarget nds32*] } {
return
}
set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
foreach t $test_list {
# We need to strip the ".d", but can leave the dirname.
verbose [file rootname $t]
run_dump_test [file rootname $t]
}

View File

@@ -0,0 +1,2 @@
#as: --fatal-warnings
#error: .*relax hint.*

View File

@@ -0,0 +1,3 @@
.relax_hint 0
ret5
.relax_hint 1