Multi-phase work merged into one commit:
* M19: flow-sensitive guard tracking (stmtAlwaysExits, walkIf early-exit)
* M20–M27: non-null marking across deref, addr-of, callsite preconds,
if/while/switch guards, AddrOf-of-subexpr, CFG-block-scoped maps
* M30 Phase A: dialect-agnostic SourceLoc + LocationMapper + frontend/
boundary marker; ClangLocationMapper wired through SafetyObserver
* M30 Phase B v2: QueryTracer + 13 SafetyObserver hooks migrated to
ir::Expr / ir::Call / ir::MemberRef / ir::Symbol / ir::SourceLoc
* M30 Phase C/D/D2/D3: ir::Symbol, ir::Expr (with Kind), ir::Call,
ir::MemberRef opaque types; ir_expr_clang.cpp houses the clang
adapters; encodeExpr migrated to switch(kind) dispatch
Scout-rule extractions from encoder.cpp (2800 → 2371 lines):
* encoder_callee_predicates.{hpp,cpp} — isMallocLikeCall, isFreeCall,
isAssertCall as pure std::string_view predicates
* encoder_type_queries.{hpp,cpp} — typeSizeBytes, sourceWidth,
isUnsignedLike, byteWidthExpr
* encoder_callee_names.{hpp,cpp} — calleeName, qualifiedFunctionName,
qualifiedCalleeName (with internal-linkage @-suffix)
* encoder_coerce.{hpp,cpp} — coerceToBv, coerceToExactBv, coerceToBool,
coerceToType (BV-64 storage model documented at the boundary)
* encoder_reachability.{hpp,cpp} — ReachabilityCounter impl, markEncoded,
recordEncoded, recordBailedNode, public profiling glue
* encoder_summary_instantiate.cpp — SMT-LIB summary substitution
(instantiateSummaryExpr / Predicate / PredicateInContext +
applySummaryParamPost; kills the redundant *Impl pass-through layer)
42 lines
1.2 KiB
C++
42 lines
1.2 KiB
C++
#include <catch2/catch_test_macros.hpp>
|
|
|
|
#include "fold/ir/source_loc.hpp"
|
|
|
|
TEST_CASE("SourceLoc default-constructed is invalid", "[ir][source_loc]") {
|
|
fold::ir::SourceLoc loc;
|
|
REQUIRE_FALSE(loc.isValid());
|
|
REQUIRE(loc.file.empty());
|
|
REQUIRE(loc.line == 0);
|
|
REQUIRE(loc.column == 0);
|
|
}
|
|
|
|
TEST_CASE("SourceLoc with file and line is valid", "[ir][source_loc]") {
|
|
fold::ir::SourceLoc loc{"foo.c", 42, 7};
|
|
REQUIRE(loc.isValid());
|
|
REQUIRE(loc.file == "foo.c");
|
|
REQUIRE(loc.line == 42);
|
|
REQUIRE(loc.column == 7);
|
|
}
|
|
|
|
TEST_CASE("SourceLoc with empty file is invalid even if line set", "[ir][source_loc]") {
|
|
fold::ir::SourceLoc loc{"", 5, 1};
|
|
REQUIRE_FALSE(loc.isValid());
|
|
}
|
|
|
|
TEST_CASE("SourceLoc with line=0 is invalid", "[ir][source_loc]") {
|
|
fold::ir::SourceLoc loc{"foo.c", 0, 0};
|
|
REQUIRE_FALSE(loc.isValid());
|
|
}
|
|
|
|
TEST_CASE("SourceLoc equality", "[ir][source_loc]") {
|
|
fold::ir::SourceLoc a{"x.c", 1, 1};
|
|
fold::ir::SourceLoc b{"x.c", 1, 1};
|
|
fold::ir::SourceLoc c{"x.c", 1, 2};
|
|
fold::ir::SourceLoc d{"y.c", 1, 1};
|
|
|
|
REQUIRE(a == b);
|
|
REQUIRE_FALSE(a == c);
|
|
REQUIRE_FALSE(a == d);
|
|
REQUIRE(a != c);
|
|
REQUIRE(a != d);
|
|
}
|