public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/116433] New: [AVR] cannot place template class static members in EEPROM
@ 2024-08-20 17:42 digger1984 at gmx dot com
  2024-08-20 17:46 ` [Bug target/116433] [AVR] cannot place template class static member variables " pinskia at gcc dot gnu.org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: digger1984 at gmx dot com @ 2024-08-20 17:42 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 116433
           Summary: [AVR] cannot place template class static members in
                    EEPROM
           Product: gcc
           Version: 13.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: digger1984 at gmx dot com
  Target Milestone: ---

Created attachment 58963
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58963&action=edit
Complete sample code with three separate use cases

Context

I designed a template class in the hope it could make EEPROM storage somehow
transparent by implementing read and write accessors in a class/struct. The
desired goal is equivalent to this:

        eemem<initial_value> variable;
        foo(variable);

The compiler would then automatically fetch the value for the internal variable
before passing it to function `foo`.

Otherwise the conventional approach is:

        auto variable EEMEM = initial_value;
        foo(eeprom_read_<appropriate_b_w_d_idom>(&variable));

And so on for every similar situation. Same goes with writing but even more
verbose.

I'm using C++ ability to supply literals as template arguments. From there the
type is deduced from the argument. In order to achieve what I want(ed) I need a
static member variable to which I append the EEMEM macro for EEPROM storage.

For the reference I've used the same tactics for program memory storage and it
works as expected, therefore I hoped it would also work for EEPROM storage.

The problem

AVR-GCC version 13.2.0 ignores the section attribute and instead places static
members of template classes in RAM, which is not the desired effect. I've
looked up bugs #89148, #116184 and #87178 to find an explanation (I *think* I
understand the issue but I'm not quite sure).

Here's a minimal example to illustrate the problem:

        template <auto V>
        struct eemem
        {
                typedef type::remove_cv_t<decltype(V)> value_type;
                static value_type value __attribute__((section(".eeprom"),
used));
        };

        template<auto V>
        eemem<V>::value_type eemem<V>::value __attribute__((section(".eeprom"),
used)) = V;

        eemem<69U> test;

Note this is *not* the full class definition; I stripped it to the bare minimum
for illustration purposes. When accessed from function `main` like this:

        PORTB = eeprom_read_word(&test.value);

the compiled code appears as follows (also note there's no warning nor errors
at compile time):

        ba:     80 e0           ldi     r24, 0x00       ; 0
        bc:     91 e0           ldi     r25, 0x01       ; 1
        be:     0e 94 65 00     call    0xca    ; 0xca <eeprom_read_word>
        c2:     85 b9           out     PORTB, r24      ; 5

I'd understand if this bug is marked as a duplicate but I'd like to stress on
the fact that I'm not trying to move my variables into a section of my own,
only into what's been defined for the AVR platform as to EEPROM storage. So if
this is not possible, is there a workaround (e.g. with a custom linker script,
maybe)?

Attached is the complete test code I. Compiler command line options are:

        -Os -mmcu=atmega328p -std=gnu++20 -DF_CPU=16000000

Only the non-template class has its static member variable stored in EEPROM, as
expected. The other two have their member variable stored in RAM, which is
undesired.

Also note with AVR-GCC 14.1.0 (from Matt Godbolt Compiler Explorer) I get the
following error message:

        <source>:46:35: error: 'stg::t2::eemem::value' causes a section type
conflict with 'stg::t3::eemem<unsigned int>::value'

Best,
C.F.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug target/116433] [AVR] cannot place template class static member variables in EEPROM
  2024-08-20 17:42 [Bug c++/116433] New: [AVR] cannot place template class static members in EEPROM digger1984 at gmx dot com
@ 2024-08-20 17:46 ` pinskia at gcc dot gnu.org
  2024-08-20 17:55 ` digger1984 at gmx dot com
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-08-20 17:46 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |DUPLICATE
           See Also|                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=43745

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
You can't do that as the template variables are comdat.

The real fix is to have named address spaces support extended to C++. See PR
43745.

*** This bug has been marked as a duplicate of bug 87178 ***

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug target/116433] [AVR] cannot place template class static member variables in EEPROM
  2024-08-20 17:42 [Bug c++/116433] New: [AVR] cannot place template class static members in EEPROM digger1984 at gmx dot com
  2024-08-20 17:46 ` [Bug target/116433] [AVR] cannot place template class static member variables " pinskia at gcc dot gnu.org
