Static symbols defined in assembly cause wrong "used but never defined"
warning.

static void asm_fn();
asm("%cc0:" :: ":"(&asm_fn));


This happens in C frontend before cgraph is created, so we need
to have a tree flag to mark a symbol as defined in assembly to disable
the warning.
TREE_ASM_WRITTEN seems to be usable for this purpose; written symbols
are always defined, and the symbol will be written separately by
toplevel assembly.

Tested on x86_64-pc-linux-gnu, ok for trunk?

        PR testsuite/123559

gcc/c/ChangeLog:

        * c-decl.cc (c_write_global_declarations_1): Check for asm
        symbols.
        * c-typeck.cc (walk_through_asm_defined_symbol): New.
        (build_asm_expr): Call walk_through_asm_defined_symbol.

gcc/ChangeLog:

        * cgraphunit.cc (check_global_declaration): Check for asm
        symbols.
---
 gcc/c/c-decl.cc   |  4 +++-
 gcc/c/c-typeck.cc | 10 ++++++++++
 gcc/cgraphunit.cc |  4 +++-
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 7e94430435c..b2d7eeb888f 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -13669,7 +13669,9 @@ 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)
+         /* Symbols defined in assembly.  */
+         && !TREE_ASM_WRITTEN (decl))
        {
          if (C_DECL_USED (decl))
            {
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 04b33111f62..f2ccbc9dea9 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -13007,6 +13007,15 @@ build_asm_stmt (bool is_volatile, tree args)
   return add_stmt (args);
 }
 
+/* Mark symbols defined in assembly.  */
+static tree
+walk_through_asm_defined_symbol (tree* t, int*, void*)
+{
+  if (VAR_OR_FUNCTION_DECL_P (*t))
+    TREE_ASM_WRITTEN (*t) = 1;
+  return NULL;
+}
+
 /* Build an asm-expr, whose components are a STRING, some OUTPUTS,
    some INPUTS, and some CLOBBERS.  The latter three may be NULL.
    SIMPLE indicates whether there was anything at all after the
@@ -13169,6 +13178,7 @@ build_asm_expr (location_t loc, tree string, tree 
outputs, tree inputs,
                                 "of a function or non-automatic variable");
                  input = error_mark_node;
                }
+             walk_tree (&t, walk_through_asm_defined_symbol, NULL, NULL);
            }
        }
       else
diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc
index 88c1071c8de..401e016b8ca 100644
--- a/gcc/cgraphunit.cc
+++ b/gcc/cgraphunit.cc
@@ -1106,7 +1106,9 @@ check_global_declaration (symtab_node *snode)
       && DECL_INITIAL (decl) == 0
       && DECL_EXTERNAL (decl)
       && ! DECL_ARTIFICIAL (decl)
-      && ! TREE_PUBLIC (decl))
+      && ! TREE_PUBLIC (decl)
+      /* Symbols defined in assembly.  */
+      && ! TREE_ASM_WRITTEN (decl))
     {
       if (warning_suppressed_p (decl, OPT_Wunused))
        ;
-- 
2.52.0

Reply via email to