On 11/22/24 4:45 AM, Jakub Jelinek wrote:
2024-11-22 Jakub Jelinek <[email protected]> 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. */treefinish_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 volif (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
