avoid double evaluation of PIC_OFFSET_TABLE_REGNUM
diff mbox

Message ID 56F3C222.4010901@redhat.com
State New
Headers show

Commit Message

Aldy Hernandez March 24, 2016, 10:32 a.m. UTC
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.

Comments

Bernd Schmidt March 24, 2016, 1:22 p.m. UTC | #1
On 03/24/2016 11:32 AM, Aldy Hernandez wrote:
> 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?

Ok for stage 1.


Bernd

Patch
diff mbox

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);