diff options
author | Xi Ruoyao <xry111@xry111.site> | 2024-02-02 08:51:08 +0800 |
---|---|---|
committer | Xi Ruoyao <xry111@xry111.site> | 2024-02-04 22:57:46 +0800 |
commit | 829b26328aebca167083f4cf81ca69f7d906e704 (patch) | |
tree | 73f4af19d0d93c7a2e4260bf79f6171e1dc15f62 /gcc/config/loongarch | |
parent | 8e6ebacc9e3cee0d2053fdaceda0ae052e34b777 (diff) | |
download | gcc-829b26328aebca167083f4cf81ca69f7d906e704.zip gcc-829b26328aebca167083f4cf81ca69f7d906e704.tar.gz gcc-829b26328aebca167083f4cf81ca69f7d906e704.tar.bz2 |
LoongArch: Avoid out-of-bounds access in loongarch_symbol_insns
We call loongarch_symbol_insns with mode = MAX_MACHINE_MODE sometimes.
But in loongarch_symbol_insns:
if (LSX_SUPPORTED_MODE_P (mode) || LASX_SUPPORTED_MODE_P (mode))
return 0;
And LSX_SUPPORTED_MODE_P is defined as:
#define LSX_SUPPORTED_MODE_P(MODE) \
(ISA_HAS_LSX \
&& GET_MODE_SIZE (MODE) == UNITS_PER_LSX_REG ... ...
GET_MODE_SIZE is expanded to a call to mode_to_bytes, which is defined:
ALWAYS_INLINE poly_uint16
mode_to_bytes (machine_mode mode)
{
#if GCC_VERSION >= 4001
return (__builtin_constant_p (mode)
? mode_size_inline (mode) : mode_size[mode]);
#else
return mode_size[mode];
#endif
}
There is an assertion in mode_size_inline:
gcc_assert (mode >= 0 && mode < NUM_MACHINE_MODES);
Note that NUM_MACHINE_MODES = MAX_MACHINE_MODE (emitted by genmodes.cc),
thus if __builtin_constant_p (mode) is evaluated true (it happens when
GCC is bootstrapped with LTO+PGO), the assertion will be triggered and
cause an ICE. OTOH if __builtin_constant_p (mode) is evaluated false,
mode_size[mode] is still an out-of-bound array access (the length or the
mode_size array is NUM_MACHINE_MODES).
So we shouldn't call LSX_SUPPORTED_MODE_P or LASX_SUPPORTED_MODE_P with
MAX_MACHINE_MODE in loongarch_symbol_insns. This is very similar to a
MIPS bug PR98491 fixed by me about 3 years ago.
gcc/ChangeLog:
* config/loongarch/loongarch.cc (loongarch_symbol_insns): Do not
use LSX_SUPPORTED_MODE_P or LASX_SUPPORTED_MODE_P if mode is
MAX_MACHINE_MODE.
Diffstat (limited to 'gcc/config/loongarch')
-rw-r--r-- | gcc/config/loongarch/loongarch.cc | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index 6172384..0428b6e 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -2007,7 +2007,8 @@ loongarch_symbol_insns (enum loongarch_symbol_type type, machine_mode mode) { /* LSX LD.* and ST.* cannot support loading symbols via an immediate operand. */ - if (LSX_SUPPORTED_MODE_P (mode) || LASX_SUPPORTED_MODE_P (mode)) + if (mode != MAX_MACHINE_MODE + && (LSX_SUPPORTED_MODE_P (mode) || LASX_SUPPORTED_MODE_P (mode))) return 0; switch (type) |