On Mon, Jan 27, 2025 at 10:20:05AM -0500, Patrick Palka wrote: > [snip] > > > @@ -18486,6 +18562,12 @@ dependent_operand_p (tree t) > > { > > while (TREE_CODE (t) == IMPLICIT_CONV_EXPR) > > t = TREE_OPERAND (t, 0); > > + > > + /* If we contain a TU_LOCAL_ENTITY assume we're non-dependent; we'll > > error > > + later when instantiating. */ > > + if (expr_contains_tu_local_entity (t)) > > + return false; > > I think it'd be more robust and cheaper (avoiding a separate tree walk) > to teach the general constexpr/dependence predicates about > TU_LOCAL_ENTITY instead of handling it only here. > > > + > > ++processing_template_decl; > > bool r = (potential_constant_expression (t) > > ? value_dependent_expression_p (t) > > @@ -20255,6 +20337,9 @@ tsubst_expr (tree t, tree args, tsubst_flags_t > > complain, tree in_decl) > > else > > object = NULL_TREE; > > > > + if (function_contains_tu_local_entity (templ)) > > + RETURN (error_mark_node); > > + > > tree tid = lookup_template_function (templ, targs); > > protected_set_expr_location (tid, EXPR_LOCATION (t)); > > > > @@ -20947,6 +21032,9 @@ tsubst_expr (tree t, tree args, tsubst_flags_t > > complain, tree in_decl) > > qualified_p = true; > > } > > > > + if (function_contains_tu_local_entity (function)) > > + RETURN (error_mark_node); > > Similarly, maybe it'd suffice to check this more generally in the > OVERLOAD case of tsubst_expr? >
So I'd completely missed the idea of handling it in the OVERLOAD case; doing this also fixes the issues I'd been having trying to handle it in potential_constant_expression. I think this should be a lot cleaner now. Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk? -- >8 -- Subject: [PATCH] c++: Handle TU_LOCAL_ENTITY in tsubst_expr and potential_constant_expression This cleans up the TU_LOCAL_ENTITY handling to avoid unnecessary tree walks and make the logic more robust. gcc/cp/ChangeLog: * constexpr.cc (potential_constant_expression_1): Handle TU_LOCAL_ENTITY. * pt.cc (expr_contains_tu_local_entity): Remove. (function_contains_tu_local_entity): Remove. (dependent_operand_p): Remove special handling for TU_LOCAL_ENTITY. (tsubst_expr): Handle TU_LOCAL_ENTITY when tsubsting OVERLOADs; remove now-unnecessary extra handling. (type_dependent_expression_p): Handle TU_LOCAL_ENTITY. Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com> --- gcc/cp/constexpr.cc | 5 +++ gcc/cp/pt.cc | 80 ++++++++------------------------------------- 2 files changed, 19 insertions(+), 66 deletions(-) diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index f142dd32bc8..b36705fd4ce 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -10825,6 +10825,11 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, case CO_RETURN_EXPR: return false; + /* Assume a TU-local entity is not constant, we'll error later when + instantiating. */ + case TU_LOCAL_ENTITY: + return false; + case NONTYPE_ARGUMENT_PACK: { tree args = ARGUMENT_PACK_ARGS (t); diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index f857b3f1180..966050a6608 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -9935,61 +9935,6 @@ complain_about_tu_local_entity (tree e) inform (TU_LOCAL_ENTITY_LOCATION (e), "declared here"); } -/* Checks if T contains a TU-local entity. */ - -static bool -expr_contains_tu_local_entity (tree t) -{ - if (!modules_p ()) - return false; - - auto walker = [](tree *tp, int *walk_subtrees, void *) -> tree - { - if (TREE_CODE (*tp) == TU_LOCAL_ENTITY) - return *tp; - if (!EXPR_P (*tp)) - *walk_subtrees = false; - return NULL_TREE; - }; - return cp_walk_tree (&t, walker, nullptr, nullptr); -} - -/* Errors and returns TRUE if X is a function that contains a TU-local - entity in its overload set. */ - -static bool -function_contains_tu_local_entity (tree x) -{ - if (!modules_p ()) - return false; - - if (!x || x == error_mark_node) - return false; - - if (TREE_CODE (x) == OFFSET_REF - || TREE_CODE (x) == COMPONENT_REF) - x = TREE_OPERAND (x, 1); - x = MAYBE_BASELINK_FUNCTIONS (x); - if (TREE_CODE (x) == TEMPLATE_ID_EXPR) - x = TREE_OPERAND (x, 0); - - if (OVL_P (x)) - for (tree ovl : lkp_range (x)) - if (TREE_CODE (ovl) == TU_LOCAL_ENTITY) - { - x = ovl; - break; - } - - if (TREE_CODE (x) == TU_LOCAL_ENTITY) - { - complain_about_tu_local_entity (x); - return true; - } - - return false; -} - /* Return a TEMPLATE_ID_EXPR corresponding to the indicated FNS and ARGLIST. Valid choices for FNS are given in the cp-tree.def documentation for TEMPLATE_ID_EXPR. */ @@ -18797,11 +18742,6 @@ dependent_operand_p (tree t) while (TREE_CODE (t) == IMPLICIT_CONV_EXPR) t = TREE_OPERAND (t, 0); - /* If we contain a TU_LOCAL_ENTITY assume we're non-dependent; we'll error - later when instantiating. */ - if (expr_contains_tu_local_entity (t)) - return false; - ++processing_template_decl; bool r = (potential_constant_expression (t) ? value_dependent_expression_p (t) @@ -20629,9 +20569,6 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) else object = NULL_TREE; - if (function_contains_tu_local_entity (templ)) - RETURN (error_mark_node); - tree tid = lookup_template_function (templ, targs); protected_set_expr_location (tid, EXPR_LOCATION (t)); @@ -21324,9 +21261,6 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) qualified_p = true; } - if (function_contains_tu_local_entity (function)) - RETURN (error_mark_node); - nargs = call_expr_nargs (t); releasing_vec call_args; tsubst_call_args (t, args, complain, in_decl, call_args); @@ -22122,7 +22056,16 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) RETURN (t); case NAMESPACE_DECL: + RETURN (t); + case OVERLOAD: + if (modules_p ()) + for (tree ovl : lkp_range (t)) + if (TREE_CODE (ovl) == TU_LOCAL_ENTITY) + { + complain_about_tu_local_entity (ovl); + RETURN (error_mark_node); + } RETURN (t); case TEMPLATE_DECL: @@ -28990,6 +28933,11 @@ type_dependent_expression_p (tree expression) STRIP_ANY_LOCATION_WRAPPER (expression); + /* Assume a TU-local entity is not dependent, we'll error later when + instantiating anyway. */ + if (TREE_CODE (expression) == TU_LOCAL_ENTITY) + return false; + /* An unresolved name is always dependent. */ if (identifier_p (expression) || TREE_CODE (expression) == USING_DECL) -- 2.47.0