llvm/llvm/lib/Analysis/Lint.cpp

//===-- Lint.cpp - Check for common errors in LLVM IR ---------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This pass statically checks for common and easily-identified constructs
// which produce undefined or likely unintended behavior in LLVM IR.
//
// It is not a guarantee of correctness, in two ways. First, it isn't
// comprehensive. There are checks which could be done statically which are
// not yet implemented. Some of these are indicated by TODO comments, but
// those aren't comprehensive either. Second, many conditions cannot be
// checked statically. This pass does no dynamic instrumentation, so it
// can't check for all possible problems.
//
// Another limitation is that it assumes all code will be executed. A store
// through a null pointer in a basic block which is never reached is harmless,
// but this pass will warn about it anyway. This is the main reason why most
// of these checks live here instead of in the Verifier pass.
//
// Optimization passes may make conditions that this pass checks for more or
// less obvious. If an optimization pass appears to be introducing a warning,
// it may be that the optimization pass is merely exposing an existing
// condition in the code.
//
// This code may be run before instcombine. In many cases, instcombine checks
// for the same kinds of things and turns instructions with undefined behavior
// into unreachable (or equivalent). Because of this, this pass makes some
// effort to look through bitcasts and so on.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/Lint.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/Analysis/ScopedNoAliasAA.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstdint>
#include <iterator>
#include <string>

usingnamespacellvm;

static const char LintAbortOnErrorArgName[] =;
static cl::opt<bool>
    LintAbortOnError(LintAbortOnErrorArgName, cl::init(false),
                     cl::desc("In the Lint pass, abort on errors."));

namespace {
namespace MemRef {
static const unsigned Read =;
static const unsigned Write =;
static const unsigned Callee =;
static const unsigned Branchee =;
} // end namespace MemRef

class Lint : public InstVisitor<Lint> {};
} // end anonymous namespace

// Check - We know that cond should be true, if not print an error message.
#define Check(C, ...)

void Lint::visitFunction(Function &F) {}

void Lint::visitCallBase(CallBase &I) {}

void Lint::visitReturnInst(ReturnInst &I) {}

// TODO: Check that the reference is in bounds.
// TODO: Check readnone/readonly function attributes.
void Lint::visitMemoryReference(Instruction &I, const MemoryLocation &Loc,
                                MaybeAlign Align, Type *Ty, unsigned Flags) {}

void Lint::visitLoadInst(LoadInst &I) {}

void Lint::visitStoreInst(StoreInst &I) {}

void Lint::visitXor(BinaryOperator &I) {}

void Lint::visitSub(BinaryOperator &I) {}

void Lint::visitLShr(BinaryOperator &I) {}

void Lint::visitAShr(BinaryOperator &I) {}

void Lint::visitShl(BinaryOperator &I) {}

static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT,
                   AssumptionCache *AC) {}

void Lint::visitSDiv(BinaryOperator &I) {}

void Lint::visitUDiv(BinaryOperator &I) {}

void Lint::visitSRem(BinaryOperator &I) {}

void Lint::visitURem(BinaryOperator &I) {}

void Lint::visitAllocaInst(AllocaInst &I) {}

void Lint::visitVAArgInst(VAArgInst &I) {}

void Lint::visitIndirectBrInst(IndirectBrInst &I) {}

void Lint::visitExtractElementInst(ExtractElementInst &I) {}

void Lint::visitInsertElementInst(InsertElementInst &I) {}

void Lint::visitUnreachableInst(UnreachableInst &I) {}

/// findValue - Look through bitcasts and simple memory reference patterns
/// to identify an equivalent, but more informative, value.  If OffsetOk
/// is true, look through getelementptrs with non-zero offsets too.
///
/// Most analysis passes don't require this logic, because instcombine
/// will simplify most of these kinds of things away. But it's a goal of
/// this Lint pass to be useful even on non-optimized IR.
Value *Lint::findValue(Value *V, bool OffsetOk) const {}

/// findValueImpl - Implementation helper for findValue.
Value *Lint::findValueImpl(Value *V, bool OffsetOk,
                           SmallPtrSetImpl<Value *> &Visited) const {}

PreservedAnalyses LintPass::run(Function &F, FunctionAnalysisManager &AM) {}

//===----------------------------------------------------------------------===//
//  Implement the public interfaces to this file...
//===----------------------------------------------------------------------===//

/// lintFunction - Check a function for errors, printing messages on stderr.
///
void llvm::lintFunction(const Function &f) {}

/// lintModule - Check a module for errors, printing messages on stderr.
///
void llvm::lintModule(const Module &M) {}