On 11/22/24 4:45 AM, Jakub Jelinek wrote:

2024-11-22  Jakub Jelinek  <ja...@redhat.com>

        PR c/41045
gcc/
        * output.h (insn_noperands): Declare.
        * final.cc (insn_noperands): No longer static.
        * varasm.cc (assemble_asm): Handle ASM_EXPR.
        * lto-streamer-out.cc (lto_output_toplevel_asms): Add sorry_at
        for non-STRING_CST toplevel asm for now.
        * doc/extend.texi (Basic @code{asm}, Extended @code{asm}): Document
        that extended asm is now allowed outside of functions with certain
        restrictions.
gcc/c/
        * c-parser.cc (c_parser_asm_string_literal): Add forward declaration.
        (c_parser_asm_definition): Parse also extended asm without
        clobbers/labels.
        * c-typeck.cc (build_asm_expr): Allow extended asm outside of
        functions and check extra restrictions.
gcc/cp/
        * cp-tree.h (finish_asm_stmt): Add TOPLEV_P argument.
        * parser.cc (cp_parser_asm_definition): Parse also extended asm
        without clobbers/labels outside of functions.
        * semantics.cc (finish_asm_stmt): Add TOPLEV_P argument, if set,
        check extra restrictions for extended asm outside of functions.
        * pt.cc (tsubst_stmt): Adjust finish_asm_stmt caller.
gcc/testsuite/
        * c-c++-common/toplevel-asm-1.c: New test.
        * c-c++-common/toplevel-asm-2.c: New test.
        * c-c++-common/toplevel-asm-3.c: New test.


--- gcc/cp/semantics.cc.jj      2024-10-29 13:51:33.257037334 +0100
+++ gcc/cp/semantics.cc 2024-11-01 14:59:29.039535043 +0100
@@ -2137,12 +2137,13 @@ finish_compound_stmt (tree stmt)
  /* Finish an asm-statement, whose components are a STRING, some
     OUTPUT_OPERANDS, some INPUT_OPERANDS, some CLOBBERS and some
     LABELS.  Also note whether the asm-statement should be
-   considered volatile, and whether it is asm inline.  */
+   considered volatile, and whether it is asm inline.  TOPLEV_P
+   is true if finishing namespace scope extended asm.  */
tree
  finish_asm_stmt (location_t loc, int volatile_p, tree string,
                 tree output_operands, tree input_operands, tree clobbers,
-                tree labels, bool inline_p)
+                tree labels, bool inline_p, bool toplev_p)
  {
    tree r;
    tree t;
@@ -2216,10 +2217,45 @@ finish_asm_stmt (location_t loc, int vol
                 mark it addressable.  */
              if (!allows_reg && !cxx_mark_addressable (*op))
                operand = error_mark_node;
+             if (allows_reg && toplev_p)
+               {
+                 error_at (loc, "invalid constraint outside of a function");

Maybe the diagnostic could say it's invalid because it allows a register?

+                 operand = error_mark_node;
+               }
            }
          else
            operand = error_mark_node;
@@ -2284,10 +2320,55 @@ finish_asm_stmt (location_t loc, int vol
                  if (TREE_CONSTANT (constop))
                    operand = constop;
                }
+             if (allows_reg && toplev_p)
+               {
+                 error_at (loc, "invalid constraint outside of a function");

Likewise.

The C++ changes are OK with that tweak.

Jason

Reply via email to