diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -1255,6 +1255,34 @@ Query for this feature with ``__has_extension(blocks)``. +ASM Goto with Output Constraints +================================ + +In addition to the functionality provided by `GCC's extended +assembly``_, clang +supports output constraints with the `goto` form. + +The goto form of GCC's extended assembly allows the programmer to branch to a C +label from within an inline assembly block. Clang extends this behavior by +allowing the programmer to use output constriants: + +.. code-block:: c++ + + int foo(int x) { + int y; + asm goto("# %0 %1 %2" : "=r"(y) : "r"(x) : : err); + return y; + err: + return -1; + } + +It's important to note that outputs are valid only on the "fallthrough" branch. +Using outputs on an indirect branch may result in undefined behavior. For +example, in the function above, use of the value assigned to `y` in the `err` +block is undefined behavior. + +Query for this feature with ``__has_extension(gnu_asm_goto_with_outputs)``. + Objective-C Features ==================== diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -252,6 +252,7 @@ EXTENSION(pragma_clang_attribute_namespaces, true) EXTENSION(pragma_clang_attribute_external_declaration, true) EXTENSION(gnu_asm, LangOpts.GNUAsm) +EXTENSION(gnu_asm_goto_with_outputs, LangOpts.GNUAsm) #undef EXTENSION #undef FEATURE diff --git a/clang/test/Parser/asm-goto.c b/clang/test/Parser/asm-goto.c --- a/clang/test/Parser/asm-goto.c +++ b/clang/test/Parser/asm-goto.c @@ -4,6 +4,9 @@ #if !__has_extension(gnu_asm) #error Extension 'gnu_asm' should be available by default #endif +#if !__has_extension(gnu_asm_goto_with_outputs) +#error Extension 'gnu_asm_goto_with_outputs' should be available by default +#endif int a, b, c, d, e, f, g, h, i, j, k, l;