Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
9b59a16
build(cmake): fetch coretrace logger and link analyzer targets
SizzleUnrlsd Feb 12, 2026
4d15327
feat(extern-example): load compile commands database before analysis
SizzleUnrlsd Feb 12, 2026
ccc0ca0
feat(cli): integrate coretrace logger and add verbose flag
SizzleUnrlsd Feb 12, 2026
4de74c8
fix(test-runner): parse recursion diagnostics after location lines
SizzleUnrlsd Feb 12, 2026
7189b80
ci(commit-checker): allow commit subjects up to 84 characters
SizzleUnrlsd Feb 12, 2026
a5ba01d
feat(recursion): attach source line and column to recursion warnings
SizzleUnrlsd Feb 12, 2026
b791610
feat(duplicate-if): detect equivalent deterministic call conditions
SizzleUnrlsd Feb 12, 2026
aa3f356
refactor(input-pipeline): normalize include ordering
SizzleUnrlsd Feb 12, 2026
c1dbcd5
fix(uninitialized): recover declaration location with robust fallbacks
SizzleUnrlsd Feb 12, 2026
27e81d5
test(no-error): assert basic main emits no diagnostics
SizzleUnrlsd Feb 12, 2026
899df27
test(offset-of): guard against false uninitialized warning on unused …
SizzleUnrlsd Feb 12, 2026
3c9a618
test(recursion-c): assert location for infinite recursion diagnostics
SizzleUnrlsd Feb 12, 2026
a3a81e5
test(recursion-c): assert location for bounded recursion diagnostic
SizzleUnrlsd Feb 12, 2026
bde728d
test(recursion-cpp): assert location for infinite recursion diagnostics
SizzleUnrlsd Feb 12, 2026
698bdbc
test(recursion-cpp): assert location for bounded recursion diagnostic
SizzleUnrlsd Feb 12, 2026
83bff87
test(uninitialized): assert location for never-initialized argument case
SizzleUnrlsd Feb 12, 2026
9a3662b
test(uninitialized): assert location for never-initialized unused local
SizzleUnrlsd Feb 12, 2026
616c5d4
test(vla): add expectation for runtime-dependent disguised constant a…
SizzleUnrlsd Feb 12, 2026
e15e875
test(vla): add location expectations for vla-scanf diagnostics
SizzleUnrlsd Feb 12, 2026
6aebde8
test(vla): add location expectations for unknown-size vla diagnostics
SizzleUnrlsd Feb 12, 2026
d892e70
chore(debug): add llvm ir dump for duplicate else-if investigation
SizzleUnrlsd Feb 12, 2026
1049206
test(duplicate-if): add regression for duplicate else-if via helper call
SizzleUnrlsd Feb 12, 2026
ed5a8b7
chore(output): improve the output logs
SizzleUnrlsd Feb 12, 2026
133844c
test(output): update output of tests
SizzleUnrlsd Feb 12, 2026
ebf4990
chore(output): improve the output logs
SizzleUnrlsd Feb 12, 2026
69df1a2
chore(style): format code with clang-format
SizzleUnrlsd Feb 12, 2026
1164bbb
chore(output): improve the output logs
SizzleUnrlsd Feb 12, 2026
d564707
test(skip): skipping the test bad-usage-memcpy.c
SizzleUnrlsd Feb 12, 2026
c22d51c
fix(diagnostics): add robust source location for multiple-store issues
SizzleUnrlsd Feb 12, 2026
9bfb47b
test(multiple-storage): cover same-index multiple-store diagnostic
SizzleUnrlsd Feb 12, 2026
f642852
test(multiple-storage): cover same-index multiple-store diagnostic
SizzleUnrlsd Feb 12, 2026
4839eb5
test(all): update logs verification
SizzleUnrlsd Feb 12, 2026
62f85dd
chore(output): improve the output logs
SizzleUnrlsd Feb 12, 2026
47798d3
chore(style): format code with clang-format
SizzleUnrlsd Feb 12, 2026
213d945
refactor(diagnostics): replace macro prefixes with typed string_view …
SizzleUnrlsd Feb 12, 2026
f7fe303
test(all): update logs verification
SizzleUnrlsd Feb 12, 2026
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
13 changes: 12 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,17 @@ FetchContent_Declare(
GIT_REPOSITORY https://github.com/CoreTrace/coretrace-compiler.git
GIT_TAG main
)

FetchContent_MakeAvailable(cc)

set(CORETRACE_LOGGER_BUILD_EXAMPLES OFF CACHE BOOL "Disable logger examples" FORCE)
set(CORETRACE_LOGGER_BUILD_TESTS OFF CACHE BOOL "Disable logger tests" FORCE)
include(FetchContent)
FetchContent_Declare(coretrace-logger
GIT_REPOSITORY https://github.com/CoreTrace/coretrace-log.git
GIT_TAG main
)
FetchContent_MakeAvailable(coretrace-logger)

message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")

