public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* static class member as interrupt handler works, but not if class is templated
@ 2021-04-10 13:33 Klaus Rudolph
  2021-04-10 15:26 ` Jonathan Wakely
  2021-04-12  9:20 ` Peter Sommerlad (C++)
  0 siblings, 2 replies; 14+ messages in thread
From: Klaus Rudolph @ 2021-04-10 13:33 UTC (permalink / raw)
  To: gcc-help, avr-gcc-list

Hi all,

if I write a class with static member function I can use it as an
interrupt handler as follows:

class Dummy
{
     static void Handler() __asm__("__vector_10")
__attribute__((__signal__, __used__, __externally_visible__));
};

void Dummy::Handler()
{

}

I can see the vector is entered in the handler table:



   1c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
   20:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
   24:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
   28:	0c 94 36 00 	jmp	0x6c	; 0x6c <__vector_10>
   2c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
   30:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>

###################

But if the class becomes a template, the function is not longer entered
in the handler. How can I fix it?

template < int i >
class Dummy
{
     static void Handler() __asm__("__vector_10")
__attribute__((__signal__, __used__, __externally_visible__));
};

template < int i>
void Dummy<i>::Handler()
{

}

Dummy<1> d1;

   20:	0c 94 3c 00 	jmp	0x78	; 0x78 <__bad_interrupt>
   24:	0c 94 3c 00 	jmp	0x78	; 0x78 <__bad_interrupt>
   28:	0c 94 3c 00 	jmp	0x78	; 0x78 <__bad_interrupt>
   2c:	0c 94 3c 00 	jmp	0x78	; 0x78 <__bad_interrupt>
   30:	0c 94 3c 00 	jmp	0x78	; 0x78 <__bad_interrupt>


I tried it with avr-g++ (Fedora 10.2.0-1.fc33) 10.2.0

Thanks!



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

* Re: static class member as interrupt handler works, but not if class is templated
  2021-04-10 13:33 static class member as interrupt handler works, but not if class is templated Klaus Rudolph
@ 2021-04-10 15:26 ` Jonathan Wakely
  2021-04-10 19:36   ` Trampas Stern
  2021-04-10 20:11   ` Klaus
  2021-04-12  9:20 ` Peter Sommerlad (C++)
  1 sibling, 2 replies; 14+ messages in thread
From: Jonathan Wakely @ 2021-04-10 15:26 UTC (permalink / raw)
  To: Klaus Rudolph; +Cc: gcc-help, avr-gcc-list

On Sat, 10 Apr 2021, 15:07 Klaus Rudolph via Gcc-help, <gcc-help@gcc.gnu.org>
wrote:

> Hi all,
>
> if I write a class with static member function I can use it as an
> interrupt handler as follows:
>
> class Dummy
> {
>      static void Handler() __asm__("__vector_10")
> __attribute__((__signal__, __used__, __externally_visible__));
> };
>
> void Dummy::Handler()
> {
>
> }
>
> I can see the vector is entered in the handler table:
>
>
>
>    1c:  0c 94 34 00     jmp     0x68    ; 0x68 <__bad_interrupt>
>    20:  0c 94 34 00     jmp     0x68    ; 0x68 <__bad_interrupt>
>    24:  0c 94 34 00     jmp     0x68    ; 0x68 <__bad_interrupt>
>    28:  0c 94 36 00     jmp     0x6c    ; 0x6c <__vector_10>
>    2c:  0c 94 34 00     jmp     0x68    ; 0x68 <__bad_interrupt>
>    30:  0c 94 34 00     jmp     0x68    ; 0x68 <__bad_interrupt>
>
> ###################
>
> But if the class becomes a template, the function is not longer entered
> in the handler. How can I fix it?
>
> template < int i >
> class Dummy
> {
>      static void Handler() __asm__("__vector_10")
> __attribute__((__signal__, __used__, __externally_visible__));
> };
>
> template < int i>
> void Dummy<i>::Handler()
> {
>
> }
>
> Dummy<1> d1;
>

This doesn't cause the instantiation of the member function.

Have you tried an explicit instantiation?

template class Dummy<1>;

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

