C++: AV Rule 85: Check templates rather than instantiations

This commit is contained in:
Ian Lynagh
2018-10-29 15:04:30 +00:00
parent eef8719a40
commit 94347aef9b
2 changed files with 25 additions and 18 deletions

View File

@@ -19,32 +19,39 @@ predicate oppositeOperators(string op1, string op2) {
/* this match is very syntactic: we simply check that op1 is defined as
!op2(_, _) */
predicate implementedAsNegationOf(Operator op1, Operator op2) {
exists(Block b, ReturnStmt r, NotExpr n, FunctionCall c |
exists(Block b, ReturnStmt r, NotExpr n, Expr o |
b = op1.getBlock() and
b.getNumStmt() = 1 and
r = b.getStmt(0) and
n = r.getExpr() and
c = n.getOperand() and
c.getTarget() = op2)
o = n.getOperand() and
(
o instanceof LTExpr and op2.hasName("operator<") or
o instanceof LEExpr and op2.hasName("operator<=") or
o instanceof GTExpr and op2.hasName("operator>") or
o instanceof GEExpr and op2.hasName("operator>=") or
o instanceof EQExpr and op2.hasName("operator==") or
o instanceof NEExpr and op2.hasName("operator!=") or
o.(FunctionCall).getTarget() = op2
)
)
}
predicate classIsCheckableFor(Class c, string op) {
oppositeOperators(op, _) and
if exists(Class templ | c.isConstructedFrom(templ))
then // If we are an instantiation, then we can't check `op` if the
// template has it but we don't (because that member wasn't
// instantiated)
exists(Class templ | c.isConstructedFrom(templ) and
(templ.getAMember().hasName(op) implies
exists(Function f | f = c.getAMember() and
f.hasName(op) and
f.isDefined())))
else any()
// We check the template, not its instantiations
not c instanceof ClassTemplateInstantiation and
// Member functions of templates are not necessarily instantiated, so
// if the function we want to check exists, then make sure that its
// body also exists
((c instanceof TemplateClass)
implies
forall(Function f | f = c.getAMember() and f.hasName(op)
| exists(f.getEntryPoint())))
}
from Class c, string op, string opp, Operator rator
where c.fromSource() and
not c instanceof TemplateClass and
oppositeOperators(op, opp) and
classIsCheckableFor(c, op) and
classIsCheckableFor(c, opp) and

View File

@@ -3,7 +3,7 @@
| 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<. |
| 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>. |
| 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<=. |
| 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>. |
| 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<=. |
| 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>. |
| 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<=. |
| 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>. |
| 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<=. |
| 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>. |
| 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<=. |