Bug 737449

Summary: PSTR definition not compatible with new avr-gcc
Product: [Fedora] Fedora Reporter: Michal Hlavinka <mhlavink>
Component: avr-libcAssignee: Thibault North <thibault.north>
Status: CLOSED CURRENTRELEASE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 15CC: andrew.elwell, jwildebo, thibault.north, trond.danielsen
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2012-01-03 22:03:56 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
SDfile.cpp that causes the problem on my machine none

Description Michal Hlavinka 2011-09-12 07:17:26 UTC
Description of problem:
After avr-gcc upgrade, it's not possible to recompile previously working code.
New gcc produces following error:

error: variable '__c' must be const in order to be put into read-only section by means of '__attribute__((progmem))'


Version-Release number of selected component (if applicable):
avr-libc-1.7.0-1

How reproducible:
always

Steps to Reproduce:
main.c
=========================================
#include <avr/pgmspace.h>

int main(void)
{
  const void *x=PSTR("hello");

  for(;x!=0;); /* nothing, just make 'x' used from gcc's point of view */

  return 0;
}
=========================================

$ avr-gcc -c -mmcu=atmega16 -Os -Wall main.c
  
Actual results:
main.c:5:11: error: variable '__c' must be const in order to be put into read-only section by means of '__attribute__((progmem))'

Expected results:
compiled

Additional info:
changing /usr/avr/include/avr/pgmspace.h:255
from
# define PSTR(s) (__extension__({static char __c[] PROGMEM = (s); &__c[0];}))
to
# define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];}))

fixes this problem

Comment 1 Thibault North 2011-09-13 02:16:59 UTC
Here is a new package which includes these fix. Does it work now ?
I have issues in the doc generation at the moment so it is not in the package.
F14: http://koji.fedoraproject.org/koji/taskinfo?taskID=3347108
F15: 
http://koji.fedoraproject.org/koji/taskinfo?taskID=3347110

Comment 2 Michal Hlavinka 2011-09-13 08:42:57 UTC
package from koji works fine

Comment 3 Jan Wildeboer 2011-09-13 10:49:30 UTC
Doesn't help on Fedora 15, x86_64

Comment 4 Jan Wildeboer 2011-09-13 10:54:37 UTC
Here the result:

SdFile.cpp: In static member function 'static uint8_t SdFile::make83Name(const char*, uint8_t*)':
SdFile.cpp:259:17: error: variable '__c' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
make: *** [SdFile.o] Error 1


rpm -qa | grep avr

avr-gcc-c++-4.6.1-2.fc15.x86_64
avr-binutils-2.21-2.fc15.x86_64
avr-libc-1.7.1-1.fc15.noarch
avr-gcc-4.6.1-2.fc15.x86_64
avrdude-5.10-3.fc15.x86_64

uname -a

Linux jhwx200.home.lan 2.6.40.4-5.fc15.x86_64 #1 SMP Tue Aug 30 14:38:32 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux

Trying to compile Sprinter (reprap 3D printer firmware)

