http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57310

            Bug ID: 57310
           Summary: [4.7/4.8/4.9 Regression] segfault with -O2 or higher
                    on x86_64-linux-gnu
           Product: gcc
           Version: 4.7.4
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: doko at gcc dot gnu.org

seen with 4.7, 4.8 and trunk on x86_64-linux-gnu, works on i585-linux-gnu, and
arm-linux-gnueabi*, works with 4.6. seen with both libffi 3.0.10 and 3.0.13.

$ gcc-4.8 -O2 ffi-test.c -lffi && ./a.out 
Segmentation fault
$ gcc-4.8 -O1 ffi-test.c -lffi && ./a.out 
(ok)
$ gcc-4.8 -O2 -fno-align-functions -fno-align-jumps -fno-align-labels
-fno-align-loops -fno-caller-saves -fno-crossjumping -fno-cse-follow-jumps
-fno-devirtualize -fno-expensive-optimizations -fno-gcse
-fno-hoist-adjacent-loads -fno-inline-small-functions -fno-ipa-cp -fno-ipa-sra
-fno-optimize-register-move -fno-optimize-sibling-calls -fno-optimize-strlen
-fno-peephole2 -fno-regmove -fno-reorder-blocks -fno-reorder-functions
-fno-rerun-cse-after-loop -fno-schedule-insns2 -fno-strict-aliasing
-fno-thread-jumps -fno-tree-builtin-call-dce -fno-tree-pre
-fno-tree-switch-conversion -fno-tree-tail-merge -fno-tree-vrp ffi-test.c -lffi
&& ./a.out 
Segmentation fault
$ gcc-4.8 -m32 -O2 ffi-test.c -lffi && ./a.out
(ok)

#include <ffi.h>

extern void abort (void);

int myfn(const char *s)
{
  return __builtin_strlen(s);
}

int main()
{
  ffi_cif cif;
  ffi_type *args[1];
  void *values[1];
  char *s;
  int rc;

  /* Initialize the argument info vectors */
  args[0] = &ffi_type_pointer;
  values[0] = &s;

  /* Initialize the cif */
  if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_sint, args) == FFI_OK)
    {
      s = "Hello World!";
      ffi_call(&cif, FFI_FN(myfn), &rc, values);
      /* rc now holds the result of the call to puts */
      if (rc != 12)
    abort();

      /* values holds a pointer to the function's arg, so to
     call puts() again all we need to do is change the
     value of s */
      s = "This is cool!";
      ffi_call(&cif, FFI_FN(myfn), &rc, values);
      if (rc != 13)
    abort();
    }

  return 0;
}

Reply via email to