Menu

#3145 _Generic fails to recognize string constant as char*

closed-fixed
None
Front-end
5
2022-04-23
2020-11-01
No

When trying to compile the examples from DR 481 about _Generic, none of them work.
This is expected for those examples that contain compound literals, because SDCC does not support them, and for the second one, provided that SDCC's _Generic implementation is correct, but IMO the first one should work and the second one should fail with a different error message.

This is the full set of examples:

char const* a = _Generic("bla", char*: "blu");                 // clang error
// char const* b = _Generic("bla", char[4]: "blu");               // gcc error
// char const* c = _Generic((int const){ 0 }, int: "blu");        // clang error
// char const* d = _Generic((int const){ 0 }, int const: "blu");  // gcc error
// char const* e = _Generic(+(int const){ 0 }, int: "blu");       // both ok
// char const* f = _Generic(+(int const){ 0 }, int const: "blu"); // both error

The exact command line was:

:~/sdcc-code> sdcc/bin/sdcc -c generic_test.c

The SDCC version was 4.0.4 rev. 11930.

The first example results in this error message:

generic_test.c:1: error 229: no matching expression in generic association
generic_test.c:1: error 9: FATAL Compiler Internal Error in file 'SDCCast.c' line number '1808' : unexpected link in expression tree 
Contact Author with source code
generic_test.c:1: error 2: Initializer element is not a constant expression

The second example results in this error message:

Internal error: validateLink failed in SPEC_NOUN(type) @ SDCCast.c:5424: expected SPECIFIER, got DECLARATOR

The remaining examples result in this error message:

generic_test.c:3: error 254: compound literals require ISO C99 or later and are not implemented

Related

Bugs: #3254
Wiki: SDCC-STD-UX

Discussion

  • Philipp Klaus Krause

    Looks like we have two bugs here:

    1) When there is no match, there is no result of the _Generic, but apparently a further stage (initialization) still tries to use it. When there is no match, and no default, an error flag is set, but apparently there is some place that doesn't check or forward the error flag correctly.
    This bug can even be shown by a simple int i = _Generic(7, char : 7);

    2) Implicit named address spaces. See the following:

    int i;
    int j = _Generic(&i, int * : 7);
    

    We get no match, since SDCC (when compiling with default options, i.e. for mcs51 small memory model). places i in __near space, and considers &i to be of type __near int *, which doesn't match int *. I guess we need to clearly separate the case of an explicit user-supplied address space vs. the case of a compiler-deduced address space to be able to fix this bug.

     
    • Benedikt Freisen

      Regarding 2),
      I get the same error message, i.e. "no matching expression in generic association", for STM8 and Z80. Do these ports even have implicitly named address spaces?

       
      • Philipp Klaus Krause

        The ports don't really have it, but the SDCC frontend nevertheless attached these to some things (I guess due to mcs51 being the fist backend historically). E.g. compiling for stm8

        char c;
        char const* a = _Generic(&c, char*: "blu");
        

        with some debug printfs added in SDCCast.c, I see:

        philipp@notebook6:/tmp$ ~/sdcc-trunk/sdcc/bin/sdcc -mstm8 test.c
        test.c:5: error 74: function 'main' undefined
        Comparing:
        unsigned-char near* fixedto:
        unsigned-char generic* fixed
        test.c:4: error 229: no matching expression in generic association
        
         
    • Philipp Klaus Krause

      1) is fixed in [r13378].

       

      Related

      Commit: [r13378]

  • Philipp Klaus Krause

    Another issue is that SDCC implicitly makes string literals const char [] instead of char *. Before _Generic this wasn't much of an issue, but it is now. I guess we need a flag for implicit const, like we have for implicit (un)signed of char.

     

    Last edit: Philipp Klaus Krause 2022-04-19
  • Philipp Klaus Krause

    Hmm.The string constant non-match still gives

    hilipp@notebook6:/tmp$ ~/sdcc-trunk/sdcc/bin/sdcc -mmcs51 -I/home/philipp/sdcc-trunk/sdcc/device/include/mcs51 test.c --fverbose-asm --i-code-in-asm
    test.c:20: error 74: function 'main' undefined
    test.c:19: error 229: no matching expression in generic association
    const-char [4] code
    test.c:19: error 9: FATAL Compiler Internal Error in file 'SDCCast.c' line number '1803' : unexpected link in expression tree 
    Contact Author with source code
    test.c:19: error 2: Initializer element is not a constant expression
    

    When compiling for mcs51. I seem to remember having fixed such an issue (i.e. the internal error) just few weeks ago (though AFAIR, I only tested on stm8).

    P.S.: This aspect is fixed in [r13391]. The fix is similar to the one 10 days ago.

     

    Related

    Commit: [r13391]


    Last edit: Philipp Klaus Krause 2022-04-20
  • Philipp Klaus Krause

    This works now in the intrinsicnamedaddressspaces branch.
    But I suspect there are still some more corner cases similar to this one that I need to look into. Once it looks reasonably complete, I'll merge to trunk#, if there are no regressions.

     
    • Philipp Klaus Krause

      As of [r13402], the fix is in trunk.

       

      Related

      Commit: [r13402]

  • Philipp Klaus Krause

    • status: open --> closed-fixed
    • assigned_to: Philipp Klaus Krause
     
    • Deqing Sun

      Deqing Sun - 2022-04-23

      Awesome!

       

Log in to post a comment.

MongoDB Logo MongoDB