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

Available facts analysis #1152

Merged
merged 35 commits into from
Aug 26, 2021

Conversation

arbipher
Copy link

I have fixed the issues in our previous code review.

Mandeep Singh Grang and others added 29 commits August 5, 2021 10:51
We introduce a 2-bit field called CheckedScopeSpecifier in the Stmt class.
During parsing when a compound statement is created we iterate the elements
(statements) of the compound statement and set the checked scope specifier for
each element to the checked scope specifier of the compound statement.

We can get the checked scope specifier for a statement by calling the
getCheckedScopeSpecifier method on the statement.
* Updated the instructions for upgrade of LLVM/Clang.
Also added a new file LLVM-Upgrade-Notes.md to track important
information related to upgrades.

* Fixed typos.

* Addressed review comments.

* Fixed an inadvertent deletion.

* Addressed review comments.

* Incorporated review comments.

* Fixed minor typos.

* Fixed typos.
Add InferredFact and adjust WhereClauseFact to be a subclass of AbstractFact
`IsSwitchCaseBlock`: use `dyn_cast_or_null` to cover the null pointer
case.

`ConditionOnEdge`: do not test if there is no edge between
pred to curr since it will only be called if there is an edge.

`GetModifiedVars`: use `TranspareCasts` to bypass some casting.
The feature to deal with membership access and the array indexing is
still TODO.
It also fixes a bug to visit dead blocks.
@arbipher arbipher requested a review from mgrang August 11, 2021 21:48
Mandeep Singh Grang added 2 commits August 12, 2021 11:24
The community has introduced a new annotation called "contains-errors" on AST
nodes that contain semantic errors. As a result, after the upgrade of Checked C
sources to LLVM 12 we need to check if an expr contains errors before operating
on the expr. One such place is in InverseUtil::IsInvertible where we need to
check if the input modifying expr contains errors.

* Added containsErrors checks to InverUtil::Inverse
Support bounds widening in presence of complex conditionals like:
  "if (*p != 0)", "if ((c = *p) == 'a')", etc.
SemaRef(SemaRef), Cfg(Cfg), Ctx(Ctx), Lex(Lex), OS(llvm::outs()),
FactComparisionMap(FactComparisionMapTy()) {}

// Pretty print a expr
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested comment change: Pretty print a expr => Pretty print an expression.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you don't mind my snooping on PRs in your repository unrelated to 3C: The GitHub "suggested change" feature (the "±" icon in the toolbar when writing a review comment) might provide a more streamlined process for changes like this. (GitHub's documentation is in item 6 here.) An example of what it looks like:

Suggested change
// Pretty print a expr
// Pretty print an expression.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you all. I will reword this and I learn the new GitHub primitive!

// Pretty print a expr
void Print(const Expr *) const;

// Pretty print a Stmt
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested comment change: Pretty print a Stmt => Pretty print a statement.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

// Pretty print a Stmt
void Print(const Stmt *) const;

// Pretty print an abstract fact
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested comment change Pretty print an abstract fact => Pretty print an abstract fact.

// Pretty print an abstract fact
void DumpAbstractFact(const AbstractFact *Fact) const;

// Pretty print a list of abstract facts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested comment change: Pretty print a list of abstract facts => Pretty print a list of abstract facts.

// Pretty print a set of variables.
void PrintKillVarSet(KillVarSetTy VarSet) const;

// Determine if the edge from PredBlock to CurrBlock is a fallthrough.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: add a space before // Determine if...

// Determine if a variable is used in a fact.
bool IsVarInFact(const AbstractFact *Fact, const VarDecl *Var) const;

// Determine if two facts equal. First check if the comparision is check before,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: two facts equal => two facts are equal, comparision => comparison, is check before => is checked before

for (auto *Fact : WC->getFacts()) {
if (auto *BF = dyn_cast<BoundsDeclFact>(Fact)) {
// ignore the result value here,
// just take the side-effect to save the normalzied bounds
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

normalzied => normalized

}
}

