https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83251
Bug ID: 83251 Summary: __builtin___bnd_narrow_ptr_bounds(x, x, ...) generates wrong code that modifies a constant Product: gcc Version: 7.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: eggert at gnu dot org Target Milestone: --- Created attachment 42773 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42773&action=edit Test case main program (you also need foobody.i) I ran into this problem trying to use -fcheck-pointer-bounds on GNU Emacs. I used gcc (Ubuntu 7.2.0-8ubuntu3) 7.2.0 on x86-64 (Ubuntu 17.10); my CPU was a Kaby Lake processor (Intel Core i3-7100U) that supports Intel MPX. To reproduce, compile and run the attached source code as follows: gcc -mmpx -fcheck-pointer-bounds -O2 -S foobody.i foomain.i gcc -mmpx -fcheck-pointer-bounds -O2 foobody.s foomain.s ./a.out a.out's output contains many incorrect lines like this: Saw a #BR! status 1 at 0x55fae4af26da The problem occurs because incorrect code is generated for the function 'calculate_address', whose source code looks like this: Lisp_Object *sym = &lispsym[1213]; char *narsym = __builtin___bnd_narrow_ptr_bounds (sym, sym, sizeof (Lisp_Object)); return (Lisp_Object) (narsym + sizeof *sym); This is a pure function that merely calculates an address and returns it. Instead, as foobody.s shows, this function's implementation also modifies global metadata, for example: movq 8+__chkp_bounds_of_lispsym(%rip), %rax cmpq %rdx, %rax cmovb %rdx, %rax movq %rax, 8+__chkp_bounds_of_lispsym(%rip) Here calculate_address's implementation conditionally shrinks __chkp_bounds_of_lispsym, the bounds of the 'lispsym' array. But lispsym is a static array and its bounds should never change. As a result of this mistaken implementation, later valid attempts to access the lispsym array (in 'obviously_safe') fail their bounds check and this mistake in GCC causes the program to crash even though it is a valid program.