Skip to content

Commit

Permalink
cc: Refactor out sarif diagnostics.
Browse files Browse the repository at this point in the history
  • Loading branch information
xlauko committed Sep 3, 2024
1 parent 398e355 commit 93a060d
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 115 deletions.
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
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
164 changes: 49 additions & 115 deletions lib/vast/Frontend/Consumer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ VAST_UNRELAX_WARNINGS
#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"
Expand All @@ -34,10 +35,6 @@ VAST_UNRELAX_WARNINGS

#include "vast/Config/config.h"

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

namespace vast::cc {

[[nodiscard]] target_dialect parse_target_dialect(string_ref from);
Expand Down Expand Up @@ -169,79 +166,40 @@ namespace vast::cc {
);
}

#ifdef VAST_ENABLE_SARIF
gap::sarif::physical_location get_physical_loc(file_loc_t loc) {
std::filesystem::path file_path{ loc.getFilename().str() };
auto abs_path = std::filesystem::absolute(file_path);
return {
.artifactLocation{ { .uri{ "file://" + abs_path.string() } } },
.region{ {
.startLine = loc.getLine(),
.startColumn = loc.getColumn(),
} },
};
}

struct sarif_diag_handler
{
gap::sarif::run &run;

void operator()(mlir::Diagnostic &diag) const {
auto result = mk_result(diag);

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

result.level = severity_to_sarif(diag.getSeverity());
run.results.push_back(std::move(result));
}
namespace sarif {
struct diagnostics;
} // namespace sarif

private:
gap::sarif::location mk_location(file_loc_t loc) const {
return {
.physicalLocation{ get_physical_loc(loc) },
};
}

gap::sarif::location mk_location(name_loc_t loc) const {
return {
.physicalLocation{
get_physical_loc(mlir::cast< file_loc_t >(loc.getChildLoc()))
},
.logicalLocations{ { .name = loc.getName().str() } },
};
#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

gap::sarif::location mk_location(loc_t loc) const {
if (auto file_loc = mlir::dyn_cast< file_loc_t >(loc)) {
return mk_location(file_loc);
} else if (auto name_loc = mlir::dyn_cast< name_loc_t >(loc)) {
return mk_location(name_loc);
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());
}

return {};
}

gap::sarif::result mk_result(mlir::Diagnostic &diag) const {
return {
.ruleId = "mlir-diag",
.message = { .text = diag.str() }
};
}

gap::sarif::level severity_to_sarif(mlir::DiagnosticSeverity severity) const {
using enum gap::sarif::level;
using enum mlir::DiagnosticSeverity;
switch (severity) {
case Note: return kNote;
case Warning: return kWarning;
case Error: return kError;
case Remark: return kNote;
}
}
};
#endif // VAST_ENABLE_SARIF
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
Expand All @@ -267,58 +225,20 @@ namespace vast::cc {
llvm::DebugFlag = true;
}

#ifdef VAST_ENABLE_SARIF
gap::sarif::run sarif_run{
.tool{
.driver{
.name = "vast-front",
.organization = "Trail of Bits, inc.",
.product = "VAST",
.version = std::string{ vast::version },
.informationUri = std::string{ vast::homepage_url },
}, },
.invocations{
{
.arguments{ vargs.args.begin(), vargs.args.end() },
.executionSuccessful = true,
}, },
};
sarif_diag_handler diag_handler{ sarif_run };
#endif // VAST_ENABLE_SARIF

// Setup and execute vast pipeline
auto file_entry = src_mgr.getFileEntryRefForID(main_file_id);
VAST_CHECK(file_entry, "failed to recover file entry ref");
auto snapshot_prefix =
std::filesystem::path(file_entry->getName().str()).stem().string();
auto snapshot_prefix = std::filesystem::path(file_entry->getName().str()).stem().string();