Comment 5 Michal Hlavinka 2011-09-13 11:21:09 UTC
(In reply to comment #3)
> Doesn't help on Fedora 15, x86_64

that's exactly where I tested it. Does my reproducer work for you?

Just curious, could you paste that broken code here?

Btw, this bug was in PSTR definition that did not use const in it's internal type definition. I guess that there is some code out there, that uses it's own types just declared as PROGMEM, but not 'const'. This will break with updated avr-gcc, but it needs to be fixed in the code affected or avr-gcc must be silenced, afaik there's not too much that can be done in avr-libc without breaking old (proper) code.

Updated test case (it's expected to fail with updated avr-gcc):
==================================
#include <avr/pgmspace.h>

int main(void)
{
  const void *x=PSTR("hello");
  static const char y[] PROGMEM ="foo";
  static char z[] PROGMEM ="bar";

  for(;x!=y && y[0] && z[0];); /* nothing, just make x,y,z used from gcc's point of view */

  return 0;
}
==================================

$ avr-gcc -c -mmcu=atmega16 -Os -Wall main.c

main.c:7:16: error: variable 'z' must be const in order to be put into read-only section by means of '__attribute__((progmem))'

Comment 6 Jan Wildeboer 2011-09-13 11:37:54 UTC
Created attachment 522908 [details]
SDfile.cpp that causes the problem on my machine

Comment 7 Jan Wildeboer 2011-09-13 11:40:25 UTC
I have added the SDfile.cpp which is the original Arduino SdFat Library AFAICS.

The problem is caused in line 259:

     // illegal FAT characters
      PGM_P p = PSTR("|<>^+=?/[];,*\"\\");

So I will now hunt for the definition of PSTR used in this context.

I need to recompile the SDfat library as my target board is a Samnguino, which uses the ATMega 644p and the precompiled libraries of the arduino IDE are not available for Sanguino.

Comment 8 Michal Hlavinka 2011-09-13 11:57:02 UTC
I've added that line to reproducer and it works fine. Also both PGM_P and PSTR definitions in pgmspace.h are correct.

#include <avr/pgmspace.h>

int main(void)
{
  const void *x=PSTR("hello");
  static const char y[] PROGMEM ="foo";
  static char z[] PROGMEM ="bar";
  PGM_P p = PSTR("|<>^+=?/[];,*\"\\");

/* preprocessed as:

 const prog_char * p = (__extension__({static const char __c[] __attribute__((__progmem__)) = ("|<>^+=?/[];,*\"\\"); &__c[0];}));

*/

  for(;x!=y && y[0] && z[0] && p!=x;); /* nothing, just make x,y,z used from gcc's point of view */

  return 0;
}

So you should verify you have correct version installed and that your sources do not bundle own copy of pgmspace.h 
check /usr/avr/include/avr/pgmspace.h line 255 for 'const'
and check preprocessed output of SDfile.cpp (just add -E to compiler) and you should know, where the problem is.

Comment 9 Jan Wildeboer 2011-09-13 12:14:13 UTC
Hm. My preprocessed file looks OK. I did:

# /usr/bin/avr-g++ -c -mmcu=atmega644p  -I. -DF_CPU=16000000 -I/usr/share/arduino/hardware/arduino/cores/arduino -Os -Wall  -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -w -ffunction-sections -fdata-sections -DARDUINO=22 -E SdFile.cpp -o SdFile.o

The generated SdFile.o has:

      const prog_char * p = (__extension__({static const char __c[] __attribute__((__progmem__)) = ("|<>^+=?/[];,*\"\\"); &__c[0];}));

But without the -E I still get:

# /usr/bin/avr-g++ -c -mmcu=atmega644p  -I. -DF_CPU=16000000 -I/usr/share/arduino/hardware/arduino/cores/arduino -Os -Wall  -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -w -ffunction-sections -fdata-sections -DARDUINO=22 SdFile.cpp -o SdFile.o
SdFile.cpp: In static member function 'static uint8_t SdFile::make83Name(const char*, uint8_t*)':
SdFile.cpp:259:17: error: variable '__c' must be const in order to be put into read-only section by means of '__attribute__((progmem))'

I have checked that I have the correct /usr/avr/include/avr/pgmspace.h and line 255 has the const.

I am a bit lost now. There is no other pgmspace.h on my box.

Comment 10 Michal Hlavinka 2011-09-13 12:47:31 UTC
(In reply to comment #9)
> I am a bit lost now. There is no other pgmspace.h on my box.

I've tried it with pre-processed output:
======================
typedef char prog_char __attribute__((__progmem__));

int main(void)
{
 const void *x=(__extension__({static const char __c[] __attribute__((__progmem__)) = ("hello"); &__c[0];}));
 static const char y[] __attribute__((__progmem__)) ="foo";
 const prog_char * p = (__extension__({static const char __c[] __attribute__((__progmem__)) = ("|<>^+=?/[];,*\"\\"); &__c[0];}));

 for(;x!=y && y[0] && p!=x;);

 return 0;
}
======================
avr-gcc ... works
avr-g++ ... complains

Seems it's bug in gcc-4.6.x, so I've googled a little and found:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49764
so file a new bug against avr-gcc

Comment 11 Jan Wildeboer 2011-09-13 13:12:33 UTC
Thank you, Michael - seems you have hit the problem on the head!

That bug report is exactly the problem I am seeing here.

Will file BZ against avr-gcc :-)

Comment 12 Jan Wildeboer 2011-09-13 13:20:58 UTC
Added BZ #737950 with a reproducer snippet

Comment 13 Thibault North 2012-01-03 22:03:56 UTC
Closing, as BZ #737950 was closed.