Menu

#2833 Cast to float triggers internal compiler error

closed
None
other
5
2018-11-12
2018-11-07
Noam Preil
No

The following function triggers an internal error during compilation:

float fails(float a) { return !(int)a; }

That gives a.c:1: error 9: FATAL Compiler Internal Error in file 'SDCCopt.c' line number '299' : 0
Compiled with the latest commit
Compiled with sdcc a.c -S -o a.asm.

SDCC has here been compiled ONLY with z80 (and apparently AVR - I copied the configure command from the Portage package manager, and I had AVR enabled globally before avr support was added to SDCC, so apparently it was enabled automatically) support (configure command: ./configure --prefix=/usr --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --mandir=/usr/share/man --infodir=/usr/share/info --datadir=/usr/share --sysconfdir=/etc --localstatedir=/var/lib --docdir=/usr/share/doc/sdcc-3.8.0 --htmldir=/usr/share/doc/sdcc-3.8.0/html --libdir=/usr/lib64 ac_cv_prog_AR=x86_64-pc-linux-gnu-ar ac_cv_prog_AS=x86_64-pc-linux-gnu-as ac_cv_prog_STRIP=true --enable-avr-port --enable-libgc --disable-device-lib --disable-ds390-port --disable-ds400-port --disable-gbz80-port --disable-hc08-port --disable-mcs51-port --disable-non-free --disable-packihx --disable-pic14-port --disable-pic16-port --disable-r2k-port --disable-r3ka-port --disable-s08-port --disable-sdbinutils --disable-sdcdb --enable-sdcpp --disable-stm8-port --disable-tlcs90-port --disable-ucsim --disable-z180-port --enable-z80-port --disable-doc --docdir=/usr/share/doc/sdcc-3.8.0 --without-ccache).

This compiles successfully with SDCC 3.5, and if the function's return type is altered then it compiles with upstream.

Discussion

