Skip to content

Commit

Permalink
M0-1-2: Remove reference to GuardCondition
Browse files Browse the repository at this point in the history
In the upgrade to 2.16.6 GuardCondition has been modified to use
the IR instead of the AST mode it used before. One of the
consequences of this change is that GuardConditions no longer exist
for uninstantiated templates (because the IR does not apply for
uninstantiated templates).

Instead of using GuardCondition we can use the same logic for
deducing infeasible paths for uninstantiated templates as for non
template code. This avoids the dependency on GuardCondition, and
provides consistency with the rest of the query, while shortening
the query.
  • Loading branch information
lcartey committed Oct 9, 2024
1 parent 896242c commit d0540e4
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 177 deletions.
4 changes: 3 additions & 1 deletion change_notes/2024-10-08-upgrade-to-2.16.6.md
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
- Updated the CodeQL version to `2.16.6`.
- Updated the CodeQL version to `2.16.6`.
- `M0-1-2` - `InfeasiblePath.ql`:
- This query may now report additional results within templates where a relational operation is performed which has a constant value given the specified arguments.
185 changes: 9 additions & 176 deletions cpp/autosar/src/rules/M0-1-2/InfeasiblePath.ql
Original file line number Diff line number Diff line change
Expand Up @@ -151,186 +151,19 @@ predicate isConstantRelationalOperation(
* Holds if the `ConditionalNode` has an infeasible `path` for the reason given in `explanation`.
*/
predicate hasInfeasiblePath(ConditionalControlFlowNode node, string message) {
//deal with the infeasible in all uninstantiated templates separately
node.isFromUninstantiatedTemplate(_) and
node instanceof ConditionControllingUnreachable and
message = "The path is unreachable in a template."
or
exists(boolean infeasiblePath, string explanation |
(
not node.isFromUninstantiatedTemplate(_) and
not node.isFromTemplateInstantiation(_) and
message = "The " + infeasiblePath + " path is infeasible because " + explanation + "."
) and
(
hasCFGDeducedInfeasiblePath(node, infeasiblePath, explanation) and
not isConstantRelationalOperation(node, infeasiblePath, _)
or
isConstantRelationalOperation(node, infeasiblePath, explanation)
)
not node.isFromTemplateInstantiation(_) and
if node.isFromUninstantiatedTemplate(_)
then message = "The path is unreachable in a template."
else message = "The " + infeasiblePath + " path is infeasible because " + explanation + "."
|
hasCFGDeducedInfeasiblePath(node, infeasiblePath, explanation) and
not isConstantRelationalOperation(node, infeasiblePath, _)
or
isConstantRelationalOperation(node, infeasiblePath, explanation)
)
}

/**
* A newtype representing "unreachable" blocks in the program. We use a newtype here to avoid
* reporting the same block in multiple `Function` instances created from one function in a template.
*/
private newtype TUnreachableBasicBlock =
TUnreachableNonTemplateBlock(BasicBlock bb) {
bb.isUnreachable() and
// Exclude anything template related from this case
not bb.getEnclosingFunction().isFromTemplateInstantiation(_) and
not bb.getEnclosingFunction().isFromUninstantiatedTemplate(_) and
// Exclude compiler generated basic blocks
not isCompilerGenerated(bb)
} or
/**
* A `BasicBlock` that occurs in at least one `Function` instance for a template. `BasicBlock`s
* are matched up across templates by location.
*/
TUnreachableTemplateBlock(
string filepath, int startline, int startcolumn, int endline, int endcolumn,
GuardCondition uninstantiatedGuardCondition
) {
exists(BasicBlock bb |
// BasicBlock occurs in this location
bb.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
// And is contained in the `uninstantiatedFunction` only
// not from anything constructed from it
// because we want infeasible paths independent of parameters
exists(Function enclosing | enclosing = bb.getEnclosingFunction() |
//guard is in the template function
(
enclosing.getBlock().getAChild*() = uninstantiatedGuardCondition and
//function template
enclosing.isFromUninstantiatedTemplate(_) and
uninstantiatedGuardCondition.isFromUninstantiatedTemplate(_) and
//true condition is unreachable: basic block starts on same line as guard
(
not exists(uninstantiatedGuardCondition.getATrueSuccessor()) and
bb.hasLocationInfo(filepath, uninstantiatedGuardCondition.getLocation().getStartLine(),
startcolumn, endline, endcolumn)
or
//false condition is unreachable: false basic block starts on one line after its true basic block
not exists(uninstantiatedGuardCondition.getAFalseSuccessor()) and
bb.hasLocationInfo(filepath,
uninstantiatedGuardCondition.getATrueSuccessor().getLocation().getEndLine() + 1,
startcolumn, endline, endcolumn)
)
)
) and
// And is unreachable
bb.isUnreachable() and
// //Exclude compiler generated control flow nodes
not isCompilerGenerated(bb) and
//Exclude nodes affected by macros, because our find-the-same-basic-block-by-location doesn't
//work in that case
not bb.(ControlFlowNode).isAffectedByMacro()
)
}

/**
* An unreachable basic block.
*/
class UnreachableBasicBlock extends TUnreachableBasicBlock {
/** Gets a `BasicBlock` which is represented by this set of unreachable basic blocks. */
BasicBlock getABasicBlock() { none() }

/** Gets a `GuardCondition` instance which we treat as the original GuardCondition. */
GuardCondition getGuardCondition() { none() }

predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}

string toString() { result = "default" }
}

