[llvm-dev] The use and error reporting on nested { } in inline asm

Paulo Matos via llvm-dev
Thu, 12 Jan 2017 12:56:19 -0000

Hi,

With this piece of code:
// inlbra2.c
void foo() { __asm__("#{{[a-zA-Z]}}":::"memory"); }
int main(void) { return 0; }

We crash with the following:
$ ~/INSTALLS/clang+llvm-3.9.0-x86_64-fedora23/bin/clang -S -o- inbra2.c
        .text
        .file   "inbra2.c"
        .globl  foo
        .p2align        4, 0x90
        .type   foo, at function
foo:                                    # @foo
        .cfi_startproc
# BB#0:
        pushq   %rbp
.Ltmp0:
        .cfi_def_cfa_offset 16
.Ltmp1:
        .cfi_offset %rbp, -16
        movq    %rsp, %rbp
.Ltmp2:
        .cfi_def_cfa_register %rbp
        #APP
fatal error: error in backend: Nested variants found in inline asm
string: '#$($([a-zA-Z]$)$)'
clang-3.9: error: clang frontend command failed with exit code 70 (use
-v to see invocation)
clang version 3.9.0 (tags/RELEASE_390/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/pmatos/INSTALLS/clang+llvm-3.9.0-x86_64-fedora23/bin
clang-3.9: note: diagnostic msg: PLEASE submit a bug report to
http://llvm.org/bugs/ and include the crash backtrace, preprocessed
source, and associated run script.
clang-3.9: note: diagnostic msg:
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang-3.9: note: diagnostic msg: /tmp/inbra2-063e2e.c
clang-3.9: note: diagnostic msg: /tmp/inbra2-063e2e.sh
clang-3.9: note: diagnostic msg:

********************


I have opened this #31615 [1], but then I did some digging and found
that all errors in AsmPrinterInlineAsm.cpp are reported with
report_fatal_error giving rise to the bug-like error message even though
this is a user error:
      case '(':             // $( -> same as GCC's { character.
        ++LastEmitted;      // Consume '(' character.
        if (CurVariant != -1)
          report_fatal_error("Nested variants found in inline asm
string: '" +
                             Twine(AsmStr) + "'");
        CurVariant = 0;     // We're in the first variant now.
        break;


That's the first issue. Shouldn't these errors be reported as errors
instead of bugs?

Second issue is related to the inline asm in the error message which
shows '#$($([a-zA-Z]$)$)' even when the user wrote #{{[a-zA-Z]}}. By the
way, I understand this is an error. The issue here is the error message.
There's an issue here. Clang seems to translate { and } to $( and $). We
cannot reverse the translation in the error message because clang also
accepts the use of $( and $). My question is, why are we converting {
and } to $( and $). Is there a good reason to accept $( and $)? Is it
documented? If it is not, maybe we could disallow $( and $) in the
source file and make error reporting easier. Any comments?


[1] - https://llvm.org/bugs/show_bug.cgi?id=31615

Kind regards,
--
Paulo Matos