Ticket #11395: 0001-Extend-gcc-on-m68k-to-allow-calling-incorrectly-decl.patch

File 0001-Extend-gcc-on-m68k-to-allow-calling-incorrectly-decl.patch, 4.3 KB (added by mkarcher, 22 months ago)

Patch for gcc to support the non-standard construct used by ghc on m68k.

  • gcc/config/m68k/m68k.c

    From 50c0af571f829e54cb3274c05d7be3da41114162 Mon Sep 17 00:00:00 2001
    From: Michael Karcher <debian@mkarcher.dialup.fu-berlin.de>
    Date: Mon, 25 Jan 2016 22:07:37 +0100
    Subject: [PATCH 1/1] Extend gcc on m68k to allow calling incorrectly declared
     externals through a function pointer of the correct type.
    
    There are users of gcc (one of them is ghc) that expect to be able to declare
    external functions with a dummy type (ghc currently uses
    "ptr-to-function fn();") and call them through a function pointer of the
    actual type of this function. I reported a ticket on ghc[1] which was
    forwarded as PR c/69221 and subsequently closed as INVALID. While I agree
    that the use case is way off the standard, and gcc emits the deserved
    warnings about incompatible types, this extension seems useful, and at
    least for m68k does no harm for conforming code.
    ---
     gcc/config/m68k/m68k.c                     | 40 ++++++++++++++++++++++--------
     gcc/testsuite/gcc.target/m68k/cast-fptr1.c | 11 ++++++++
     gcc/testsuite/gcc.target/m68k/cast-fptr2.c | 12 +++++++++
     3 files changed, 53 insertions(+), 10 deletions(-)
     create mode 100644 gcc/testsuite/gcc.target/m68k/cast-fptr1.c
     create mode 100644 gcc/testsuite/gcc.target/m68k/cast-fptr2.c
    
    diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
    index 03f474e..da7a5f0 100644
    a b m68k_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED) 
    52885288
    52895289  /* If the function returns a pointer, push that into %a0.  */
    52905290  if (func && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (func))))
     5291  {
    52915292    /* For compatibility with the large body of existing code which
    52925293       does not always properly declare external functions returning
    52935294       pointer types, the m68k/SVR4 convention is to copy the value
    52945295       returned for pointer functions from a0 to d0 in the function
    52955296       epilogue, so that callers that have neglected to properly
    52965297       declare the callee can still find the correct return value in
    5297        d0.  */
    5298     return gen_rtx_PARALLEL
    5299       (mode,
    5300        gen_rtvec (2,
    5301                   gen_rtx_EXPR_LIST (VOIDmode,
    5302                                      gen_rtx_REG (mode, A0_REG),
    5303                                      const0_rtx),
    5304                   gen_rtx_EXPR_LIST (VOIDmode,
    5305                                      gen_rtx_REG (mode, D0_REG),
    5306                                      const0_rtx)));
     5298       d0.
     5299       expand_call uses the first register in the PARALLEL rtx.  Order
     5300       the registers such that expand_call uses the same register as
     5301       if func was not given.  */
     5302    if (POINTER_TYPE_P (valtype))
     5303    {
     5304      return gen_rtx_PARALLEL
     5305        (mode,
     5306         gen_rtvec (2,
     5307                    gen_rtx_EXPR_LIST (VOIDmode,
     5308                                       gen_rtx_REG (mode, A0_REG),
     5309                                       const0_rtx),
     5310                    gen_rtx_EXPR_LIST (VOIDmode,
     5311                                       gen_rtx_REG (mode, D0_REG),
     5312                                       const0_rtx)));
     5313    }
     5314    else
     5315    {
     5316      return gen_rtx_PARALLEL
     5317        (mode,
     5318         gen_rtvec (2,
     5319                    gen_rtx_EXPR_LIST (VOIDmode,
     5320                                       gen_rtx_REG (mode, D0_REG),
     5321                                       const0_rtx),
     5322                    gen_rtx_EXPR_LIST (VOIDmode,
     5323                                       gen_rtx_REG (mode, A0_REG),
     5324                                       const0_rtx)));
     5325    }
     5326  }
    53075327  else if (POINTER_TYPE_P (valtype))
    53085328    return gen_rtx_REG (mode, A0_REG);
    53095329  else
  • new file gcc/testsuite/gcc.target/m68k/cast-fptr1.c

    diff --git a/gcc/testsuite/gcc.target/m68k/cast-fptr1.c b/gcc/testsuite/gcc.target/m68k/cast-fptr1.c
    new file mode 100644
    index 0000000..3116167
    - +  
     1/* { dg-do compile } */
     2/* { dg-options "-O -Wno-incompatible-pointer-types" } */
     3/* { dg-final { scan-assembler "cmp.l %d0,%d1" } } */
     4
     5void *extfn();
     6
     7int main(void)
     8{
     9  int(*f)(void) = extfn;
     10  return f() == 42;
     11}
  • new file gcc/testsuite/gcc.target/m68k/cast-fptr2.c

    diff --git a/gcc/testsuite/gcc.target/m68k/cast-fptr2.c b/gcc/testsuite/gcc.target/m68k/cast-fptr2.c
    new file mode 100644
    index 0000000..1aff7eb
    - +  
     1/* { dg-do compile } */
     2/* { dg-options "-O -Wno-incompatible-pointer-types" } */
     3/* { dg-final { scan-assembler "cmp.l #foo,%a0" } } */
     4
     5int extfn();
     6extern char foo[];
     7
     8int main(void)
     9{
     10  void*(*f)(void) = extfn;
     11  return f() == &foo;
     12}