On 6/5/20 5:16 PM, Patrick Palka wrote:
The previous patch mostly avoided making any changes that had no
functional impact, such as adjusting now-outdated comments and
performing renamings.  Such changes have been consolidated to this
followup patch for easier review.

The main change here is that we now reuse struct deferred_access_check
as the element type of the vector TI_TYPEDEFS_NEEDING_ACCESS_CHECKING
(now renamed to TI_DEFERRED_ACCESS_CHECKS, since it now may contain all
kinds of access checks).

gcc/cp/ChangeLog:

        PR c++/41437
        PR c++/47346
        * cp-tree.h (qualified_typedef_usage_s): Delete.
        (qualified_typedef_usage_t): Delete.
        (deferred_access_check): Move up in file.
        (tree_template_info::typedefs_needing_access_checking): Delete.
        (tree_template_info::deferred_access_checks): New field.
        (TI_TYPEDEFS_NEEDING_ACCESS_CHECKING): Rename to ...
        (TI_DEFERRED_ACCESS_CHECKS): ... this, and adjust accordingly.
        * pt.c (perform_typedefs_access_check): Rename to ...
        (perform_instantiation_time_access_checks): ... this, and adjust
        accordingly.  Remove unnecessary tree tests.
        (instantiate_class_template_1): Adjust accordingly.
        (instantiate_decl): Likewise.
        * semantics.c (enforce_access): Adjust to build up a
        deferred_access_check.
---
  gcc/cp/cp-tree.h   | 58 +++++++++++++++----------------------------
  gcc/cp/pt.c        | 61 +++++++++++++++++-----------------------------
  gcc/cp/semantics.c | 12 ++++-----
  3 files changed, 48 insertions(+), 83 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 771d51cc283..50d83add458 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1449,27 +1449,6 @@ struct GTY (()) tree_lambda_expr
    int discriminator;
  };
-/* A (typedef,context,usage location) triplet.
-   It represents a typedef used through a
-   context at a given source location.
-   e.g.
-   struct foo {
-     typedef int myint;
-   };
-
-   struct bar {
-    foo::myint v; // #1<-- this location.
-   };
-
-   In bar, the triplet will be (myint, foo, #1).
-   */
-struct GTY(()) qualified_typedef_usage_s {
-  tree typedef_decl;
-  tree context;
-  location_t locus;
-};
-typedef struct qualified_typedef_usage_s qualified_typedef_usage_t;
-
  /* Non-zero if this template specialization has access violations that
     should be rechecked when the function is instantiated outside argument
     deduction.  */
@@ -1489,11 +1468,24 @@ typedef struct qualified_typedef_usage_s 
qualified_typedef_usage_t;
  #define TINFO_VAR_DECLARED_CONSTINIT(NODE) \
    (TREE_LANG_FLAG_2 (TEMPLATE_INFO_CHECK (NODE)))
+/* The representation of a deferred access check. */
+
+struct GTY(()) deferred_access_check {
+  /* The base class in which the declaration is referenced. */
+  tree binfo;
+  /* The declaration whose access must be checked.  */
+  tree decl;
+  /* The declaration that should be used in the error message.  */
+  tree diag_decl;
+  /* The location of this access.  */
+  location_t loc;
+};
+
  struct GTY(()) tree_template_info {
    struct tree_base base;
    tree tmpl;
    tree args;
-  vec<qualified_typedef_usage_t, va_gc> *typedefs_needing_access_checking;
+  vec<deferred_access_check, va_gc> *deferred_access_checks;
  };
// Constraint information for a C++ declaration. Constraint information is
@@ -3532,14 +3524,15 @@ struct GTY(()) lang_decl {
    ? int_cst_value (NON_DEFAULT_TEMPLATE_ARGS_COUNT (NODE)) \
    : TREE_VEC_LENGTH (INNERMOST_TEMPLATE_ARGS (NODE))
  #endif
-/* The list of typedefs - used in the template - that need
-   access checking at template instantiation time.
+
+/* The list of access checks that were deferred during parsing
+   which need to be performed at template instantiation time.
FIXME this should be associated with the TEMPLATE_DECL, not the
     TEMPLATE_INFO.  */
-#define TI_TYPEDEFS_NEEDING_ACCESS_CHECKING(NODE) \
+#define TI_DEFERRED_ACCESS_CHECKS(NODE) \
    ((struct tree_template_info*)TEMPLATE_INFO_CHECK \
-     (NODE))->typedefs_needing_access_checking
+     (NODE))->deferred_access_checks
/* We use TREE_VECs to hold template arguments. If there is only one
     level of template arguments, then the TREE_VEC contains the
@@ -7090,19 +7083,6 @@ extern int shared_member_p                       (tree);
  extern bool any_dependent_bases_p (tree = current_nonlambda_class_type ());
  extern bool maybe_check_overriding_exception_spec (tree, tree);
-/* The representation of a deferred access check. */
-
-struct GTY(()) deferred_access_check {
-  /* The base class in which the declaration is referenced. */
-  tree binfo;
-  /* The declaration whose access must be checked.  */
-  tree decl;
-  /* The declaration that should be used in the error message.  */
-  tree diag_decl;
-  /* The location of this access.  */
-  location_t loc;
-};
-
  /* in semantics.c */
  extern void push_deferring_access_checks      (deferring_kind);
  extern void resume_deferring_access_checks    (void);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index be319c50783..142392224c6 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -215,7 +215,7 @@ static bool 
