| Summary: | [4.0 Regression] libcpp is miscompiled with -fno-pcc-struct-return -O2 | ||
|---|---|---|---|
| Product: | gcc | Reporter: | wanderer |
| Component: | middle-end | Assignee: | Jason Merrill <jason> |
| Status: | RESOLVED FIXED | ||
| Severity: | critical | CC: | aaronavay62, gcc-bugs, jason, olh, pinskia, reichelt |
| Priority: | P2 | Keywords: | build, ice-on-valid-code, monitored, wrong-code |
| Version: | 4.0.0 | ||
| Target Milestone: | 4.0.0 | ||
| Host: | Target: | i686-*-* | |
| Build: | Known to work: | ||
| Known to fail: | Last reconfirmed: | 2004-09-23 11:52:51 | |
| Bug Depends on: | 36326 | ||
| Bug Blocks: | 18107 | ||
| Attachments: |
compressed .ii file
testcase |
||
|
Description
wanderer
2004-09-16 20:54:30 UTC
Created attachment 7155 [details]
compressed .ii file
#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). I can't reproduce this with mainline on linux x86 from 20040917. What flags did you use? W. This was on x86-openbsd which is close to freebsd as I can get. 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,
Created attachment 7200 [details]
testcase
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. Confirmed, I had saw the wide testcases in the testsuite seg faulting and I wondered why. 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. I should note that I used --disable-nls but that should not matter. Hmm, this is host related because a cross compiler will not work. So what that means is that I cannot debug it at all :(. 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) So that is why I cannot reproduce it with a cross compiler is because this is wrong code. Someone needs to try to reduce this problem, it is a miscompiling in libcpp. 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. 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.
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. *** Bug 18139 has been marked as a duplicate of this bug. *** 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'. I also note I can reproduce this when using the C compiler so it definitely has nothing to do with the C++ compiler. I should note that it does not effect i686-pc-linux-gnu for some reason 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 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). It looks like init_iconv_desc is miscompiled. 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;
}
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;
}
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; } ================================ 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; } =============================== 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. 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 Fixed. 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 Current CVS mainline bootstrap fine at self with and without reverting patch in #30. Ops... sorry. I withdraw my prev. note. Current mainline CVS GCC fail bootstrap with reverted patch in #30 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 |