#1825 Putting Arguments on Stack can Cause 78: incompatible types


This was originally observed after I modified some code of the Contiki OS for cc2430 SoCs. It can be stripped down to a simple example, as the one in the attached foo.c

Assume a function accepting two pointer arguments and returning a pointer, as in:
unsigned char * foo(struct ip6_addr * addr, unsigned char * l);

The call itself works. Problems start if we attempt to pass its return value directly to another function, as in:
memcpy(a, foo(b, c), 8);

The attached file demonstrates some working and some non-working cases

foo.c will compile just fine with:
sdcc -c foo.c

However, if we compile with --stack-auto, we get the following error:

geo@lin-geo:~/workspace/test-proj$ sdcc --stack-auto -c foo.c
foo.c:24: error 78: incompatible types
from type 'unsigned-char generic* auto'
to type 'struct ip6_addr generic* fixed'

As anticipated, if we add __reentrant to foo's prototype and compile without --stack-auto we get the same error.

However, if we make any of the following changes (demonstrated in the attached), --stack-auto works
- If foo returns void *
- If we cast its return value to (void *)
- If it takes only a single argument
- If it takes two arguments but neither of type struct xyz *

The outer function doesn't have to be memcpy. The problem only appears to manifest itself when foo's return value is a pointer of a different type than the one expected by the outer function.

I tried with the following versions:
SDCC : mcs51 3.0.4 #6748 (Aug 17 2011) (Linux)
SDCC : mcs51 3.0.4 #6726 (Aug 8 2011) (Mac OS X x86_64)
SDCC : mcs51 3.0.1 #6188 (Feb 3 2011) (CYGWIN)

--model-xyz does not make any difference that I've noticed (tried small, large, huge). Target MCU doesn't seem to make any difference either (quickly re-built and tried -mhc08 with the same results)

This is a follow-up (with some more test cases) to the conversation that started with this:

Hope this Helps


  • George Oikonomou

    Self-contained source file with test cases

  • Philipp Klaus Krause

    When I compile foo.c using sdcc -c foo.c I get:

    foo.c:43: error 78: incompatible types
    from type 'unsigned-char generic* fixed'
    to type 'struct ip6addr generic* fixed'

    which AFAIK is correct (implicit casts AFAIK being only allowed from / to void pointers).

    When I use
    sdcc -c --stack-auto foo.c
    I get lots of erros that shouldn't be there, as per this bug report.

    However when using sdcc -c -mz80 foo.c
    I only get the error message as with sdcc -c foo.c. Even though the Z80 ports puts local variables on the stack and makes all functions reentrant.


  • Philipp Klaus Krause

    Sorry, not "lots of erro[r]s§, just the one for line 24 from the bug report, which is clearly wrong sicne nowhere is an unsigned char * cast to struct ip6_addr * in that line. And yes, it is not memcpy()-specific, the same behaviour is visible when adding
    void xmemcpy(void *dst, const void *src, size_t n);
    and reaplcing the memcpy() call by that one (AFAIK the mcs51 port doesn't handle memcpy() different from normal functions anyway).


  • Philipp Klaus Krause

    Here's a minimal example to reproduce this issue:

    unsigned long *f(int *, unsigned char *);
    void g(void *);
    void h(void)
    g(f(0, 0));

    Error message:

    unsigned long *f(int *, unsigned char *);
    void g(void *);

    void h(void)
    g(f(0, 0));


    P.S.: My earlier post statement about z80 not beign affected was wrong.

  • Philipp Klaus Krause

    Last post for today; seems I'm too tired to make posts that make sense today. So another correction to a previous post:

    The error message of course is

    foo2.c:6: error 78: incompatible types
    from type 'unsigned-char generic* literal'
    to type 'int generic* fixed'


  • Philipp Klaus Krause

    Minimal example to reproduce the bug

  • Maarten Brock

    Maarten Brock - 2011-09-16

    This is a duplicate of bug 3166064 at which I happened to be looking earlier today.


    It seems to be triggered when the result of a function call is cast to the argument type of the surrounding function. decorateType and processParms are executed twice but the second time the argument list has been reversed for a reentrant function. I think there is a missing assignment of decorateType somewhere.

  • Maarten Brock

    Maarten Brock - 2011-09-18

    Fixed in SDCC 3.0.4 #6855.

  • Maarten Brock

    Maarten Brock - 2011-09-18
    • milestone: --> fixed
    • assigned_to: nobody --> maartenbrock
    • status: open --> closed-fixed

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

No, thanks