For code in .initN and .finiN there are no calls, hence let the
compiler add "used" attribute.
Ok for trunk?
Johann
--
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.
commit e0e33695a97576cd8cc23da5d5162e4fa595e7ba
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 --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
index 71c03b42148..0ce06a1e580 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
{