On x86, PIC_OFFSET_TABLE_REGNUM calls a function
(ix86_use_pseudo_pic_reg) so its value can theoretically change between
its first and second use in the following conditional:
if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
&& fixed_regs[PIC_OFFSET_TABLE_REGNUM])
Since the macro can return -1 on x86, the second use can cause an out of
bounds access.
In practice ix86_use_pseudo_pic_reg() is probably a pure function, since
we really shouldn't be changing the semantics of the pic register
mid-flight, but it's probably safer to just avoid calling the function
twice.
OK pending tests?
+ * builtins.c (expand_builtin_nonlocal_goto): Avoid evaluating
+ PIC_OFFSET_TABLE_REGNUM twice.
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 058ecc3..d4f7e94 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -1101,8 +1101,8 @@ expand_builtin_nonlocal_goto (tree exp)
to targets with a nonlocal_goto pattern; they are free
to implement it in their own way. Note also that this is
a no-op if the GP register is a global invariant.) */
- if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
- && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
+ unsigned regnum = PIC_OFFSET_TABLE_REGNUM;
+ if (regnum != INVALID_REGNUM && fixed_regs[regnum])
emit_use (pic_offset_table_rtx);
emit_indirect_jump (r_label);