On Wed, Apr 03, 2024 at 01:14:46PM -0400, Jason Merrill wrote: > On 4/2/24 13:52, Marek Polacek wrote: > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/13? > > > > -- >8 -- > > We evaluate constexpr functions on the original, pre-genericization bodies. > > That means that the function body we're evaluating will not have gone > > through cp_genericize_r's "Map block scope extern declarations to visible > > declarations with the same name and type in outer scopes if any". Here: > > > > constexpr bool bar() { return true; } // #1 > > constexpr bool foo() { > > constexpr bool bar(void); // #2 > > return bar(); > > } > > > > it means that we: > > 1) register_constexpr_fundef (#1) > > 2) cp_genericize (#1) > > nothing interesting happens > > 3) register_constexpr_fundef (foo) > > does copy_fn, so we have two copies of the BIND_EXPR > > 4) cp_genericize (foo) > > this remaps #2 to #1, but only on one copy of the BIND_EXPR > > 5) retrieve_constexpr_fundef (foo) > > we find it, no problem > > 6) retrieve_constexpr_fundef (#2) > > and here #2 isn't found in constexpr_fundef_table, because > > we're working on the BIND_EXPR copy where #2 wasn't mapped to #1 > > so we fail. We've only registered #1. > > > > It should work to use DECL_LOCAL_DECL_ALIAS (which used to be > > extern_decl_map). We evaluate constexpr functions on pre-cp_fold > > bodies to avoid diagnostic problems, but the remapping I'm proposing > > should not interfere with diagnostics. > > > > This is not a problem for a global scope redeclaration; there we go > > through duplicate_decls which keeps the DECL_UID: > > DECL_UID (olddecl) = olddecl_uid; > > and DECL_UID is what constexpr_fundef_hasher::hash uses. > > > > PR c++/111132 > > > > gcc/cp/ChangeLog: > > > > * constexpr.cc (get_function_named_in_call): If there's > > a DECL_LOCAL_DECL_ALIAS, use it. > > Perhaps this function should use cp_get_fndecl_from_callee, and this change > should be made there instead?
It doesn't seem that get_function_named_in_call can use cp_get_fndecl_from_callee, (or be replaced with cp_get_callee_fndecl_nofold). We can get e.g. a CALL_EXPR whose CALL_EXPR_FN is a TEMPLATE_ID_EXPR, and get_function_named_in_call returns the TEMPLATE_ID_EXPR whereas cp_get_fndecl_from_callee would return null: if (TREE_CODE (fn) == FUNCTION_DECL) return fn; tree type = TREE_TYPE (fn); if (type == NULL_TREE || !INDIRECT_TYPE_P (type)) return NULL_TREE; Marek