* Re: static class member as interrupt handler works, but not if class is templated
  2021-04-10 15:26 ` Jonathan Wakely
@ 2021-04-10 19:36   ` Trampas Stern
  2021-04-10 20:11   ` Klaus
  1 sibling, 0 replies; 14+ messages in thread
From: Trampas Stern @ 2021-04-10 19:36 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: Klaus Rudolph, gcc-help, avr-gcc-list

I wish there was a better way to interrupt handlers in classes, for
embedded.  For example I write a UART class as a driver which I
initialize by passing a pointer to hardware address.  However because
different UARTs use different interrupt vectors I end up having to have the
extern C and create each handler which then I have to register a callback
for the handler to call the correct method in class instance.

If you guys have a better way I would love to know.

Thanks
Trampas



On Sat, Apr 10, 2021 at 11:26 AM Jonathan Wakely <jwakely.gcc@gmail.com>
wrote:

>
>
> On Sat, 10 Apr 2021, 15:07 Klaus Rudolph via Gcc-help, <
> gcc-help@gcc.gnu.org> wrote:
>
>> Hi all,
>>
>> if I write a class with static member function I can use it as an
>> interrupt handler as follows:
>>
>> class Dummy
>> {
>>      static void Handler() __asm__("__vector_10")
>> __attribute__((__signal__, __used__, __externally_visible__));
>> };
>>
>> void Dummy::Handler()
>> {
>>
>> }
>>
>> I can see the vector is entered in the handler table:
>>
>>
>>
>>    1c:  0c 94 34 00     jmp     0x68    ; 0x68 <__bad_interrupt>
>>    20:  0c 94 34 00     jmp     0x68    ; 0x68 <__bad_interrupt>
>>    24:  0c 94 34 00     jmp     0x68    ; 0x68 <__bad_interrupt>
>>    28:  0c 94 36 00     jmp     0x6c    ; 0x6c <__vector_10>
>>    2c:  0c 94 34 00     jmp     0x68    ; 0x68 <__bad_interrupt>
>>    30:  0c 94 34 00     jmp     0x68    ; 0x68 <__bad_interrupt>
>>
>> ###################
>>
>> But if the class becomes a template, the function is not longer entered
>> in the handler. How can I fix it?
>>
>> template < int i >
>> class Dummy
>> {
>>      static void Handler() __asm__("__vector_10")
>> __attribute__((__signal__, __used__, __externally_visible__));
>> };
>>
>> template < int i>
>> void Dummy<i>::Handler()
>> {
>>
>> }
>>
>> Dummy<1> d1;
>>
>
> This doesn't cause the instantiation of the member function.
>
> Have you tried an explicit instantiation?
>
> template class Dummy<1>;
>
>
>
>

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

* Re: static class member as interrupt handler works, but not if class is templated
  2021-04-10 15:26 ` Jonathan Wakely
  2021-04-10 19:36   ` Trampas Stern
@ 2021-04-10 20:11   ` Klaus
  2021-04-11 12:21     ` David Brown
  1 sibling, 1 reply; 14+ messages in thread
From: Klaus @ 2021-04-10 20:11 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc-help, avr-gcc-list

Hi,



Am 10.04.21 um 17:26 schrieb Jonathan Wakely:

>
>     Dummy<1> d1;
>
>
> This doesn't cause the instantiation of the member function.
>
> Have you tried an explicit instantiation?
>
> template class Dummy<1>;

Did not change anything.

If I use my original code, I get the instantiation of the function:

0000007e <Dummy<1>::Handler()>:
   7e:	18 95       	reti

But it is simply not named as "__vector_10" which is the problem. The
member function is instantiated but still with wrong name even with my
or your code.

Klaus


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

* Re: static class member as interrupt handler works, but not if class is templated
  2021-04-10 20:11   ` Klaus
@ 2021-04-11 12:21     ` David Brown
  2021-04-11 23:33       ` Trampas Stern
  0 siblings, 1 reply; 14+ messages in thread
From: David Brown @ 2021-04-11 12:21 UTC (permalink / raw)
  To: Klaus, Jonathan Wakely; +Cc: gcc-help, avr-gcc-list

