Bug 17526 - [4.0 Regression] libcpp is miscompiled with -fno-pcc-struct-return -O2
Summary: [4.0 Regression] libcpp is miscompiled with -fno-pcc-struct-return -O2
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.0.0
: P2 critical
Target Milestone: 4.0.0
Assignee: Jason Merrill
URL:
Keywords: build, ice-on-valid-code, monitored, wrong-code
: 18139 (view as bug list)
Depends on: 36326
Blocks: 18107
  Show dependency treegraph
 
Reported: 2004-09-16 20:54 UTC by wanderer
Modified: 2008-05-25 16:47 UTC (History)
6 users (show)

See Also:
Host:
Target: i686-*-*
Build:
Known to work:
Known to fail:
Last reconfirmed: 2004-09-23 11:52:51


Attachments
compressed .ii file (71.74 KB, application/octet-stream)
2004-09-16 21:07 UTC, wanderer
Details
testcase (107 bytes, text/plain)
2004-09-23 09:14 UTC, wanderer
Details

Note You need to log in before you can comment on or make changes to this bug.
Description wanderer 2004-09-16 20:54:30 UTC
Current mainline CVS GCC version bootsrap terminated with error:

---8X----------------------------------------------
/bin/sh ../libtool --tag CXX --
mode=compile /usr/home/wanderer/pkg/build/gcc/obj/gcc/xgcc -shared-libgcc -
B/usr/home/wanderer/pkg/build/gcc/obj/gcc/ -nostdinc++ -
L/usr/home/wanderer/pkg/build/gcc/obj/i386-unknown-freebsd5.1/libstdc++-
v3/src -L/usr/home/wanderer/pkg/build/gcc/obj/i386-unknown-
freebsd5.1/libstdc++-v3/src/.libs -B/home/wanderer/pkg/gcc/i386-unknown-
freebsd5.1/bin/ -B/home/wanderer/pkg/gcc/i386-unknown-freebsd5.1/lib/ -
isystem /home/wanderer/pkg/gcc/i386-unknown-freebsd5.1/include -
isystem /home/wanderer/pkg/gcc/i386-unknown-freebsd5.1/sys-include  -
I/usr/home/wanderer/pkg/build/gcc/obj/i386-unknown-freebsd5.1/libstdc++-
v3/include/i386-unknown-freebsd5.1 -I/usr/home/wanderer/pkg/build/gcc/obj/i386-
unknown-freebsd5.1/libstdc++-v3/include -
I/home/wanderer/pkg/build/gcc/src/gcc/gcc/libstdc++-v3/libsupc++ -O2 -g -O2 -
g -O2 -fno-implicit-templates -Wall -Wextra -Wwrite-strings -Wcast-qual  -
fdiagnostics-show-location=once  -ffunction-sections -fdata-sections  -c -o 
locale_facets.lo /home/wanderer/pkg/build/gcc/src/gcc/gcc/libstdc++-
v3/src/locale_facets.cc
/usr/home/wanderer/pkg/build/gcc/obj/gcc/xgcc -shared-libgcc -
B/usr/home/wanderer/pkg/build/gcc/obj/gcc/ -nostdinc++ -
L/usr/home/wanderer/pkg/build/gcc/obj/i386-unknown-freebsd5.1/libstdc++-
v3/src -L/usr/home/wanderer/pkg/build/gcc/obj/i386-unknown-
freebsd5.1/libstdc++-v3/src/.libs -B/home/wanderer/pkg/gcc/i386-unknown-
freebsd5.1/bin/ -B/home/wanderer/pkg/gcc/i386-unknown-freebsd5.1/lib/ -
isystem /home/wanderer/pkg/gcc/i386-unknown-freebsd5.1/include -
isystem /home/wanderer/pkg/gcc/i386-unknown-freebsd5.1/sys-include -
I/usr/home/wanderer/pkg/build/gcc/obj/i386-unknown-freebsd5.1/libstdc++-
v3/include/i386-unknown-freebsd5.1 -I/usr/home/wanderer/pkg/build/gcc/obj/i386-
unknown-freebsd5.1/libstdc++-v3/include -
I/home/wanderer/pkg/build/gcc/src/gcc/gcc/libstdc++-v3/libsupc++ -O2 -g -O2 -
g -O2 -fno-implicit-templates -Wall -Wextra -Wwrite-strings -Wcast-qual -
fdiagnostics-show-location=once -ffunction-sections -fdata-sections -
c /home/wanderer/pkg/build/gcc/src/gcc/gcc/libstdc++-v3/src/locale_facets.cc  -
fPIC -DPIC -o .libs/locale_facets.o
/home/wanderer/pkg/build/gcc/src/gcc/gcc/libstdc++-v3/src/locale_facets.cc:47: 
internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
gmake[4]: *** [locale_facets.lo] Error 1
gmake[4]: Leaving directory `/usr/home/wanderer/pkg/build/gcc/obj/i386-unknown-
freebsd5.1/libstdc++-v3/src'
gmake[3]: *** [all-recursive] Error 1
gmake[3]: Leaving directory `/usr/home/wanderer/pkg/build/gcc/obj/i386-unknown-
freebsd5.1/libstdc++-v3'
gmake[2]: *** [all] Error 2
gmake[2]: Leaving directory `/usr/home/wanderer/pkg/build/gcc/obj/i386-unknown-
freebsd5.1/libstdc++-v3'
gmake[1]: *** [all-target-libstdc++-v3] Error 2
gmake[1]: Leaving directory `/usr/home/wanderer/pkg/build/gcc/obj'
gmake: *** [bootstrap] Error 2
---X8--------------------------

