c++: Simplify typedef access checking

I discovered that the template typedef access check was rather more
expensive than needed.  The call of get_types_needed_access_check in
the FOR_EACH_VEC_SAFE_ELT is the moral equivalent of 'for (size_t pos
= 0; pos != strlen (string); pos++)'.  Let's not do that.

	* pt.c (perform_typedefs_access_check): Cache expensively
	calculated object references.
	(check_auto_in_tmpl_args): Just assert we do not get unexpected
	nodes, rather than silently do nothing.
	(append_type_to_template_for_access): Likewise, cache expensie
	object reference.
This commit is contained in:
Nathan Sidwell 2020-05-13 13:17:25 -07:00
parent 833c7b4b5e
commit 2bb30de62f
2 changed files with 37 additions and 38 deletions

View File

@ -1,5 +1,12 @@
2020-05-13 Nathan Sidwell <nathan@acm.org>
* pt.c (perform_typedefs_access_check): Cache expensively
calculated object references.
(check_auto_in_tmpl_args): Just assert we do not get unexpected
nodes, rather than silently do nothing.
(append_type_to_template_for_access): Likewise, cache expensie
object reference.
* pt.c (canonical_type_parameter): Simplify.
Formatting fixups & some simplifications.

View File

@ -11513,26 +11513,28 @@ perform_typedefs_access_check (tree tmpl, tree targs)
&& TREE_CODE (tmpl) != FUNCTION_DECL))
return;
FOR_EACH_VEC_SAFE_ELT (get_types_needing_access_check (tmpl), i, iter)
{
tree type_decl = iter->typedef_decl;
tree type_scope = iter->context;
if (vec<qualified_typedef_usage_t, va_gc> *tdefs
= get_types_needing_access_check (tmpl))
FOR_EACH_VEC_ELT (*tdefs, i, iter)
{
tree type_decl = iter->typedef_decl;
tree type_scope = iter->context;
if (!type_decl || !type_scope || !CLASS_TYPE_P (type_scope))
continue;
if (!type_decl || !type_scope || !CLASS_TYPE_P (type_scope))
continue;
if (uses_template_parms (type_decl))
type_decl = tsubst (type_decl, targs, tf_error, NULL_TREE);
if (uses_template_parms (type_scope))
type_scope = tsubst (type_scope, targs, tf_error, NULL_TREE);
if (uses_template_parms (type_decl))
type_decl = tsubst (type_decl, targs, tf_error, NULL_TREE);
if (uses_template_parms (type_scope))
type_scope = tsubst (type_scope, targs, tf_error, NULL_TREE);
/* Make access check error messages point to the location
of the use of the typedef. */
iloc_sentinel ils (iter->locus);
perform_or_defer_access_check (TYPE_BINFO (type_scope),
type_decl, type_decl,
tf_warning_or_error);
}
/* Make access check error messages point to the location
of the use of the typedef. */
iloc_sentinel ils (iter->locus);
perform_or_defer_access_check (TYPE_BINFO (type_scope),
type_decl, type_decl,
tf_warning_or_error);
}
}
static tree
@ -29217,25 +29219,13 @@ check_auto_in_tmpl_args (tree tmpl, tree args)
vec<qualified_typedef_usage_t, va_gc> *
get_types_needing_access_check (tree t)
{
tree ti;
vec<qualified_typedef_usage_t, va_gc> *result = NULL;
gcc_checking_assert ((CLASS_TYPE_P (t) || TREE_CODE (t) == FUNCTION_DECL));
if (tree ti = get_template_info (t))
if (TI_TEMPLATE (ti))
return TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (ti);
if (!t || t == error_mark_node)
return NULL;
if (!(ti = get_template_info (t)))
return NULL;
if (CLASS_TYPE_P (t)
|| TREE_CODE (t) == FUNCTION_DECL)
{
if (!TI_TEMPLATE (ti))
return NULL;
result = TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (ti);
}
return result;
return NULL;
}
/* Append the typedef TYPE_DECL used in template T to a list of typedefs
@ -29320,9 +29310,11 @@ append_type_to_template_for_access_check (tree templ,
gcc_assert (type_decl && (TREE_CODE (type_decl) == TYPE_DECL));
/* Make sure we don't append the type to the template twice. */
FOR_EACH_VEC_SAFE_ELT (get_types_needing_access_check (templ), i, iter)
if (iter->typedef_decl == type_decl && scope == iter->context)
return;
if (vec<qualified_typedef_usage_t, va_gc> *tdefs
= get_types_needing_access_check (templ))
FOR_EACH_VEC_ELT (*tdefs, i, iter)
if (iter->typedef_decl == type_decl && scope == iter->context)
return;
append_type_to_template_for_access_check_1 (templ, type_decl,
scope, location);