Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3340e79

Browse files
authored
Merge pull request #371 from ian-semmle/av85
C++: Fix AV Rule 85
2 parents 3e17196 + 94347ae commit 3340e79

3 files changed

Lines changed: 56 additions & 39 deletions

File tree

cpp/ql/src/jsf/4.10 Classes/AV Rule 85.ql

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,50 @@ predicate oppositeOperators(string op1, string op2) {
1919
/* this match is very syntactic: we simply check that op1 is defined as
2020
!op2(_, _) */
2121
predicate implementedAsNegationOf(Operator op1, Operator op2) {
22-
exists(Block b, ReturnStmt r, NotExpr n, FunctionCall c |
22+
exists(Block b, ReturnStmt r, NotExpr n, Expr o |
2323
b = op1.getBlock() and
2424
b.getNumStmt() = 1 and
2525
r = b.getStmt(0) and
2626
n = r.getExpr() and
27-
c = n.getOperand() and
28-
c.getTarget() = op2)
27+
o = n.getOperand() and
28+
(
29+
o instanceof LTExpr and op2.hasName("operator<") or
30+
o instanceof LEExpr and op2.hasName("operator<=") or
31+
o instanceof GTExpr and op2.hasName("operator>") or
32+
o instanceof GEExpr and op2.hasName("operator>=") or
33+
o instanceof EQExpr and op2.hasName("operator==") or
34+
o instanceof NEExpr and op2.hasName("operator!=") or
35+
o.(FunctionCall).getTarget() = op2
36+
)
37+
)
38+
}
39+
40+
predicate classIsCheckableFor(Class c, string op) {
41+
oppositeOperators(op, _) and
42+
// We check the template, not its instantiations
43+
not c instanceof ClassTemplateInstantiation and
44+
// Member functions of templates are not necessarily instantiated, so
45+
// if the function we want to check exists, then make sure that its
46+
// body also exists
47+
((c instanceof TemplateClass)
48+
implies
49+
forall(Function f | f = c.getAMember() and f.hasName(op)
50+
| exists(f.getEntryPoint())))
2951
}
3052

3153
from Class c, string op, string opp, Operator rator
3254
where c.fromSource() and
3355
oppositeOperators(op, opp) and
56+
classIsCheckableFor(c, op) and
57+
classIsCheckableFor(c, opp) and
3458
rator = c.getAMember() and
3559
rator.hasName(op) and
36-
not exists(Operator oprator | oprator = c.getAMember() and
37-
oprator.hasName(opp) and
38-
( implementedAsNegationOf(rator, oprator)
39-
or implementedAsNegationOf(oprator, rator)))
60+
forex(Operator aRator |
61+
aRator = c.getAMember() and aRator.hasName(op) |
62+
not exists(Operator oprator |
63+
oprator = c.getAMember() and
64+
oprator.hasName(opp) and
65+
( implementedAsNegationOf(aRator, oprator)
66+
or implementedAsNegationOf(oprator, aRator))))
4067
select c, "When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator " + op +
4168
" is declared on line " + rator.getLocation().getStartLine().toString() + ", but it is not defined in terms of its opposite operator " + opp + "."

cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 85/AV Rule 85.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,25 @@ void f9(void) {
124124
b = myClass9 >= myClass9;
125125
}
126126

127+
template <typename T>
128+
class MyClass10 {
129+
public:
130+
int i;
131+
template <typename U>
132+
bool operator< (const MyClass10<U> &rhs){ return i < rhs.i; }
133+
template <typename U>
134+
bool operator>= (const MyClass10<U> &rhs){ return !(*this < rhs); }
135+
// GOOD
136+
template <typename U>
137+
bool operator> (const MyClass10<U> &rhs){ return i < rhs.i; }
138+
template <typename U>
139+
bool operator<= (const MyClass10<U> &rhs){ return i >= rhs.i; }
140+
// BAD: neither operator defined in terms of the other
141+
};
142+
void f10(void) {
143+
bool b;
144+
MyClass10<int> myClass10;
145+
b = myClass10 < myClass10;
146+
b = myClass10 > myClass10;
147+
}
148+

cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 85/AV Rule 85.expected

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,7 @@
33
| AV Rule 85.cpp:9:7:9:14 | MyClass2 | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator>= is declared on line 13, but it is not defined in terms of its opposite operator operator<. |
44
| AV Rule 85.cpp:25:7:25:14 | MyClass4 | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator<= is declared on line 32, but it is not defined in terms of its opposite operator operator>. |
55
| AV Rule 85.cpp:25:7:25:14 | MyClass4 | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator> is declared on line 31, but it is not defined in terms of its opposite operator operator<=. |
6-
| AV Rule 85.cpp:37:7:37:14 | MyClass5<T> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator< is declared on line 40, but it is not defined in terms of its opposite operator operator>=. |
7-
| AV Rule 85.cpp:37:7:37:14 | MyClass5<T> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator<= is declared on line 44, but it is not defined in terms of its opposite operator operator>. |
8-
| AV Rule 85.cpp:37:7:37:14 | MyClass5<T> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator> is declared on line 43, but it is not defined in terms of its opposite operator operator<=. |
9-
| AV Rule 85.cpp:37:7:37:14 | MyClass5<T> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator>= is declared on line 41, but it is not defined in terms of its opposite operator operator<. |
10-
| AV Rule 85.cpp:49:7:49:14 | MyClass6<T> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator< is declared on line 52, but it is not defined in terms of its opposite operator operator>=. |
11-
| AV Rule 85.cpp:49:7:49:14 | MyClass6<T> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator<= is declared on line 56, but it is not defined in terms of its opposite operator operator>. |
12-
| AV Rule 85.cpp:49:7:49:14 | MyClass6<T> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator> is declared on line 55, but it is not defined in terms of its opposite operator operator<=. |
13-
| AV Rule 85.cpp:49:7:49:14 | MyClass6<T> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator>= is declared on line 53, but it is not defined in terms of its opposite operator operator<. |
14-
| AV Rule 85.cpp:62:7:62:14 | MyClass7<T> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator< is declared on line 66, but it is not defined in terms of its opposite operator operator>=. |
15-
| AV Rule 85.cpp:62:7:62:14 | MyClass7<T> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator<= is declared on line 73, but it is not defined in terms of its opposite operator operator>. |
16-
| AV Rule 85.cpp:62:7:62:14 | MyClass7<T> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator> is declared on line 71, but it is not defined in terms of its opposite operator operator<=. |
17-
| AV Rule 85.cpp:62:7:62:14 | MyClass7<T> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator>= is declared on line 68, but it is not defined in terms of its opposite operator operator<. |
18-
| AV Rule 85.cpp:62:7:62:14 | MyClass7<int> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator< is declared on line 66, but it is not defined in terms of its opposite operator operator>=. |
19-
| AV Rule 85.cpp:62:7:62:14 | MyClass7<int> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator<= is declared on line 73, but it is not defined in terms of its opposite operator operator>. |
20-
| AV Rule 85.cpp:62:7:62:14 | MyClass7<int> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator> is declared on line 71, but it is not defined in terms of its opposite operator operator<=. |
21-
| AV Rule 85.cpp:62:7:62:14 | MyClass7<int> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator>= is declared on line 68, but it is not defined in terms of its opposite operator operator<. |
22-
| AV Rule 85.cpp:79:7:79:14 | MyClass8<T> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator< is declared on line 83, but it is not defined in terms of its opposite operator operator>=. |
236
| AV Rule 85.cpp:79:7:79:14 | MyClass8<T> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator<= is declared on line 90, but it is not defined in terms of its opposite operator operator>. |
247
| AV Rule 85.cpp:79:7:79:14 | MyClass8<T> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator> is declared on line 88, but it is not defined in terms of its opposite operator operator<=. |
25-
| AV Rule 85.cpp:79:7:79:14 | MyClass8<T> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator>= is declared on line 85, but it is not defined in terms of its opposite operator operator<. |
26-
| AV Rule 85.cpp:79:7:79:14 | MyClass8<int> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator< is declared on line 83, but it is not defined in terms of its opposite operator operator>=. |
27-
| AV Rule 85.cpp:79:7:79:14 | MyClass8<int> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator<= is declared on line 90, but it is not defined in terms of its opposite operator operator>. |
28-
| AV Rule 85.cpp:79:7:79:14 | MyClass8<int> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator> is declared on line 88, but it is not defined in terms of its opposite operator operator<=. |
29-
| AV Rule 85.cpp:79:7:79:14 | MyClass8<int> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator>= is declared on line 85, but it is not defined in terms of its opposite operator operator<. |
30-
| AV Rule 85.cpp:103:7:103:14 | MyClass9<T> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator< is declared on line 107, but it is not defined in terms of its opposite operator operator>=. |
318
| AV Rule 85.cpp:103:7:103:14 | MyClass9<T> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator<= is declared on line 114, but it is not defined in terms of its opposite operator operator>. |
329
| AV Rule 85.cpp:103:7:103:14 | MyClass9<T> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator> is declared on line 112, but it is not defined in terms of its opposite operator operator<=. |
33-
| AV Rule 85.cpp:103:7:103:14 | MyClass9<T> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator>= is declared on line 109, but it is not defined in terms of its opposite operator operator<. |
34-
| AV Rule 85.cpp:103:7:103:14 | MyClass9<double> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator< is declared on line 107, but it is not defined in terms of its opposite operator operator>=. |
35-
| AV Rule 85.cpp:103:7:103:14 | MyClass9<double> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator<= is declared on line 114, but it is not defined in terms of its opposite operator operator>. |
36-
| AV Rule 85.cpp:103:7:103:14 | MyClass9<double> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator> is declared on line 112, but it is not defined in terms of its opposite operator operator<=. |
37-
| AV Rule 85.cpp:103:7:103:14 | MyClass9<double> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator>= is declared on line 109, but it is not defined in terms of its opposite operator operator<. |
38-
| AV Rule 85.cpp:103:7:103:14 | MyClass9<int> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator< is declared on line 107, but it is not defined in terms of its opposite operator operator>=. |
39-
| AV Rule 85.cpp:103:7:103:14 | MyClass9<int> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator<= is declared on line 114, but it is not defined in terms of its opposite operator operator>. |
40-
| AV Rule 85.cpp:103:7:103:14 | MyClass9<int> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator> is declared on line 112, but it is not defined in terms of its opposite operator operator<=. |
41-
| AV Rule 85.cpp:103:7:103:14 | MyClass9<int> | When two operators are opposites, both should be defined and one should be defined in terms of the other. Operator operator>= is declared on line 109, but it is not defined in terms of its opposite operator operator<. |

0 commit comments

Comments
 (0)