1 2 > >> (Page 1 of 2)
  • Noam Preil

    Noam Preil - 2018-11-07

    I'm bisecting right now.

     
  • Philipp Klaus Krause

    I can reproduce the issue in current SDCC [r10635] on my Debian GNU/Linux testing system. I tried z80, mcs51, stm8, and see the problem for all of them.

    Philipp

     
  • Philipp Klaus Krause

    • Priority: 9 --> 5
     
  • Philipp Klaus Krause

    Reducing priority to 5. High priorities should only be used for worse issues (e.g. problems that do not have easy workarounds, or result in silent generation of broken code).

    Philipp

     

    Last edit: Philipp Klaus Krause 2018-11-07
  • Noam Preil

    Noam Preil - 2018-11-08

    Looking at [#2458], that patch fixed one bug while causing another. I don't have much experience with the SDCC internals (my biggest work on SDCC was for a fork - a patch that cleans up the generated asm so that only the parts needed by the assembler are kept, which didn't go near the internals), but it looks to me like the problem is that SDCC is trying to convert the cast from bool to float into a function call, but SDCC doesn't support a function to do that.

     

    Related

    Bugs: #2458


    Last edit: Maarten Brock 2018-11-11
    • Philipp Klaus Krause

      Well, developers don't introduce bugs intentionally, so fixing different bugs or introducing features are the main ways of introducing bugs.

      Yes the problem is in casting bool to float. Indeed even

      float f2(_Bool b) {return b;}
      

      triggers the bug. Fortunately, we can just reuse the support function for casts from unsigned char (__uchar2fs) for casts from bool (unless people cast bool to float a lot, then it might be worth to have a special, more efficient one).

      Philipp

       
  • Philipp Klaus Krause

    I added a (for now disabled) regression test for this bug in [r10646].

    Philipp

     
  • Noam Preil

    Noam Preil - 2018-11-08

    I have to double check, but the following appears to fail even before that commit:

    float fails(_Bool b) {
        return b;
    }
    
     
  • Noam Preil

    Noam Preil - 2018-11-08

    (Note: before that commit, it appears to succeed with return !b.

     
  • Noam Preil

    Noam Preil - 2018-11-08

    Looking at the AST for both from before that commit, without the not it's CAST from type (_Bool auto) to type (float fixed) whereas with the not its CAST from type (signed-char fixed) to type (float fixed) with the NOT implicitly converting it to a signed-char fixed.

     

    Last edit: Maarten Brock 2018-11-11
  • Noam Preil

    Noam Preil - 2018-11-08

    I think I understand the code enough to patch it on my own - I'll try to submit a patch within a couple hours.

     
  • Noam Preil

    Noam Preil - 2018-11-08
    --- a/sdcc/src/SDCCopt.c
    +++ b/sdcc/src/SDCCopt.c
    @@ -296,6 +296,11 @@ cnvToFloatCast (iCode * ic, eBBlock * ebp)
           goto found;
         }
    
    +  if (IS_BOOL(type)) {
    +     func = conv[0][0][1];
    +     goto found;
    +  }
    +
       assert (0);
     found:
    

    Tested that, it works.

    Generated the following z80:

    ;-------------------------------------------------------
    ; File Created by KCC : free open source ANSI-C Compiler
    ; Version 3.4.1 #9072 (Linux)
    ;-------------------------------------------------------
    
        .globl _fails
        .area _RSEG (ABS)
        .org 0x0000
        .area _CODE
        .map    a.c, 1, "float fails(_Bool b) {"
    _fails::
        .map    a.c, 2, "return !b;"
        ld  hl, #2+0
        add hl, sp
        ld  a, (hl)
        xor a, #0x01
        push    af
        inc sp
        call    ___uchar2fs
        inc sp
        .map    a.c, 3, "}"
        ret
        .area _CABS (ABS)
    
     
  • Noam Preil

    Noam Preil - 2018-11-08

    Running the regression suite now...

     
  • Noam Preil

    Noam Preil - 2018-11-08

    I get the following attempting to build the simulator:

    x86_64-pc-linux-gnu-g++ -g -O2 -g -Wall -I../../../../sim/ucsim/cmd.src -I../../../../sim/ucsim -I.. -I../../../../sim/ucsim/sim.src -I../../../../sim/ucsim/gui.src  -c ../../../../sim/ucsim/cmd.src/set.cc -o set.o
    ../../../../sim/ucsim/cmd.src/set.cc: In member function ‘virtual int cl_set_mem_cmd::do_work(cl_uc*, cl_cmdline*, cl_console_base*)’:
    ../../../../sim/ucsim/cmd.src/set.cc:72:54: error: unable to find string literal operator ‘operator""_A_’ with ‘const char [30]’, ‘long unsigned int’ arguments
           con->dd_printf("Start address less then 0x%"_A_"x\n",
                                                          ^~~~~
    make[2]: *** [Makefile:116: set.o] Error 1
    
     
    • Philipp Klaus Krause

      Which version of SDCC are you using? In current [r10648], I only see a cmd_set.cc file in that directory, and while it has a similar line 72, it doesn't not contain any _A_.

      Philipp

       

      Last edit: Philipp Klaus Krause 2018-11-08
  • Noam Preil

    Noam Preil - 2018-11-08

    Oops. Looks like I broke it when I was bisecting it.

     
  • Noam Preil

    Noam Preil - 2018-11-08

    On a clean build, I get "/bin/sh: aclocal-1.16: command not found" when it tries to build the pic14 device lib... and my autotools are apparently too new for SDCC?

     
  • Noam Preil

    Noam Preil - 2018-11-08

    Never mind, it's fine if I do it manually in that specific directory

     
  • Noam Preil

    Noam Preil - 2018-11-09

    Alright, it's a good thing I ran that regression test - that patch needs to be amended slightly. The only failing test was the new one, bug-2833 (I edited it to run properly).

    IS_BOOL in the patch needs to be replaced with IS_BOOLEAN.

    I'm cleaning up the regression dir and running the tests again.

     
  • Noam Preil

    Noam Preil - 2018-11-09
    gen/ds390/bug-2833/bug-2833.out:3:--- FAIL: "Assertion failed" on cast1 (0.0f) == b1 at gen/ds390/bug-2833/bug-2833.c:23
    gen/ds390/bug-2833/bug-2833.out:4:--- FAIL: "Assertion failed" on cast2 (1.0f) == b1 at gen/ds390/bug-2833/bug-2833.c:26
    

    Also a bunch of failures in the gcc-torture-execute stuff on the host target (and only the host target).

     
    • Philipp Klaus Krause

      I guess it is still better to have this work for most backends, and file a bug report for the ds390 issue. Are the host failures the following: gcc-torture-execute-20040409-1, gcc-torture-execute-20040409-2, gcc-torture-execute-20040409-3?

      It probably would be good to have an assertion (using wassert()) before func = conv[0][0][1]; that that checks that multypes[0][0] is an unsigned 1-byte type.

      Philipp

       
      • Noam Preil

        Noam Preil - 2018-11-09

        Shouldn't I be making sure that multypes[0][1] (not [0][0]) is an unsigned 1-byte type?

         
        • Noam Preil

          Noam Preil - 2018-11-09
          /* Dims: BYTE/WORD/DWORD/QWORD SIGNED/UNSIGNED */
          extern sym_link *multypes[4][2];
          /* Dims: to/from float, BYTE/WORD/DWORD/QWORD, SIGNED/USIGNED */
          extern symbol *conv[2][4][2];
          
           
        • Philipp Klaus Krause

          Yes. Sorry for the confusion.

          Philipp

           
1 2 > >> (Page 1 of 2)

Log in to post a comment.