Expand Down Expand Up @@ -117,13 +125,15 @@ target_link_libraries(stack_usage_analyzer_lib
PUBLIC
${llvm_libs}
cc::compilerlib_static
coretrace::logger
)
# by this one :
if(LLVM_LINK_LLVM_DYLIB)
target_link_libraries(stack_usage_analyzer_lib
PUBLIC
LLVM
cc::compilerlib_static
coretrace::logger
)
else()
llvm_map_components_to_libnames(llvm_libs
Expand All @@ -135,6 +145,7 @@ else()
PUBLIC
${llvm_libs}
cc::compilerlib_static
coretrace::logger
)
endif()

Expand Down
13 changes: 13 additions & 0 deletions extern-project/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <llvm/Support/SourceMgr.h>
#include <llvm/IR/LLVMContext.h>
#include <iostream>
#include "analysis/CompileCommands.hpp"

int main(int argc, char **argv)
{
Expand All @@ -12,14 +13,26 @@ int main(int argc, char **argv)
}

std::string filename = argv[1];
std::string compile_file = argv[2];
std::string dbLoadError;

std::cout << compile_file << std::endl;
auto db = ctrace::stack::analysis::CompilationDatabase::loadFromFile(compile_file,
dbLoadError);
if (!db)
{
std::cerr << "Failed to load compilation database: " << dbLoadError << std::endl;
return 1;
}
llvm::LLVMContext ctx;
llvm::SMDiagnostic diag;

ctrace::stack::AnalysisConfig cfg;
cfg.mode = ctrace::stack::AnalysisMode::IR;
cfg.stackLimit = 8 * 1024 * 1024;

cfg.compilationDatabase = std::move(db);
// std::call_once(ctrace::stack::initializeLLVM, ctrace::stack::initializeLLVMFlag);
auto res = ctrace::stack::analyzeFile(filename, cfg, ctx, diag);

// Example: SARIF output to stdout
Expand Down
8 changes: 5 additions & 3 deletions include/StackUsageAnalyzer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,13 @@ namespace ctrace::stack
ConstParameterNotModified = 11,
SizeMinusOneWrite = 12,
DuplicateIfCondition = 13,
UninitializedLocalRead = 14
UninitializedLocalRead = 14,
StackFrameTooLarge = 15
};

template <> struct EnumTraits<DescriptiveErrorCode>
{
static constexpr std::array<std::string_view, 15> names = {"None",
static constexpr std::array<std::string_view, 16> names = {"None",
"StackBufferOverflow",
"NegativeStackIndex",
"VLAUsage",
Expand All @@ -140,7 +141,8 @@ namespace ctrace::stack
"ConstParameterNotModified",
"SizeMinusOneWrite",
"DuplicateIfCondition",
"UninitializedLocalRead"};
"UninitializedLocalRead",
"StackFrameTooLarge"};
};

