I have some PowerPC assembly code translated with a gcc cross compiler with this function:
uint32_t fill_cache(void)
{
__asm__ ("addi 3, 0, 0\n"); /* R3 = 0 */
/* More asm here modifying R3 and filling the cache lines. */
}
which, under the PowerPC EABI, returns the value computed in R3. When compiling I get
foo.c:105: warning: control reaches end of non-void function
Is there a way to teach gcc that a value is actually returned? Or is there a way to suppress the warning (without removing -Wall or adding -Wno-*)? I would like to very selectively suppress this warning for only this function in order to leave the general warning level as high as possible.
It is not an option to make this function return void since the value computed is required by the caller.
Solution 1: with diagnostic pragmas you can locally suppress certain diagnostic checks. The specific option (which also is implied by -Wall) that complains for no return in a non-void function is -Wreturn-type. So the specific code to suppress the warning is:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wreturn-type"
/* Your code here */
#pragma GCC diagnostic pop
You can find out which option is causing the warning by compiling with -fdiagnostics-show-option. It will simply append the option to the warning message.
Solution 2: define a register variable and put it in the desired register. Refer to the variable in an inline assembler template, with the resulting code:
uint32_t fill_cache(void)
{
register uint32_t cacheVal __asm__ ("r3");
__asm__ __volatile__ ("addi %0, 0, 0" : "=r" (cacheVal));
/* More code here */
return cacheVal;
}
The volatile modifier is to ensure that the instruction is not removed or in some other way affected undesirably by the optimization strategy.
Solution 2 is preferred for at least two reasons: