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

[BoundsWidening] Handle complex conditionals in bounds widening #1149

Merged
merged 8 commits into from
Aug 12, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
45 changes: 37 additions & 8 deletions clang/include/clang/Sema/BoundsWideningAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,23 @@ namespace clang {
using InvertibleStmtMapTy = llvm::DenseMap<const Stmt *,
LValuesToReplaceInBoundsTy>;

// A struct representing various information about the terminating condition
// of a block.
struct TermCondInfoTy {
// The expression that dereferences a pointer or subscripts an array. For
// example:
// if (*(p + i) == 0) ==> DerefExpr = p + i
Expr *DerefExpr;

// Whether the terminating condition asserts nullness of the element. For
// example:
// if (*p == 0) ==> DoesCondAssertNullness = True
// if (*p != 0) ==> DoesCondAssertNullness = False
// if (*p == 'a') ==> DoesCondAssertNullness = False
// if (*p != 'a') ==> DoesCondAssertNullness = True
bool DoesCondAssertNullness;
};

mgrang marked this conversation as resolved.
Show resolved Hide resolved
} // end namespace clang

namespace clang {
Expand Down Expand Up @@ -159,11 +176,19 @@ namespace clang {
// @return Returns the expression E + Offset.
Expr *AddOffsetToExpr(Expr *E, unsigned Offset) const;

// From the given expression get the dereference expression. A dereference
// expression can be of the form "*(p + 1)" or "p[1]".
// @param[in] E is the given expression.
// @return Returns the dereference expression, if it exists.
Expr *GetDerefExpr(const Expr *E) const;
// Get various information about the terminating condition of a block.
// @param[in] TermCond is the terminating condition of a block.
// @return A struct containing various information about the terminating
// condition.
TermCondInfoTy GetTermCondInfo(const Expr *TermCond) const;

// Fill the TermCondInfo parameter with information about the terminating
// condition TermCond.
// @param[in] TermCond is the terminating condition of a block.
// @param[out] TermCondInfo is the struct that is filled with various
// information about the terminating condition.
void FillTermCondInfo(const Expr *TermCond,
TermCondInfoTy &TermCondInfo) const;

// Get the variable in an expression that is a pointer to a null-terminated
// array.
Expand All @@ -178,6 +203,11 @@ namespace clang {
// @return E with casts stripped off.
Expr *IgnoreCasts(const Expr *E) const;

// Strip off more casts than IgnoreCasts.
// @param[in] E is the expression whose casts must be stripped.
// @return E with casts stripped off.
Expr *StripCasts(const Expr *E) const;

// We do not want to run dataflow analysis on null blocks or the exit
// block. So we skip them.
// @param[in] B is the block which may need to be skipped from dataflow
Expand Down Expand Up @@ -287,9 +317,8 @@ namespace clang {
// The last statement of the block. This is nullptr if the block is empty.
const Stmt *LastStmt = nullptr;

// The terminating condition that dereferences a pointer. This is nullptr
// if the terminating condition does not dereference a pointer.
Expr *TermCondDerefExpr = nullptr;
// Various information about the terminating condition of the block.
TermCondInfoTy TermCondInfo;

// The In set of the last statment of each block.
BoundsMapTy InOfLastStmt;
Expand Down