[Bug Report] Rewriter crashes when compilation database contains files with same name

This is the clang bug report. This bug report is also posted to the Clang Bugzilla

Overview

If the compilation database contains the files with same name but different path and size, the program written using clang libtooling and clang Rewriter crashes.

The files that I used to reproduce the bug can be found here. Detailed description of these files are presented in About Example Files section.

Steps to Reproduce

  1. Create the build system that generates the following compile_commands.json:
[
{
"arguments": [
"cc",
"-c",
"-o",
"a.o",
"a.c"
],
"directory": "/home/user/build_system/lib",
"file": "a.c"
},
{
"arguments": [
"cc",
"-c",
"-o",
"a.o",
"a.c"
],
"directory": "/home/user/build_system/src",
"file": "a.c"
}
]

In here, the length of the content of /home/user/build_system/src/a.c should be larger than that of /home/user/build_system/lib/a.c.

  1. Create a program with clang libtooling, which reads the compilation database and for every file in compilation database, does rewriting on every statement in the file.

  2. Run the program on the created compilation database. The program runs cleanly on lib/a.c, but it shows segfault when processing src/a.c.

Actual Results

The program with clang libtooling shows segfault.

Expected Results

The program with clang libtooling should run cleanly, not showing segfault.

Tested Environment

  • OS: Ubuntu LTS 16.04 Xenial
  • LLVM Version: 6.0.1

About Example Files

This section describes the details of files that I linked.

  • build_example/: Example build system
  • lib/
  • a.c: Example c file (shorter one)
  • Makefile: A makefile to compile a.c
  • src/
  • a.c: Example c file (longer one)
  • Makefile: A makefile to compile a.c
  • compile_commands.json: Compilation database. This file is generated by running the command $ bear make
  • Makefile: A makefile to build the whole example build system
  • Makefile: A makefile to build target.cpp
  • target.cpp: A program that uses clang libtooling and clang Rewriter. This program fails when run on the given compilation database, which shouldn’t

Other Comments

I also used clang-check on lib/a.c and src/a.c ($ clang-check lib/a.c src/a.c), and it shows errors with src/a.c which are not actual errors.

I think when the SourceManager processes src/a.c, it uses the buffer that is created when processing lib/a.c (because it has same file name), and this causes an error.

Thanks.
Hyunsu Lim