https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81073

--- Comment #4 from Georg-Johann Lay <gjl at gcc dot gnu.org> ---
(In reply to Jason Merrill from comment #3)
> The testcase in comment 1 works on trunk and current 7 branch.  The original
> testcase looks ill-formed to me; [dcl.constexpr] says that a constexpr
> function can't define a variable with static storage duration, and I think
> the same applies to statement-expressions, for the same reason: when we
> optimize to a constant value, we no longer have the declaration, which leads
> to link errors like this.

Some more background: It's a condensed C++ test case from AVR that looked
something like this:

#defin PROGMEM __attribute__((__progmem__))

struct test { const int *addr; };

const test* setup()
{
    static const test atest PROGMEM =
    {
        ({ static const int inner PROGMEM = 123; &inner; })
    };

    return &atest;
}

int main(){}

PROGMEM is similar to section attribute and puts data into flash section which
cannot be written at run-time.  As C++ doesn't support named address spaces
like __flash, data must be read by inline assembly that emits special
instructions that perform reading from flash (reading from flash / RAM requires
different instructions and addressing modes).

This is needed because .rodata must be loaded to RAM, and in order so save very
precious RAM that might be only some bytes depending on device.

The trouble with "const" is that const in C++ is not really const (like a const
in static storage in C that is .rodata or optimized away) but might need
constructing, and the backend won't see whether C++ will cook up a constructor.
 In that case the backend could issue an error, but the current state of
affairs is that constructing leads to wrong code because
TARGET_INSERT_ATTRIBUTES cannot diagnose on that situation.  What's the right
hook to issue a diagnostic if a const object in static storage needs
constructing?

I would already be happy if the AVR backend could diagnose situation where C++
magic shreds assumptions of const + PROGMEM.

In order to make clear what the user *really needs* (something that's *really*
const so it could reside in flash) and to show the problem on x86, I switched
from const to constexpr -- however I am not a C++ guy...

To make things even worse, all the PROGMEM + inline asm + statement-expression
stuff is hidden behind common usability macros that are used by actually every
avr-g++ user like Arduino.

Reply via email to