https://gcc.gnu.org/g:f529f3d0ecde48e785ed792b24ae2fce635c5b55
commit r15-8672-gf529f3d0ecde48e785ed792b24ae2fce635c5b55 Author: Georg-Johann Lay <a...@gjlay.de> Date: Fri Mar 21 14:29:13 2025 +0100 AVR: Add attribute "used" for code in .initN and .initN sections. Code in .initN and .initN sections is never called since these sections are special and part of the startup resp. shutdown code. This patch adds attribute "used" so they won't be optimized out. gcc/ * config/avr/avr.cc (avr_attrs_section_name): New function. (avr_insert_attributes): Add "used" attribute to functions in .initN and .finiN. Diff: --- gcc/config/avr/avr.cc | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc index 71c03b421489..0ce06a1e580a 100644 --- a/gcc/config/avr/avr.cc +++ b/gcc/config/avr/avr.cc @@ -11736,6 +11736,23 @@ avr_handle_isr_attribute (tree node, tree *attrs, const char *name) } +/* Helper for `avr_insert_attributes'. + Return the section name from attribute "section" in attribute list ATTRS. + When no "section" attribute is present, then return nullptr. */ + +static const char * +avr_attrs_section_name (tree attrs) +{ + if (tree a_sec = lookup_attribute ("section", attrs)) + if (TREE_VALUE (a_sec)) + if (tree t_section_name = TREE_VALUE (TREE_VALUE (a_sec))) + if (TREE_CODE (t_section_name) == STRING_CST) + return TREE_STRING_POINTER (t_section_name); + + return nullptr; +} + + /* Implement `TARGET_INSERT_ATTRIBUTES'. */ static void @@ -11768,25 +11785,31 @@ avr_insert_attributes (tree node, tree *attributes) NULL, *attributes); } + const char *section_name = avr_attrs_section_name (*attributes); + + // When the function is in an .initN or .finiN section, then add "used" + // since such functions are never called. + if (section_name + && strlen (section_name) == strlen (".init*") + && IN_RANGE (section_name[5], '0', '9') + && (startswith (section_name, ".init") + || startswith (section_name, ".fini")) + && !lookup_attribute ("used", *attributes)) + { + *attributes = tree_cons (get_identifier ("used"), NULL, *attributes); + } + #if defined WITH_AVRLIBC if (avropt_call_main == 0 && TREE_CODE (node) == FUNCTION_DECL && MAIN_NAME_P (DECL_NAME (node))) { - const char *s_section_name = nullptr; - - if (tree a_sec = lookup_attribute ("section", *attributes)) - if (TREE_VALUE (a_sec)) - if (tree t_section_name = TREE_VALUE (TREE_VALUE (a_sec))) - if (TREE_CODE (t_section_name) == STRING_CST) - s_section_name = TREE_STRING_POINTER (t_section_name); - - bool in_init9_p = s_section_name && !strcmp (s_section_name, ".init9"); + bool in_init9_p = section_name && !strcmp (section_name, ".init9"); - if (s_section_name && !in_init9_p) + if (section_name && !in_init9_p) { warning (OPT_Wattributes, "%<section(\"%s\")%> attribute on main" - " function inhibits %<-mno-call-main%>", s_section_name); + " function inhibits %<-mno-call-main%>", section_name); } else {