I posted the typedefs earlier e.g.
/** This is the aligned version of ip4_addr_t,
used as local variable, on the stack, etc. */
struct ip4_addr {
u32_t addr;
};
Apologies, I missed that.
Yes, this will be returned in
r0 on
arm-none-eabi AKA
aacs32 (which is what I believe you are using), and passed in a single register when supplied as a parameter (
ip4_addr_t addr).
To repeat, the warning issue you are seeing is
not because the cause varies at different optimization levels; it is just that at some optimization levels the compiler just happens to not detect the pattern and thus omits the warning, most likely because the pattern is spread over too much code (which gets eliminated and thus pattern more compact when optimizations are enabled).
You can see something similar when you examine the code GCC generates for the last function in my previous message: it pushes a lot of extra registers on stack, because when not optimized, it
uses those registers. Register use is a bit of a weak point in GCC, and has always been, so current optimization schemes still cannot fully optimize it in this case. Plus, it apparently does not notice those registers are no longer modified, so doesn't remove them from the saved+restored set. So, when looking at say
-O2 optimized code, those extra registers it pushes and pops look insane.
Similarly, because GCC doesn't see the warnings as something it
has to check, but something it
may do, it doesn't spend much resources in trying to detect the pattern causing the warning; therefore only when the pattern is easily discernible, will it detect and emit the warning. (In other words, the lack of the warning is
not an indication that the return value is initialized. It is only best-effort warning, nothing conclusive.)
Also, whether
ipaddr is initialized in the caller or not
does not and should not affect the warning, because the warning is about returning an uninitialized value from a function. It does not matter that the ABI might pass the result by reference and the immediate caller clears it to zero first,
because the compiler must not assume it sees all callers while compiling this file. (If the function had only local linkage, i.e. it was
static, then it would be different, as the compiler would indeed see all callers while compiling this file.)