const volatile behaviour change in GCC 7

Sebastian Huber sebastian.huber@embedded-brains.de
Thu Sep 22 07:23:00 GMT 2016


Hello,

for RTEMS we use linker sets to initialize the system. The following 
code worked up to GCC 6, but no longer in GCC 7:

typedef void ( *rtems_sysinit_handler )( void );

typedef struct {
   rtems_sysinit_handler handler;
} rtems_sysinit_item;

rtems_sysinit_item volatile const _Linker_set__Sysinit_begin[0]
__attribute__((__section__(".rtemsroset." "_Sysinit" ".begin")))
__attribute__((__used__));

rtems_sysinit_item volatile const _Linker_set__Sysinit_end[0]
__attribute__((__section__(".rtemsroset." "_Sysinit" ".end")))
__attribute__((__used__));

void rtems_initialize_executive(void)
{
   const volatile rtems_sysinit_item *cur = _Linker_set__Sysinit_begin;
   const volatile rtems_sysinit_item *end = _Linker_set__Sysinit_end;

   while ( cur != end ) {
     ( *cur->handler )();
     ++cur;
   }
}

The corresponding GNU ld linker script section is:

     .rtemsroset : ALIGN_WITH_INPUT {
         KEEP (*(SORT(.rtemsroset.*)))
     } > REGION_RODATA AT > REGION_RODATA_LOAD

In GCC 7, the compiler deduces that "cur != end" is always true and 
generates an infinite loop.

Up to GCC 6 the "volatile const" seemed to prevent this optimization. I 
know that this linker set stuff is quite non-standard, but is there a 
way to get this to work again on GCC 7?

The nice thing with the "type volatile const X[0]..." construct is that 
you can generate arbitrary linker sets via it without a need to edit the 
linker command file and with no storage overhead.

-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber@embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.



More information about the Gcc mailing list