Bug 37755 - Mistaken Segmentation fault
Summary: Mistaken Segmentation fault
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.2.3
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic, wrong-code
Depends on:
Blocks:
 
Reported: 2008-10-06 21:15 UTC by Charalampos Pournaris
Modified: 2008-10-07 07:37 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build: gcc -Wall -W
Known to work:
Known to fail:
Last reconfirmed: 2008-10-06 21:25:33


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Charalampos Pournaris 2008-10-06 21:15:03 UTC
GCC Version: 4.2.3
Host: Ubuntu 8.04

When I compile the following code:

#include <stdio.h>

typedef struct person {
  char name[40];
  int age;
} Person;

static Person make_person(void);

int main(void) {
  printf("%s\n", make_person().name);

  return 0;
}

static Person make_person(void) {
  static Person p = { "alexander", 18 };

  return p;
}

I get a false warning:

warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char[40]’

and when I execute the file I get a segmentation fault.

If I use: printf("%s\n", &make_person().name[0]);

everything works as expected and the output "alexander" is printed
Comment 1 Andrew Pinski 2008-10-06 21:25:21 UTC
I don't get a seg fault on ppc but I do on x86.  It works correctly for the C++ front-end where the array decays into a pointer.

The warning is also bogus but it shows what the issue is really.
Comment 2 Andrew Pinski 2008-10-06 21:25:33 UTC
Confirmed.
Comment 3 jsm-csl@polyomino.org.uk 2008-10-06 21:39:26 UTC
Subject: Re:   New: Mistaken Segmentation fault

On Mon, 6 Oct 2008, charpour at gnet dot gr wrote:

>   printf("%s\n", make_person().name);

make_person().name is a non-lvalue array, so it only decays to a pointer 
for C99, not for C90.  If you use -std=c99/-std=gnu99 then the program 
works.

The program does not, however, have defined behavior for C99, only for 
C1x.  In C99 the lifetime of the array ends at the next sequence point, 
before the call to printf.  In C1x it instead ends at the end of the 
evaluation of the containing full expression, which is the call to printf.

I do not believe any changes to GCC are needed to implement this 
particular C1x requirement, since GCC discards information about variables 
lifetimes smaller than a function for gimplification and tree 
optimizations that may change those lifetimes, so it will in practice 
treat the lifetime as being anywhere it cannot show the temporary not to 
be live.

Comment 4 Richard Biener 2008-10-07 07:37:56 UTC
As Joseph said.  Invalid for -std=c89, worksforme for -std=c99.  No changes
needed for -std=c1x.