Fixes the case when invoking -fsanitize=address twice due to serializing
through bitcode or LLVM assembly and then compiling that down to native
code. Without this there are assertion failures from the instrumentation
passes.
Fixes PR32700.
Differential D41222
Handle previously ASAN-instrumented IR gracefully when ASAN re-invoked tejohnson on Dec 13 2017, 7:48 PM. Authored by
Details
Fixes the case when invoking -fsanitize=address twice due to serializing Fixes PR32700.
Diff Detail
Event TimelineComment Actions Is it possible to reduce the test case s.t the test file doesn't contain instrumented IR? ASan instrumentation is prone to change, so I worry that the test could start passing for invalid reasons. This might happen if 1) __asan_before_dynamic_init is renamed, 2) GlobalsMetadata::doInit is written more defensively, and 3) a non-idempotent ASan transform is introduced later. I envision something like: RUN: opt -asan -asan-module < %s -S -o %t.ll RUN: opt -asan -asan-module < %t.ll -S -o %t.2.ll RUN: diff %t.ll %t.2.ll I spent a few minutes trying to come up with a test like this but did not succeed, because my test file didn't trip the assert you hit. Comment Actions That's a great idea. The reason you weren't able to trigger it is because what is being tripped over the second time is the llvm.asan.globals metadata, which is inserted by clang via SanitizerMetadata::reportGlobalToASan. I was able to get this in the .ll by building the .c file with "-fsanitize=address -emit-llvm -Xclang -disable-llvm-passes". Then running it through opt twice in the manner you describe above hits the assert. I was then able to simplify the initial .ll file even more and still hit the original assert. Updated test case being uploaded momentarily. Comment Actions clang-format didn't find anything. Is there something specific that doesn't look right?
Comment Actions If this doesn't even fix the ThinLTO bug I don't see why we should land it. The other scenarios mentioned on the bug are "no warranty" scenarios because they use flags like -emit-llvm which aren't really user facing. Comment Actions The fix is small though, and seems better than asserting (or a runtime error as in the release build case)? Comment Actions The asan pass is more like something like codegenprepare in that we shouldn't really expect it to be run twice. If it does run twice, it most likely indicates a logic error in the pass pipeline, and it would be best to diagnose that with an assertion failure rather than silently ignoring it (which could also hide other unnecessary duplication of passes in the pipeline). Besides which, this fix is not complete. If a module does not contain dynamically-initialized globals and the globaldce pass happens to run between the two invocations of the asan passes then the reference to the __asan_before_dynamic_init function will be dropped and the passes will still run twice. If we really wanted to do something about this I think we should be inserting module-level metadata and testing for presence of that metadata (and, ideally, asserting if we see the metadata). |
Simple if statements here and below. However it looks like that existing ifs do not follow LLVM style. So please keep the patch as is.