Change the check functions from templates to overloads. Add "set unwindonsignal on" to gdbinit.in to gracefully handle aborts in functions used from gdb.
Tested on x86-64. Index: gcc/ChangeLog.cxx-conversion 2012-05-30 Lawrence Crowl <cr...@google.com> * tree.h (tree_check): Change from template to const overload. (tree_not_check): Likewise. (tree_check2): Likewise. (tree_not_check2): Likewise. (tree_check3): Likewise. (tree_not_check3): Likewise. (tree_check4): Likewise. (tree_not_check4): Likewise. (tree_check5): Likewise. (tree_not_check5): Likewise. (contains_struct_check): Likewise. (tree_class_check): Likewise. (tree_range_check): Likewise. (omp_clause_subcode_check): Likewise. (omp_clause_range_check): Likewise. (expr_check): Likewise. (non_type_check): Likewise. (tree_vec_elt_check): Likewise. (omp_clause_elt_check): Likewise. (tree_operand_check): Likewise. (tree_operand_check_code): Likewise. (tree_operand_length): Merge duplicate copy. * gdbinit.in (set unwindonsignal on): New. Index: gcc/tree.h =================================================================== --- gcc/tree.h (revision 187989) +++ gcc/tree.h (working copy) @@ -3598,18 +3598,17 @@ union GTY ((ptr_alias (union lang_tree_n }; #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) -template <typename Tree> -inline Tree -tree_check (Tree __t, const char *__f, int __l, const char *__g, tree_code __c) + +inline tree +tree_check (tree __t, const char *__f, int __l, const char *__g, tree_code __c) { if (TREE_CODE (__t) != __c) tree_check_failed (__t, __f, __l, __g, __c, 0); return __t; } -template <typename Tree> -inline Tree -tree_not_check (Tree __t, const char *__f, int __l, const char *__g, +inline tree +tree_not_check (tree __t, const char *__f, int __l, const char *__g, enum tree_code __c) { if (TREE_CODE (__t) == __c) @@ -3617,9 +3616,8 @@ tree_not_check (Tree __t, const char *__ return __t; } -template <typename Tree> -inline Tree -tree_check2 (Tree __t, const char *__f, int __l, const char *__g, +inline tree +tree_check2 (tree __t, const char *__f, int __l, const char *__g, enum tree_code __c1, enum tree_code __c2) { if (TREE_CODE (__t) != __c1 @@ -3628,9 +3626,8 @@ tree_check2 (Tree __t, const char *__f, return __t; } -template <typename Tree> -inline Tree -tree_not_check2 (Tree __t, const char *__f, int __l, const char *__g, +inline tree +tree_not_check2 (tree __t, const char *__f, int __l, const char *__g, enum tree_code __c1, enum tree_code __c2) { if (TREE_CODE (__t) == __c1 @@ -3639,9 +3636,8 @@ tree_not_check2 (Tree __t, const char *_ return __t; } -template <typename Tree> -inline Tree -tree_check3 (Tree __t, const char *__f, int __l, const char *__g, +inline tree +tree_check3 (tree __t, const char *__f, int __l, const char *__g, enum tree_code __c1, enum tree_code __c2, enum tree_code __c3) { if (TREE_CODE (__t) != __c1 @@ -3651,9 +3647,8 @@ tree_check3 (Tree __t, const char *__f, return __t; } -template <typename Tree> -inline Tree -tree_not_check3 (Tree __t, const char *__f, int __l, const char *__g, +inline tree +tree_not_check3 (tree __t, const char *__f, int __l, const char *__g, enum tree_code __c1, enum tree_code __c2, enum tree_code __c3) { if (TREE_CODE (__t) == __c1 @@ -3663,9 +3658,8 @@ tree_not_check3 (Tree __t, const char *_ return __t; } -template <typename Tree> -inline Tree -tree_check4 (Tree __t, const char *__f, int __l, const char *__g, +inline tree +tree_check4 (tree __t, const char *__f, int __l, const char *__g, enum tree_code __c1, enum tree_code __c2, enum tree_code __c3, enum tree_code __c4) { @@ -3677,9 +3671,8 @@ tree_check4 (Tree __t, const char *__f, return __t; } -template <typename Tree> -inline Tree -tree_not_check4 (Tree __t, const char *__f, int __l, const char *__g, +inline tree +tree_not_check4 (tree __t, const char *__f, int __l, const char *__g, enum tree_code __c1, enum tree_code __c2, enum tree_code __c3, enum tree_code __c4) { @@ -3691,9 +3684,8 @@ tree_not_check4 (Tree __t, const char *_ return __t; } -template <typename Tree> -inline Tree -tree_check5 (Tree __t, const char *__f, int __l, const char *__g, +inline tree +tree_check5 (tree __t, const char *__f, int __l, const char *__g, enum tree_code __c1, enum tree_code __c2, enum tree_code __c3, enum tree_code __c4, enum tree_code __c5) { @@ -3706,9 +3698,8 @@ tree_check5 (Tree __t, const char *__f, return __t; } -template <typename Tree> -inline Tree -tree_not_check5 (Tree __t, const char *__f, int __l, const char *__g, +inline tree +tree_not_check5 (tree __t, const char *__f, int __l, const char *__g, enum tree_code __c1, enum tree_code __c2, enum tree_code __c3, enum tree_code __c4, enum tree_code __c5) { @@ -3721,9 +3712,8 @@ tree_not_check5 (Tree __t, const char *_ return __t; } -template <typename Tree> -inline Tree -contains_struct_check (Tree __t, const enum tree_node_structure_enum __s, +inline tree +contains_struct_check (tree __t, const enum tree_node_structure_enum __s, const char *__f, int __l, const char *__g) { if (tree_contains_struct[TREE_CODE(__t)][__s] != 1) @@ -3731,9 +3721,8 @@ contains_struct_check (Tree __t, const e return __t; } -template <typename Tree> -inline Tree -tree_class_check (Tree __t, const enum tree_code_class __class, +inline tree +tree_class_check (tree __t, const enum tree_code_class __class, const char *__f, int __l, const char *__g) { if (TREE_CODE_CLASS (TREE_CODE(__t)) != __class) @@ -3741,21 +3730,8 @@ tree_class_check (Tree __t, const enum t return __t; } -/* Compute the number of operands in an expression node NODE. For - tcc_vl_exp nodes like CALL_EXPRs, this is stored in the node itself, - otherwise it is looked up from the node's code. */ -static inline int -tree_operand_length (const_tree node) -{ - if (VL_EXP_CLASS_P (node)) - return VL_EXP_OPERAND_LENGTH (node); - else - return TREE_CODE_LENGTH (TREE_CODE (node)); -} - -template <typename Tree> -inline Tree -tree_range_check (Tree __t, +inline tree +tree_range_check (tree __t, enum tree_code __code1, enum tree_code __code2, const char *__f, int __l, const char *__g) { @@ -3764,9 +3740,8 @@ tree_range_check (Tree __t, return __t; } -template <typename Tree> -inline Tree -omp_clause_subcode_check (Tree __t, enum omp_clause_code __code, +inline tree +omp_clause_subcode_check (tree __t, enum omp_clause_code __code, const char *__f, int __l, const char *__g) { if (TREE_CODE (__t) != OMP_CLAUSE) @@ -3776,9 +3751,8 @@ omp_clause_subcode_check (Tree __t, enum return __t; } -template <typename Tree> -inline Tree -omp_clause_range_check (Tree __t, +inline tree +omp_clause_range_check (tree __t, enum omp_clause_code __code1, enum omp_clause_code __code2, const char *__f, int __l, const char *__g) @@ -3792,9 +3766,9 @@ omp_clause_range_check (Tree __t, } /* These checks have to be special cased. */ -template <typename Tree> -inline Tree -expr_check (Tree __t, const char *__f, int __l, const char *__g) + +inline tree +expr_check (tree __t, const char *__f, int __l, const char *__g) { char const __c = TREE_CODE_CLASS (TREE_CODE (__t)); if (!IS_EXPR_CODE_CLASS (__c)) @@ -3803,18 +3777,17 @@ expr_check (Tree __t, const char *__f, i } /* These checks have to be special cased. */ -template <typename Tree> -inline Tree -non_type_check (Tree __t, const char *__f, int __l, const char *__g) + +inline tree +non_type_check (tree __t, const char *__f, int __l, const char *__g) { if (TYPE_P (__t)) tree_not_class_check_failed (__t, tcc_type, __f, __l, __g); return __t; } -template <typename Tree> inline tree * -tree_vec_elt_check (Tree __t, int __i, +tree_vec_elt_check (tree __t, int __i, const char *__f, int __l, const char *__g) { if (TREE_CODE (__t) != TREE_VEC) @@ -3824,9 +3797,8 @@ tree_vec_elt_check (Tree __t, int __i, return &CONST_CAST_TREE (__t)->vec.a[__i]; } -template <typename Tree> -inline Tree * -omp_clause_elt_check (Tree __t, int __i, +inline tree * +omp_clause_elt_check (tree __t, int __i, const char *__f, int __l, const char *__g) { if (TREE_CODE (__t) != OMP_CLAUSE) @@ -3836,10 +3808,232 @@ omp_clause_elt_check (Tree __t, int __i, return &__t->omp_clause.ops[__i]; } +inline const_tree +tree_check (const_tree __t, const char *__f, int __l, const char *__g, + tree_code __c) +{ + if (TREE_CODE (__t) != __c) + tree_check_failed (__t, __f, __l, __g, __c, 0); + return __t; +} + +inline const_tree +tree_not_check (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c) +{ + if (TREE_CODE (__t) == __c) + tree_not_check_failed (__t, __f, __l, __g, __c, 0); + return __t; +} + +inline const_tree +tree_check2 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2) +{ + if (TREE_CODE (__t) != __c1 + && TREE_CODE (__t) != __c2) + tree_check_failed (__t, __f, __l, __g, __c1, __c2, 0); + return __t; +} + +inline const_tree +tree_not_check2 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2) +{ + if (TREE_CODE (__t) == __c1 + || TREE_CODE (__t) == __c2) + tree_not_check_failed (__t, __f, __l, __g, __c1, __c2, 0); + return __t; +} + +inline const_tree +tree_check3 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3) +{ + if (TREE_CODE (__t) != __c1 + && TREE_CODE (__t) != __c2 + && TREE_CODE (__t) != __c3) + tree_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, 0); + return __t; +} + +inline const_tree +tree_not_check3 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3) +{ + if (TREE_CODE (__t) == __c1 + || TREE_CODE (__t) == __c2 + || TREE_CODE (__t) == __c3) + tree_not_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, 0); + return __t; +} + +inline const_tree +tree_check4 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3, + enum tree_code __c4) +{ + if (TREE_CODE (__t) != __c1 + && TREE_CODE (__t) != __c2 + && TREE_CODE (__t) != __c3 + && TREE_CODE (__t) != __c4) + tree_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, __c4, 0); + return __t; +} + +inline const_tree +tree_not_check4 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3, + enum tree_code __c4) +{ + if (TREE_CODE (__t) == __c1 + || TREE_CODE (__t) == __c2 + || TREE_CODE (__t) == __c3 + || TREE_CODE (__t) == __c4) + tree_not_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, __c4, 0); + return __t; +} + +inline const_tree +tree_check5 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3, + enum tree_code __c4, enum tree_code __c5) +{ + if (TREE_CODE (__t) != __c1 + && TREE_CODE (__t) != __c2 + && TREE_CODE (__t) != __c3 + && TREE_CODE (__t) != __c4 + && TREE_CODE (__t) != __c5) + tree_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, __c4, __c5, 0); + return __t; +} + +inline const_tree +tree_not_check5 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3, + enum tree_code __c4, enum tree_code __c5) +{ + if (TREE_CODE (__t) == __c1 + || TREE_CODE (__t) == __c2 + || TREE_CODE (__t) == __c3 + || TREE_CODE (__t) == __c4 + || TREE_CODE (__t) == __c5) + tree_not_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, __c4, __c5, 0); + return __t; +} + +inline const_tree +contains_struct_check (const_tree __t, const enum tree_node_structure_enum __s, + const char *__f, int __l, const char *__g) +{ + if (tree_contains_struct[TREE_CODE(__t)][__s] != 1) + tree_contains_struct_check_failed (__t, __s, __f, __l, __g); + return __t; +} + +inline const_tree +tree_class_check (const_tree __t, const enum tree_code_class __class, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE_CLASS (TREE_CODE(__t)) != __class) + tree_class_check_failed (__t, __class, __f, __l, __g); + return __t; +} + +inline const_tree +tree_range_check (const_tree __t, + enum tree_code __code1, enum tree_code __code2, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) < __code1 || TREE_CODE (__t) > __code2) + tree_range_check_failed (__t, __f, __l, __g, __code1, __code2); + return __t; +} + +inline const_tree +omp_clause_subcode_check (const_tree __t, enum omp_clause_code __code, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) != OMP_CLAUSE) + tree_check_failed (__t, __f, __l, __g, OMP_CLAUSE, 0); + if (__t->omp_clause.code != __code) + omp_clause_check_failed (__t, __f, __l, __g, __code); + return __t; +} + +inline const_tree +omp_clause_range_check (const_tree __t, + enum omp_clause_code __code1, + enum omp_clause_code __code2, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) != OMP_CLAUSE) + tree_check_failed (__t, __f, __l, __g, OMP_CLAUSE, 0); + if ((int) __t->omp_clause.code < (int) __code1 + || (int) __t->omp_clause.code > (int) __code2) + omp_clause_range_check_failed (__t, __f, __l, __g, __code1, __code2); + return __t; +} + +inline const_tree +expr_check (const_tree __t, const char *__f, int __l, const char *__g) +{ + char const __c = TREE_CODE_CLASS (TREE_CODE (__t)); + if (!IS_EXPR_CODE_CLASS (__c)) + tree_class_check_failed (__t, tcc_expression, __f, __l, __g); + return __t; +} + +inline const_tree +non_type_check (const_tree __t, const char *__f, int __l, const char *__g) +{ + if (TYPE_P (__t)) + tree_not_class_check_failed (__t, tcc_type, __f, __l, __g); + return __t; +} + +inline const_tree * +tree_vec_elt_check (const_tree __t, int __i, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) != TREE_VEC) + tree_check_failed (__t, __f, __l, __g, TREE_VEC, 0); + if (__i < 0 || __i >= __t->vec.length) + tree_vec_elt_check_failed (__i, __t->vec.length, __f, __l, __g); + return CONST_CAST (const_tree *, &__t->vec.a[__i]); + //return &__t->vec.a[__i]; +} + +inline const_tree * +omp_clause_elt_check (const_tree __t, int __i, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) != OMP_CLAUSE) + tree_check_failed (__t, __f, __l, __g, OMP_CLAUSE, 0); + if (__i < 0 || __i >= omp_clause_num_ops [__t->omp_clause.code]) + omp_clause_operand_check_failed (__i, __t, __f, __l, __g); + return CONST_CAST (const_tree *, &__t->omp_clause.ops[__i]); +} + +#endif + +/* Compute the number of operands in an expression node NODE. For + tcc_vl_exp nodes like CALL_EXPRs, this is stored in the node itself, + otherwise it is looked up from the node's code. */ +static inline int +tree_operand_length (const_tree node) +{ + if (VL_EXP_CLASS_P (node)) + return VL_EXP_OPERAND_LENGTH (node); + else + return TREE_CODE_LENGTH (TREE_CODE (node)); +} + +#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) + /* Special checks for TREE_OPERANDs. */ -template <typename Tree> inline tree * -tree_operand_check (Tree __t, int __i, +tree_operand_check (tree __t, int __i, const char *__f, int __l, const char *__g) { const_tree __u = EXPR_CHECK (__t); @@ -3848,9 +4042,8 @@ tree_operand_check (Tree __t, int __i, return &CONST_CAST_TREE (__u)->exp.operands[__i]; } -template <typename Tree> -inline Tree * -tree_operand_check_code (Tree __t, enum tree_code __code, int __i, +inline tree * +tree_operand_check_code (tree __t, enum tree_code __code, int __i, const char *__f, int __l, const char *__g) { if (TREE_CODE (__t) != __code) @@ -3860,18 +4053,25 @@ tree_operand_check_code (Tree __t, enum return &__t->exp.operands[__i]; } -#else +inline const_tree * +tree_operand_check (const_tree __t, int __i, + const char *__f, int __l, const char *__g) +{ + const_tree __u = EXPR_CHECK (__t); + if (__i < 0 || __i >= TREE_OPERAND_LENGTH (__u)) + tree_operand_check_failed (__i, __u, __f, __l, __g); + return CONST_CAST (const_tree *, &__u->exp.operands[__i]); +} -/* Compute the number of operands in an expression node NODE. For - tcc_vl_exp nodes like CALL_EXPRs, this is stored in the node itself, - otherwise it is looked up from the node's code. */ -static inline int -tree_operand_length (const_tree node) +inline const_tree * +tree_operand_check_code (const_tree __t, enum tree_code __code, int __i, + const char *__f, int __l, const char *__g) { - if (VL_EXP_CLASS_P (node)) - return VL_EXP_OPERAND_LENGTH (node); - else - return TREE_CODE_LENGTH (TREE_CODE (node)); + if (TREE_CODE (__t) != __code) + tree_check_failed (__t, __f, __l, __g, __code, 0); + if (__i < 0 || __i >= TREE_OPERAND_LENGTH (__t)) + tree_operand_check_failed (__i, __t, __f, __l, __g); + return CONST_CAST (const_tree *, &__t->exp.operands[__i]); } #endif Index: gcc/gdbinit.in =================================================================== --- gcc/gdbinit.in (revision 187989) +++ gcc/gdbinit.in (working copy) @@ -190,6 +190,9 @@ macro define __LINE__ 1 # These are used in accessor macros. skip "tree.h" +# Gracefully handle aborts in functions used from gdb. +set unwindonsignal on + # Put breakpoints at exit and fancy_abort in case abort is mapped # to either fprintf/exit or fancy_abort. b fancy_abort -- This patch is available for review at http://codereview.appspot.com/6256075