Version gcc version 4.0.0 20040914 (experimental) bootstrap succesfully.
Comment 1 wanderer 2004-09-16 21:07:39 UTC
Created attachment 7155 [details]
compressed .ii file
Comment 2 Andrew Pinski 2004-09-17 08:53:49 UTC
#1  0x005c0e14 in cpp_interpret_string () at /home/gates/pinskia/src/gnu/gcc/src/libcpp/charset.c:
1163
#2  0x0015fe77 in lex_string () at /home/gates/pinskia/src/gnu/gcc/src/gcc/c-lex.c:731
#3  0x001606dd in c_lex_with_flags () at /home/gates/pinskia/src/gnu/gcc/src/gcc/c-lex.c:431
#4  0x000adef1 in cp_lexer_get_preprocessor_token () at /home/gates/pinskia/src/gnu/gcc/src/gcc/
cp/parser.c:628
#5  0x000adff1 in cp_lexer_read_token () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/parser.c:
509
#6  0x000ae52a in cp_lexer_peek_token () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/parser.c:
715
#7  0x000b29a6 in cp_lexer_next_token_is_not () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/
parser.c:698
#8  0x000b3629 in cp_parser_initializer_clause () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/
parser.c:12106
#9  0x000bf395 in cp_parser_init_declarator () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/
parser.c:12049
#10 0x000bfe86 in cp_parser_single_declaration () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/
parser.c:15042
#11 0x000bffd3 in cp_parser_explicit_specialization () at /home/gates/pinskia/src/gnu/gcc/src/gcc/
cp/parser.c:9204

