Bug#909234: clang-7: clang::ast_matchers::MatchFinder::MatchFinder is miscompiled

Mike Hommey mh+reportbug at glandium.org
Thu Sep 20 05:43:36 BST 2018


Package: clang-7
Version: 1:7-1
Severity: normal

Dear Maintainer,

Using a clang plugin that creates a MatchFinder crashes. One way to
reproduce is to get the Firefox source code from
https://hg.mozilla.org/mozilla-central, create a .mozconfig file with
the following contents:
  ac_add_options --enable-clang-plugin
  ac_add_options CC=clang-7
  ac_add_options LLVM_CONFIG=llvm-config-7

and run ./mach build

This results in the compiler crashing when it uses the plugin.

The constructor C++ code is:

  MatchFinder::MatchFinder(MatchFinderOptions Options)
      : Options(std::move(Options)), ParsingDone(nullptr) {}

where MatchFinderOptions is defined as:

  struct MatchFinderOptions {
    struct Profiling {
      Profiling(llvm::StringMap<llvm::TimeRecord> &Records)
          : Records(Records) {}

      /// Per bucket timing information.
      llvm::StringMap<llvm::TimeRecord> &Records;
    };

    /// Enables per-check timers.
    ///
    /// It prints a report after match.
    llvm::Optional<Profiling> CheckProfiling;
  };

I won't go on detailing how Optional is defined, but the point is
MatchFinderOptions, and thus the Optional is passed by value.

But the function as it appears in the clang-7 executable looks like:

  lea    0xb0(%rdi),%rax
  movq   $0x0,(%rdi)
  mov    %rax,0x90(%rdi)
  mov    %rax,0x98(%rdi)
  movzbl 0x8(%rsi),%eax
  movq   $0x0,0x8(%rdi)
  movq   $0x0,0x10(%rdi)
  movq   $0x0,0x18(%rdi)
  movq   $0x0,0x20(%rdi)
  (...)
  mov    %al,0x138(%rdi)
  test   %al,%al
  je     <_ZN5clang12ast_matchers11MatchFinderC2ENS1_18MatchFinderOptionsE+215>
  mov    (%rsi),%rax
  mov    %rax,0x130(%rdi)
  movq   $0x0,0x140(%rdi)
  retq   

The crashing instruction is the movzbl, which tries to dereference %rsi
as a pointer, and its value is 0. What's happening here, essentially, is
that it's compiled with the assumption that %rsi is a pointer to the
MatchFinderOptions. That's clearly not what's supposed to happen given
the C++ code.

As bootstrapped by clang-7 itself, the same function is compiled as
  lea    0xb0(%rdi),%rax
  xorps  %xmm0,%xmm0
  movups %xmm0,0x80(%rdi)
  (...)
  movups %xmm0,(%rdi)
  mov    %rax,0x90(%rdi)
  mov    %rax,0x98(%rdi)
  movq   $0x10,0xa0(%rdi)
  movl   $0x0,0xa8(%rdi)
  mov    %rsi,0x130(%rdi)
  mov    %dl,0x138(%rdi)
  movq   $0x0,0x140(%rdi)
  retq   

which is compiled with the assumption that %rsi and %rdx (really %rdl)
represent the value of the MatchFinderOptions.

Interestingly, there's already a #ifdef in Optional.h in llvm to disable
some code for GCC because it miscompiles it. It looks like things got
worse.

It feels like the clang package should be bootstrapped in 2 stages...

I'd file a GCC upstream bug for the miscompilation, but as the package
wasn't built on buildds, buildd.debian.org doesn't contain logs that
could tell me what specific version was used.

Mike

-- System Information:
Debian Release: buster/sid
  APT prefers unstable-debug
  APT policy: (500, 'unstable-debug'), (500, 'unstable'), (500, 'testing'), (1, 'experimental-debug'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.17.0-1-amd64 (SMP w/4 CPU cores)
Locale: LANG=ja_JP.UTF-8, LC_CTYPE=ja_JP.UTF-8 (charmap=UTF-8), LANGUAGE=ja_JP.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages clang-7 depends on:
ii  binutils               2.31.1-4
ii  libc6                  2.27-5
ii  libc6-dev              2.27-5
ii  libclang-common-7-dev  1:7-1
ii  libclang1-7            1:7-1
ii  libgcc-8-dev           8.2.0-3
ii  libgcc1                1:8.2.0-3
ii  libllvm7               1:7-1
ii  libobjc-8-dev          8.2.0-3
ii  libstdc++-8-dev        8.2.0-3
ii  libstdc++6             8.2.0-3

Versions of packages clang-7 recommends:
ii  libomp-dev  6.0.1-1
ii  llvm-7-dev  1:7-1
ii  python      2.7.15-3

Versions of packages clang-7 suggests:
pn  clang-7-doc  <none>

-- no debconf information



More information about the Pkg-llvm-team mailing list