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