[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] avr-gcc 3.4.3 confused about function pointers

From: Björn Haase
Subject: Re: [avr-gcc-list] avr-gcc 3.4.3 confused about function pointers
Date: Tue, 18 Apr 2006 09:07:08 +0200
User-agent: KMail/1.7.1

> Message: 3
> Date: Tue, 18 Apr 2006 07:11:21 +0200
> From: Joerg Wunsch <address@hidden>
> Subject: Re: [avr-gcc-list] avr-gcc 3.4.3 confused about function
>       pointers
> To: address@hidden
> Message-ID: <address@hidden>
> Content-Type: text/plain; charset=us-ascii
> As John Regehr wrote:
> > > Sorry, I can't follow the somewhat tangled logic of that code, so
> > > I can't see whether GCC 4.1.0 still produces buggy code for it or
> > > not.
> >
> > You weren't supposed to follow the logic, it was an automatically
> > extracted subset of a machine generated file.
> Sure, I assumed that.
> > A shorter program that gcc 4.1.0 miscompiles is below.  Compile with
> > -Os and the problem should be obvious: the program icalls to the
> > byte address of bar() rather than the double-byte address.
> I can see it now.  However, I'm not even sure whether GCC is really at
> fault here, I'd have to look into the standard.
> >   c[0].e = bar + 1;
> This is the root of your evil.  You are performing address
> calculations on a function pointer address.  Without looking into the
> standard, I'd say you can't do that: what is supposed to be "next"
> address of a function pointer?  If the standard specifies the result
> to be undefined, the compiler's resulting misbehaviour must be
> tolerated, and cannot be considered a bug.
> The problem here is that this statement obviously confuses the
> compiler's address computation logic, and it `forgets' that these
> function pointer addresses are actually word addresses that need to be
> byte-shifted.  Sure, your +1 address cannot meaningfully be
> byte-shifted by one, but subsequently, it also `forgets' this for the
> address of bar() itself.
> If you omit that nonsensical statement, everything gets fine again.
> Things become different if you write it as:
> struct fseqp_void
> {
>   void (*p) (void);
>   char *e;
> };
> ...
> int main (void)
> {
>   c[0].e = (char *)bar + 2;
>   c[0].p = bar;
> This still triggers the bug, but now it's clearly a bug, and I'd say
> you should report that one.

IUUC, GCC itself only works with byte addresses. For Ram as well as for 
program memory. The memory space is simply identified by the 0x80.... 
prefixes for ram, e.g. .

Wether a word or a byte address is used simply depends on the type of use and 
the shifting >> 1 is effectively done later on by the assembler/linker. E.g. 
there are these expressions like lpm_hi8 (argument) that you will see in the 
assembly code that trigger the shifting. For all cases I have investigated so 
far, the right asm directives have been generated.

The problem shows up, when not leaving the address-expression generation to 
the linker. I.e. when calculating the address at run-time. Note that there is 
no problem, when using variables that dynamically hold addresses that are 
generated by use of the @ operator or when using addresses that are stored in 
initialized tables in rom or ram!

In order to resolve the issue strictly correctly, one would need to introduce 
different types of pointers that possibly have even different different size: 
Imagine the devices with more than 128k. To my best knowledge the C language 
standard does not support the concept of such different pointer classes by 
assuming the existence of one uniform address space.

Possibly you stepped over a general weakness of the "C" language that exposes 
general difficulties with Harvard-type architectures.I'd suggest you to write 
a bug report using Joerg's example and one will find out rapidly.

Concerning your code, I'd strongly suggest to resolve the issue by using a 
different programming style. Frankly speaking, I could not imagine any 
situation where one will have any need for function address calculations 
except for strange hand-optimized assembly code.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]