Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add infrastructure to support SARIF output #701

Merged
merged 7 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jobs:
image-version: [22.04]
build-type: [Release, Debug]
sanitizers: [ON, OFF]
features: ["nosarif", "sarif"]

runs-on: ubuntu-${{ matrix.image-version }}
timeout-minutes: 60
Expand All @@ -49,10 +50,11 @@ jobs:
fetch-depth: 1

- name: Configure build - sanitizers ${{ matrix.sanitizers }}
run: cmake --preset ci
run: cmake --preset ci-${{ matrix.features }}

- name: Build ${{ matrix.build-type }} with sanitizers set ${{ matrix.sanitizers }}
run: cmake --build --preset ci --config ${{ matrix.build-type }} -j $(nproc)
run: cmake --build --preset ci-${{ matrix.features }} --config ${{ matrix.build-type }} -j $(nproc)

- name: Test ${{ matrix.build-type }} with sanitizers set ${{ matrix.sanitizers }}
run: ctest --preset ci --build-config ${{ matrix.build-type }}
run: ctest --preset ci-${{ matrix.features }} --build-config ${{ matrix.build-type }}

14 changes: 14 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,20 @@ target_link_libraries(vast_settings
"$<BUILD_LOCAL_INTERFACE:gap::gap-mlir>"
)

if (sarif IN_LIST VCPKG_MANIFEST_FEATURES)
option(VAST_ENABLE_SARIF "Enable SARIF export" ON)
else()
option(VAST_ENABLE_SARIF "Enable SARIF export" OFF)
endif()

if (VAST_ENABLE_SARIF)
target_link_libraries(vast_settings
INTERFACE
"$<BUILD_LOCAL_INTERFACE:gap::gap-sarif>"
)
target_compile_definitions(vast_settings INTERFACE VAST_ENABLE_SARIF)
endif()

#
# VAST libraries
#
Expand Down
30 changes: 26 additions & 4 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,19 @@
"CMAKE_VERBOSE_MAKEFILE": "True"
}
},
{
"name": "ci-nosarif",
"displayName": "Configure VAST for CI withour SARIF support",
"inherits": "ci"
},
{
"name": "ci-sarif",
"displayName": "Configure VAST for CI withour SARIF support",
"inherits": "ci",
"cacheVariables": {
"VCPKG_MANIFEST_FEATURES": "sarif"
}
},
{
"name": "compiler-explorer",
"displayName": "Configure VAST for Compiler Explorer",
Expand Down Expand Up @@ -85,8 +98,12 @@
"configuration": "RelWithDebInfo"
},
{
"name": "ci",
"configurePreset": "ci"
"name": "ci-nosarif",
"configurePreset": "ci-nosarif"
},
{
"name": "ci-sarif",
"configurePreset": "ci-sarif"
},
{
"name": "ci-release",
Expand Down Expand Up @@ -157,8 +174,13 @@
"configuration": "RelWithDebInfo"
},
{
"name": "ci",
"configurePreset": "ci",
"name": "ci-nosarif",
"configurePreset": "ci-nosarif",
"inherits": "test-base"
},
{
"name": "ci-sarif",
"configurePreset": "ci-sarif",
"inherits": "test-base"
}
],
Expand Down
3 changes: 3 additions & 0 deletions docs/Tools/vast-front.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ Additional customization options include:
- After each pass that was specified as an option store MLIR into a file (format is `src.pass_name`).
- `"*"` stores snapshot after every conversion.

- `-vast-output-sarif="report.sarif"`
- Outputs diagnostics as a SARIF report file.

## Pipelines

WIP pipelines documentation
34 changes: 34 additions & 0 deletions include/vast/Analysis/Sarif/Sarif.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) 2024-present, Trail of Bits, Inc.

#pragma once

#ifdef VAST_ENABLE_SARIF
#include <vector>

#include <gap/sarif/sarif.hpp>

