This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [C++ RFC / Patch] PR 31260


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
seeing?


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:

   ...
   case TEMPLATE_TYPE_PARM:
   case TEMPLATE_TEMPLATE_PARM:
   case BOUND_TEMPLATE_TEMPLATE_PARM:
   case TEMPLATE_PARM_INDEX:
     {
   int idx;
   int level;
   int levels;
   tree arg = NULL_TREE;

r = NULL_TREE;

   gcc_assert (TREE_VEC_LENGTH (args) > 0);
   if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
       || TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM
       || TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
     {
       idx = TEMPLATE_TYPE_IDX (t);
       level = TEMPLATE_TYPE_LEVEL (t);
     }
   else
     {
       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,
Paolo.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]