Confirmed but not reduded yet (but I don't have a gdb to debug this).
Comment 3 Wolfgang Bangerth 2004-09-18 21:57:08 UTC
I can't reproduce this with mainline on linux x86 from 20040917. What flags 
did 
you use? 
 
W. 
Comment 4 Andrew Pinski 2004-09-19 05:30:05 UTC
This was on x86-openbsd which is close to freebsd as I can get.
Comment 5 wanderer 2004-09-23 09:13:01 UTC
I extract from locale_facets.cc small tescase:
--8X----------------
    const wchar_t*
    _S_timezones[14] =
    { 
      L"GMT", L"HST", L"AKST", L"PST", L"MST", L"CST", L"EST", L"AST", 
      L"NST", L"CET", L"IST", L"EET", L"CST", L"JST"  
    };

--X8----------------

Note: This simplifed code guarded in original source code by 
#ifdef _GLIBCXX_USE_WCHAR_T check


xgcc ICE at it with command line 
/usr/home/wanderer/pkg/build/gcc/obj/gcc/xgcc -
B/usr/home/wanderer/pkg/build/gcc/obj/gcc/ -c test.cc

Error:
test.cc:4: internal compiler error: Segmentation fault
Please submit a full bug report,

Comment 6 wanderer 2004-09-23 09:14:38 UTC
Created attachment 7200 [details]
testcase
Comment 7 wanderer 2004-09-23 09:26:37 UTC
Also /usr/home/wanderer/pkg/build/gcc/obj/gcc/stage1/xgcc 
and /usr/home/wanderer/pkg/build/gcc/obj/gcc/stage2/xgcc 
with smae options ICE with same output.

Comment 8 Andrew Pinski 2004-09-23 11:52:50 UTC
Confirmed, I had saw the wide testcases in the testsuite seg faulting and I wondered why.
Comment 9 Andrew Pinski 2004-09-23 13:17:57 UTC
Here is the full back trace:
#0  0x00000000 in ?? ()
#1  0x007f9400 in cpp_interpret_string () at /home/gates/pinskia/src/gnu/gcc/src/libcpp/charset.c:
1168
#2  0x0011aaca in cp_parser_string_literal () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/
parser.c:2548
#3  0x0011af7b in cp_parser_primary_expression () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/
parser.c:2695
#4  0x0011ce12 in cp_parser_postfix_expression () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/
parser.c:3946
#5  0x0011e22d in cp_parser_unary_expression () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/
parser.c:4722
#6  0x0011ecd4 in cp_parser_cast_expression () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/
parser.c:5215
#7  0x0012e984 in cp_parser_simple_cast_expression () at /home/gates/pinskia/src/gnu/gcc/src/gcc/
cp/parser.c:14852
#8  0x0011ed1e in cp_parser_binary_expression () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/
parser.c:5305
#9  0x0011efe4 in cp_parser_assignment_expression () at /home/gates/pinskia/src/gnu/gcc/src/gcc/
cp/parser.c:5453
#10 0x0011f2de in cp_parser_constant_expression () at /home/gates/pinskia/src/gnu/gcc/src/gcc/
cp/parser.c:5677
#11 0x00128b5b in cp_parser_initializer_clause () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/
parser.c:11955
#12 0x00128d42 in cp_parser_initializer_list () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/
parser.c:12034
#13 0x00128c64 in cp_parser_initializer_clause () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/
parser.c:11972
#14 0x00128ab6 in cp_parser_initializer () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/parser.c:
11912
#15 0x00126177 in cp_parser_init_declarator () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/
parser.c:10576
#16 0x00120e39 in cp_parser_simple_declaration () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/
parser.c:6912
#17 0x00120ce9 in cp_parser_block_declaration () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/
parser.c:6822
#18 0x00120b67 in cp_parser_declaration () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/parser.c:
6739
#19 0x001208b6 in cp_parser_declaration_seq_opt () at /home/gates/pinskia/src/gnu/gcc/src/gcc/
cp/parser.c:6643
#20 0x0011ac5d in cp_parser_translation_unit () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/
parser.c:2600
#21 0x00130674 in c_parse_file () at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/parser.c:15777
#22 0x0022bf3a in c_common_parse_file () at /home/gates/pinskia/src/gnu/gcc/src/gcc/c-opts.c:
1097
#23 0x006c7657 in compile_file () at /home/gates/pinskia/src/gnu/gcc/src/gcc/toplev.c:991
#24 0x006c99d7 in do_compile () at /home/gates/pinskia/src/gnu/gcc/src/gcc/toplev.c:2079
#25 0x006c9a39 in toplev_main () at /home/gates/pinskia/src/gnu/gcc/src/gcc/toplev.c:2111
#26 0x00240bb3 in main (argc=2, argv=0xdfbfd8bc) at /home/gates/pinskia/src/gnu/gcc/src/gcc/
main.c:35

Seg faulting here (well after jumping to cvt.func).
1168                  if (!APPLY_CONVERSION (cvt, base, p - base, &tbuf))

This is a bug in the preprocessor but I cannot debug it any further as my gdb does not work well at all 
on my openbsd box.
Comment 10 Andrew Pinski 2004-09-23 13:19:23 UTC
I should note that I used --disable-nls but that should not matter.
Comment 11 Andrew Pinski 2004-09-23 13:36:03 UTC
Hmm, this is host related because a cross compiler will not work.
So what that means is that I cannot debug it at all :(.
Comment 12 wanderer 2004-09-26 15:38:00 UTC
Additinal information:
I can now (and may be early) bootstrap current mainline CVS version GCC
using system FreeBSD compiler (gcc version 3.2.2 [FreeBSD] 20030205 (release)).

Buf AFTER install bootstraped gcc i can't successfully finish gcc bootstrap
from same sources (same error: ICE at locale_facets.cc:47)
Comment 13 Andrew Pinski 2004-09-26 15:41:21 UTC
So that is why I cannot reproduce it with a cross compiler is because this is wrong code.
Comment 14 Andrew Pinski 2004-09-26 17:23:06 UTC
Someone needs to try to reduce this problem, it is a miscompiling in libcpp.
Comment 15 Andrew Pinski 2004-09-26 19:41:15 UTC
Hmm, must be only on x86 :( because on powerpc-apple-darwin we don't miscompile libcpp.  So this 
might be even worse than that, we miscompile a part which is used on x86 but not on powerpc.
Comment 16 wanderer 2004-10-06 16:47:27 UTC
I found time window when problem created.

Used step sequence for all tests: 
1)bootstrap and install GCC (using system FreeBSD complier)
2)bootstrap GCC (from same sources using installed GCC)

Test for GCC CVS sources at 2004-07-14 18:00 GMT is ok 
(second GCC bootstrap finished without problems)

But test for GCC CVS sources at 2004-07-14 18:20 GMT failed with error:
../../../../src/gcc/libstdc++-v3/src/locale_facets.cc:47: internal compiler 
error: Segmentation fault

Only single path listed in this time range:

> CVSROOT:	/cvs/gcc
> Module name:	gcc
> Changes by:	jason@gcc.gnu.org	2004-07-14 18:16:50
> 
> Modified files:
> 	gcc            : ChangeLog tree-gimple.c tree-gimple.h 
> 	                 gimplify.c 
> 
> Log message:
> 	* tree-gimple.c (is_gimple_reg_rhs, is_gimple_mem_rhs): New fns.
> 	(rhs_test_for): New fn.
> 	(is_gimple_tmp_rhs): Rename from is_gimple_rhs.
> 	* tree-gimple.h: Declare them.
> 	* gimplify.c (gimplify_modify_expr): Use the new fns.

I attempt but fail check patch reverting affect: source changes block clean 
revert.
Comment 17 wanderer 2004-10-07 09:38:50 UTC
Base at steps requared for bug reproducing and related CVS changes in 
gimplification I think recent changes component in bug report to C++ are wrong.

Comment 18 Andrew Pinski 2004-10-25 11:41:19 UTC
*** Bug 18139 has been marked as a duplicate of this bug. ***
Comment 19 Aaron W. LaFramboise 2004-10-25 19:48:44 UTC
I also don't think this is a C++ bug: its a bug in whatever compiled libcpp,
which probably wasn't a C++ compiler.

Also, does this affect all x86 targets?  Does it affect i?86-pc-linux*?

The testcase can be simplified; parsing any wide character literal with the
miscompiled libcpp will cause the ICE, such as simply L'c'.
Comment 20 Andrew Pinski 2004-10-25 19:55:13 UTC
I also note I can reproduce this when using the C compiler so it definitely has nothing to do with the 
C++ compiler.
Comment 21 Andrew Pinski 2004-10-25 19:59:28 UTC
I should note that it does not effect i686-pc-linux-gnu for some reason
Comment 22 Danny Smith 2004-10-26 02:26:47 UTC
A data point:

Free/OpenBsd and windows targets differ drom i386-linux in defining
#define DEFAULT_PCC_STRUCT_RETURN 0
which affect aggregate_value_p and thus gimplify_return_expr.  

Compiling charset.c with -O2 -funit-at-a-time -fpcc-struct-return on mingw
builds a "good" cc1.exe

Danny

Comment 23 Andrew Pinski 2004-10-26 02:48:17 UTC
Thanks  Danny for looking into what causes correct code, I will look into it soon (after I build a new 
cross compiler from powerpc-darwin).
Comment 24 Andrew Pinski 2004-10-26 03:13:43 UTC
It looks like init_iconv_desc is miscompiled.
Comment 25 Andrew Pinski 2004-10-26 04:23:15 UTC
And here is a semi reduced/self-contained source which I came up after debuggin this a little bit:
struct cset_converter { int func; int cd; };
void abort(void); int puts(const char*);
int f(int i){return i;}
void g(void){puts("hi");}
struct conversion
{
  int pair;
  int func;
  int fake_cd;
};
static const struct conversion conversion_tab[] = {
  { 2, 2, 2 },
  { 3, 3, 3 }
};
static struct cset_converter
init_iconv_desc (int i)
{
  struct cset_converter ret;
  unsigned i1;
  char *pair;
  if (!i)
    {
      ret.func = 0;
      ret.cd = 0;
      return ret;
    }
  pair = __builtin_alloca(i*3);
  for (i1 = 0; i1 < (sizeof (conversion_tab) / sizeof ((conversion_tab)[0])); i1++)
    if (i == conversion_tab[i1].pair)
      {
	 ret.func = conversion_tab[i1].func;
	 ret.cd = conversion_tab[i1].fake_cd;
	 return ret;
      }
    
  ret.func = 2;
  ret.cd = f(i);
  if (ret.cd == 4)
    {
      g();
      ret.func = 4;
    }
  return ret;
}
struct f
{
  struct cset_converter a;
  struct cset_converter b;
};

void ff(struct f *a)
{
  a->a = init_iconv_desc(0);
  a->b = init_iconv_desc(1);
}

int main(void)
{
  struct f a;
  ff (&a);
  if (a.a.func!=0 || a.a.cd !=0)
    abort();
  if (a.b.func!=2 || a.b.cd !=1)
    abort();
  return 0;
}
Comment 26 Andrew Pinski 2004-10-26 04:35:32 UTC
Here is it reduced further, maybe now someone will look into it now (I can reproduce it with -O2 -fno-
pcc-struct-return on i686-pc-linux-gnu):
struct cset_converter { int func; int cd; };
void abort(void);
struct cset_converter
init_iconv_desc (int i)
{
  struct cset_converter ret;
  unsigned i1;
  char *pair;
  if (!i)
    {
      ret.func = 0;
      ret.cd = 0;
      return ret;
    }
  ret.func = 2;
  ret.cd = 2;
  return ret;
}
struct f
{
  struct cset_converter a;
  struct cset_converter b;
};
void ff(struct f *a)
{
  a->a = init_iconv_desc(0);
  a->b = init_iconv_desc(1);
}
int main(void)
{
  struct f a;
  ff (&a);
  if (a.a.func!=0 || a.a.cd !=0)
    abort();
  if (a.b.func!=2 || a.b.cd !=1)
    abort();
  return 0;
}
Comment 27 Volker Reichelt 2004-10-26 09:18:58 UTC
Andrew's example in comment #26 is broken.
ret.cd is set to 2 and therefore we have a.b.cd!=1 which triggers the abort.

Nevertheless, here's a reduced testcase derived from comment #25:

================================
void abort(void);

typedef struct { int i; } A;

A foo(void)
{
  A a = { 1 };
  int j;
  for (j=0; j<2; j++) ;
  return a;
}

void bar(A *p)
{
  *p = foo();
}

int main(void)
{
  A a;
  bar(&a);
  if (a.i != 1)
    abort();
  return 0;
}
================================
Comment 28 Volker Reichelt 2004-10-26 09:45:48 UTC
I can confirm that the bug was introduced with Jason's patch
http://gcc.gnu.org/ml/gcc-cvs/2004-07/msg00788.html
as pointed out in comment #16.

Jason, could you please have a look?

Btw, here's an even shorter testcase:

===============================
void abort(void);

typedef struct { int i; } A;

A foo(void)
{
    A a = { 0 };
    return a;
}

void bar(A *p)
{
    *p = foo();
}

int main(void)
{
    A a;
    bar(&a);
    if (a.i) abort();
    return 0;
}
===============================
Comment 29 Jason Merrill 2004-10-29 21:46:30 UTC
The problem seems to be an incorrect tailcall.  Before my patch, "*p = foo()"
was turned into "T.1 = foo(); *p = T.1;".  After my patch, the gimplifier no
longer introduced a temporary.  If A is returned in memory the tailcall pass
then marks the line "*p = foo()" as a tailcall, losing the assignment in the
process.

I think I'll fix this by using a temporary for all non-BLKmode types, but this
also seems like a bug in the tailcall pass.
Comment 30 GCC Commits 2004-10-31 09:17:46 UTC
Subject: Bug 17526

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	jason@gcc.gnu.org	2004-10-31 09:17:42

Modified files:
	gcc            : ChangeLog tree-gimple.c 

Log message:
	PR middle-end/17526
	* tree-gimple.c (is_gimple_mem_rhs): Also require a val for
	aggregate types that are not BLKmode.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.6111&r2=2.6112
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-gimple.c.diff?cvsroot=gcc&r1=2.29&r2=2.30

Comment 31 Andrew Pinski 2004-10-31 15:09:57 UTC
Fixed.
Comment 32 olh 2005-03-03 23:52:32 UTC
can these errors still be reproduced with current gcc 4.0 branch?
the applied patch causes regressions:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20282
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20305

Comment 33 wanderer 2005-03-04 10:43:29 UTC
Current CVS mainline bootstrap fine at self with and without reverting patch 
in #30.
Comment 34 wanderer 2005-03-04 11:27:40 UTC
Ops... sorry.

I withdraw my prev. note.
Current mainline CVS GCC fail bootstrap with reverted patch in #30
Comment 35 Richard Biener 2008-05-25 17:17:25 UTC
Subject: Bug 17526

Author: rguenth
Date: Sun May 25 17:16:38 2008
New Revision: 135876

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=135876
Log:
2008-05-25  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/17526
	* gcc.dg/torture/pr17526.c: New testcase.

Added:
    trunk/gcc/testsuite/gcc.dg/torture/pr17526.c
Modified:
    trunk/gcc/testsuite/ChangeLog