[Bug tree-optimization/93156] abused nonnull attribute evokes new segfault in gcc 10 since Nov 4 commit, 0fb958ab8aa

bruno at clisp dot org gcc-bugzilla@gcc.gnu.org
Sun Jan 5 20:44:00 GMT 2020


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93156

--- Comment #8 from Bruno Haible <bruno at clisp dot org> ---
(In reply to Andrew Pinski from comment #6)
> a?-1:0 is transformed into -1 before we figure out that a is always true; an
> ordering difference.

Fortunately the GCC optimization affects only the return value of null_ptr().
It does not cause side effects to occur that shouldn't occur.

Test case:
=========================================================================
extern char *canonicalize_file_name (const char *__name)
  __attribute__ ((__nonnull__ (1)));
extern int rand (void);
extern void brick_the_hard_disk (void);

/* Return NULL.  */
static void *
null_ptr (void)
{
  unsigned int x = rand ();
  unsigned int y = x * x;
  /* The following statement is equivalent to if (false),
     since a square is always congruent to 0 or 1 mod 4.  */
  if (y & 2) {
    brick_the_hard_disk ();
    return (void *) -1;
  } else
    return (void *) 0;
}

int
main (void)
{
  return !!canonicalize_file_name (null_ptr ());
}
=========================================================================

Compiled with gcc -O6 -S foo.c from a recent GCC 10 snapshot:

=========================================================================
        .file   "foo.c"
        .text
        .section        .text.startup,"ax",@progbits
        .p2align 4
        .globl  main
        .type   main, @function
main:
.LFB1:
        .cfi_startproc
        subq    $8, %rsp
        .cfi_def_cfa_offset 16
        call    rand
        imull   %eax, %eax
        testb   $2, %al
        je      .L2
        call    brick_the_hard_disk
.L2:
        movq    $-1, %rdi
        call    canonicalize_file_name
        testq   %rax, %rax
        setne   %al
        addq    $8, %rsp
        .cfi_def_cfa_offset 8
        movzbl  %al, %eax
        ret
        .cfi_endproc
.LFE1:
        .size   main, .-main
        .ident  "GCC: (GNU) 10.0.0 20191229 (experimental)"
        .section        .note.GNU-stack,"",@progbits
=========================================================================

As you can see, it still performs the (y & 2) and will thus never execute
brick_the_hard_disk().


More information about the Gcc-bugs mailing list