Skip to content

Commit 3446685

Browse files
Address copilot feedback
1 parent acc7ee7 commit 3446685

File tree

5 files changed

+40
-40
lines changed

5 files changed

+40
-40
lines changed

cpp/common/src/codingstandards/cpp/dominance/SuccessorUnless.qll renamed to cpp/common/src/codingstandards/cpp/dominance/FeasiblePath.qll

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import cpp
22

33
/**
4-
* The configuration signature for the SuccessorUnless module.
4+
* The configuration signature for the FeasiblePath module.
55
*
66
* Typically, the `Node` type should be a `ControlFlowNode`, but it can be overridden to enable
77
* other kinds of graphs.
88
*/
9-
signature module SuccessorUnlessConfigSig {
9+
signature module FeasiblePathConfigSig {
1010
/** The state type used to carry context through the CFG exploration. */
1111
class State;
1212

@@ -17,14 +17,14 @@ signature module SuccessorUnlessConfigSig {
1717

1818
predicate isStart(State state, Node node);
1919

20-
predicate isUnless(State state, Node node);
20+
predicate isExcludedPath(State state, Node node);
2121

2222
predicate isEnd(State state, Node node);
2323
}
2424

2525
/**
26-
* A module that finds successor of a node -- unless there is an intermediate node that satisfies
27-
* a given condition.
26+
* A module that finds whether a feasible path exists between two control flow nodes, and
27+
* additionally support configuration that should not be traversed.
2828
*
2929
* Also accepts a state parameter to allow a context to flow through the CFG.
3030
*
@@ -33,21 +33,21 @@ signature module SuccessorUnlessConfigSig {
3333
* Implement the module `ConfigSig`, with some context type:
3434
*
3535
* ```ql
36-
* module MyConfig implements SuccessorUnless<SomeContext>::ConfigSig {
36+
* module MyConfig implements FeasiblePathConfigSig {
3737
* predicate isStart(SomeContext state, ControlFlowNode node) {
3838
* node = state.someStartCondition()
3939
* }
4040
*
41-
* predicate isUnless(SomeContext state, ControlFlowNode node) {
42-
* node = state.someUnlessCondition()
41+
* predicate isExcludedPath(SomeContext state, ControlFlowNode node) {
42+
* node = state.someExcludedPathCondition()
4343
* }
4444
*
4545
* predicate isEnd(SomeContext state, ControlFlowNode node) {
4646
* node = state.someEndCondition()
4747
* }
4848
* }
4949
*
50-
* import SuccessorUnless<SomeContext>::Make<MyConfig> as Successor
50+
* import FeasiblePath<MyConfig> as MyFeasiblePath
5151
* ```
5252
*
5353
* ## Rationale
@@ -62,7 +62,7 @@ signature module SuccessorUnlessConfigSig {
6262
* not exists(ControlFlowNode mid |
6363
* mid = start.getASuccessor+() and
6464
* end = mid.getASuccessor*() and
65-
* isUnless(mid)
65+
* isExcludedPath(mid)
6666
* )
6767
* }
6868
* ```
@@ -73,19 +73,19 @@ signature module SuccessorUnlessConfigSig {
7373
* while (cond) {
7474
* start();
7575
* end();
76-
* unless();
76+
* excluded();
7777
* }
7878
* ```
7979
*
80-
* In the above code, `unless()` is a successor of `start()`, and `end()` is also a successor of
81-
* `unless()` (via the loop back edge). However, there is no path from `start()` to `end()` that
82-
* does not pass through `unless()`.
80+
* In the above code, `excluded()` is a successor of `start()`, and `end()` is also a successor of
81+
* `excluded()` (via the loop back edge). However, there is no path from `start()` to `end()` that
82+
* does not pass through `excluded()`.
8383
*
8484
* This module will correctly handle this case. Forward exploration through the graph will stop
85-
* at the `unless()` nodes, such that only paths from `start()` to `end()` that do not pass through
86-
* `unless()` nodes will be found.
85+
* at the `excluded()` nodes, such that only paths from `start()` to `end()` that do not pass
86+
* through `excluded()` nodes will be found.
8787
*/
88-
module SuccessorUnless<SuccessorUnlessConfigSig Config> {
88+
module FeasiblePath<FeasiblePathConfigSig Config> {
8989
predicate isSuccessor(Config::State state, Config::Node start, Config::Node end) {
9090
isMid(state, start, end) and
9191
Config::isEnd(state, end)
@@ -100,7 +100,7 @@ module SuccessorUnless<SuccessorUnlessConfigSig Config> {
100100
exists(Config::Node prevMid |
101101
isMid(state, start, prevMid) and
102102
mid = prevMid.getASuccessor() and
103-
not Config::isUnless(state, mid) and
103+
not Config::isExcludedPath(state, mid) and
104104
not Config::isEnd(state, prevMid)
105105
)
106106
)

cpp/common/src/codingstandards/cpp/standardlibrary/STLContainers.qll

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,14 @@ class BoundedIndex extends TBoundedIndex {
4141
float getUpperBound() { result = ub }
4242

4343
predicate mayOverlap(BoundedIndex other) {
44-
// The lower bound is contained by the other index range.
45-
lb <= other.getUpperBound() and lb >= other.getLowerBound()
46-
or
47-
// or the upper bound is contained by the other index range.
48-
ub <= other.getUpperBound() and ub >= other.getLowerBound()
44+
// It's easier to think about bounds that cannot overlap, and then negate that.
45+
not (
46+
// If our lower bound is greater than the other's upper bound, they can't overlap.
47+
lb > other.getUpperBound()
48+
or
49+
// If our upper bound is less than the other's lower bound, they can't overlap.
50+
ub < other.getLowerBound()
51+
)
4952
}
5053

5154
predicate forIndexExpr(Expr expr) {
@@ -120,7 +123,7 @@ class STLContainerUnknownElementModification extends FunctionCall {
120123
"clear", "push_back", "pop_back", "pop_front", "insert", "emplace", "emplace_back",
121124
"emplace_front", "emplace_hint", "erase", "resize", "assign", "assign_range", "swap",
122125
"push", "pop", "fill", "extract", "merge", "insert_or_assign", "try_emplace",
123-
"operaator+=", "replace", "replace_with_range", "copy"
126+
"operator+=", "replace", "replace_with_range", "copy"
124127
])
125128
}
126129
}
@@ -164,7 +167,7 @@ class STLContainer extends Class {
164167
STLContainer() {
165168
getNamespace() instanceof StdNS and
166169
// TODO: add to change log that we added std::array
167-
getSimpleName() in ["vector", "deque", "array", "valarray",] and
170+
getSimpleName() in ["vector", "deque", "array", "valarray"] and
168171
containerKind = TIndexableContainer()
169172
or
170173
getSimpleName() in [
@@ -175,7 +178,8 @@ class STLContainer extends Class {
175178
getNamespace() instanceof StdNS and
176179
getSimpleName() in [
177180
"multiset", "map", "multimap", "unordered_multiset", "unordered_map", "unordered_multimap"
178-
]
181+
] and
182+
containerKind = TAssociativeContainer()
179183
or
180184
// TODO: This intentionally doesn't check namespace::std, what are the implications?
181185
// TODO: add support for `std::string_view`?

cpp/common/test/includes/standard-library/utility.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ template <class T> typename add_rvalue_reference<T>::type declval() noexcept;
1212
template <class T> void swap(T &a, T &b) noexcept;
1313

1414
template <class T1, class T2> struct pair {
15-
T1 first;
16-
T2 second;
17-
pair(const T1& a, const T2& b);
15+
T1 first;
16+
T2 second;
17+
pair(const T1 &a, const T2 &b);
1818
};
1919

2020
} // namespace std
2121

22-
#endif _GHLIBCPP_UTILITY
22+
#endif // _GHLIBCPP_UTILITY

cpp/misra/src/rules/RULE-0-1-1/UnnecessaryWriteToLocalObject.ql

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,12 @@
1717

1818
import cpp
1919
import semmle.code.cpp.dataflow.DataFlow
20-
import semmle.code.cpp.dataflow.internal.TaintTrackingUtil as Taint
2120
import codingstandards.cpp.misra
2221
import codingstandards.cpp.lifetimes.CppObjects
2322
import codingstandards.cpp.lifetimes.CppSubObjects
24-
import codingstandards.cpp.dominance.BehavioralSet
25-
import codingstandards.cpp.dominance.SuccessorUnless
23+
import codingstandards.cpp.dominance.FeasiblePath
2624
import codingstandards.cpp.types.TrivialType
2725
import codingstandards.cpp.standardlibrary.STLContainers
28-
import semmle.code.cpp.ir.dataflow.internal.SsaInternalsCommon as Ssa
29-
import semmle.code.cpp.dataflow.new.DataFlow as NewDataFlow
3026

3127
/**
3228
* A type that is relevant for analysis by this rule.
@@ -384,7 +380,7 @@ class CrementAwareNode extends TCrementAwareNode {
384380
or
385381
this = TPreCrementNode(_) and result = "pre crement node"
386382
or
387-
this = TPostCrementNode(_) and result = "pre crement node"
383+
this = TPostCrementNode(_) and result = "post crement node"
388384
}
389385

390386
Location getLocation() { result = getControlFlowNode().getLocation() }
@@ -577,7 +573,7 @@ predicate isExcludedWrite(RelevantControlFlowNode node, RelevantObject obj) {
577573
node.getAPredecessor+() = [obj.getASubobjectAddressExpr(), obj.getASubobjectTakenAsReference()]
578574
}
579575

580-
module WriteWithReadConfig implements SuccessorUnlessConfigSig {
576+
module WriteWithReadConfig implements FeasiblePathConfigSig {
581577
class State = TrackedObject;
582578

583579
class Node = CrementAwareNode;
@@ -589,7 +585,7 @@ module WriteWithReadConfig implements SuccessorUnlessConfigSig {
589585
)
590586
}
591587

592-
predicate isUnless(TrackedObject state, CrementAwareNode node) {
588+
predicate isExcludedPath(TrackedObject state, CrementAwareNode node) {
593589
exists(TrackedObject rewritten |
594590
rewritten = state.getParent*() and
595591
isWrite(_, rewritten, node) and
@@ -609,7 +605,7 @@ module WriteWithReadConfig implements SuccessorUnlessConfigSig {
609605
}
610606
}
611607

612-
predicate isWriteWithRead = SuccessorUnless<WriteWithReadConfig>::isSuccessor/3;
608+
predicate isWriteWithRead = FeasiblePath<WriteWithReadConfig>::isSuccessor/3;
613609

614610
predicate isWriteWithObserve(RelevantObject obj, CrementAwareNode node) {
615611
isWrite(obj, _, node) and

cpp/misra/test/rules/RULE-0-1-1/test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ void f14() {
247247
// Test that dereferencing can observe the pointer base, but only when
248248
// assigned to.
249249
//
250-
// Note that the cases involve assigment to dereferenced pointers could be
250+
// Note that the cases involve assignment to dereferenced pointers could be
251251
// fully modeled to count as an assignment to the pointee object, but we don't
252252
// currently do that advanced of an analysis.
253253
int l0[] = {0, 1, 2}; // COMPLIANT

0 commit comments

Comments
 (0)