@ 2024-08-20 17:55 ` digger1984 at gmx dot com
  2024-08-20 21:41 ` gjl at gcc dot gnu.org
  2024-08-21  7:57 ` digger1984 at gmx dot com
  3 siblings, 0 replies; 5+ messages in thread
From: digger1984 at gmx dot com @ 2024-08-20 17:55 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from C.F. <digger1984 at gmx dot com> ---
(In reply to Andrew Pinski from comment #1)
> You can't do that as the template variables are comdat.
> 
> The real fix is to have named address spaces support extended to C++. See PR
> 43745.
> 
> *** This bug has been marked as a duplicate of bug 87178 ***

I'm not sure I understand the link with VTABLES though. (Fact is I don't
understand anything in that PR report)... But I guess it means there's a
proposition to address this issue in an upcoming version of GCC, right?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug target/116433] [AVR] cannot place template class static member variables in EEPROM
  2024-08-20 17:42 [Bug c++/116433] New: [AVR] cannot place template class static members in EEPROM digger1984 at gmx dot com
  2024-08-20 17:46 ` [Bug target/116433] [AVR] cannot place template class static member variables " pinskia at gcc dot gnu.org
  2024-08-20 17:55 ` digger1984 at gmx dot com
@ 2024-08-20 21:41 ` gjl at gcc dot gnu.org
  2024-08-21  7:57 ` digger1984 at gmx dot com
  3 siblings, 0 replies; 5+ messages in thread
From: gjl at gcc dot gnu.org @ 2024-08-20 21:41 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Georg-Johann Lay <gjl at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #1)
> The real fix is to have named address spaces support extended to C++. See
> PR43745.
That's a different issue.  EEPROM handling is too complicated, we don't want
/that/ code in the compiler and support > 300 devices where each one might need
different SFR handling.  When you want EEPROM support, you can just wrap
routines from AVR-LibC.  But that's not possible with PR43745 because there is
no way you can specify that VTABLEs be located in flash *and* to use the
appropriate access instructions.  It isn't possible in GCC either because just
putting VTALBEs in progmem won't fd the trick of using the right accessor
instructions.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug target/116433] [AVR] cannot place template class static member variables in EEPROM
  2024-08-20 17:42 [Bug c++/116433] New: [AVR] cannot place template class static members in EEPROM digger1984 at gmx dot com
                   ` (2 preceding siblings ...)
  2024-08-20 21:41 ` gjl at gcc dot gnu.org
@ 2024-08-21  7:57 ` digger1984 at gmx dot com
  3 siblings, 0 replies; 5+ messages in thread
From: digger1984 at gmx dot com @ 2024-08-21  7:57 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from C.F. <digger1984 at gmx dot com> ---
(In reply to Georg-Johann Lay from comment #3)
> EEPROM handling is too complicated, we don't want
> /that/ code in the compiler and support > 300 devices where each one might
> need different SFR handling.

Out of curiosity I'd like to know and understand why it is complicated. I'm not
questioning it is, I'd really like to understand why it is so. Explained in
laymans' terms, preferably. Also, are you talking about just AVR (which is
relevant to this bug and duplicates I suppose)? Or are you talking more in the
general sense?

> When you want EEPROM support, you can just wrap routines from AVR-LibC.

Well, that precisely *is* what I had wished I could avoid and make EEPROM
storage transparent, looking like accessing ordinary variables using a bit of
"C++ magic". I guess I'm back to the drawing board then...

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-08-21  7:57 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-08-20 17:42 [Bug c++/116433] New: [AVR] cannot place template class static members in EEPROM digger1984 at gmx dot com
2024-08-20 17:46 ` [Bug target/116433] [AVR] cannot place template class static member variables " pinskia at gcc dot gnu.org
2024-08-20 17:55 ` digger1984 at gmx dot com
2024-08-20 21:41 ` gjl at gcc dot gnu.org
2024-08-21  7:57 ` digger1984 at gmx dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).