/*
Expand Down
79 changes: 64 additions & 15 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include "analysis/CompileCommands.hpp"
#include "mangle.hpp"

#include <coretrace/logger.hpp>

using namespace ctrace::stack;

enum class OutputFormat
Expand Down Expand Up @@ -391,6 +393,14 @@ static AnalysisResult filterWarningsOnly(const AnalysisResult& result, const Ana

int main(int argc, char** argv)
{
coretrace::enable_logging();
coretrace::set_prefix("==stack-analyzer==");
coretrace::set_min_level(coretrace::Level::Info);
coretrace::set_source_location(true);

coretrace::log(coretrace::Level::Debug, coretrace::Module("cli"),
"Starting analysis for {} input(s)\n", argc - 1);

llvm::LLVMContext context;
std::vector<std::string> inputFilenames;
OutputFormat outputFormat = OutputFormat::Human;
Expand All @@ -400,12 +410,21 @@ int main(int argc, char** argv)
cfg.warningsOnly = false;
std::string compileCommandsPath;
bool compileCommandsExplicit = false;
// cfg.mode = AnalysisMode::IR; -> already set by default constructor
// cfg.stackLimit = 8ull * 1024ull * 1024ull; // 8 MiB -> already set by default constructor but needed to be set with args

cfg.extraCompileArgs.emplace_back("-O0");
cfg.extraCompileArgs.emplace_back("--ct-optnone");

if (argc < 2)
{
printHelp();
return 1;
}
else if (argc < 2)
{
printHelp();
return 1;
}

for (int i = 1; i < argc; ++i)
{
const char* arg = argv[i];
Expand All @@ -420,6 +439,12 @@ int main(int argc, char** argv)
cfg.quiet = true;
continue;
}
if (argStr == "--verbose")
{
cfg.quiet = false;
coretrace::set_min_level(coretrace::Level::Debug);
continue;
}
if (argStr == "--STL" || argStr == "--stl")
{
cfg.includeSTL = true;
Expand Down Expand Up @@ -502,6 +527,18 @@ int main(int argc, char** argv)
cfg.stackLimit = value;
continue;
}
else if (argStr == "--stack-limit")
{
std::string error;
StackSize value = 0;
if (!parseStackLimitValue(argStr.substr(std::strlen("--stack-limit=")), value, error))
{
llvm::errs() << "Invalid --stack-limit value: " << error << "\n";
return 1;
}
cfg.stackLimit = value;
continue;
}
if (argStr.rfind("--stack-limit=", 0) == 0)
{
std::string error;
Expand Down Expand Up @@ -654,7 +691,8 @@ int main(int argc, char** argv)
{
if (compileCommandsPath.empty())
{
llvm::errs() << "compile commands path is empty\n";
// llvm::errs() << "compile commands path is empty\n";
coretrace::log(coretrace::Level::Error, "Compile commands path is empty\n");
return 1;
}

Expand All @@ -666,20 +704,25 @@ int main(int argc, char** argv)
}
else if (fsErr)
{
llvm::errs() << "Failed to inspect compile commands path: " << fsErr.message() << "\n";
coretrace::log(coretrace::Level::Error, "Failed to inspect compile commands path: {}\n",
fsErr.message());
return 1;
}

if (!std::filesystem::exists(compdbPath, fsErr))
{
if (fsErr)
{
llvm::errs() << "Failed to inspect compile commands path: " << fsErr.message()
<< "\n";
// llvm::errs() << "Failed to inspect compile commands path: " << fsErr.message()
// << "\n";
coretrace::log(coretrace::Level::Error,
"Failed to inspect compile commands path: {}\n", fsErr.message());
}
else
{
llvm::errs() << "compile commands file not found: " << compdbPath.string() << "\n";
// llvm::errs() << "compile commands file not found: " << compdbPath.string() << "\n";
coretrace::log(coretrace::Level::Error, "Compile commands file not found: {}\n",
compdbPath.string());
}
return 1;
}
Expand All @@ -689,7 +732,8 @@ int main(int argc, char** argv)
ctrace::stack::analysis::CompilationDatabase::loadFromFile(compdbPath.string(), error);
if (!db)
{
llvm::errs() << "Failed to load compile commands: " << error << "\n";
// llvm::errs() << "Failed to load compile commands: " << error << "\n";
coretrace::log(coretrace::Level::Error, "Failed to load compile commands: {}\n", error);
return 1;
}
cfg.compilationDatabase = std::move(db);
Expand All @@ -698,8 +742,11 @@ int main(int argc, char** argv)

if (inputFilenames.empty())
{
llvm::errs() << "Usage: stack_usage_analyzer <file.ll> [file2.ll ...] [options]\n"
<< "Try --help for more information.\n";
// llvm::errs() << "Usage: stack_usage_analyzer <file.ll> [file2.ll ...] [options]\n"
// << "Try --help for more information.\n";
coretrace::log(coretrace::Level::Error,
"Usage: stack_usage_analyzer <file.ll> [file2.ll ...] [options]\n");
coretrace::log(coretrace::Level::Error, "Try --help for more information.\n");
return 1;
}

Expand Down Expand Up @@ -751,6 +798,8 @@ int main(int argc, char** argv)
else
{
llvm::errs() << "Failed to analyze: " << inputFilename << "\n";
coretrace::log(coretrace::Level::Error, coretrace::Module("cli"),
"Failed to analyze:{}\n", inputFilename);
localErr.print("stack_usage_analyzer", llvm::errs());
return 1;
}
Expand Down Expand Up @@ -853,7 +902,7 @@ int main(int argc, char** argv)
<< "\n";
if (f.localStackUnknown)
{
llvm::outs() << " local stack: unknown";
llvm::outs() << "\tlocal stack: unknown";
if (f.localStack > 0)
{
llvm::outs() << " (>= " << f.localStack << " bytes)";
Expand All @@ -862,12 +911,12 @@ int main(int argc, char** argv)
}
else
{
llvm::outs() << " local stack: " << f.localStack << " bytes\n";
llvm::outs() << "\tlocal stack: " << f.localStack << " bytes\n";
}

if (f.maxStackUnknown)
{
llvm::outs() << " max stack (including callees): unknown";
llvm::outs() << "\tmax stack (including callees): unknown";
if (f.maxStack > 0)
{
llvm::outs() << " (>= " << f.maxStack << " bytes)";
Expand All @@ -876,7 +925,7 @@ int main(int argc, char** argv)
}
else
{
llvm::outs() << " max stack (including callees): " << f.maxStack << " bytes\n";
llvm::outs() << "\tmax stack (including callees): " << f.maxStack << " bytes\n";
}

if (!result.config.quiet)
Expand All @@ -891,7 +940,7 @@ int main(int argc, char** argv)

if (d.line != 0)
{
llvm::outs() << " at line " << d.line << ", column " << d.column << "\n";
llvm::outs() << "\tat line " << d.line << ", column " << d.column << "\n";
}
llvm::outs() << d.message << "\n";
}
Expand Down
Loading
Loading