On 10/04/2021 22:11, Klaus via Gcc-help wrote:
> Hi,
> 
> 
> 
> Am 10.04.21 um 17:26 schrieb Jonathan Wakely:
> 
>>
>>     Dummy<1> d1;
>>
>>
>> This doesn't cause the instantiation of the member function.
>>
>> Have you tried an explicit instantiation?
>>
>> template class Dummy<1>;
> 
> Did not change anything.
> 
> If I use my original code, I get the instantiation of the function:
> 
> 0000007e <Dummy<1>::Handler()>:
>   7e:    18 95           reti
> 
> But it is simply not named as "__vector_10" which is the problem. The
> member function is instantiated but still with wrong name even with my
> or your code.
> 
> Klaus
> 
> 

To my knowledge, there isn't a better way than to make specific
dedicated stand-alone functions:

static void Handler_1() __asm__("__vector_10")
__attribute__((__signal__, __used__, __externally_visibile__))
{
	Dummy<1>::Handler();
}

For device drivers like that, you have a specific number of
instantiations that match the number of peripherals on the particular
microcontroller.  And they each have different vectors.  There really
isn't any other better way, to my knowledge.  (You can use a bit of
pre-processing macros and conditional compilation to automate it a bit,
generating as many of these functions as there are UARTs or whatever
defined in the device header files for the microcontroller.)

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

* Re: static class member as interrupt handler works, but not if class is templated
  2021-04-11 12:21     ` David Brown
@ 2021-04-11 23:33       ` Trampas Stern
  0 siblings, 0 replies; 14+ messages in thread
From: Trampas Stern @ 2021-04-11 23:33 UTC (permalink / raw)
  To: David Brown; +Cc: Klaus, Jonathan Wakely, gcc-help, avr-gcc-list

In C++ for interrupt vectors in drivers I set up an array of pointers to
function all the peripheral driver code  like this for timer counters.

static voidCallback_t _isr_funcs[TC_INST_NUM]={NULL};

Then in each handler if the pointer is not null I call it.  This is a lot
of work and overhead but it works.

On Sun, Apr 11, 2021 at 8:21 AM David Brown <david.brown@hesbynett.no>
wrote:

> On 10/04/2021 22:11, Klaus via Gcc-help wrote:
> > Hi,
> >
> >
> >
> > Am 10.04.21 um 17:26 schrieb Jonathan Wakely:
> >
> >>
> >>     Dummy<1> d1;
> >>
> >>
> >> This doesn't cause the instantiation of the member function.
> >>
> >> Have you tried an explicit instantiation?
> >>
> >> template class Dummy<1>;
> >
> > Did not change anything.
> >
> > If I use my original code, I get the instantiation of the function:
> >
> > 0000007e <Dummy<1>::Handler()>:
> >   7e:    18 95           reti
> >
> > But it is simply not named as "__vector_10" which is the problem. The
> > member function is instantiated but still with wrong name even with my
> > or your code.
> >
> > Klaus
> >
> >
>
> To my knowledge, there isn't a better way than to make specific
> dedicated stand-alone functions:
>
> static void Handler_1() __asm__("__vector_10")
> __attribute__((__signal__, __used__, __externally_visibile__))
> {
>         Dummy<1>::Handler();
> }
>
> For device drivers like that, you have a specific number of
> instantiations that match the number of peripherals on the particular
> microcontroller.  And they each have different vectors.  There really
> isn't any other better way, to my knowledge.  (You can use a bit of
> pre-processing macros and conditional compilation to automate it a bit,
> generating as many of these functions as there are UARTs or whatever
> defined in the device header files for the microcontroller.)
>
>

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

