------- Additional Comments From roger at eyesopen dot com 2004-04-04 20:54 ------- I believe that the 2^31 limit is a reasonable hard limit caused by the way that GCC internally maintains line numbers, for example, in scan.h, we use "extern int lineno". It looks like these line numbers must be signed, as negative values are used as "rogue" values in REG_NOTES, and also occassionally, but perhaps not intentionally during normal compilation [a gdb watch on "lineno" reveals it holds the value -70 temporarily during a typical compile].
The 2^19 limit is caused by GCC's representation/encoding of the tree node EXPR_WITH_FILE_LOCATION. The EXPR_WFL_LINECOL stores a line and column number in a single 32-bit integer, "complexity", using the bottom 12 bits for the column position, and the top 20 bits for the line number. In the C++ testcase, the line number is temporarily saved/restored during C++ template parsing by push_tinset_level/pop_tinst_level which maintains a stack of file locations, using a linked list of EXPR_WITH_FILE_LOCATION tree nodes, current_tinst_level. Because EXPR_WFL_LINENO uses a right shift of a signed field to extract the top 20 bits back out of the EXPR_WFL_LINECOL, on many (but not all!) machines we return a negative value if the msb is set, i.e. the value was greater than 2^19. This negative value is what eventually causes the ICE in final.c. The EXPR_WFL_LINECOL representation is unchanged on mainline and in 3.4, so this problem still exists in current CVS, but is just latent due to other changes, not to removing the 2^19 line restriction. Possible solutions include: [1] Using an unsigned right shift, i.e. (int)((unsigned int)x >> 12), to extract the top twenty bits for EXPR_WFL_LINECOL. This requires that we never need to represent negative values in EXPR_WFL_LINECOL. The negative values of the global "lineno" make this fix non-obvious. It would however avoid the final.c ICE caused by negative line numbers, and simply truncate the lineno field, wrapping around a 2^20 relatively harmlessly, except for debugging information. [2] Change the division of bits in EXPR_WFL_LINECOL, so that we use less than 12 bits for column, and more than 20 bits for line number. This is a less than ideal work-around. [3] Change the representation of current_tinst_level to avoid problematic use of EXPR_WITH_FILE_LOCATION. A linked list of location structs would allow more accurate representation/recovery of these fields and probably save space, avoiding all the unneeded common tree bits. This wouldn't help other uses of the EXPR_WITH_FILE_LOCATION though. [4] Expand EXPR_WITH_FILE_LOCATION's tree node so that it can store a full integer for line number, perhaps combining column with other fields or just increasing the size of this node. I'm a bit confused why its using the "complexity" field at the moment, and just as confused why we have a complexity field, why the C front end is using it for C_EXP_ORIGINAL_CODE, and why the f77 front-end that doesn't even set/use C_EXP_ORIGINAL_CODE tests for it!! [5] Defensively tweak the middle-end to avoid creating line number notes when current "lineno < 0". This would avoid unintentionally creating invalid NOTES, but again would be papering over the problem, and may cause problems if we later rely on finding these notes in the insn stream. I'm currently investigating why lineno is ever negative... -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14711 ------- You are receiving this mail because: ------- You reported the bug, or are watching the reporter.