trailofbits / vast

VAST is an experimental compiler pipeline designed for program analysis of C and C++. It provides a tower of IRs as MLIR dialects to choose the best fit representations for a program analysis or further program abstraction.
https://trailofbits.github.io/vast/
Apache License 2.0
391 stars 23 forks source link

[Bug]: Verifier fails to verify nested statement expressions that return shadowed variables #651

Open PappasBrent opened 2 months ago

PappasBrent commented 2 months ago

VAST version

Ubuntu clang version 18.1.8 (++20240615103753+3b5b5c1ec4a3-1~exp1~20240615223858.136) Target: x86_64-pc-linux-gnu Thread model: posix

LLVM version

18.1.8

Operating system

Ubuntu 22.04.4 LTS x86_64

Description

The VAST codegen module verifier fails to verify nested statement expressions that return variables whose names shadow those of variables from an outer statement expression. I receive the following error:

test_verify_dominance.c:8:9: error: unexpected error: operand #0 does not dominate this use
        x;
        ^
test_verify_dominance.c:8:9: error: unexpected note: see current operation: %3 = "hl.ref"(%5) : (!hl.lvalue<!hl.int>) -> !hl.lvalue<!hl.int>
        x;
        ^
test_verify_dominance.c:5:17: error: unexpected note: operand defined here (op in a child region)
            int x;
                ^