namespace vast::analysis::sarif {

class sarif_analysis
{
std::vector< gap::sarif::result > sarif_results;

public:
virtual ~sarif_analysis() = default;

const std::vector< gap::sarif::result > &results() const noexcept {
return sarif_results;
}

protected:
void append_result(const gap::sarif::result &result) {
sarif_results.push_back(result);
}

void append_result(gap::sarif::result &&result) {
sarif_results.emplace_back(std::move(result));
}
};

} // namespace vast::analysis::sarif
#endif // VAST_ENABLE_SARIF
2 changes: 2 additions & 0 deletions include/vast/Config/config.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ namespace vast {

constexpr std::string_view version = "${VAST_VERSION}";

constexpr std::string_view homepage_url = "${PROJECT_HOMEPAGE_URL}";

constexpr std::string_view bug_report_url = "${BUG_REPORT_URL}";

constexpr std::string_view default_resource_dir = "${VAST_DEFAULT_RESOURCE_DIR}";
Expand Down
2 changes: 2 additions & 0 deletions include/vast/Frontend/Options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ namespace vast::cc
constexpr option_t vast_verify_diags = "verify-diags";
constexpr option_t disable_emit_cxx_default = "disable-emit-cxx-default";

constexpr option_t output_sarif = "output-sarif";

bool emit_only_mlir(const vast_args &vargs);
bool emit_only_llvm(const vast_args &vargs);
} // namespace opt
Expand Down
53 changes: 53 additions & 0 deletions include/vast/Frontend/Sarif.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright (c) 2024, Trail of Bits, Inc.

Check notice on line 1 in include/vast/Frontend/Sarif.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter (18, 22.04)

Run clang-format on include/vast/Frontend/Sarif.hpp

File include/vast/Frontend/Sarif.hpp does not conform to Custom style guidelines. (lines 3, 22, 28, 29, 30, 31, 34)

#pragma once


#ifdef VAST_ENABLE_SARIF
#include <gap/sarif/sarif.hpp>

#include "vast/Frontend/Options.hpp"
#include "vast/Util/Common.hpp"

