STF_STRIP_DEPENDENT: allow the stripping of aliases with dependent
template parameters, relying on code elsewhere to report any
- appropriate diagnostics. */
+ appropriate diagnostics.
+
+ STF_KEEP_INJ_CLASS_NAME: don't strip injected-class-name typedefs
+ because we're dealing with a non-coerced template argument.
+*/
const unsigned int STF_USER_VISIBLE = 1U;
const unsigned int STF_STRIP_DEPENDENT = 1U << 1;
+const unsigned int STF_KEEP_INJ_CLASS_NAME = 1U << 2;
/* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM
node. */
// to hash differently from its TYPE_CANONICAL, to avoid hash
// collisions that compare as different in template_args_equal.
// These could be dependent specializations that strip_typedefs
- // left alone, or untouched specializations because
- // coerce_template_parms returns the unconverted template
- // arguments if it sees incomplete argument packs.
+ // left alone for example.
tree ti = TYPE_ALIAS_TEMPLATE_INFO (ats);
return hash_tmpl_and_args (TI_TEMPLATE (ti), TI_ARGS (ti));
}
/* We don't know how many args we have yet, just use the
unconverted (and still packed) ones for now. */
ggc_free (new_inner_args);
- new_inner_args = orig_inner_args;
+ new_inner_args = strip_typedefs (orig_inner_args,
+ /*remove_attrs=*/nullptr,
+ STF_KEEP_INJ_CLASS_NAME);
arg_idx = nargs;
break;
}
/* We don't know how many args we have yet, just
use the unconverted (but unpacked) ones for now. */
ggc_free (new_inner_args);
- new_inner_args = inner_args;
+ new_inner_args = strip_typedefs (inner_args,
+ /*remove_attrs=*/nullptr,
+ STF_KEEP_INJ_CLASS_NAME);
arg_idx = nargs;
break;
}
/* Builds a qualified variant of T that is either not a typedef variant
(the default behavior) or not a typedef variant of a user-facing type
- (if FLAGS contains STF_USER_FACING). If T is not a type, then this
+ (if FLAGS contains STF_USER_VISIBLE). If T is not a type, then this
just dispatches to strip_typedefs_expr.
E.g. consider the following declarations:
&& !user_facing_original_type_p (t))
return t;
+ if ((flags & STF_KEEP_INJ_CLASS_NAME)
+ && CLASS_TYPE_P (t)
+ && DECL_SELF_REFERENCE_P (TYPE_NAME (t)))
+ return t;
+
if (dependent_opaque_alias_p (t))
return t;
--- /dev/null
+// PR c++/118454
+// { dg-do compile { target c++11 } }
+// { dg-additional-options --param=hash-table-verification-limit=1000 }
+
+template<class T> using identity = T;
+
+template<class T, class U0, class... Us> struct dual;
+
+template<class T, class... Ts>
+using ty1 = dual<identity<T>, Ts...>;
+
+template<class T, class... Ts>
+using ty2 = dual<T, Ts...>;