* Re: static class member as interrupt handler works, but not if class is templated
  2021-04-10 13:33 static class member as interrupt handler works, but not if class is templated Klaus Rudolph
  2021-04-10 15:26 ` Jonathan Wakely
@ 2021-04-12  9:20 ` Peter Sommerlad (C++)
  2021-04-12 11:16   ` Klaus Rudolph
  1 sibling, 1 reply; 14+ messages in thread
From: Peter Sommerlad (C++) @ 2021-04-12  9:20 UTC (permalink / raw)
  To: Klaus Rudolph; +Cc: gcc-help, avr-gcc-list

Klaus,

I do not have a solution, but I try to be helpful and give a list what I 
would try to understand the situation:

- why is the special name __vector_10 used to get the function address 
into the interrupt table? Is there another way, or is the environment 
insisting on such a name? Can you change the linker (i.e. with a 
dedicated map file) to get the Dummy<i>::Handler into the table.

- Is the static Handler() function dependent on the template parameter? 
If not, you can put it into a base class of the class template.

- what is the means that a function is considered to be an interrupt 
handler? What does the tooling do between the compiler generating object 
code and the binary that ends up in flash? How does it work?

- figure out, where the special handling of the __vector_10 seems to 
happen, and why it is not happening in the class template case. This 
might help diagnose if and where to fix it within the compiler.

That is what I have in the top of my head at the moment.

In the end, you might need to either change the tools or their 
configuration to get what you want.

Regards
Peter.

Klaus Rudolph wrote on 10.04.21 15:33:
> Hi all,
> 
> if I write a class with static member function I can use it as an
> interrupt handler as follows:
> 
> class Dummy
> {
>      static void Handler() __asm__("__vector_10")
> __attribute__((__signal__, __used__, __externally_visible__));
> };
> 
> void Dummy::Handler()
> {
> 
> }
> 
> I can see the vector is entered in the handler table:
> 
> 
> 
>    1c:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
>    20:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
>    24:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
>    28:    0c 94 36 00     jmp    0x6c    ; 0x6c <__vector_10>
>    2c:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
>    30:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
> 
> ###################
> 
> But if the class becomes a template, the function is not longer entered
> in the handler. How can I fix it?
> 
> template < int i >
> class Dummy
> {
>      static void Handler() __asm__("__vector_10")
> __attribute__((__signal__, __used__, __externally_visible__));
> };
> 
> template < int i>
> void Dummy<i>::Handler()
> {
> 
> }
> 
> Dummy<1> d1;
> 
>    20:    0c 94 3c 00     jmp    0x78    ; 0x78 <__bad_interrupt>
>    24:    0c 94 3c 00     jmp    0x78    ; 0x78 <__bad_interrupt>
>    28:    0c 94 3c 00     jmp    0x78    ; 0x78 <__bad_interrupt>
>    2c:    0c 94 3c 00     jmp    0x78    ; 0x78 <__bad_interrupt>
>    30:    0c 94 3c 00     jmp    0x78    ; 0x78 <__bad_interrupt>
> 
> 
> I tried it with avr-g++ (Fedora 10.2.0-1.fc33) 10.2.0
> 
> Thanks!
> 
> 
> 


-- 
Peter Sommerlad

Better Software: Consulting, Training, Reviews
Modern, Safe & Agile C++

peter.cpp@sommerlad.ch
+41 79 432 23 32

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

* Re: static class member as interrupt handler works, but not if class is templated
  2021-04-12  9:20 ` Peter Sommerlad (C++)
@ 2021-04-12 11:16   ` Klaus Rudolph
  2021-04-12 11:53     ` Matthijs Kooijman
  0 siblings, 1 reply; 14+ messages in thread
From: Klaus Rudolph @ 2021-04-12 11:16 UTC (permalink / raw)
  To: Peter Sommerlad (C++); +Cc: gcc-help, avr-gcc-list

Hi,


Am 12.04.21 um 11:20 schrieb Peter Sommerlad (C++):

> - why is the special name __vector_10 used to get the function address
> into the interrupt table? Is there another way, or is the environment
> insisting on such a name? Can you change the linker (i.e. with a
> dedicated map file) to get the Dummy<i>::Handler into the table.

Currently the library (avr-libc) has a interrupt vector table which
simple uses the names __vector_xx. The linker collects all functions
with this naming conventions and replace the function address in that
table.

>
> - Is the static Handler() function dependent on the template parameter?
> If not, you can put it into a base class of the class template.

Yes, if not, it can be omitted, quite clear.

>
> - what is the means that a function is considered to be an interrupt
> handler? What does the tooling do between the compiler generating object
> code and the binary that ends up in flash? How does it work?

The attribute for an interrupt handler added to a function adds the
following to the code of the function:

Save all registers
.. normal function content ...
restore all registers
use "reti" instead of "ret" for returning to the "calling context".


>
> - figure out, where the special handling of the __vector_10 seems to
> happen, and why it is not happening in the class template case. This
> might help diagnose if and where to fix it within the compiler.