// Initiazlize Gen and Out of a block
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initiazlize => Initialize

using OrderedBlocksTy = std::vector<const CFGBlock *>;

// AvailableFactsKillKind denotes two kinds of kill variables.
// KillExpr denotes a variable to kill a EqualityOpFact or a InferredFact
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe these could be rephrased as:

  // KillExpr denotes a variable that kills an EqualityOpFact or an InferredFact
  // KillBounds denotes a variable that kills a BoundsDeclFact.

// AvailableFactsKillKind denotes two kinds of kill variables.
// KillExpr denotes a variable to kill a EqualityOpFact or a InferredFact
// KillBounds denotes a variable to kill a BoundsDeclFact.
enum AvailableFactsKillKind {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to declare this as an enum class to possibly avoid future conflicts of KillExpr and KillBounds with variables of the same name.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see!

using StmtKillVarSetTy = llvm::DenseMap<const Stmt *, KillVarSetTy>;

// FactComparisionMapTy denotes the comparision result of two facts.
using FactComparision = std::pair<const AbstractFact *, const AbstractFact *>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typos in comment: FactComparisionMapTy denotes the comparision result of two facts. --> FactComparisonMapTy denotes the comparison result of two facts.

Typo in variable name: FactComparision --> FactComparison

bool IsSwitchCaseBlock(const CFGBlock *PredBlock,
const CFGBlock *CurrBlock) const;

// Determine the boolean state of an edge when the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment seems incomplete.


const CFGBlock *Block;

// Block-wise
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Period (.) needed after each comment.

void DumpAvailableFacts(FunctionDecl *FD);

private:
void AddSuccsToWorkList(const CFGBlock *CurrBlock, WorkListTy &WorkList);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments needed for the function.

void ComputeStmtGenKillSets(ElevatedCFGBlock *EB, const Stmt *CurrStmt,
StmtSetTy NestedStmts);

void CollectFactsInDecl(AbstractFactListTy &Gen,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments needed for function.

// This file implements a dataflow analysis for available facts analysis.
//===---------------------------------------------------------------------===//

#include "clang/AST/ExprUtils.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please order the includes alphabetically.

EB->Kill = EB->StmtKill[CurrStmt];
EB->GenAllSucc = EB->StmtGen[CurrStmt];
} else {
EB->Kill = AFUtil.Union(EB->Kill, EB->StmtKill[CurrStmt]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be costly (in terms of space) to persist the accumulated Kill and StmtGen sets. Is it possible to locally compute them when needed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh you are right. The accumulated Kill is one per block which may not be large, but definitely StmtGem is costly. That is for debugging originally.

kkjeer and others added 3 commits August 20, 2021 15:05
… 1 in TargetSrcEquality (#1162)

* Add AllowTempEquality parameter to RecordEqualityWithTarget

* Use a ModifiedSameValue variable to determine the return value for UpdateSameValueAfterAssignment

* Rename ModifiedSameValue to RemovedAnyExprs and clean up comments
…nces (#1163)

* In CheckAddressOfOperand, add case for address-of array subscripts to C99-specific logic

* Move address-of array subscript check after other checks such as taking the address of an lvalue

* Adjust expected AST output to account for different types of address-of array subscripts

* Restore deleted comment about checking for array subscript expressions

* Add comment explaining the placement of the address-of array subscript logic

* Put &e1[e2] typing rules under a Checked C flag
@arbipher
Copy link
Author

I have fixed the issues you mentioned (sorry for so many typos).
When developing the code for SMT prover, I made some changes to the analysis and later I will split the related part to this PR.

@arbipher arbipher changed the title Available facts analysis wip Available facts analysis Aug 25, 2021
@arbipher arbipher force-pushed the available-facts-analysis-wip branch from 5bae193 to 4f8aa5b Compare August 25, 2021 17:41
Copy link
Contributor

@sulekhark sulekhark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thank you very much for this work!

@arbipher arbipher merged commit a167f43 into internship-2021-checkins Aug 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants