]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
AVR: Add attribute "used" for code in .initN and .initN sections.
authorGeorg-Johann Lay <avr@gjlay.de>
Fri, 21 Mar 2025 13:29:13 +0000 (14:29 +0100)
committerGeorg-Johann Lay <avr@gjlay.de>
Sat, 22 Mar 2025 16:47:36 +0000 (17:47 +0100)
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.

gcc/config/avr/avr.cc

index 71c03b4214890a20acb5fb1fb40a7bb865c3d640..0ce06a1e580a33863c4995b15442de68789fcbd5 100644 (file)
@@ -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
        {