#include "TestingSupport.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Analysis/FlowSensitive/CFGMatchSwitch.h"
#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
#include "clang/Analysis/FlowSensitive/NoopLattice.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Testing/Annotations/Annotations.h"
#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"
#include <memory>
namespace {
usingnamespaceclang;
usingnamespacedataflow;
usingnamespaceast_matchers;
usingnamespacetest;
UnorderedElementsAre;
enum class Sign : int { … };
Sign getSign(int64_t V) { … }
LatticeTransferState;
constexpr char kVar[] = …;
void initNegative(Value &Val, Environment &Env) { … }
void initPositive(Value &Val, Environment &Env) { … }
void initZero(Value &Val, Environment &Env) { … }
struct SignProperties { … };
void setSignProperties(Value &Val, const SignProperties &Ps) { … }
SignProperties initUnknown(Value &Val, Environment &Env) { … }
SignProperties getSignProperties(const Value &Val, const Environment &Env) { … }
void transferUninitializedInt(const DeclStmt *D,
const MatchFinder::MatchResult &M,
LatticeTransferState &State) { … }
std::tuple<Value *, SignProperties, SignProperties>
getValueAndSignProperties(const UnaryOperator *UO,
const MatchFinder::MatchResult &M,
LatticeTransferState &State) { … }
void transferBinary(const BinaryOperator *BO, const MatchFinder::MatchResult &M,
LatticeTransferState &State) { … }
void transferUnaryMinus(const UnaryOperator *UO,
const MatchFinder::MatchResult &M,
LatticeTransferState &State) { … }
void transferUnaryNot(const UnaryOperator *UO,
const MatchFinder::MatchResult &M,
LatticeTransferState &State) { … }
Value *getOrCreateValue(const Expr *E, Environment &Env) { … }
void transferExpr(const Expr *E, const MatchFinder::MatchResult &M,
LatticeTransferState &State) { … }
auto refToVar() { … }
auto buildTransferMatchSwitch() { … }
class SignPropagationAnalysis
: public DataflowAnalysis<SignPropagationAnalysis, NoopLattice> { … };
BoolValue &joinBoolValues(BoolValue &Bool1, const Environment &Env1,
BoolValue &Bool2, const Environment &Env2,
Environment &JoinedEnv) { … }
void SignPropagationAnalysis::join(QualType Type, const Value &Val1,
const Environment &Env1, const Value &Val2,
const Environment &Env2, Value &JoinedVal,
Environment &JoinedEnv) { … }
template <typename Matcher>
void runDataflow(llvm::StringRef Code, Matcher Match,
LangStandard::Kind Std = LangStandard::lang_cxx17,
llvm::StringRef TargetFun = "fun") { … }
template <typename NodeType, typename MatcherType>
const NodeType *findFirst(ASTContext &ASTCtx, const MatcherType &M) { … }
template <typename Node>
std::pair<testing::AssertionResult, Value *>
getProperty(const Environment &Env, ASTContext &ASTCtx, const Node *N,
StringRef Property) { … }
template <typename Node>
testing::AssertionResult isPropertyImplied(const Environment &Env,
ASTContext &ASTCtx, const Node *N,
StringRef Property, bool Implies) { … }
template <typename Node>
testing::AssertionResult isNegative(const Node *N, ASTContext &ASTCtx,
const Environment &Env) { … }
template <typename Node>
testing::AssertionResult isPositive(const Node *N, ASTContext &ASTCtx,
const Environment &Env) { … }
template <typename Node>
testing::AssertionResult isZero(const Node *N, ASTContext &ASTCtx,
const Environment &Env) { … }
template <typename Node>
testing::AssertionResult isTop(const Node *N, ASTContext &ASTCtx,
const Environment &Env) { … }
TEST(SignAnalysisTest, Init) { … }
TEST(SignAnalysisTest, UnaryMinus) { … }
TEST(SignAnalysisTest, UnaryNot) { … }
TEST(SignAnalysisTest, UnaryNotInIf) { … }
TEST(SignAnalysisTest, BinaryGT) { … }
TEST(SignAnalysisTest, BinaryLT) { … }
TEST(SignAnalysisTest, BinaryGE) { … }
TEST(SignAnalysisTest, BinaryLE) { … }
TEST(SignAnalysisTest, BinaryEQ) { … }
TEST(SignAnalysisTest, ComplexLoopCondition) { … }
TEST(SignAnalysisTest, JoinToTop) { … }
TEST(SignAnalysisTest, JoinToNeg) { … }
TEST(SignAnalysisTest, NestedIfs) { … }
}