Using a recent gcc build (4.2.0 20060418) the following code: template <class foo> class junk { void bar(int a) { unsigned char *c = new unsigned char[a*sizeof(foo)]; } }; gets an ICE: foo.c: In member function 'void junk<foo>::bar(int)': foo.c:4: internal compiler error: tree check: did not expect class 'type', have 'type' (template_type_parm) in contains_placeholder_p, at tree.c:2139 However 4.0 and 4.1 dont.
Confirmed. #0 internal_error ( gmsgid=0x8a04870 "tree check: did not expect class %qs, have %qs (%s) in %s, at %s:%d") at /space/rguenther/src/svn/gcc/gcc/diagnostic.c:586 #1 0x0875e9b2 in tree_not_class_check_failed (node=0xb7e1b450, cl=tcc_type, file=0x8a0310c "/space/rguenther/src/svn/gcc/gcc/tree.c", line=2139, function=0x8a039d8 "contains_placeholder_p") at /space/rguenther/src/svn/gcc/gcc/tree.c:6124 #2 0x0873e15f in contains_placeholder_p (exp=0xb7de2a60) at /space/rguenther/src/svn/gcc/gcc/tree.c:2139 #3 0x0873e7b8 in contains_placeholder_p (exp=0xb7d69144) at /space/rguenther/src/svn/gcc/gcc/tree.c:2141 #4 0x0873e23b in contains_placeholder_p (exp=0xb7de2ac0) at /space/rguenther/src/svn/gcc/gcc/tree.c:2139 #5 0x0873c05f in save_expr (expr=0xb7de2ae0) at /space/rguenther/src/svn/gcc/gcc/tree.c:1956 #6 0x081b1c21 in build_new (placement=0x0, type=0xb7d72114, nelts=0xb7de2ac0, init=0x0, use_global_new=0) at /space/rguenther/src/svn/gcc/gcc/cp/init.c:2111 #7 0x0815d30a in cp_parser_new_expression (parser=0xb7e1e3a8) at /space/rguenther/src/svn/gcc/gcc/cp/parser.c:5070 #2 0x0873e15f in contains_placeholder_p (exp=0xb7de2a60) at /space/rguenther/src/svn/gcc/gcc/tree.c:2139 2139 return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0)); (gdb) call debug_tree(exp) <sizeof_expr 0xb7de2a60 type <integer_type 0xb7d722e0 unsigned int public unsigned type_6 SI size <integer_cst 0xb7d613d8 constant invariant 32> unit size <integer_cst 0xb7d61168 constant invariant 4> align 32 symtab 0 alias set -1 precision 32 min <integer_cst 0xb7d61450 0> max <integer_cst 0xb7d61438 4294967295>> readonly arg 0 <template_type_parm 0xb7e1b450 foo type_0 type_6 VOID align 8 symtab 0 alias set -1 index 0 level 1 orig_level 1 chain <type_decl 0xb7de8958 foo>>> (gdb) up #3 0x0873e7b8 in contains_placeholder_p (exp=0xb7d69144) at /space/rguenther/src/svn/gcc/gcc/tree.c:2141 2141 return (CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0)) (gdb) #4 0x0873e23b in contains_placeholder_p (exp=0xb7de2ac0) at /space/rguenther/src/svn/gcc/gcc/tree.c:2139 2139 return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0)); (gdb) call debug_tree(exp) <non_dependent_expr 0xb7de2ac0 type <integer_type 0xb7d722e0 unsigned int public unsigned type_6 SI size <integer_cst 0xb7d613d8 constant invariant 32> unit size <integer_cst 0xb7d61168 constant invariant 4> align 32 symtab 0 alias set -1 precision 32 min <integer_cst 0xb7d61450 0> max <integer_cst 0xb7d61438 4294967295>> arg 0 <mult_expr 0xb7d69144 type <integer_type 0xb7d722e0 unsigned int> arg 0 <parm_decl 0xb7d6a780 a type <integer_type 0xb7d72284 int> used SI file t.C line 2 size <integer_cst 0xb7d613d8 32> unit size <integer_cst 0xb7d61168 4> align 32 context <function_decl 0xb7e19c00 bar> initial <integer_type 0xb7d72284 int> arg-type <integer_type 0xb7d72284 int>> arg 1 <sizeof_expr 0xb7de2a60 type <integer_type 0xb7d722e0 unsigned int> readonly arg 0 <template_type_parm 0xb7e1b450 foo>>>>
Even shorter testcase: =================================== template<typename T> void foo() { new char[2*sizeof(T)]; } ===================================
This patch fixes the ICE for me but I don't know if it is the correct one: Index: tree.h =================================================================== --- tree.h (revision 113199) +++ tree.h (working copy) @@ -3981,7 +3981,7 @@ extern bool contains_placeholder_p (tree case of a constant to save time. Also check for null. */ #define CONTAINS_PLACEHOLDER_P(EXP) \ - ((EXP) != 0 && ! TREE_CONSTANT (EXP) && contains_placeholder_p (EXP)) + ((EXP) != 0 && !TYPE_P (EXP) && !TREE_CONSTANT (EXP) && contains_placeholder_p (EXP)) /* Return 1 if any part of the computation of TYPE involves a PLACEHOLDER_EXPR. This includes size, bounds, qualifiers (for QUAL_UNION_TYPE) and field --------------------------------------------------------------------------- Basicially a type can never contain a placeholder expression and TREE_CONSTANT does not exist on a type.
*** Bug 27284 has been marked as a duplicate of this bug. ***
*** Bug 27410 has been marked as a duplicate of this bug. ***
Janis could you do a regression hunt on this bug?
A regression hunt identified this patch: http://gcc.gnu.org/viewcvs?view=rev&rev=112869 r112869 | mmitchel | 2006-04-11 22:59:57 +0000 (Tue, 11 Apr 2006)
(In reply to comment #7) > A regression hunt identified this patch: > > http://gcc.gnu.org/viewcvs?view=rev&rev=112869 > > r112869 | mmitchel | 2006-04-11 22:59:57 +0000 (Tue, 11 Apr 2006) Mark, can you comment?
Subject: Bug 27210 Author: mmitchel Date: Sun May 21 17:23:59 2006 New Revision: 113958 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=113958 Log: PR c++/27210 * cp-tree.h (cp_save_expr): New function. * init.c (build_new): Correct logic for zero-element array warning. Use cp_save_expr. * tree.c (cp_save_expr): New function. PR c++/27210 * g++.dg/warn/new1.C: New test. * g++.dg/template/new5.C: Likewise. Added: trunk/gcc/testsuite/g++.dg/template/new5.C trunk/gcc/testsuite/g++.dg/warn/new1.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/cp-tree.h trunk/gcc/cp/init.c trunk/gcc/cp/tree.c trunk/gcc/testsuite/ChangeLog
Fixed in 4.2.0.