[RFC] PR c/12245 (not really C frontend issue)

Jan Hubicka hubicka@ucw.cz
Sun Feb 22 15:47:00 GMT 2009


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



More information about the Gcc-patches mailing list