Skip to content

Lower Bounds Inference #718

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

Merged
merged 118 commits into from
Dec 2, 2021
Merged
Show file tree
Hide file tree
Changes from 84 commits
Commits
Show all changes
118 commits
Select commit Hold shift + click to select a range
93802d7
Initial implementation of range bounds
john-h-kastner Jul 28, 2021
c6c3d79
Add tests
john-h-kastner Sep 30, 2021
eeddaca
Update testgenerator.py to handle new bounds
john-h-kastner Sep 30, 2021
78eacbb
Update generated tests
john-h-kastner Sep 30, 2021
a6f6b4b
Update assigment expression containing pointers with range bounds
john-h-kastner Sep 30, 2021
a41cc25
Update generated test
john-h-kastner Sep 30, 2021
22f2159
add test
john-h-kastner Sep 30, 2021
a9cb21f
Use same logic to check for pointer arithmetic in an assignment in ar…
john-h-kastner Oct 4, 2021
fad5d29
Cleanup and reduce duplicate code
john-h-kastner Oct 4, 2021
0de3945
Don't add range bounds for fields or global variables
john-h-kastner Oct 5, 2021
a1b84aa
Cleanup
john-h-kastner Oct 6, 2021
e474df6
Add `insertText` function to insert text with same checks as rewriteS…
john-h-kastner Oct 6, 2021
a4d2f9b
Add another test case
john-h-kastner Oct 6, 2021
53ffbc4
Fix error in range bounds for byte count
john-h-kastner Oct 8, 2021
821270c
Avoid rewrite error when an update of a pointer with range bounds is in
john-h-kastner Oct 13, 2021
550f773
Add tests and tidy code
john-h-kastner Oct 15, 2021
ecccac0
Move some reference parameters into returned structure.
john-h-kastner Oct 15, 2021
de7bb97
Comments
john-h-kastner Oct 15, 2021
f233422
Test byte count range bounds
john-h-kastner Oct 15, 2021
9a02e56
Fix order of new declarations in multi-decls
john-h-kastner Oct 15, 2021
17b9fc1
Merge remote-tracking branch 'origin/main' into range_bounds
john-h-kastner Oct 18, 2021
3557eb9
Tidying and comments
john-h-kastner Oct 18, 2021
a440e50
Also don't add range bounds on constant size arrays
john-h-kastner Oct 18, 2021
d0e718e
More cleanup
john-h-kastner Oct 18, 2021
79d8121
Merge remote-tracking branch 'origin/main' into range_bounds
john-h-kastner Oct 19, 2021
d842773
Merge remote-tracking branch 'origin/main' into range_bounds
john-h-kastner Oct 25, 2021
cd60b76
Small test update
john-h-kastner Oct 26, 2021
023e282
comment fix
john-h-kastner Oct 26, 2021
241e9d5
Abounds.cpp cleanup
john-h-kastner Oct 27, 2021
c24b5d0
Add test case for count-plus-one bounds
john-h-kastner Oct 28, 2021
cc3ae93
ScopeVisitor cleanup
john-h-kastner Oct 29, 2021
371b9a1
wip
john-h-kastner Oct 29, 2021
778741b
wip
john-h-kastner Nov 1, 2021
703f6e1
Add a new field to ABounds
john-h-kastner Oct 27, 2021
de8eb79
wip
john-h-kastner Nov 3, 2021
aedd269
wip
john-h-kastner Nov 4, 2021
f8886ad
wip
john-h-kastner Nov 5, 2021
11ae7ae
Improved method for find invalidated base pointers
john-h-kastner Nov 8, 2021
b4ada01
Cleanup
john-h-kastner Nov 9, 2021
8cdfeb4
Initial propagation of temp lower bound
john-h-kastner Nov 9, 2021
98a99ae
Finish propagating temp lower bounds
john-h-kastner Nov 9, 2021
d8641dc
Don't add extra fresh lower bounds
john-h-kastner Nov 10, 2021
de80ab6
Cleanup old code
john-h-kastner Nov 10, 2021
878a865
WIP: Fix regression tests
john-h-kastner Nov 11, 2021
f0e11e3
WIP
john-h-kastner Nov 11, 2021
d14fedc
WIP
john-h-kastner Nov 11, 2021
7b57c83
fixes
john-h-kastner Nov 12, 2021
c82a93d
Fix bug in context sensitive assignment
john-h-kastner Nov 12, 2021
09187d4
Avoid referencing undefined parameter names
john-h-kastner Nov 12, 2021
2931014
update test
john-h-kastner Nov 12, 2021
b5d09c1
Update generated tests
john-h-kastner Nov 12, 2021
2ec3486
Fix bug
john-h-kastner Nov 12, 2021
a4c671f
remove debug prints
john-h-kastner Nov 12, 2021
ee97b36
Don't propagate lower bounds over context sensitive edges
john-h-kastner Nov 12, 2021
d1829ba
Add tests for new inference
john-h-kastner Nov 12, 2021
623dbbd
Hopefully better handling of conflicting lower bounds
john-h-kastner Nov 15, 2021
c9a7a54
fix condition
john-h-kastner Nov 16, 2021
6bd858d
Add missing null checks
john-h-kastner Nov 16, 2021
bbc60f1
Improve rewriting with lower bound generation and function redeclaration
john-h-kastner Nov 17, 2021
0b05be7
Use name from generated lower bound ProgramVar
john-h-kastner Nov 17, 2021
cfec386
Rewrite inference algorithm
john-h-kastner Nov 17, 2021
17314a4
Use sets for lower bound
john-h-kastner Nov 18, 2021
c7f02fa
Fix for existing bounds
john-h-kastner Nov 19, 2021
bf92e18
Add a test case
john-h-kastner Nov 19, 2021
6d4636f
Revert "Use sets for lower bound"
john-h-kastner Nov 19, 2021
e587082
wip
john-h-kastner Nov 19, 2021
d0a0984
Fix potential infinte loop.
john-h-kastner Nov 22, 2021
50ec3d1
Fix for malloc not invalidating lower bound
john-h-kastner Nov 22, 2021
da2b45e
Merge remote-tracking branch 'origin/main' into infer_lower_bound
john-h-kastner Nov 23, 2021
1290806
Don't invalidate function paramter lower bound based on arguments
john-h-kastner Nov 23, 2021
bd2ba95
Add more test cases
john-h-kastner Nov 23, 2021
fd7f2f2
Shome comments and cleanup
john-h-kastner Nov 23, 2021
4993902
Tidy code
john-h-kastner Nov 23, 2021
0f7ddfc
Merge branch 'infer_lower_bound' into range_bounds
john-h-kastner Nov 24, 2021
8213cf9
More code cleanup
john-h-kastner Nov 24, 2021
728f1b1
Make some methods private
john-h-kastner Nov 24, 2021
bf55a40
Remove semicolon
john-h-kastner Nov 24, 2021
5dd0882
Cleanup unnecessary change
john-h-kastner Nov 24, 2021
d7581c8
More cleanup
john-h-kastner Nov 24, 2021
abdb844
Change warning to assert
john-h-kastner Nov 24, 2021
bb04cde
comments
john-h-kastner Nov 24, 2021
533e1ca
Comments
john-h-kastner Nov 24, 2021
aab187c
Rename "BasePointer" -> "LowerBound"
john-h-kastner Nov 24, 2021
d7b3ade
Cmakelist
john-h-kastner Nov 24, 2021
739bebc
Work around Rewriter::ReplaceText bug with a previous insertion.
mattmccutchen-cci Nov 24, 2021
9dbcca8
Revert change to PrevEnd computation in DeclRewriter::rewriteMultiDecl.
mattmccutchen-cci Nov 24, 2021
2e42f3e
Change mkStringForDeclWithUnchangedType back to return a string.
mattmccutchen-cci Nov 30, 2021
48fad85
Use getNextComma to insert supplementary declarations in a multi-decl.
mattmccutchen-cci Nov 30, 2021
4bd4263
Update clang/include/clang/3C/RewriteUtils.h
john-h-kastner Dec 1, 2021
ed7e41d
Update clang/include/clang/3C/LowerBoundAssignment.h
john-h-kastner Dec 1, 2021
815ef0e
Update clang/lib/3C/ConstraintBuilder.cpp
john-h-kastner Dec 1, 2021
cd51b81
Update clang/test/3C/range_bounds.c
john-h-kastner Dec 1, 2021
fefd429
Update clang/lib/3C/ConstraintBuilder.cpp
john-h-kastner Dec 1, 2021
b3b5a74
Update clang/include/clang/3C/LowerBoundAssignment.h
john-h-kastner Dec 1, 2021
edec320
Update clang/test/3C/range_bounds.c
john-h-kastner Dec 1, 2021
dc27d9b
Update clang/test/3C/range_bounds.c
john-h-kastner Dec 1, 2021
0d69fc4
Update clang/test/3C/range_bounds.c
john-h-kastner Dec 1, 2021
c8b2532
-itypes-for-extern should not force supplementary decls to be unchecked.
mattmccutchen-cci Dec 1, 2021
ce27524
Update testgenerator comments
john-h-kastner Dec 1, 2021
77905e6
Add realloc to allocator heuristics
john-h-kastner Dec 1, 2021
c28ee43
Rename function
john-h-kastner Dec 1, 2021
7a2cfe4
Merge remote-tracking branch 'origin/range_bounds.msfdwut_refactor' i…
john-h-kastner Dec 1, 2021
1013f61
Merge remote-tracking branch 'origin/range_bounds.itypes_for_extern' …
john-h-kastner Dec 1, 2021
2aee4ef
Comment tweak
john-h-kastner Dec 1, 2021
70c0443
Add -itypes-for-extern test
john-h-kastner Dec 1, 2021
4e245cb
Remove FIXME
john-h-kastner Dec 1, 2021
bc780d3
Expand on TODO comment
john-h-kastner Dec 1, 2021
b3907ed
Update field comments
john-h-kastner Dec 1, 2021
91a19a6
More comment tweaks
john-h-kastner Dec 1, 2021
33ccff0
Merge remote-tracking branch 'origin/range_bounds.matt_rewrite_offset…
john-h-kastner Dec 1, 2021
17a6145
Rename __3c_tmp -> __3c_lower_bound
john-h-kastner Dec 1, 2021
cf4c849
Merge remote-tracking branch 'origin/range_bounds.getnextcomma' into …
john-h-kastner Dec 1, 2021
03f3685
Revert hack in testgenerator.py no longer required now that extra new
john-h-kastner Dec 1, 2021
702e658
Add another test case
john-h-kastner Dec 1, 2021
81f9b6f
Reword some comments to talk about fresh lower bounds rather than ran…
john-h-kastner Dec 1, 2021
7fc73b2
Some comments and minor code tweaks
john-h-kastner Dec 1, 2021
6584d3c
Work around issue encounted in vsftpd port phase two
john-h-kastner Dec 2, 2021
8f4c58b
Tidy
john-h-kastner Dec 2, 2021
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
122 changes: 58 additions & 64 deletions clang/include/clang/3C/ABounds.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,26 @@ class ABounds {
CountPlusOneBoundKind,
// Bounds that represent number of bytes.
ByteBoundKind,
// Bounds that represent range.
RangeBoundKind,
};
BoundsKind getKind() const { return Kind; }

