Hi,

lately I spent quite a bit of time triaging and resolving ICEs and noticed this recently filed regression which, in a wicked way, I find somehow funny. In short, we are seeing an ICE in tsubst_copy_and_build, when, for an INDIRECT_REF, TREE_TYPE (r) is found null:

case INDIRECT_REF:
   {
    tree r = RECUR (TREE_OPERAND (t, 0));

    if (REFERENCE_REF_P (t))
      {
        /* A type conversion to reference type will be enclosed in
           such an indirect ref, but the substitution of the cast
           will have also added such an indirect ref.  */
        if (TREE_CODE (TREE_TYPE (r)) == REFERENCE_TYPE)
          r = convert_from_reference (r);

Since Jason's r226642, which fixed a serious issue with multiple Bugzillas, we have lookup_template_variable doing:

  /* The type of the expression is NULL_TREE since the template-id could refer
     to an explicit or partial specialization. */
  tree type = NULL_TREE;

instead of setting type = unknown_type_node and that ultimately leads to the ICE for the testcase at issue. Now, I found in a way funny that the body of convert_from_reference has:

tree
convert_from_reference (tree val)
{
  if (TREE_TYPE (val)
      && TREE_CODE (TREE_TYPE (val)) == REFERENCE_TYPE)

thus, if only somebody had cleaned up with no functionality change the above bits of tsubst_copy_and_build to unconditionally call convert_from_reference we would not have PR82085. Or at least we would not have it in this form, maybe we are only uncovering a much deeper issue?!? Anyway, the trivial patchlet below certainly passes testing on x86_64-linux. What do you think?

Thanks, Paolo.

/////////////////////

Index: cp/pt.c
===================================================================
--- cp/pt.c     (revision 254198)
+++ cp/pt.c     (working copy)
@@ -17079,8 +17079,7 @@ tsubst_copy_and_build (tree t,
            /* A type conversion to reference type will be enclosed in
               such an indirect ref, but the substitution of the cast
               will have also added such an indirect ref.  */
-           if (TREE_CODE (TREE_TYPE (r)) == REFERENCE_TYPE)
-             r = convert_from_reference (r);
+           r = convert_from_reference (r);
          }
        else
          r = build_x_indirect_ref (input_location, r, RO_UNARY_STAR,
Index: testsuite/g++.dg/cpp1y/var-templ56.C
===================================================================
--- testsuite/g++.dg/cpp1y/var-templ56.C        (nonexistent)
+++ testsuite/g++.dg/cpp1y/var-templ56.C        (working copy)
@@ -0,0 +1,11 @@
+// PR c++/82085
+// { dg-do compile { target c++14 } }
+
+template <const char& V>
+using char_sequence_t = int;
+
+template <typename T>
+constexpr char name_of_v = 'x';
+
+template <typename T>
+using type = char_sequence_t<name_of_v<T>>;

Reply via email to