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