That is compiler internals... yes, if it is a compiler bug, it is the
way to have a solution. But in that case, it seems to be a generic
problem for gcc as attributes are not assigned to any templated class
member functions. No idea if this is related to the target ( avr ) or
generic for all platforms. But I never did any change inside the
compiler. Any help is welcome!


> In the end, you might need to either change the tools or their
> configuration to get what you want.

I was in hope, that I did something wrong or a workaround is known to
this problem. If that is not the case, I can fix the compiler, change
the linker, modify the avr-libc... yes. But in all this cases, I will
still use C style handlers for this purpose. It is uggly, but C++ on AVR
is always ugly ( v-table in RAM, jump for switch case in RAM, no STL
support ).

If someone can point me to the "problem" inside the compiler, I can give
it a try, but it seems to be the long way :-) But maybe a funny one and
helpful for others.

In general: Why assigning attributes to member functions in templated
class context fails? For me it looks like a bug.

Klaus

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

* Re: static class member as interrupt handler works, but not if class is templated
  2021-04-12 11:16   ` Klaus Rudolph
@ 2021-04-12 11:53     ` Matthijs Kooijman
  2021-04-12 12:12       ` Klaus Rudolph
  0 siblings, 1 reply; 14+ messages in thread
From: Matthijs Kooijman @ 2021-04-12 11:53 UTC (permalink / raw)
  To: Klaus Rudolph; +Cc: Peter Sommerlad (C++), gcc-help, avr-gcc-list

[-- Attachment #1: Type: text/plain, Size: 1921 bytes --]

> > - figure out, where the special handling of the __vector_10 seems to
> > happen, and why it is not happening in the class template case. This
> > might help diagnose if and where to fix it within the compiler.
> 
> That is compiler internals... yes, if it is a compiler bug, it is the
> way to have a solution. But in that case, it seems to be a generic
> problem for gcc as attributes are not assigned to any templated class
> member functions. No idea if this is related to the target ( avr ) or
> generic for all platforms. But I never did any change inside the
> compiler. Any help is welcome!

My suspiciou would be that this is a generic gcc problem, where the
"asm" attribute is not honoured for template functions. It probably also
makes some sense, since a template is intended to be instantiated
multiple times, and each instantiation gets a name that is generated
based on (I believe) the template arguments passed, so I suspect that
the "generate a name for this template instantiation" code doesn't look
at the asm attribute.

Also note that *if* it would, then each instantiation would use the same
name and multiple instanations would result in duplicate symbols. If you
would bring this up as a gcc bug, I wouldn't be surprised that it would
be closed as wontfix for this reason.

Another workaround that I think hasn't been suggested yet, would be to
just define a global `__vector_10` function and from that just call your
templated static member. Combined with the `always_inline` attribute,
you can ensure that the call is inlined and there is no runtime overhead
(with LTO, this probably already happens when there's just a single call
to the member).

Maybe not as nice and self-contained as the asm attribute, but it does
allow multiple instantiations (where the global function defines which
instantiation is going to be used for the ISR).

Gr.

Matthijs

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: static class member as interrupt handler works, but not if class is templated
  2021-04-12 11:53     ` Matthijs Kooijman
