c++: Clean up previous change [PR41437]

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 may contain any kind
of access check).

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): Likewise.
This commit is contained in:
Patrick Palka
2020-06-16 08:21:36 -04:00
parent 92bed03609
commit 668ef28fbb
3 changed files with 46 additions and 82 deletions

View File

@@ -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);

View File

@@ -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);
@@ -11512,46 +11512,38 @@ 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 when parsing 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;
tree decl = chk->decl;
tree diag_decl = chk->diag_decl;
tree type_scope = TREE_TYPE (chk->binfo);
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);
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);
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);
}
}
@@ -12080,11 +12072,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;
@@ -25631,12 +25619,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);

View File

@@ -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;
}