This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[RFC] PR c/12245 (not really C frontend issue)
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: gcc-patches at gcc dot gnu dot org, rguenther at suse dot de, mark at codesourcery dot com
- Date: Sun, 22 Feb 2009 13:56:05 +0100
- Subject: [RFC] PR c/12245 (not really C frontend issue)
Hi,
the testcase of PR contains one large initializer all of constant 18.
This shows problem in a way we construct a constructors. One problem
mentioned by Richi (and he hopefuly have patch) is that we use
INTEGER_CST to count the indices that makes us to build constants
1.....large_number.
Other problem however is that each time we parse a constant, we build it
in one type, then build CONVERT_EXPR (constant) just to be immediately
folded to the resulting constant.
The backtrace is:
#0 convert_to_integer (type=0x2aaaab3ba240, expr=0x2aaaabe44330) at ../../gcc/convert.c:752
#1 0x00000000004648bc in convert (type=0x2aaaab3ba240, expr=0x2aaaabe44330) at ../../gcc/c-convert.c:101
#2 0x000000000046b03f in convert_and_check (type=0x2aaaab3ba240, expr=0x2aaaabe44330) at ../../gcc/c-common.c:1791
#3 0x000000000044e8e3 in convert_for_assignment (type=0x2aaaab3ba240, rhs=0x2aaaabe44330, errtype=ic_init, fundecl=0x0, function=0x0, parmnum=0)
at ../../gcc/c-typeck.c:4141
#4 0x000000000045442b in digest_init (type=0x2aaaab3ba240, init=0x2aaaabe44330, strict_string=0 '\0', require_constant=1) at ../../gcc/c-typeck.c:4993
#5 0x0000000000458796 in output_init_element (value=0x2aaaabe44330, strict_string=0 '\0', type=0x2aaaab3ba240, field=0x2aaaad252030, pending=1, implicit=0 '\0')
at ../../gcc/c-typeck.c:6406
#6 0x000000000045a196 in process_init_element (value={value = 0x2aaaabe44330, original_code = ERROR_MARK}, implicit=0 '\0') at ../../gcc/c-typeck.c:6910
#7 0x00000000004b7847 in c_parser_initval (parser=0x2aaaab385140, after=0x0) at ../../gcc/c-parser.c:3249
#8 0x00000000004b774a in c_parser_initelt (parser=0x2aaaab385140) at ../../gcc/c-parser.c:3225
the main problem is that convert calls:
if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
return fold (convert_to_integer (type, e));
and convert_to_integer is not folding the result. I added a hunk:
Index: convert.c
===================================================================
--- convert.c (revision 144352)
+++ convert.c (working copy)
@@ -749,6 +749,11 @@ convert_to_integer (tree type, tree expr
break;
}
+ /* When parsing long initializers, we might end up with a lot of casts.
+ Shortcut this. */
+ if (TREE_CODE (expr) == INTEGER_CST)
+ return fold_unary (CONVERT_EXPR, type, expr);
+
return build1 (CONVERT_EXPR, type, expr);
case REAL_TYPE:
and I expected it to break, since there are places in C++ frontend
explicitly not folding the result of convert that I assume is important
for templates and type checking.
However this seems terribly ineefecient and quite common case (i.e.
every constant we parse :), so I wonder if we can do better here.
We do similarly stupid job for reals and all other types.
One option would be to add fold_result_p argument to convert_to_integer
and friends and fold result only with this predicate that would be used
by C++ to avoid unneeded folding. Or are there better alternatives?
Honza