any_template_arguments_need_structural_equality_p (tree);
  static bool dependent_type_p_r (tree);
  static tree tsubst_copy       (tree, tree, tsubst_flags_t, tree);
  static tree tsubst_decl (tree, tree, tsubst_flags_t);
-static void perform_typedefs_access_check (tree tmpl, tree targs);
+static void perform_instantiation_time_access_checks (tree, tree);
  static tree listify (tree);
  static tree listify_autos (tree, tree);
  static tree tsubst_template_parm (tree, tree, tsubst_flags_t);
@@ -11502,46 +11502,39 @@ apply_late_template_attributes (tree *decl_p, tree 
attributes, int attr_flags,
      }
  }
-/* Perform (or defer) access check for typedefs that were referenced
-   from within the template TMPL code.
-   This is a subroutine of instantiate_decl and instantiate_class_template.
-   TMPL is the template to consider and TARGS is the list of arguments of
-   that template.  */
+/* The template TMPL is being instantiated with the template arguments TARGS.
+   Perform the access checks that we deferred during parsing of the
+   template.  */
static void
-perform_typedefs_access_check (tree tmpl, tree targs)
+perform_instantiation_time_access_checks (tree tmpl, tree targs)
  {
    unsigned i;
-  qualified_typedef_usage_t *iter;
+  deferred_access_check *chk;
- if (!tmpl
-      || (!CLASS_TYPE_P (tmpl)
-         && TREE_CODE (tmpl) != FUNCTION_DECL))
+  if (!CLASS_TYPE_P (tmpl) && TREE_CODE (tmpl) != FUNCTION_DECL)
      return;
- if (vec<qualified_typedef_usage_t, va_gc> *tdefs
-      = TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (get_template_info (tmpl)))
-    FOR_EACH_VEC_ELT (*tdefs, i, iter)
+  if (vec<deferred_access_check, va_gc> *access_checks
+      = TI_DEFERRED_ACCESS_CHECKS (get_template_info (tmpl)))
+    FOR_EACH_VEC_ELT (*access_checks, i, chk)
        {
-       tree type_decl = iter->typedef_decl;
-       tree type_scope = iter->context;
-
-       if (!type_decl || !type_scope || !CLASS_TYPE_P (type_scope))
-         continue;
-
-       if (uses_template_parms (type_decl)
-           || (TREE_CODE (type_decl) == FIELD_DECL
-               && uses_template_parms (DECL_CONTEXT (type_decl))))
-         type_decl = tsubst_copy (type_decl, targs, tf_error, NULL_TREE);
+       tree decl = chk->decl;
+       tree diag_decl = chk->diag_decl;
+       tree type_scope = TREE_TYPE (chk->binfo);
+
+       if (uses_template_parms (decl)
+           || (TREE_CODE (decl) == FIELD_DECL
+               && uses_template_parms (DECL_CONTEXT (decl))))
+         decl = tsubst_copy (decl, targs, tf_error, NULL_TREE);

Can decl still be dependent?

        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);
+       iloc_sentinel ils (chk->loc);
        perform_or_defer_access_check (TYPE_BINFO (type_scope),
-                                      type_decl, type_decl,
-                                      tf_warning_or_error);
+                                      decl, diag_decl, tf_warning_or_error);
        }
  }
@@ -12070,11 +12063,7 @@ instantiate_class_template_1 (tree type)
       definitions or default arguments, of the class member functions,
       member classes, static data members and member templates....  */
- /* Some typedefs referenced from within the template code need to be access
-     checked at template instantiation time, i.e now. These types were
-     added to the template at parsing time. Let's get those and perform
-     the access checks then.  */
-  perform_typedefs_access_check (pattern, args);
+  perform_instantiation_time_access_checks (pattern, args);
    perform_deferred_access_checks (tf_warning_or_error);
    pop_nested_class ();
    maximum_field_alignment = saved_maximum_field_alignment;
@@ -25621,12 +25610,8 @@ instantiate_decl (tree d, bool defer_ok, bool 
expl_inst_class_mem_p)
        else
        start_preparsed_function (d, NULL_TREE, SF_PRE_PARSED);
- /* Some typedefs referenced from within the template code need to be
-        access checked at template instantiation time, i.e now. These
-        types were added to the template at parsing time. Let's get those
-        and perform the access checks then.  */
-      perform_typedefs_access_check (DECL_TEMPLATE_RESULT (td),
-                                    args);
+      perform_instantiation_time_access_checks (DECL_TEMPLATE_RESULT (td),
+                                               args);
/* Create substitution entries for the parameters. */
        register_parameter_specializations (code_pattern, d);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index bf1d720347a..b94cd88166e 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -295,12 +295,12 @@ enforce_access (tree basetype_path, tree decl, tree 
diag_decl,
          return true;
/* Defer this access check until instantiation time. */
-       qualified_typedef_usage_t typedef_usage;
-       typedef_usage.typedef_decl = decl;
-       typedef_usage.context = TREE_TYPE (basetype_path);
-       typedef_usage.locus = input_location;
-       vec_safe_push (TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (template_info),
-                      typedef_usage);
+       deferred_access_check access_check;
+       access_check.binfo = basetype_path;
+       access_check.decl = decl;
+       access_check.diag_decl = diag_decl;
+       access_check.loc = input_location;
+       vec_safe_push (TI_DEFERRED_ACCESS_CHECKS (template_info), access_check);
        return true;
        }

Reply via email to