This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/21018] Initializing string literal data improperly marked frame-relative?, should be readonly static const.
- From: "j at uriah dot heep dot sax dot de" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 15 Nov 2007 21:21:50 -0000
- Subject: [Bug middle-end/21018] Initializing string literal data improperly marked frame-relative?, should be readonly static const.
- References: <bug-21018-9497@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #6 from j at uriah dot heep dot sax dot de 2007-11-15 21:21 -------
I'm not sure whether this is related or not... but from the description, it
looks so.
avr-libc contains a macro that helps the users declaring a flash-ROM string,
lacking any real support in GCC for different memory sections (as proposed
by the Embedded C draft). This works by using the GCC extension that a
block can return a value: a block is openened, and a block-scope static
variable is allocated, using the string literal passed in by the user. Then,
that block returns the address of this variable to the caller. By giving
the block-scope variable the "progmem" attribute, it will eventually be
allocated in ROM rather than RAM.
Now, if that macro is called with identical string literals within one
translation unit, the strings are allocated separately rather than merged
into a single location.
This behaviour is reproducable as well on the i386 target, so it looks like
not really related to the avr backend.
Here's a simple test case. For simplicity, the original PSTR() macro is
just reproduced in the file rather than including the entire original
header(s).
#if defined(__AVR__)
# define PROGMEM __attribute__((__progmem__))
#else
# define PROGMEM /* nothing */
#endif
#define PSTR(x) \
(__extension__({static const char __c[] PROGMEM = (x); &__c[0];}))
extern void puts_P(const char *);
void
dosomething(void)
{
puts_P(PSTR("Hello world!"));
puts_P(PSTR("Hello world!"));
}
Compiling for the avr target yields:
.file "foo.c"
__SREG__ = 0x3f
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__tmp_reg__ = 0
__zero_reg__ = 1
.global __do_copy_data
.global __do_clear_bss
.text
.global dosomething
.type dosomething, @function
dosomething:
/* prologue: frame size=0 */
/* prologue end (size=0) */
ldi r24,lo8(__c.1471)
ldi r25,hi8(__c.1471)
rcall puts_P
ldi r24,lo8(__c.1473)
ldi r25,hi8(__c.1473)
rcall puts_P
/* epilogue: frame size=0 */
ret
/* epilogue end (size=1) */
/* function dosomething size 7 (6) */
.size dosomething, .-dosomething
.section .progmem.data,"a",@progbits
.type __c.1473, @object
.size __c.1473, 13
__c.1473:
.string "Hello world!"
.type __c.1471, @object
.size __c.1471, 13
__c.1471:
.string "Hello world!"
/* File "foo.c": code 7 = 0x0007 ( 6), prologues 0, epilogues 1 */
Compiling the same file for the i386 target also shows two copies of the
string literal:
.file "foo.c"
.section .rodata
.type __c.0, @object
.size __c.0, 13
__c.0:
.string "Hello world!"
.type __c.1, @object
.size __c.1, 13
__c.1:
.string "Hello world!"
.text
.globl dosomething
.type dosomething, @function
dosomething:
pushl %ebp
movl %esp, %ebp
pushl $__c.0
call puts_P
movl $__c.1, (%esp)
call puts_P
leave
ret
.size dosomething, .-dosomething
.ident "GCC: (GNU) 3.4.4 [FreeBSD] 20050518"
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21018