/**
* A non-templated unreachable basic block.
*/
class UnreachableNonTemplateBlock extends UnreachableBasicBlock, TUnreachableNonTemplateBlock {
BasicBlock getBasicBlock() { this = TUnreachableNonTemplateBlock(result) }

override BasicBlock getABasicBlock() { result = getBasicBlock() }

override GuardCondition getGuardCondition() { result.controls(getBasicBlock(), true) }

override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
getBasicBlock().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}

override string toString() { result = getBasicBlock().toString() }
}

/**
* A templated unreachable basic block.
*/
class UnreachableTemplateBlock extends UnreachableBasicBlock, TUnreachableTemplateBlock {
override BasicBlock getABasicBlock() {
exists(
string filepath, int startline, int startcolumn, int endline, int endcolumn,
GuardCondition uninstantiatedGuardCondition
|
this =
TUnreachableTemplateBlock(filepath, startline, startcolumn, endline, endcolumn,
uninstantiatedGuardCondition) and
result.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
exists(Function enclosing |
//guard is in the template function
(
enclosing.getBlock().getAChild*() = uninstantiatedGuardCondition and
//function template
enclosing.isFromUninstantiatedTemplate(_) and
uninstantiatedGuardCondition.isFromUninstantiatedTemplate(_) and
//true condition is unreachable: basic block starts on same line as guard
(
not exists(uninstantiatedGuardCondition.getATrueSuccessor()) and
this.hasLocationInfo(filepath,
uninstantiatedGuardCondition.getLocation().getStartLine(), startcolumn, endline,
endcolumn)
or
//false condition is unreachable: false basic block starts on one line after its true basic block
not exists(uninstantiatedGuardCondition.getAFalseSuccessor()) and
this.hasLocationInfo(filepath,
uninstantiatedGuardCondition.getATrueSuccessor().getLocation().getEndLine() + 1,
startcolumn, endline, endcolumn)
)
)
)
|
result.isUnreachable() and
// Exclude compiler generated control flow nodes
not isCompilerGenerated(result) and
// Exclude nodes affected by macros, because our find-the-same-basic-block-by-location doesn't
// work in that case
not result.(ControlFlowNode).isAffectedByMacro()
)
}

override GuardCondition getGuardCondition() {
this = TUnreachableTemplateBlock(_, _, _, _, _, result)
}

override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this = TUnreachableTemplateBlock(filepath, startline, startcolumn, endline, endcolumn, _)
}

override string toString() { result = getABasicBlock().toString() }
}

class ConditionControllingUnreachable extends GuardCondition {
ConditionControllingUnreachable() {
exists(UnreachableTemplateBlock b | this = b.getGuardCondition())
}
}

from ConditionalControlFlowNode cond, string explanation
where
not isExcluded(cond, DeadCodePackage::infeasiblePathQuery()) and
Expand Down

0 comments on commit d0540e4

Please sign in to comment.