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 new AST interfaces and initial form of UnitializedValues analysis. #682

Closed
wants to merge 46 commits into from
Closed
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
fba509e
interfaces:ast: Add new interfaces.
anthro-poid Jul 29, 2024
43ce257
interfaces:ast: Add new methods and apply new naming conventions.
anthro-poid Jul 29, 2024
7f64efc
hl: Apply new naming conventions for AST interfaces.
anthro-poid Jul 29, 2024
cb12250
analyses: Add first form of UnitializedValues analysis.
anthro-poid Jul 29, 2024
da226be
analyses: Move all files based on Clang analyses to direcotry include…
anthro-poid Jul 30, 2024
1af71cb
analyses: Get rid of all _Ts.
anthro-poid Jul 30, 2024
8c032df
analyses: Apply VAST_UNIMPLEMENTED instead of TODO.
anthro-poid Jul 30, 2024
2fed47c
interfaces:ast: Add new interfaces and use :: before return types.
anthro-poid Jul 30, 2024
11bf6ca
analysis: Allow to use Visit from StmtVisitor.h.
anthro-poid Jul 30, 2024
dedb720
analyses: Create Clang directory for files related with Clang analyses.
anthro-poid Jul 30, 2024
b67c597
interfaces:ast: Provide implementation for clang::StmtVisitor in vast.
anthro-poid Jul 30, 2024
11eeccf
interfaces:analyses: Add AnalysisDeclContextInterface.
anthro-poid Jul 30, 2024
077b04f
analyses: Apply changes related to AnalysisDeclContextInterface.
anthro-poid Jul 30, 2024
643d2a2
interfaces:ast: Make using base public.
anthro-poid Jul 30, 2024
936c5c5
interfaces:ast: Apply some naming changes.
anthro-poid Jul 30, 2024
55eedc2
interfaces:ast: Unify include format.
anthro-poid Jul 30, 2024
f5b65db
analyses: Add iterator for ast::DeclContext.
anthro-poid Jul 31, 2024
76ca5e1
analyses: Move source file with iterator to lib/vast/Analyses.
anthro-poid Aug 2, 2024
22d14e5
analyses: Add implementation of UninitUse.
anthro-poid Aug 2, 2024
dc78cb1
analyses: Implement another required functionality.
anthro-poid Aug 2, 2024
27a9176
interfaces:ast: Add several interfaces and methods.
anthro-poid Aug 2, 2024
4074bae
analyses: Remove all T suffixes.
anthro-poid Aug 5, 2024
33e6dd2
interfaces:cfg: Add interfaces for Clang CFG classes.
anthro-poid Aug 8, 2024
50df128
analyses: Add new iterators.
anthro-poid Aug 8, 2024
d1f45ec
analyses: Update DatafloWorklist to use interfaces.
anthro-poid Aug 8, 2024
086c4b3
analyses: Add new functionality to UnitializedValues analysis and mak…
anthro-poid Aug 8, 2024
09d7e5d
hl: Make FuncOp to inherit from DeclContext and AnalysisDeclContext i…
anthro-poid Aug 8, 2024
5f87f49
interfaces:ast: Add new methods to Expr interfaces.
anthro-poid Aug 8, 2024
ee1b3e2
interfaces:analysis: Add new methods for AnalysisDeclContext interfaces.
anthro-poid Aug 8, 2024
51474e6
interfaces:ast: Add new methods for Type interfaces.
anthro-poid Aug 8, 2024
e6f8344
interfaces:analysis: Change lib name to resolve conflicts.
anthro-poid Aug 8, 2024
2697ba8
repl: Allow repl to run UnitializedVariable analysis.
anthro-poid Aug 8, 2024
55a6c89
analyses: Change decl_interface_iterator to use mlir::Operation *.
anthro-poid Aug 12, 2024
78cd574
interfaces:ast: Update interface methods in DeclInterface.td.
anthro-poid Aug 12, 2024
a894a0f
hl: Provide implementation for FuncOp::decls_begin.
anthro-poid Aug 12, 2024
f7308ba
vast: Replace all usages of 'analyses' to 'analysis'.
anthro-poid Aug 12, 2024
858aa92
analysis: Remove old reprezentation of CFG structures.
anthro-poid Sep 6, 2024
b65ea67
hl: Attach new interfaces.
anthro-poid Sep 6, 2024
eae51e3
core: Attach new interfaces.
anthro-poid Sep 6, 2024
6a9e0ed
interfaces:cfg: Update functionality of CFG interfaces.
anthro-poid Sep 6, 2024
8a33d83
interfaces:ast: Update DeclInterface and TypeInteface functionality.
anthro-poid Sep 6, 2024
3fc5eeb
core: Add necessary include.
anthro-poid Sep 6, 2024
c7b42e9
analysis: Implement operator++ method for decl_interface_iterator.
anthro-poid Sep 6, 2024
bc36d28
hl: Provide implementations for interface methods.
anthro-poid Sep 6, 2024
0bd4da5
repl: Allow to call UnitializedVariablesAnalysis from repl.
anthro-poid Sep 6, 2024
e69ef29
analysis: Add current state of UnitializedValues analysis implementat…
anthro-poid Sep 6, 2024
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
3 changes: 3 additions & 0 deletions include/vast/Analysis/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Copyright (c) 2024-present, Trail of Bits, Inc.