protected:
ABounds(BoundsKind K, BoundsKey L, BoundsKey B) : Kind(K), LenVar(L),
LowerBoundVar(B) {}
ABounds(BoundsKind K, BoundsKey L) : ABounds(K, L, 0) {}

BoundsKind Kind;

protected:
ABounds(BoundsKind K) : Kind(K) {}
void addBoundsUsedKey(BoundsKey);
// Bounds key representing the length of the bounds from the base pointer of
// the range. The exact interpretation of this field varies by subclass.
BoundsKey LenVar;

// The base pointer representing the start of the range of the bounds. If this
// is not equal to 0, then this ABounds has a specific lower bound that should
// be used when emitting array pointer bounds. Otherwise, if it is 0, then the
// lower bound should implicitly be the pointer the bound is applied to.
BoundsKey LowerBoundVar;

// Get the variable name of the the given bounds key that corresponds
// to the given declaration.
static std::string getBoundsKeyStr(BoundsKey, AVarBoundsInfo *,
Expand All @@ -51,50 +60,69 @@ class ABounds {
public:
virtual ~ABounds() {}

virtual std::string mkString(AVarBoundsInfo *, clang::Decl *D = nullptr) = 0;
// Make a string representation of this array bound. If the array has a
// defined lower bound pointer that is not the same as the pointer for which
// the bound string is being generated (passed as parameter BK), then a range
// bound is generated using that lower bound. Otherwise, a standard count
// bound is generated.
std::string
mkString(AVarBoundsInfo *ABI, clang::Decl *D = nullptr, BoundsKey BK = 0);

// Make a string representation of this array bound always generating explicit
// lower bounds in range bounds expressions.
virtual std::string
mkStringWithLowerBound(AVarBoundsInfo *ABI, clang::Decl *D) = 0;

// Make a string representation of this array bound ignoring any lower bound
// information. A standard count bound is always generated.
virtual std::string
mkStringWithoutLowerBound(AVarBoundsInfo *ABI, clang::Decl *D) = 0;

virtual bool areSame(ABounds *, AVarBoundsInfo *) = 0;
virtual BoundsKey getBKey() = 0;
virtual ABounds *makeCopy(BoundsKey NK) = 0;

// Set that maintains all the bound keys that are used inin
// TODO: Is this still needed?
static std::set<BoundsKey> KeysUsedInBounds;
static bool isKeyUsedInBounds(BoundsKey ToCheck);
BoundsKey getLengthKey() const { return LenVar; }
BoundsKey getLowerBoundKey() const { return LowerBoundVar; }
void setLowerBoundKey(BoundsKey LB) { LowerBoundVar = LB; }

static ABounds *getBoundsInfo(AVarBoundsInfo *AVBInfo, BoundsExpr *BExpr,
const ASTContext &C);
};

class CountBound : public ABounds {
public:
CountBound(BoundsKey Var) : ABounds(CountBoundKind), CountVar(Var) {
addBoundsUsedKey(Var);
}
CountBound(BoundsKey L, BoundsKey B) : ABounds(CountBoundKind, L, B) {}
CountBound(BoundsKey L) : ABounds(CountBoundKind, L) {}

~CountBound() override {}
std::string
mkStringWithLowerBound(AVarBoundsInfo *ABI, clang::Decl *D) override;
std::string
mkStringWithoutLowerBound(AVarBoundsInfo *ABI, clang::Decl *D) override;

std::string mkString(AVarBoundsInfo *ABI, clang::Decl *D = nullptr) override;
bool areSame(ABounds *O, AVarBoundsInfo *ABI) override;
BoundsKey getBKey() override;

ABounds *makeCopy(BoundsKey NK) override;

static bool classof(const ABounds *S) {
return S->getKind() == CountBoundKind;
}

BoundsKey getCountVar() { return CountVar; }

protected:
BoundsKey CountVar;
};

class CountPlusOneBound : public CountBound {
public:
CountPlusOneBound(BoundsKey Var) : CountBound(Var) {
CountPlusOneBound(BoundsKey L, BoundsKey B) : CountBound(L, B) {
this->Kind = CountPlusOneBoundKind;
}

std::string mkString(AVarBoundsInfo *ABI, clang::Decl *D = nullptr) override;
CountPlusOneBound(BoundsKey L) : CountBound(L) {
this->Kind = CountPlusOneBoundKind;
}

std::string
mkStringWithLowerBound(AVarBoundsInfo *ABI, clang::Decl *D) override;
std::string
mkStringWithoutLowerBound(AVarBoundsInfo *ABI, clang::Decl *D) override;

bool areSame(ABounds *O, AVarBoundsInfo *ABI) override;

static bool classof(const ABounds *S) {
Expand All @@ -104,54 +132,20 @@ class CountPlusOneBound : public CountBound {

class ByteBound : public ABounds {
public:
ByteBound(BoundsKey Var) : ABounds(ByteBoundKind), ByteVar(Var) {
addBoundsUsedKey(Var);
}
ByteBound(BoundsKey L, BoundsKey B) : ABounds(ByteBoundKind, L, B) {}
ByteBound(BoundsKey L) : ABounds(ByteBoundKind, L) {}

~ByteBound() override {}
std::string
mkStringWithLowerBound(AVarBoundsInfo *ABI, clang::Decl *D) override;
std::string
mkStringWithoutLowerBound(AVarBoundsInfo *ABI, clang::Decl *D) override;

std::string mkString(AVarBoundsInfo *ABI, clang::Decl *D = nullptr) override;
bool areSame(ABounds *O, AVarBoundsInfo *ABI) override;
BoundsKey getBKey() override;
ABounds *makeCopy(BoundsKey NK) override;

static bool classof(const ABounds *S) {
return S->getKind() == ByteBoundKind;
}
BoundsKey getByteVar() { return ByteVar; }

private:
BoundsKey ByteVar;
};

class RangeBound : public ABounds {
public:
RangeBound(BoundsKey L, BoundsKey R) : ABounds(RangeBoundKind), LB(L), UB(R) {
addBoundsUsedKey(L);
addBoundsUsedKey(R);
}

~RangeBound() override {}

std::string mkString(AVarBoundsInfo *ABI, clang::Decl *D = nullptr) override;
bool areSame(ABounds *O, AVarBoundsInfo *ABI) override;

BoundsKey getBKey() override {
assert(false && "Not implemented.");
return 0;
}

ABounds *makeCopy(BoundsKey NK) override {
assert(false && "Not Implemented");
return nullptr;
}

static bool classof(const ABounds *S) {
return S->getKind() == RangeBoundKind;
}

private:
BoundsKey LB;
BoundsKey UB;
};
#endif // LLVM_CLANG_3C_ABOUNDS_H
101 changes: 91 additions & 10 deletions clang/include/clang/3C/AVarBoundsInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ class AvarBoundsInference {
// BoundsKey that failed the flow inference.
std::set<BoundsKey> BKsFailedFlowInference;

static ABounds *getPreferredBound(const BndsKindMap &BKindMap);
ABounds *getPreferredBound(BoundsKey BK);
};

// Class that maintains information about potential bounds for
Expand Down Expand Up @@ -181,7 +181,8 @@ class AVarBoundsInfo {
public:
AVarBoundsInfo()
: ProgVarGraph(this), CtxSensProgVarGraph(this),
RevCtxSensProgVarGraph(this), CSBKeyHandler(this) {
RevCtxSensProgVarGraph(this), CSBKeyHandler(this),
LowerBoundGraph(this) {
BCount = 1;
PVarInfo.clear();
InProgramArrPtrBoundsKeys.clear();
Expand Down Expand Up @@ -231,11 +232,9 @@ class AVarBoundsInfo {

// Add Assignments between variables. These methods will add edges between
// corresponding BoundsKeys
bool addAssignment(clang::Decl *L, clang::Decl *R);
bool addAssignment(clang::DeclRefExpr *L, clang::DeclRefExpr *R);
bool addAssignment(BoundsKey L, BoundsKey R);
bool handlePointerAssignment(clang::Stmt *St, clang::Expr *L, clang::Expr *R,
ASTContext *C, ConstraintResolver *CR);
bool handlePointerAssignment(clang::Expr *L, clang::Expr *R, ASTContext *C,
ConstraintResolver *CR);
bool handleAssignment(clang::Expr *L, const CVarSet &LCVars,
const std::set<BoundsKey> &CSLKeys, clang::Expr *R,
const CVarSet &RCVars,
Expand All @@ -252,11 +251,40 @@ class AVarBoundsInfo {
// for pointers that has pointer arithmetic performed on them.
void recordArithmeticOperation(clang::Expr *E, ConstraintResolver *CR);

// Check if the given bounds key has a pointer arithmetic done on it.
bool hasPointerArithmetic(BoundsKey BK);
// Check if the given bounds key will need to be duplicated during rewriting
// to generate a fresh lower bound. This happens when a pointer is not a valid
// lower bounds due to pointer arithmetic, and lower bounds inference fails to
// find a consistent lower bound among existing pointers in the source code.
bool needsFreshLowerBound(BoundsKey BK);
bool needsFreshLowerBound(ConstraintVariable *CV);

// Return true when a lower bound could be inferred for the array pointer
// corresponding to `BK`. This is the case either when `BK` was not
// invalidated as lower bound by pointer arithmetic meaning it is it's own
// lower bound, or when `BK` was invalidated, but a valid lower bound could be
// inferred.
bool hasLowerBound(BoundsKey BK);

// Record that a pointer cannot be rewritten to use range bounds. This might
// be due to 3C rewriting limitations (assignments appearing inside macros),
// or it might be a Checked C limitation (the current style of range bounds
// can't properly initialized on global variables without error).
void markIneligibleForFreshLowerBound(BoundsKey BK);

// Get the ProgramVar for the provided VarKey.
ProgramVar *getProgramVar(BoundsKey VK);
// This method can return `nullptr` if there is no corresponding ProgramVar.
// It's not obvious when a BoundsKey can be expected to have a ProgramVar, so
// callers should typically check for null.
ProgramVar *getProgramVar(BoundsKey VK) const;

// Get the Scope of the provided BoundsKey.
// This method returns nullptr if `getProgramVar(BK)` would return nullptr.
const ProgramVarScope *getProgramVarScope(BoundsKey BK) const;

// Return true when BoundsKey `To` can be accessed from the scope of `from`.
// Note that this returns false if either BoundsKey cannot be mapped to a
// ProgramVar (and therefore can't be mapped to a scope).
bool isInAccessibleScope(BoundsKey From, BoundsKey To);

// Propagate the array bounds information for all array ptrs.
void performFlowAnalysis(ProgramInfo *PI);
Expand Down Expand Up @@ -294,6 +322,8 @@ class AVarBoundsInfo {

void addConstantArrayBounds(ProgramInfo &I);

void inferLowerBounds(ProgramInfo *PI);

private:
friend class AvarBoundsInference;
friend class CtxSensitiveBoundsKeyHandler;
Expand All @@ -315,8 +345,16 @@ class AVarBoundsInfo {
// Set that contains BoundsKeys of variables which have invalid bounds.
std::set<BoundsKey> InvalidBounds;
// These are the bounds key of the pointers that has arithmetic operations
// performed on them.
// performed on them. These pointers cannot have the standard `count(n)`
// bounds and instead must use range bounds e.g., `bounds(p, p + n)`.
std::set<BoundsKey> ArrPointersWithArithmetic;

// Some pointers, however, cannot be automatically given range bounds. This
// includes global variables and structure fields. If a pointer is in both the
// above pointer arithmetic set and this set, then it cannot be assigned any
// bound.
std::set<BoundsKey> IneligibleForRangeBounds;

// Set of BoundsKeys that correspond to pointers.
std::set<BoundsKey> PointerBoundsKey;
// Set of BoundsKey that correspond to array pointers.
Expand Down Expand Up @@ -356,6 +394,24 @@ class AVarBoundsInfo {
// Context-sensitive bounds key handler
CtxSensitiveBoundsKeyHandler CSBKeyHandler;

AVarGraph LowerBoundGraph;
const BoundsKey InvalidLowerBoundKey = 0;

// BoundsKeys that that cannot be used as a lower bound. These are used in an
// update such as `a = a + 1`, or are transitively assigned from such a
// pointer.
std::set<BoundsKey> InvalidLowerBounds;

// Mapping from pointers to their inferred lower bounds. A pointer maps to
// itself if it can use a simple count bound. Missing pointers have no valid
// lower bound, so no length should be inferred during bounds inference.
std::map<BoundsKey, BoundsKey> LowerBounds;

// Some variables have to valid lower bound in the original source code, but
// we are able to insert a temporary pointer variable to be the lower bound.
// Keep track of these for special handling during rewriting.
std::set<BoundsKey> NeedFreshLowerBounds;

// BoundsKey helper function: These functions help in getting bounds key from
// various artifacts.
bool hasVarKey(PersistentSourceLoc &PSL);
Expand Down Expand Up @@ -389,6 +445,31 @@ class AVarBoundsInfo {
void insertParamKey(ParamDeclType ParamDecl, BoundsKey NK);

void dumpBounds();

// Compute which array pointers are not valid lower bounds. This includes any
// pointers directly updated in pointer arithmetic expression, as well as any
// pointers transitively assigned to from these pointers. This is computed
// using essentially the same algorithm as is used for solving the checked
// type constraint graph.
void computeInvalidLowerBounds();

// During lower bound inference it may be necessary to generate temporary
// pointers to act as lower bounds for arrays that otherwise don't have a
// consistent lower bound. This method takes a bounds key for an array pointer
// and returns a fresh bounds key that can be used as the lower bound for the
// array bounds of that pointer.
BoundsKey getFreshLowerBound(BoundsKey Arr);

// Return true if the scope of the BoundsKey is one in which lower bounds
// can be inserted. BoundsKeys in context sensitive scope should not get lower
// bounds. The corresponding non-context-sensitive BoundsKey should instead.
bool scopeCanHaveLowerBound(BoundsKey BK);

// Check if a fresh lower bound can be be inserted by 3C for the pointer
// corresponding to the bounds key. When a pointer needs a fresh lower bound,
// it is possible that 3C will not support inserting the new declaration.
// No array bounds can be inferred for such pointers.
bool isEligibleForFreshLowerBound(BoundsKey BK);
};

#endif // LLVM_CLANG_3C_AVARBOUNDSINFO_H
Loading