Skip to content
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
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ set(STACK_ANALYZER_SOURCES
src/analysis/AnalyzerUtils.cpp
src/analysis/CompileCommands.cpp
src/analysis/ConstParamAnalysis.cpp
src/analysis/DuplicateIfCondition.cpp
src/analysis/DynamicAlloca.cpp
src/analysis/FunctionFilter.cpp
src/analysis/IRValueUtils.cpp
Expand Down
8 changes: 5 additions & 3 deletions include/StackUsageAnalyzer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,13 @@ namespace ctrace::stack
AllocaUsageWarning = 9,
InvalidBaseReconstruction = 10,
ConstParameterNotModified = 11,
SizeMinusOneWrite = 12
SizeMinusOneWrite = 12,
DuplicateIfCondition = 13
};

template <> struct EnumTraits<DescriptiveErrorCode>
{
static constexpr std::array<std::string_view, 13> names = {"None",
static constexpr std::array<std::string_view, 14> names = {"None",
"StackBufferOverflow",
"NegativeStackIndex",
"VLAUsage",
Expand All @@ -135,7 +136,8 @@ namespace ctrace::stack
"AllocaUsageWarning",
"InvalidBaseReconstruction",
"ConstParameterNotModified",
"SizeMinusOneWrite"};
"SizeMinusOneWrite",
"DuplicateIfCondition"};
};

/*
Expand Down
25 changes: 25 additions & 0 deletions include/analysis/DuplicateIfCondition.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include <functional>
#include <string>
#include <vector>

namespace llvm
{
class Function;
class Instruction;
class Module;
} // namespace llvm

namespace ctrace::stack::analysis
{
struct DuplicateIfConditionIssue
{
std::string funcName;
const llvm::Instruction* conditionInst = nullptr;
};

std::vector<DuplicateIfConditionIssue>
analyzeDuplicateIfConditions(llvm::Module& mod,
const std::function<bool(const llvm::Function&)>& shouldAnalyze);
} // namespace ctrace::stack::analysis
66 changes: 66 additions & 0 deletions src/StackUsageAnalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "analysis/AllocaUsage.hpp"
#include "analysis/AnalyzerUtils.hpp"
#include "analysis/ConstParamAnalysis.hpp"
#include "analysis/DuplicateIfCondition.hpp"
#include "analysis/DynamicAlloca.hpp"
#include "analysis/FunctionFilter.hpp"
#include "analysis/InputPipeline.hpp"
Expand Down Expand Up @@ -861,6 +862,66 @@ namespace ctrace::stack
}
}

static void appendDuplicateIfConditionDiagnostics(
AnalysisResult& result, const std::vector<analysis::DuplicateIfConditionIssue>& issues)
{
for (const auto& issue : issues)
{
unsigned line = 0;
unsigned column = 0;
unsigned startLine = 0;
unsigned startColumn = 0;
unsigned endLine = 0;
unsigned endColumn = 0;
bool haveLoc = false;

if (issue.conditionInst)
{
llvm::DebugLoc DL = issue.conditionInst->getDebugLoc();
if (DL)
{
line = DL.getLine();
startLine = DL.getLine();
column = DL.getCol();
startColumn = DL.getCol();
endLine = DL.getLine();
endColumn = DL.getCol();
haveLoc = true;

if (auto* loc = DL.get())
{
if (auto* scope = llvm::dyn_cast<llvm::DILocation>(loc))
{
if (scope->getColumn() != 0)
{
endColumn = scope->getColumn() + 1;
}
}
}
}
}

std::ostringstream body;
body << " [!] unreachable else-if branch: condition is equivalent to a previous "
"'if' condition\n";
body << " else branch implies previous condition is false\n";

Diagnostic diag;
diag.funcName = issue.funcName;
diag.line = haveLoc ? line : 0;
diag.column = haveLoc ? column : 0;
diag.startLine = haveLoc ? startLine : 0;
diag.startColumn = haveLoc ? startColumn : 0;
diag.endLine = haveLoc ? endLine : 0;
diag.endColumn = haveLoc ? endColumn : 0;
diag.severity = DiagnosticSeverity::Warning;
diag.errCode = DescriptiveErrorCode::DuplicateIfCondition;
diag.ruleId = "DuplicateIfCondition";
diag.message = body.str();
result.diagnostics.push_back(std::move(diag));
}
}

static void appendInvalidBaseReconstructionDiagnostics(
AnalysisResult& result,
const std::vector<analysis::InvalidBaseReconstructionIssue>& issues)
Expand Down Expand Up @@ -1200,6 +1261,11 @@ namespace ctrace::stack
std::vector<analysis::MultipleStoreIssue> multiStoreIssues =
analysis::analyzeMultipleStores(mod, shouldAnalyzeFunction);
appendMultipleStoreDiagnostics(result, multiStoreIssues);

// 12b) Détection de branches else-if inatteignables (condition dupliquée)
std::vector<analysis::DuplicateIfConditionIssue> duplicateIfIssues =
analysis::analyzeDuplicateIfConditions(mod, shouldAnalyzeFunction);
appendDuplicateIfConditionDiagnostics(result, duplicateIfIssues);
logDuration("Multiple stores", t0);

// 13) Detect invalid base pointer reconstructions (offsetof/container_of)
Expand Down
Loading
Loading