add_subdirectory(Clang)
3 changes: 3 additions & 0 deletions include/vast/Analysis/Clang/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Copyright (c) 2024-present, Trail of Bits, Inc.

add_subdirectory(FlowSensitive)
1 change: 1 addition & 0 deletions include/vast/Analysis/Clang/FlowSensitive/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Copyright (c) 2024-present, Trail of Bits, Inc.
68 changes: 68 additions & 0 deletions include/vast/Analysis/Clang/FlowSensitive/DataflowWorklist.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (c) 2024-present, Trail of Bits, Inc.
#pragma once

#include "vast/Interfaces/CFG/CFGInterface.hpp"

#include <clang/Analysis/Analyses/IntervalPartition.h>
#include <clang/Analysis/Analyses/PostOrderCFGView.h>
#include <llvm/ADT/PriorityQueue.h>

namespace vast::analysis {

/// A worklist implementation where the enqueued blocks will be dequeued based
/// on the order defined by 'Comp'.
template< typename Comp, unsigned QueueSize >
class DataflowWorklistBase {
llvm::BitVector EnqueuedBlocks;
llvm::PriorityQueue< cfg::CFGBlockInterface,
llvm::SmallVector< cfg::CFGBlockInterface, QueueSize >,
Comp > WorkList;
public:
DataflowWorklistBase(cfg::CFGInterface Cfg, Comp C)
: EnqueuedBlocks(Cfg.getNumBlockIDs()), WorkList(C) {}

void enqueueBlock(cfg::CFGBlockInterface Block) {
if (Block && !EnqueuedBlocks[Block.getBlockID()]) {
EnqueuedBlocks[Block.getBlockID()] = true;
WorkList.push(Block);
}
}

cfg::CFGBlockInterface dequeue() {
if (WorkList.empty()) {
return {};
}
cfg::CFGBlockInterface B = WorkList.top();
WorkList.pop();
EnqueuedBlocks[B.getBlockID()] = false;
return B;
}
};

struct ReversePostOrderCompare {
clang::PostOrderCFGView::BlockOrderCompare Cmp;
bool operator()(cfg::CFGBlockInterface lhs, cfg::CFGBlockInterface rhs) const {
VAST_UNIMPLEMENTED;
// return Cmp(rhs, lhs);
}
};

/// A worklist implementation for forward dataflow analysis. The enqueued
/// blocks will be dequeued in reverse post order. The worklist cannot contain
/// the same block multiple times at once.
struct ForwardDataflowWorklist
: DataflowWorklistBase< ReversePostOrderCompare, 20 > {

ForwardDataflowWorklist(cfg::CFGInterface Cfg, clang::PostOrderCFGView *POV)
: DataflowWorklistBase(Cfg, ReversePostOrderCompare{POV->getComparator()}) {}

ForwardDataflowWorklist(cfg::CFGInterface Cfg, AnalysisDeclContextInterface Ctx)
: ForwardDataflowWorklist(Cfg, Ctx. template getAnalysis< clang::PostOrderCFGView >()) {}

void enqueueSuccessors(cfg::CFGBlockInterface Block) {
for (auto B : Block.succs()) {
enqueueBlock(mlir::dyn_cast< cfg::CFGBlockInterface >(*B));
}
}
};
} // namespace vast::analysis
168 changes: 168 additions & 0 deletions include/vast/Analysis/Iterators.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#pragma once

#include "vast/Util/Warnings.hpp"

VAST_RELAX_WARNINGS
#include <clang/Analysis/Support/BumpVector.h>
#include <llvm/ADT/iterator.h>
#include <llvm/ADT/iterator_range.h>
#include <mlir/IR/Operation.h>
VAST_RELAX_WARNINGS

#include <iterator>