@ 2021-04-12 12:12       ` Klaus Rudolph
  2021-04-12 13:46         ` David Brown
  2021-04-12 14:25         ` Anton Staaf
  0 siblings, 2 replies; 14+ messages in thread
From: Klaus Rudolph @ 2021-04-12 12:12 UTC (permalink / raw)
  To: Peter Sommerlad (C++), gcc-help, avr-gcc-list

Am 12.04.21 um 13:53 schrieb Matthijs Kooijman:
>>> - figure out, where the special handling of the __vector_10 seems to
>>> happen, and why it is not happening in the class template case. This
>>> might help diagnose if and where to fix it within the compiler.
>>
>> That is compiler internals... yes, if it is a compiler bug, it is the
>> way to have a solution. But in that case, it seems to be a generic
>> problem for gcc as attributes are not assigned to any templated class
>> member functions. No idea if this is related to the target ( avr ) or
>> generic for all platforms. But I never did any change inside the
>> compiler. Any help is welcome!
>
> My suspiciou would be that this is a generic gcc problem, where the
> "asm" attribute is not honoured for template functions. It probably also
> makes some sense, since a template is intended to be instantiated
> multiple times, and each instantiation gets a name that is generated
> based on (I believe) the template arguments passed, so I suspect that
> the "generate a name for this template instantiation" code doesn't look
> at the asm attribute.
>
> Also note that *if* it would, then each instantiation would use the same
> name and multiple instanations would result in duplicate symbols. If you
> would bring this up as a gcc bug, I wouldn't be surprised that it would
> be closed as wontfix for this reason.

I disagree as a template "always" would be instantiated multiple times.
And even if it would be, the linker will fire a error message, as it
sees multiple definitions. So there is no "general" problem in
"renaming" a templated function. It simply *can* work.

But it looks that not only the "renaming" stuff did not work, all the
flags are not handled with the templated function. Looks like that the
asm declaration did not find its target :-)

>
> Another workaround that I think hasn't been suggested yet, would be to
> just define a global `__vector_10` function and from that just call your
> templated static member.

That is the classical way "we" all work. And it optimizes well in that
case as the code from the static templated member is fully inlined. But
it is still a workaround and it simply breaks standard c++ coding. Yes,
we can write C with classes, but I simply dislike :-)

> Combined with the `always_inline` attribute,
> you can ensure that the call is inlined and there is no runtime overhead
> (with LTO, this probably already happens when there's just a single call
> to the member).

It already optimizes well in O2 if templated member function and free
handler definition is in same translation unit.

Klaus


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

* Re: static class member as interrupt handler works, but not if class is templated
  2021-04-12 12:12       ` Klaus Rudolph
