A couple silly function attribute manipulations lead to situations that result in segfaults:
$ f() { :; }; declare -Af f; declare -pf f [ segfault ] diff --git a/builtins/setattr.def b/builtins/setattr.def index 251bcacb..1a828291 100644 --- a/builtins/setattr.def +++ b/builtins/setattr.def @@ -474,9 +474,9 @@ show_var_attributes (var, pattr, nodefs) #if defined (ARRAY_VARS) if (invisible_p (var) && (array_p (var) || assoc_p (var))) printf ("%s\n", var->name); - else if (array_p (var)) + else if (array_p (var) && function_p (var) == 0) print_array_assignment (var, 0); - else if (assoc_p (var)) + else if (assoc_p (var) && function_p (var) == 0) print_assoc_assignment (var, 0); else #endif (Maybe the better solution would be to prevent meaningless attributes from getting assigned to functions in the first place, but they seem harmless otherwise). $ f() { :; }; declare +f -f f; declare -pf f declare -- f=" " $ f() { :; }; declare -Af f; declare +f -f f; unset -f f [ segfault ] diff --git a/builtins/declare.def b/builtins/declare.def index 7eac6f58..bc44f54c 100644 --- a/builtins/declare.def +++ b/builtins/declare.def @@ -558,6 +558,7 @@ restart_new_var_name: else /* declare -[fF] -[rx] name [name...] */ { VSETATTR (var, flags_on); + flags_off &= ~att_function; VUNSETATTR (var, flags_off); } }