auto pipeline =
setup_pipeline(pipeline_source::ast, target, mctx, vargs, snapshot_prefix);
auto pipeline = setup_pipeline(pipeline_source::ast, target, mctx, vargs, snapshot_prefix);
VAST_CHECK(pipeline, "failed to setup pipeline");

#ifdef VAST_ENABLE_SARIF
if (auto sarif_path = vargs.get_option(opt::output_sarif)) {
mctx.getDiagEngine().registerHandler(diag_handler);
}
#endif // VAST_ENABLE_SARIF
#ifdef VAST_ENABLE_SARIF
auto sarif_diagnostics = setup_sarif_diagnostics(vargs, mctx);
#endif // VAST_ENABLE_SARIF

auto result = pipeline->run(mod);

#ifdef VAST_ENABLE_SARIF
sarif_run.invocations[0].executionSuccessful = mlir::succeeded(result);

gap::sarif::root sarif_report{
.version = gap::sarif::version::k2_1_0,
.runs{ sarif_run },
};

if (auto sarif_path = vargs.get_option(opt::output_sarif)) {
std::ofstream os{ sarif_path.value().str() };
nlohmann::json j = sarif_report;
os << j.dump(2);
}
#endif // VAST_ENABLE_SARIF

VAST_CHECK(
mlir::succeeded(result), "MLIR pass manager failed when running vast passes"
);
Expand All @@ -330,6 +250,20 @@ namespace vast::cc {
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
79 changes: 79 additions & 0 deletions lib/vast/Frontend/Sarif.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright (c) 2024, Trail of Bits, Inc.

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

View workflow job for this annotation

GitHub Actions / cpp-linter (18, 22.04)

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

File lib/vast/Frontend/Sarif.cpp does not conform to Custom style guidelines. (lines 5, 29, 30, 52, 53, 54, 55, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74)

#include "vast/Frontend/Sarif.hpp"

#ifdef VAST_ENABLE_SARIF

#include "vast/Config/config.h"

namespace vast::cc::sarif {

gap::sarif::location mk_location(loc_t loc) {
if (auto file_loc = mlir::dyn_cast< file_loc_t >(loc)) {
return mk_location(file_loc);
} else if (auto name_loc = mlir::dyn_cast< name_loc_t >(loc)) {
return mk_location(name_loc);
}

return {};
}

gap::sarif::location mk_location(file_loc_t loc) {
return {
.physicalLocation{ get_physical_loc(loc) },
};
}

gap::sarif::location mk_location(name_loc_t loc) {
return {
.physicalLocation{
get_physical_loc(mlir::cast< file_loc_t >(loc.getChildLoc()))
},
.logicalLocations{ { .name = loc.getName().str() } },
};
}

gap::sarif::physical_location get_physical_loc(file_loc_t loc) {
std::filesystem::path file_path{ loc.getFilename().str() };
auto abs_path = std::filesystem::absolute(file_path);
return {
.artifactLocation{ { .uri{ "file://" + abs_path.string() } } },
.region{ {
.startLine = loc.getLine(),
.startColumn = loc.getColumn(),
} },
};
}

gap::sarif::level get_severity_level(mlir::DiagnosticSeverity severity) {
using enum gap::sarif::level;
using enum mlir::DiagnosticSeverity;
switch (severity) {
case Note: return kNote;
case Warning: return kWarning;
case Error: return kError;
case Remark: return kNote;
}
}

diagnostics::diagnostics(const vast_args &vargs)
: run(gap::sarif::run{
.tool{
.driver{
.name = "vast-front",
.organization = "Trail of Bits, inc.",
.product = "VAST",
.version = std::string{ vast::version },
.informationUri = std::string{ vast::homepage_url },
},
},
.invocations{{
.arguments{ std::begin(vargs.args), std::end(vargs.args) },
.executionSuccessful = true,
}}
})
{}

} // namespace vast::cc::sarif

#endif // VAST_ENABLE_SARIF

0 comments on commit 93a060d

Please sign in to comment.