[Bug c++/93279] [9/10 Regression] C++ Template substitution ICE

mpolacek at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Jan 24 16:20:00 GMT 2020


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93279

--- Comment #5 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
Since r9-6405-gbddee796d0b4800b5ac3d7e7e9e315c23799424d, when we see in a
lambda a use of an operator that might be overloaded, we do name lookup and
save it away in an internal attribute on the lambda call operator.  Here we
have a (generic) lambda and the * operator, so we stash 

  operator* -> OVERLOAD [template_decl]

into the attribute.  Then push_operator_bindings pushes it to the function
parameter binding level using push_local_binding.

When we instantiate_decl the function operator* we end up substituting the m *
l expr.  Then build_x_binary_op builds it, it calls build_new_op_1 which will
invoke add_operator_candidates.  That will add the operator* TEMPLATE_DECL
stashed above into the candidate set.  It's a template and we try to deduce the
template arguments in fn_type_unification.  We have a template parameter of
type B<E>::f, and we will tsubst its template arguments = E.  This will wind up
lookup_template_class (E, <T, N>) which calls coerce_template_parms.  So we
convert_template_argument:

#3  0x00000000009a0fdf in maybe_constant_value (t=<template_parm_index
0x7fffeaa4a360>, decl=<tree 0x0>, 
    manifestly_const_eval=true) at
/home/mpolacek/src/gcc/gcc/cp/constexpr.c:6596
#4  0x0000000000bad57a in convert_nontype_argument (type=<integer_type
0x7fffea8fb5e8 int>, 
    expr=<template_parm_index 0x7fffeaa4a360>, complain=0) at
/home/mpolacek/src/gcc/gcc/cp/pt.c:7116
#5  0x0000000000bb1cc8 in convert_template_argument (parm=<parm_decl
0x7fffea906300 N>, 
    arg=<template_parm_index 0x7fffeaa4a360>, args=<tree_vec 0x7fffeaa5a690>,
complain=0, i=1, 
    in_decl=<template_decl 0x7fffea906400 E>) at
/home/mpolacek/src/gcc/gcc/cp/pt.c:8350

And so maybe_constant_value gets a template_parm_index.  But
processing_template_decl is 0 so this check

  if (!is_nondependent_constant_expression (t))

in maybe_constant_value won't work: value_dependent_expression_p always returns
false when !processing_template_decl.  So the template_parm_index winds up
going to the constexpr machinery and that ICEs.

I would think we need
++processing_template_decl;
...
--processing_template_decl;
somewhere, but can't find the right spot.


More information about the Gcc-bugs mailing list