[C++ RFC / Patch] PR 31260

Paolo Carlini pcarlini@suse.de
Sun Sep 30 13:21:00 GMT 2007

Hi again Mark, hi all,

>It's true that tsubst_expr, etc., are (unfortunately) not idemopotent;
>you can't safely do tsubst_expr (tsubst_expr (t)).  However, I don't
>understand the logic of the comment that you've (re)-added.  In
>particular, something like:
>  dynamic_cast <S*> (some expression)
>will have type "S*" if "S*" is not a dependent type.  But, that doesn't
>mean that the expression is "at simple as it can get"; there may still
>be substitutions to do in the expression.
>I assume the crash is occurring because of the S3<S2> default argument
>in your test case?  But, how does that relate to the crash that you're
as promised some additional analysis. We are dealing with this testcase

template<class T1>
  struct S1
    template<bool T2> struct S2;

    template<template<bool> class T3>
      struct S3
    template<typename T4 = S3<S2> >
      struct S4;

    struct S5
    : S4<> { };

and, as you pointed out above, we are calling fold_non_dependent_expr 
from tsubst_template_arg exactly because of the default S3<S2>  for T4. 
 From now on, due to the tsubst_copy_and_build call inside it with 
/*args=*/NULL_TREE, we have args always NULL_TREE in all the next 
tsubst_* calls. Then, at some point we enter tsubst with this t argument:

 <template_type_parm 0x2b6fe534f820 T1 type_0 type_6 VOID
    align 8 symtab 0 alias set -1 canonical type 0x2b6fe534f820
   index 0 level 1 orig_level 1
    chain <type_decl 0x2b6fe534f8f0 T1>>

and therefore we have a crash in the gcc_assert:

    int idx;
    int level;
    int levels;
    tree arg = NULL_TREE;

    r = NULL_TREE;

    gcc_assert (TREE_VEC_LENGTH (args) > 0);
        idx = TEMPLATE_TYPE_IDX (t);
        level = TEMPLATE_TYPE_LEVEL (t);
        idx = TEMPLATE_PARM_IDX (t);
        level = TEMPLATE_PARM_LEVEL (t);

    levels = TMPL_ARGS_DEPTH (args);

I tried changing the testcase in various ways avoiding the crash - e.g., 
S4<S3<S2> > as in the audit trail, moving S2 outside of S1 - and I'm 
coming to the conclusion that there is nothing seriously wrong in the 
way we are dealing with this type of situations except, args can be 
NULL_TREE at that assertion exactly because fold_non_dependent_expr 
(correctly, as far as I can see) calls tsubst_copy_and_build with a 
NULL_TREE for it. In fact, adding an 'if (args == NULL_TREE) return t;' 
before the assertion avoids the crash and passes the testsuite. What do 
you think? Do you have any additional hints for me?

Thanks in advance,

More information about the Gcc-patches mailing list