https://gcc.gnu.org/g:fa20d1d7095122c7fc0e701b08ec383a60404bb0

commit r16-7332-gfa20d1d7095122c7fc0e701b08ec383a60404bb0
Author: Michal Jires <[email protected]>
Date:   Fri Jan 30 16:42:48 2026 +0100

    c,c++: Fix incorrect warning with asm defined symbols
    
    Static symbols defined in assembly cause wrong "used but never defined"
    warning.
    
    static void asm_fn();
    asm("%cc0:" :: ":"(&asm_fn));
    
    This happens in C,C++ frontends before cgraph is created where the
    relevant flags are located.
    
    We can suppress these warnings with OPT_Wunused.
    C,C++ frontends and cgraphunit suppressed OPT_Wunused and
    OPT_Wunused_function interchangeably, so we unify suppression to
    only OPT_Wunused.
    
            PR testsuite/123559
    
    gcc/c/ChangeLog:
    
            * c-decl.cc (c_write_global_declarations_1): Check and suppress
            OPT_Wunused.
            * c-typeck.cc (build_asm_expr): Suppress OPT_Wunused.
    
    gcc/ChangeLog:
    
            * cgraphunit.cc (check_global_declaration): Suppress OPT_Wunused.
    
    gcc/cp/ChangeLog:
    
            * decl.cc (wrapup_namespace_globals): Check and suppress 
OPT_Wunused.
            * semantics.cc (finish_asm_stmt): Suppress OPT_Wunused.
    
    gcc/testsuite/ChangeLog:
    
            * c-c++-common/toplevel-extended-asm-1.c: New test.

Diff:
---
 gcc/c/c-decl.cc                                      | 17 +++++++----------
 gcc/c/c-typeck.cc                                    |  2 ++
 gcc/cgraphunit.cc                                    | 11 +++++++----
 gcc/cp/decl.cc                                       |  9 +++++----
 gcc/cp/semantics.cc                                  |  2 ++
 gcc/testsuite/c-c++-common/toplevel-extended-asm-1.c |  5 +++++
 6 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 7dddc23b5e17..ea0eaec0bb5d 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -13679,25 +13679,22 @@ c_write_global_declarations_1 (tree globals)
       if (TREE_CODE (decl) == FUNCTION_DECL
          && DECL_INITIAL (decl) == NULL_TREE
          && DECL_EXTERNAL (decl)
-         && !TREE_PUBLIC (decl))
+         && !TREE_PUBLIC (decl)
+         && !warning_suppressed_p (decl, OPT_Wunused))
        {
          if (C_DECL_USED (decl))
            {
-             /* TODO: Add OPT_Wundefined-inline.  */
              if (pedwarn (input_location, 0, "%q+F used but never defined",
                           decl))
-               suppress_warning (decl /* OPT_Wundefined-inline.  */);
+               suppress_warning (decl, OPT_Wunused);
            }
          /* For -Wunused-function warn about unused static prototypes.  */
          else if (warn_unused_function
                   && ! DECL_ARTIFICIAL (decl)
-                  && ! warning_suppressed_p (decl, OPT_Wunused_function))
-           {
-             if (warning (OPT_Wunused_function,
-                          "%q+F declared %<static%> but never defined",
-                          decl))
-               suppress_warning (decl, OPT_Wunused_function);
-           }
+                  && warning (OPT_Wunused_function,
+                              "%q+F declared %<static%> but never defined",
+                              decl))
+           suppress_warning (decl, OPT_Wunused);
        }
 
       wrapup_global_declaration_1 (decl);
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 098a4b553399..dc803dc6388a 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -13170,6 +13170,8 @@ build_asm_expr (location_t loc, tree string, tree 
outputs, tree inputs,
                                 "of a function or non-automatic variable");
                  input = error_mark_node;
                }
+             else if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
+               suppress_warning (TREE_OPERAND (t, 0), OPT_Wunused);
            }
        }
       else
diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc
index 88c1071c8de9..b0a0061abb5d 100644
--- a/gcc/cgraphunit.cc
+++ b/gcc/cgraphunit.cc
@@ -1111,10 +1111,13 @@ check_global_declaration (symtab_node *snode)
       if (warning_suppressed_p (decl, OPT_Wunused))
        ;
       else if (snode->referred_to_p (/*include_self=*/false))
-       pedwarn (input_location, 0, "%q+F used but never defined", decl);
-      else
-       warning (OPT_Wunused_function, "%q+F declared %<static%> but never "
-                                      "defined", decl);
+       {
+         if (pedwarn (input_location, 0, "%q+F used but never defined", decl))
+           suppress_warning (decl, OPT_Wunused);
+       }
+      else if (warning (OPT_Wunused_function,
+                       "%q+F declared %<static%> but never defined", decl))
+       suppress_warning (decl, OPT_Wunused);
     }
 
   /* Warn about static fns or vars defined but not used.  */
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 6dabf349befb..c6aac6a8779e 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -1015,10 +1015,11 @@ wrapup_namespace_globals ()
              && !TREE_PUBLIC (decl)
              && !DECL_ARTIFICIAL (decl)
              && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl)
-             && !warning_suppressed_p (decl, OPT_Wunused_function))
-           warning_at (DECL_SOURCE_LOCATION (decl),
-                       OPT_Wunused_function,
-                       "%qF declared %<static%> but never defined", decl);
+             && !warning_suppressed_p (decl, OPT_Wunused)
+             && warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wunused_function,
+                            "%qF declared %<static%> but never defined",
+                            decl))
+               suppress_warning (decl, OPT_Wunused);
 
          if (VAR_P (decl)
              && DECL_EXTERNAL (decl)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index fb1be25edf5f..236bc625c25d 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -2495,6 +2495,8 @@ finish_asm_stmt (location_t loc, int volatile_p, tree 
string,
                                "of a function or non-automatic variable");
                      operand = error_mark_node;
                    }
+                 else if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
+                   suppress_warning (TREE_OPERAND (t, 0), OPT_Wunused);
                }
            }
          else
diff --git a/gcc/testsuite/c-c++-common/toplevel-extended-asm-1.c 
b/gcc/testsuite/c-c++-common/toplevel-extended-asm-1.c
new file mode 100644
index 000000000000..531c94231659
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/toplevel-extended-asm-1.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+static void asm_fn(); /* { dg-bogus "but never defined" } */
+asm("%cc0:" :: ":"(&asm_fn));

Reply via email to