namespace vast::cc::sarif {

gap::sarif::location mk_location(loc_t loc);
gap::sarif::location mk_location(file_loc_t loc);
gap::sarif::location mk_location(name_loc_t loc);

gap::sarif::physical_location get_physical_loc(file_loc_t loc);

gap::sarif::level get_severity_level(mlir::DiagnosticSeverity severity);

struct diagnostics {
gap::sarif::run run;

explicit diagnostics(const vast_args &vargs);

auto handler() {
return [&] (auto &diag) {
gap::sarif::result result = {
.ruleId = "mlir-diag",
.message = { .text = diag.str() }
};

if (auto loc = mk_location(diag.getLocation()); loc.physicalLocation.has_value()) {
result.locations.push_back(std::move(loc));
}

result.level = get_severity_level(diag.getSeverity());
run.results.push_back(std::move(result));
};
};

gap::sarif::root emit(logical_result result) && {
run.invocations[0].executionSuccessful = mlir::succeeded(result);
return {
.version = gap::sarif::version::k2_1_0,
.runs{ std::move(run) },
};
}
};

} // namespace vast::cc::sarif
#endif // VAST_ENABLE_SARIF
4 changes: 3 additions & 1 deletion include/vast/Util/Common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ namespace vast {

using values_t = mlir::SmallVector< mlir_value >;

using loc_t = mlir::Location;
using loc_t = mlir::Location;
using name_loc_t = mlir::NameLoc;
using file_loc_t = mlir::FileLineColLoc;

using mlir_builder = mlir::OpBuilder;
using op_state = mlir::OperationState;
Expand Down
1 change: 1 addition & 0 deletions lib/vast/Frontend/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ add_vast_library(Frontend
Consumer.cpp
Options.cpp
Pipelines.cpp
Sarif.cpp
Targets.cpp

LINK_LIBS PUBLIC
Expand Down
74 changes: 66 additions & 8 deletions lib/vast/Frontend/Consumer.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) 2023-present, Trail of Bits, Inc.

Check notice on line 1 in lib/vast/Frontend/Consumer.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter (18, 22.04)

Run clang-format on lib/vast/Frontend/Consumer.cpp

File lib/vast/Frontend/Consumer.cpp does not conform to Custom style guidelines. (lines 171, 174, 175, 177, 178, 179, 184, 189, 190, 191, 192, 193, 194, 195, 197, 198, 199, 200, 237, 253, 261, 262, 263)

#include "vast/Frontend/Consumer.hpp"
#include "mlir/IR/Diagnostics.h"
#include "mlir/IR/Location.h"

VAST_RELAX_WARNINGS
#include <llvm/Support/Signals.h>
Expand All @@ -17,18 +19,22 @@
VAST_UNRELAX_WARNINGS

#include <filesystem>
#include <fstream>

#include "vast/CodeGen/CodeGenDriver.hpp"

#include "vast/Util/Common.hpp"

#include "vast/Frontend/Pipelines.hpp"
#include "vast/Frontend/Sarif.hpp"
#include "vast/Frontend/Targets.hpp"

#include "vast/Target/LLVMIR/Convert.hpp"

#include "vast/Dialect/Core/CoreOps.hpp"

#include "vast/Config/config.h"

namespace vast::cc {

[[nodiscard]] target_dialect parse_target_dialect(string_ref from);
Expand Down Expand Up @@ -101,9 +107,7 @@

void vast_consumer::HandleVTable(clang::CXXRecordDecl * /* decl */) { VAST_UNIMPLEMENTED; }

owning_mlir_module_ref vast_consumer::result() {
return driver->freeze();
}
owning_mlir_module_ref vast_consumer::result() { return driver->freeze(); }

//
// vast stream consumer
Expand Down Expand Up @@ -153,18 +157,51 @@
process_mlir_module(target_dialect::llvm, mod.get());

auto final_mlir_module = mlir::cast< mlir_module >(mod->getBody()->front());
auto llvm_mod = target::llvmir::translate(final_mlir_module, llvm_context);
auto dl = driver->acontext().getTargetInfo().getDataLayoutString();
auto llvm_mod = target::llvmir::translate(final_mlir_module, llvm_context);
auto dl = driver->acontext().getTargetInfo().getDataLayoutString();

clang::EmitBackendOutput(
opts.diags, opts.headers, opts.codegen, opts.target, opts.lang, dl, llvm_mod.get(),
backend_action, &opts.vfs, std::move(output_stream)
);
}

void vast_stream_consumer::process_mlir_module(
target_dialect target, mlir_module mod
namespace sarif {
struct diagnostics;
} // namespace sarif

#ifdef VAST_ENABLE_SARIF
std::unique_ptr< vast::cc::sarif::diagnostics > setup_sarif_diagnostics(
const vast_args &vargs, mcontext_t &mctx
) {
if (vargs.get_option(opt::output_sarif)) {
auto diags = std::make_unique< vast::cc::sarif::diagnostics >(vargs);
mctx.getDiagEngine().registerHandler(diags->handler());
return diags;
} else {
return nullptr;
}
}
#endif // VAST_ENABLE_SARIF

void emit_sarif_diagnostics(
vast::cc::sarif::diagnostics &&sarif_diagnostics, logical_result result, string_ref path
) {
#ifdef VAST_ENABLE_SARIF
std::error_code ec;
llvm::raw_fd_ostream os(path, ec, llvm::sys::fs::OF_None);
if (ec) {
VAST_FATAL("Failed to open file for SARIF output: {}", ec.message());
}

nlohmann::json report = std::move(sarif_diagnostics).emit(result);
os << report.dump(2);
#else
VAST_REPORT("SARIF support is disabled");
#endif // VAST_ENABLE_SARIF
}

void vast_stream_consumer::process_mlir_module(target_dialect target, mlir_module mod) {
// Handle source manager properly given that lifetime analysis
// might emit warnings and remarks.
auto &src_mgr = driver->acontext().getSourceManager();
Expand Down Expand Up @@ -196,8 +233,15 @@
auto pipeline = setup_pipeline(pipeline_source::ast, target, mctx, vargs, snapshot_prefix);
VAST_CHECK(pipeline, "failed to setup pipeline");

#ifdef VAST_ENABLE_SARIF
auto sarif_diagnostics = setup_sarif_diagnostics(vargs, mctx);
#endif // VAST_ENABLE_SARIF

auto result = pipeline->run(mod);
VAST_CHECK(mlir::succeeded(result), "MLIR pass manager failed when running vast passes");

VAST_CHECK(
mlir::succeeded(result), "MLIR pass manager failed when running vast passes"
);

// Verify the diagnostic handler to make sure that each of the
// diagnostics matched.
Expand All @@ -206,6 +250,20 @@
VAST_FATAL("failed mlir codegen");
}

if (auto path = vargs.get_option(opt::output_sarif)) {
#ifdef VAST_ENABLE_SARIF
if (sarif_diagnostics) {
emit_sarif_diagnostics(
std::move(*sarif_diagnostics), result, path.value().str()
);
} else {
VAST_REPORT("SARIF diagnostics are missing");
}
#else
VAST_REPORT("SARIF support is disabled");
#endif // VAST_ENABLE_SARIF
}

// Emit remaining defaulted C++ methods
// if (!vargs.has_option(opt::disable_emit_cxx_default)) {
// generator->build_default_methods();
Expand Down
Loading