On Thu, Jun 02, 2022 at 08:42:36AM -0400, Patrick Palka wrote: > On Wed, 1 Jun 2022, Marek Polacek via Gcc-patches wrote: > > > Here we ICE because value_dependent_expression_p gets a NEW_EXPR > > whose operand is a type, and we go to the default case which just > > calls v_d_e_p on each operand of the NEW_EXPR. Since one of them > > is a type, we crash on the new assert in t_d_e_p. > > Looks like NEW_EXPR is considered to be not potentially constant > according to potential_constant_expression. I thought we shouldn't > be calling value_dependent_expression_p on such exprs?
You're correct. This is non-obvious: instantiation_dependent_expression_p calls p_c_e before v_d_e_p, but the expression is CAST_EXPR<[NEW_EXPR]>, where the [] denotes a TREE_LIST, created in cp_parser_functional_cast. This TREE_LIST has no type. So p_c_e_1/CAST_EXPR goes to 9183 /* If this is a dependent type, it could end up being a class 9184 with conversions. */ 9185 if (type == NULL_TREE || WILDCARD_TYPE_P (type)) 9186 return true; and returns true. So we call v_d_e_p, which looks at the CAST_EXPR's op and sees a TREE_LIST, so it calls any_value_dependent_elements_p, and we end up with a NEW_EXPR. An alternative/more proper fix would be to fix p_c_e_1/CAST_EXPR. Maybe by calling any_type_dependent_elements_p (which currently has no uses). Thoughts? > > --- /dev/null > > +++ b/gcc/testsuite/g++.dg/template/new13.C > > @@ -0,0 +1,11 @@ > > +// PR c++/105803 > > +// { dg-do compile } > > +// { dg-additional-options "-fchecking=2" } > > + > > +namespace std { > > +template <typename> class shared_ptr; > > +} > > +struct S {}; > > +template <int> void build_matrices() { > > + std::shared_ptr<S>(new S); > > +} > > I think this testcase might be IFNDR since shared_ptr<S> is incomplete > at the point of its non-dependent use. Ah, overreduced. I've made shared_ptr complete. Marek