@ 2021-04-12 13:46         ` David Brown
  2021-04-12 14:56           ` Klaus Rudolph
  2021-04-12 14:25         ` Anton Staaf
  1 sibling, 1 reply; 14+ messages in thread
From: David Brown @ 2021-04-12 13:46 UTC (permalink / raw)
  To: Klaus Rudolph, Peter Sommerlad (C++), gcc-help, avr-gcc-list

On 12/04/2021 14:12, Klaus Rudolph via Gcc-help wrote:
> Am 12.04.21 um 13:53 schrieb Matthijs Kooijman:
>>>> - figure out, where the special handling of the __vector_10 seems to
>>>> happen, and why it is not happening in the class template case. This
>>>> might help diagnose if and where to fix it within the compiler.
>>>
>>> That is compiler internals... yes, if it is a compiler bug, it is the
>>> way to have a solution. But in that case, it seems to be a generic
>>> problem for gcc as attributes are not assigned to any templated class
>>> member functions. No idea if this is related to the target ( avr ) or
>>> generic for all platforms. But I never did any change inside the
>>> compiler. Any help is welcome!
>>
>> My suspiciou would be that this is a generic gcc problem, where the
>> "asm" attribute is not honoured for template functions. It probably also
>> makes some sense, since a template is intended to be instantiated
>> multiple times, and each instantiation gets a name that is generated
>> based on (I believe) the template arguments passed, so I suspect that
>> the "generate a name for this template instantiation" code doesn't look
>> at the asm attribute.
>>
>> Also note that *if* it would, then each instantiation would use the same
>> name and multiple instanations would result in duplicate symbols. If you
>> would bring this up as a gcc bug, I wouldn't be surprised that it would
>> be closed as wontfix for this reason.
> 
> I disagree as a template "always" would be instantiated multiple times.
> And even if it would be, the linker will fire a error message, as it
> sees multiple definitions. So there is no "general" problem in
> "renaming" a templated function. It simply *can* work.

Certainly templates can be instantiated zero, once, or multiple times.
And certainly some templates are intended only to be instantiated a
single time.  But it would surely be difficult to have a feature that
only works when there is a single instantiation.

There is also the issue of linkage of the names here.  A template
instantiation has function/method names that are mangled with the
template type, template parameters, parameter types, etc.  These have a
particular kind of linkage that lets the toolchain (compiler, assembler
and linker) know that they can be defined in more than one unit, and at
link time one of them (by unspecified choice) can be picked for the
final binary.  An assembly-defined specific name for an interrupt
vector, on the other hand, is a C external linkage name that can only be
defined once.  I don't see that these two uses could easily be combined.

It seems natural to me that a feature which can only be relevant to a
single instantiation of a template should be connected to an
instantiation, not a definition.  This is particularly true when the
details of the attribute you want - the "vector" assembly name - are
dependent on a non-type parameter for the template.

> 
> But it looks that not only the "renaming" stuff did not work, all the
> flags are not handled with the templated function. Looks like that the
> asm declaration did not find its target :-)
> 
>>
>> Another workaround that I think hasn't been suggested yet, would be to
>> just define a global `__vector_10` function and from that just call your
>> templated static member.
> 
> That is the classical way "we" all work. And it optimizes well in that
> case as the code from the static templated member is fully inlined. But
> it is still a workaround and it simply breaks standard c++ coding. Yes,
> we can write C with classes, but I simply dislike :-)
> 

Unfortunately, C++ can't do everything - even with gcc extensions.
There are all sorts of things that could be useful to have, but simply
are not practical or possible to implement.

One that I would like is a way to have a class or template instantiation
that is at file/namespace scope, but which is constructed before first
use rather than before main() starts.  But it should not have the
overhead of run-time checks or indirect access (so no static class
member).  I think it is fair to say it is not going to happen - so I
need manual "init" functions with lists of "init" method calls for each
object.

>> Combined with the `always_inline` attribute,
>> you can ensure that the call is inlined and there is no runtime overhead
>> (with LTO, this probably already happens when there's just a single call
>> to the member).
> 
> It already optimizes well in O2 if templated member function and free
> handler definition is in same translation unit.
> 
> Klaus
> 
> 


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

* Re: static class member as interrupt handler works, but not if class is templated
  2021-04-12 12:12       ` Klaus Rudolph
  2021-04-12 13:46         ` David Brown
@ 2021-04-12 14:25         ` Anton Staaf
  2021-04-12 15:06           ` Klaus Rudolph
  1 sibling, 1 reply; 14+ messages in thread
From: Anton Staaf @ 2021-04-12 14:25 UTC (permalink / raw)
  To: Klaus Rudolph; +Cc: Peter Sommerlad (C++), gcc-help, avr-gcc-list

Klaus, I'm not sure if my previous answer didn't make it through or was
just missed, but I believe your problem is related to this GCC bug:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70435

-Anton


On Mon, Apr 12, 2021 at 5:14 AM Klaus Rudolph <lts-rudolph@gmx.de> wrote:

> Am 12.04.21 um 13:53 schrieb Matthijs Kooijman:
> >>> - figure out, where the special handling of the __vector_10 seems to
> >>> happen, and why it is not happening in the class template case. This
> >>> might help diagnose if and where to fix it within the compiler.
> >>
> >> That is compiler internals... yes, if it is a compiler bug, it is the
> >> way to have a solution. But in that case, it seems to be a generic
> >> problem for gcc as attributes are not assigned to any templated class
> >> member functions. No idea if this is related to the target ( avr ) or
> >> generic for all platforms. But I never did any change inside the
> >> compiler. Any help is welcome!
> >
> > My suspiciou would be that this is a generic gcc problem, where the
> > "asm" attribute is not honoured for template functions. It probably also
> > makes some sense, since a template is intended to be instantiated
> > multiple times, and each instantiation gets a name that is generated
> > based on (I believe) the template arguments passed, so I suspect that
> > the "generate a name for this template instantiation" code doesn't look
> > at the asm attribute.
> >
> > Also note that *if* it would, then each instantiation would use the same
> > name and multiple instanations would result in duplicate symbols. If you
> > would bring this up as a gcc bug, I wouldn't be surprised that it would
> > be closed as wontfix for this reason.
>
> I disagree as a template "always" would be instantiated multiple times.
> And even if it would be, the linker will fire a error message, as it
> sees multiple definitions. So there is no "general" problem in
> "renaming" a templated function. It simply *can* work.
>
> But it looks that not only the "renaming" stuff did not work, all the
> flags are not handled with the templated function. Looks like that the
> asm declaration did not find its target :-)
>
> >
> > Another workaround that I think hasn't been suggested yet, would be to
> > just define a global `__vector_10` function and from that just call your
> > templated static member.
>
> That is the classical way "we" all work. And it optimizes well in that
> case as the code from the static templated member is fully inlined. But
> it is still a workaround and it simply breaks standard c++ coding. Yes,
> we can write C with classes, but I simply dislike :-)
>
> > Combined with the `always_inline` attribute,
> > you can ensure that the call is inlined and there is no runtime overhead
> > (with LTO, this probably already happens when there's just a single call
> > to the member).
>
> It already optimizes well in O2 if templated member function and free
> handler definition is in same translation unit.
>
> Klaus
>
>
>

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

* Re: static class member as interrupt handler works, but not if class is templated
  2021-04-12 13:46         ` David Brown