namespace vast::ast {

class DeclInterface;
class ExprInterface;
class StmtInterface;
}

namespace vast::analysis {

class decl_interface_iterator {
mlir::Operation *Current = nullptr;

public:
decl_interface_iterator() = default;
explicit decl_interface_iterator(mlir::Operation *C) : Current(C) {}

mlir::Operation *operator*() const;
mlir::Operation *operator->() const;
decl_interface_iterator &operator++();
decl_interface_iterator operator++(int);

friend bool operator==(decl_interface_iterator, decl_interface_iterator);
friend bool operator!=(decl_interface_iterator, decl_interface_iterator);
};

template< typename SpecificDecl >
class specific_decl_interface_iterator {
using decl_interface_iterator = vast::analysis::decl_interface_iterator;
decl_interface_iterator Current;

void SkipToNextDecl() {
while (*Current && !isa< SpecificDecl >(*Current)) {
++Current;
}
}

public:
specific_decl_interface_iterator() = default;
explicit specific_decl_interface_iterator(decl_interface_iterator C) : Current(C) {
SkipToNextDecl();
}

SpecificDecl operator*() const { return dyn_cast< SpecificDecl >(*Current); }
SpecificDecl operator->() const { return *this; }

specific_decl_interface_iterator &operator++() {
++Current;
SkipToNextDecl();
return *this;
}

specific_decl_interface_iterator operator++(int) {
specific_decl_interface_iterator tmp(*this);
++(*this);
return tmp;
}

friend bool operator==(const specific_decl_interface_iterator &x,
const specific_decl_interface_iterator &y) {
return x.Current == y.Current;
}

friend bool operator!=(const specific_decl_interface_iterator &x,
const specific_decl_interface_iterator &y) {
return x.Current != y.Current;
}
};

template< typename T, typename TPtr = T *, typename StmtPtr = ast::StmtInterface * >
struct CastIterator
: llvm::iterator_adaptor_base< CastIterator< T, TPtr, StmtPtr >, StmtPtr *,
std::random_access_iterator_tag, T > {
using Base = typename CastIterator::iterator_adaptor_base;

CastIterator() : Base(nullptr) {}
CastIterator(StmtPtr *I) : Base(I) {}

typename Base::value_type operator*() const {
return cast_or_null< T >((*this->I)->getOperation());
}
};

using ExprInterfaceIterator = CastIterator< ast::ExprInterface >;
using call_expr_arg_iterator = ExprInterfaceIterator;
} // namespace vast::analysis

namespace vast::cfg {

class CFGBlockInterface;
class CFGElementInterface;
}

namespace vast::cfg {

class AdjacentBlock {
enum Kind {
AB_Normal,
AB_Unreachable,
AB_Alternate
};

mlir::Operation *ReachableBlock;
llvm::PointerIntPair< mlir::Operation *, 2 > UnreachableBlock;

public:
/// Construct an AdjacentBlock with a possibly unreachable block.
AdjacentBlock(cfg::CFGBlockInterface *B, bool isReachable);

/// Construct an AdjacentBlock with a reachable block and an alternate
/// unreachable block.
AdjacentBlock(cfg::CFGBlockInterface *B, cfg::CFGBlockInterface *AlternateBlock);

/// Get the reachable block, if one exists.
mlir::Operation *getReachableBlock() const {
return ReachableBlock;
}

/// Get the potentially unreachable block.
mlir::Operation *getPossiblyUnreachableBlock() const {
return UnreachableBlock.getPointer();
}

/// Provide an implicit conversion to cfg::CFGBlockInterface so that
/// AdjacentBlock can be substituted for cfg::CFGBlockInterface.
/*
operator mlir::Operation*() const {
return getReachableBlock();
}
*/

mlir::Operation *operator*() const {
return getReachableBlock();
}

mlir::Operation *operator->() const {
return getReachableBlock();
}

bool isReachable() const {
Kind K = (Kind) UnreachableBlock.getInt();
return K == Kind::AB_Normal || K == Kind::AB_Alternate;
}
};

using AdjacentBlocks = clang::BumpVector< AdjacentBlock >;
using pred_iterator = AdjacentBlocks::iterator;

using CFGBlockListTy = clang::BumpVector< CFGBlockInterface >;
using CFGIterator = CFGBlockListTy::iterator;

using succ_iterator = AdjacentBlocks::iterator;
using succ_range = llvm::iterator_range< succ_iterator >;

using CFGBlockIterator = std::reverse_iterator< clang::BumpVector< CFGElementInterface >::iterator >;
} // namespace vast::cfg
Loading