https://gcc.gnu.org/g:fd2afe61c2860a2b3e8f02a31bad86b768d16265
commit r16-6981-gfd2afe61c2860a2b3e8f02a31bad86b768d16265 Author: Marek Polacek <[email protected]> Date: Wed Jan 21 14:04:34 2026 -0500 c++: fix user_provided_p A user-provided function is a user-declared function that is not explicitly defaulted or deleted on its first declaration ([dcl.fct.def.default]). So, void bar (int, long) = delete; in namespace scope should not be user-provided. But user_provided_p was mistakenly returning true for this case, so eval_is_user_provided had to work around that. This patch corrects user_provided_p. It makes use of the fact that a function deleted after its first declaration is ill-formed rather than user-provided: void f(); void f() = delete; // error, not first declaration gcc/cp/ChangeLog: * class.cc (user_provided_p): Return false for a deleted namespace-scope function. * reflect.cc (eval_is_user_provided): Don't check DECL_NAMESPACE_SCOPE_P or DECL_DELETED_FN. Reviewed-by: Jason Merrill <[email protected]> Diff: --- gcc/cp/class.cc | 9 +++++++-- gcc/cp/reflect.cc | 6 +----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc index c610236f2601..6f00ca671e47 100644 --- a/gcc/cp/class.cc +++ b/gcc/cp/class.cc @@ -5726,7 +5726,7 @@ in_class_defaulted_default_constructor (tree t) } /* Returns true iff FN is a user-provided function, i.e. user-declared - and not defaulted at its first declaration. */ + and not explicitly defaulted or deleted on its first declaration. */ bool user_provided_p (tree fn) @@ -5734,7 +5734,12 @@ user_provided_p (tree fn) fn = STRIP_TEMPLATE (fn); return (!DECL_ARTIFICIAL (fn) && !(DECL_INITIALIZED_IN_CLASS_P (fn) - && (DECL_DEFAULTED_FN (fn) || DECL_DELETED_FN (fn)))); + && (DECL_DEFAULTED_FN (fn) || DECL_DELETED_FN (fn))) + /* At namespace scope, + void f () = delete; + is *not* user-provided (and any function deleted after its first + declaration is ill-formed). */ + && !(DECL_NAMESPACE_SCOPE_P (fn) && DECL_DELETED_FN (fn))); } /* Returns true iff class T has a user-provided constructor. */ diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc index 0b0fc2769d88..788c00c6f305 100644 --- a/gcc/cp/reflect.cc +++ b/gcc/cp/reflect.cc @@ -1780,11 +1780,7 @@ static tree eval_is_user_provided (tree r) { r = maybe_get_first_fn (r); - if (TREE_CODE (r) == FUNCTION_DECL - && user_provided_p (r) - // TODO: user_provided_p is false for non-members defaulted on - // first declaration. - && (!DECL_NAMESPACE_SCOPE_P (r) || !DECL_DELETED_FN (r))) + if (TREE_CODE (r) == FUNCTION_DECL && user_provided_p (r)) return boolean_true_node; else return boolean_false_node;