@ 2021-04-12 14:56           ` Klaus Rudolph
  0 siblings, 0 replies; 14+ messages in thread
From: Klaus Rudolph @ 2021-04-12 14:56 UTC (permalink / raw)
  To: David Brown, Peter Sommerlad (C++), gcc-help, avr-gcc-list

Am 12.04.21 um 15:46 schrieb David Brown:

> Certainly templates can be instantiated zero, once, or multiple times.
> And certainly some templates are intended only to be instantiated a
> single time.  But it would surely be difficult to have a feature that
> only works when there is a single instantiation.

You don't have to be worry about. If it is instantiated zero times,
nothing happens, if it instantiates once, it gets the new name, if it
instantiates multiple times, it get multiple instances with the same
name and fails during linking. Absolutely fine!



>
> There is also the issue of linkage of the names here.  A template
> instantiation has function/method names that are mangled with the
> template type, template parameters, parameter types, etc.  These have a
> particular kind of linkage that lets the toolchain (compiler, assembler
> and linker) know that they can be defined in more than one unit, and at
> link time one of them (by unspecified choice) can be picked for the
> final binary.  An assembly-defined specific name for an interrupt
> vector, on the other hand, is a C external linkage name that can only be
> defined once.  I don't see that these two uses could easily be combined.

There should be anything combined. The templated instance simply should
have the name from asm statement which has C linkage.


>
> It seems natural to me that a feature which can only be relevant to a
> single instantiation of a template should be connected to an
> instantiation, not a definition.  This is particularly true when the
> details of the attribute you want - the "vector" assembly name - are
> dependent on a non-type parameter for the template.

The opposite is meant! It is intended by using the asm statement that we
have a single name, fully independent of parameters for the template.

Klaus

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

* Re: static class member as interrupt handler works, but not if class is templated
  2021-04-12 14:25         ` Anton Staaf
@ 2021-04-12 15:06           ` Klaus Rudolph
  0 siblings, 0 replies; 14+ messages in thread
From: Klaus Rudolph @ 2021-04-12 15:06 UTC (permalink / raw)
  To: Anton Staaf; +Cc: Peter Sommerlad (C++), gcc-help, avr-gcc-list

Am 12.04.21 um 16:25 schrieb Anton Staaf:
> Klaus, I'm not sure if my previous answer didn't make it through or was
> just missed, but I believe your problem is related to this GCC bug:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70435
> <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70435>

Yes, looks related! Thanks! No idea if the [[attribute]] thing is
internally walking the same path as the "asm" attribute. But it looks
that template stuff is not taking part in both actions.

But as we can see: The bug is from Feb 2016 and multiple times confirmed
until 2019...

and after that we see some started to do something but runs into
trouble... last mail from Nov 2019...

Seems to be that there is no chance to get it working as also the
experts are running against a wall.

OK, we have to live with it....

Maybe someone else have a chance to take a look on it?

Thanks
  Klaus

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

end of thread, other threads:[~2021-04-12 15:06 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-10 13:33 static class member as interrupt handler works, but not if class is templated Klaus Rudolph
2021-04-10 15:26 ` Jonathan Wakely
2021-04-10 19:36   ` Trampas Stern
2021-04-10 20:11   ` Klaus
2021-04-11 12:21     ` David Brown
2021-04-11 23:33       ` Trampas Stern
2021-04-12  9:20 ` Peter Sommerlad (C++)
2021-04-12 11:16   ` Klaus Rudolph
2021-04-12 11:53     ` Matthijs Kooijman
2021-04-12 12:12       ` Klaus Rudolph
2021-04-12 13:46         ` David Brown
2021-04-12 14:56           ` Klaus Rudolph
2021-04-12 14:25         ` Anton Staaf
2021-04-12 15:06           ` Klaus Rudolph

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).