c++: Simplify typedef access checking
authorNathan Sidwell <nathan@acm.org>
Wed, 13 May 2020 20:17:25 +0000 (13:17 -0700)
committerNathan Sidwell <nathan@acm.org>
Wed, 13 May 2020 20:17:25 +0000 (13:17 -0700)
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.

gcc/cp/ChangeLog
gcc/cp/pt.c

index 10f212f..a63f04e 100644 (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.
index ec2ca3e..52ed462 100644 (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 (!type_decl || !type_scope || !CLASS_TYPE_P (type_scope))
-       continue;
+  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 (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 (!type_decl || !type_scope || !CLASS_TYPE_P (type_scope))
+         continue;
 
-      /* 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);
-    }
+       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);
+      }
 }
 
 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;
-
-  if (!t || t == error_mark_node)
-    return 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 (!(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);