// -----// IR Dump After SpliceTrailingScopes Failed (vast-hl-splice-trailing-scopes) //----- //
"builtin.module"() <{sym_name = "/home/bpappas/github.com/trailofbits/vast/test_verify_dominance.c"}> ({
  "hl.func"() ({
    %0 = "hl.stmt.expr"() ({
      %1 = "hl.var"() ({
        %5 = "hl.const"() {value = #core.integer<0> : !hl.int} : () -> !hl.int
        "hl.value.yield"(%5) : (!hl.int) -> ()
      }, {
      }) {name = "x"} : () -> !hl.lvalue<!hl.int>
      %2 = "hl.stmt.expr"() ({
        %5 = "hl.var"() ({
        }, {
        }) {name = "x"} : () -> !hl.lvalue<!hl.int>
        %6 = "hl.ref"(%5) : (!hl.lvalue<!hl.int>) -> !hl.lvalue<!hl.int>
        %7 = "hl.implicit_cast"(%6) {kind = 4 : i64} : (!hl.lvalue<!hl.int>) -> !hl.int
        "hl.value.yield"(%7) : (!hl.int) -> ()
      }) : () -> !hl.int
      %3 = "hl.ref"(%5) : (!hl.lvalue<!hl.int>) -> !hl.lvalue<!hl.int>
      %4 = "hl.implicit_cast"(%3) {kind = 4 : i64} : (!hl.lvalue<!hl.int>) -> !hl.int
      "hl.value.yield"(%4) : (!hl.int) -> ()
    }) : () -> !hl.int
    "hl.return"(%0) : (!hl.int) -> ()
  }) {function_type = !core.fn<() -> (!hl.int)>, linkage = #core.global_linkage_kind<external>, sym_name = "main"} : () -> ()
}) {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<!hl.int, {vast.abi_align.key = 32 : i32, vast.dl.bw = 32 : i32}>>, vast.core.lang = #core<lang c>, vast.core.target_triple = "x86_64-pc-linux-gnu"} : () -> ()

[VAST fatal] MLIR pass manager failed when running vast passes
PLEASE submit a bug report to https://github.com/trailofbits/vast/issues and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: ./builds/default/tools/vast-front/Debug/vast-front -x c -vast-emit-mlir=hl -vast-disable-vast-verifier -Wno-everything test_verify_dominance.c
1.      <eof> parser at end of file
 #0 0x00007f8cf16d5716 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/usr/lib/llvm-18/lib/libLLVM.so.18.1+0xd94716)
 #1 0x00007f8cf16d36d0 llvm::sys::RunSignalHandlers() (/usr/lib/llvm-18/lib/libLLVM.so.18.1+0xd926d0)
 #2 0x00007f8cf16251f0 (/usr/lib/llvm-18/lib/libLLVM.so.18.1+0xce41f0)
 #3 0x00007f8cf03c3520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x000055b7060fd808 vast::cc::vast_stream_consumer::process_mlir_module(vast::cc::target_dialect, mlir::ModuleOp) /home/bpappas/github.com/trailofbits/vast/lib/vast/Frontend/Consumer.cpp:198:9
 #5 0x000055b7060fcfe1 vast::cc::vast_stream_consumer::emit_mlir_output(vast::cc::target_dialect, mlir::OwningOpRef<mlir::ModuleOp>) /home/bpappas/github.com/trailofbits/vast/lib/vast/Frontend/Consumer.cpp:220:9
 #6 0x000055b7060fcb15 vast::cc::vast_stream_consumer::HandleTranslationUnit(clang::ASTContext&) /home/bpappas/github.com/trailofbits/vast/lib/vast/Frontend/Consumer.cpp:133:28
 #7 0x00007f8cf8aeffc6 clang::ParseAST(clang::Sema&, bool, bool) (/usr/lib/llvm-18/lib/libclang-cpp.so.18.1+0xb7ffc6)
 #8 0x000055b705cd2e05 vast::cc::vast_stream_action::ExecuteAction() /home/bpappas/github.com/trailofbits/vast/lib/vast/Frontend/Action.cpp:75:5
 #9 0x00007f8cfa920ab5 clang::FrontendAction::Execute() (/usr/lib/llvm-18/lib/libclang-cpp.so.18.1+0x29b0ab5)
#10 0x00007f8cfa89a084 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/usr/lib/llvm-18/lib/libclang-cpp.so.18.1+0x292a084)
#11 0x000055b705cbad17 vast::cc::execute_compiler_invocation(clang::CompilerInstance*, vast::cc::vast_args const&) /home/bpappas/github.com/trailofbits/vast/tools/vast-front/compiler_invocation.cpp:101:28
#12 0x000055b705ccf410 vast::cc::cc1(vast::cc::vast_args const&, llvm::ArrayRef<char const*>, char const*, void*) /home/bpappas/github.com/trailofbits/vast/tools/vast-front/cc1.cpp:116:23
#13 0x000055b705cc0444 execute_cc1_tool(llvm::SmallVectorImpl<char const*>&) /home/bpappas/github.com/trailofbits/vast/tools/vast-front/driver.cpp:71:16
#14 0x000055b705ccb41d int llvm::function_ref<int (llvm::SmallVectorImpl<char const*>&)>::callback_fn<int (*)(llvm::SmallVectorImpl<char const*>&)>(long, llvm::SmallVectorImpl<char const*>&) /usr/lib/llvm-18/include/llvm/ADT/STLFunctionalExtras.h:45:5
#15 0x00007f8cfa5525c9 (/usr/lib/llvm-18/lib/libclang-cpp.so.18.1+0x25e25c9)
#16 0x00007f8cf1624f8c llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/usr/lib/llvm-18/lib/libLLVM.so.18.1+0xce3f8c)
#17 0x00007f8cfa551f5e clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (/usr/lib/llvm-18/lib/libclang-cpp.so.18.1+0x25e1f5e)
#18 0x00007f8cfa51a4d1 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/usr/lib/llvm-18/lib/libclang-cpp.so.18.1+0x25aa4d1)
#19 0x00007f8cfa51a71e clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/usr/lib/llvm-18/lib/libclang-cpp.so.18.1+0x25aa71e)
#20 0x00007f8cfa536d2d clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/usr/lib/llvm-18/lib/libclang-cpp.so.18.1+0x25c6d2d)
#21 0x000055b705cc0ada vast::cc::driver::execute() /home/bpappas/github.com/trailofbits/vast/include/vast/Frontend/Driver.hpp:180:30
#22 0x000055b705cbfad8 main /home/bpappas/github.com/trailofbits/vast/tools/vast-front/driver.cpp:161:19
#23 0x00007f8cf03aad90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#24 0x00007f8cf03aae40 call_init ./csu/../csu/libc-start.c:128:20
#25 0x00007f8cf03aae40 __libc_start_main ./csu/../csu/libc-start.c:379:5
#26 0x000055b705cb9715 _start (./builds/default/tools/vast-front/Debug/vast-front+0xe49715)
vast-front: error: clang frontend command failed with exit code 132 (use -v to see invocation)
Ubuntu clang version 18.1.8 (++20240615103753+3b5b5c1ec4a3-1~exp1~20240615223858.136)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /home/bpappas/github.com/trailofbits/vast/./builds/default/tools/vast-front/Debug
vast-front: error: unable to execute command: Illegal instruction (core dumped)
vast-front: note: diagnostic msg: Error generating preprocessed source(s).

Steps to Reproduce

Create a file test_verify_dominance.c with the following contents:

int main(void) {
   return  ({
        int x = 0;
        ({
            int x;
            x;
        });
        x;
    });
}

Run vast-front on the file like so:

vast-front -x c -vast-emit-mlir=hl test_verify_dominance.c
xlauko commented 2 months ago

This will require new symbol tables I am working on.

Jezurko commented 2 months ago

This is most likely a bit more complicated version of #634 (although StmtExpr might be special in some magical way, so I would keep both of the issues?)