+/* An alias template is complex from a SFINAE perspective if a template-id
+ using that alias can be ill-formed when the expansion is not, as with
+ the void_t template. We determine this by checking whether the
+ expansion for the alias template uses all its template parameters. */
+
+struct uses_all_template_parms_data
+{
+ int level;
+ bool *seen;
+};
+
+static int
+uses_all_template_parms_r (tree t, void *data_)
+{
+ struct uses_all_template_parms_data &data
+ = *(struct uses_all_template_parms_data*)data_;
+ tree idx = get_template_parm_index (t);
+
+ if (TEMPLATE_PARM_LEVEL (idx) == data.level)
+ data.seen[TEMPLATE_PARM_IDX (idx)] = true;
+ return 0;
+}
+
+static bool
+complex_alias_template_p (const_tree tmpl)
+{
+ struct uses_all_template_parms_data data;
+ tree pat = DECL_ORIGINAL_TYPE (DECL_TEMPLATE_RESULT (tmpl));
+ tree parms = DECL_TEMPLATE_PARMS (tmpl);
+ data.level = TMPL_PARMS_DEPTH (parms);
+ int len = TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS (parms));
+ data.seen = XALLOCAVEC (bool, len);
+ for (int i = 0; i < len; ++i)
+ data.seen[i] = false;
+
+ for_each_template_parm (pat, uses_all_template_parms_r, &data, NULL, true);
+ for (int i = 0; i < len; ++i)
+ if (!data.seen[i])
+ return true;
+ return false;
+}
+
+/* Return TRUE iff T is a specialization of a complex alias template with