On Thu, Jan 22, 2026 at 11:41:27AM +0100, Michal Jires wrote:
> 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.

Why just the C FE?
C++ has the same problem:
pr123359.c:1:13: warning: ‘void asm_fn()’ declared ‘static’ but never defined 
[-Wunused-function]
    1 | static void asm_fn();
      |             ^~~~~~
pr123359.c:1:13: warning: ‘void asm_fn()’ declared ‘static’ but never defined 
[-Wunused-function]

> --- 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*)

The usual GCC coding style puts a space before *, not after it.

> +{
> +  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);

Why?
Immediately above this there is
              if (TREE_CODE (t) != ADDR_EXPR
                  || !(TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
                       || (VAR_P (TREE_OPERAND (t, 0))
                           && is_global_var (TREE_OPERAND (t, 0)))))
                error
So, why not simply add
              else
                TREE_ASM_WRITTEN (TREE_OPERAND (t, 0)) = 1;
with a comment?
And do it for C as well and add a testcase for it into c-c++-common
with dg-bogus?

        Jakub

Reply via email to