Skip to content

Commit 189d82b

Browse files
committed
C++: Change exclusion to not be only operator=
1 parent 6385dd3 commit 189d82b

File tree

3 files changed

+21
-5
lines changed

3 files changed

+21
-5
lines changed

cpp/ql/src/Likely Bugs/Likely Typos/ExprHasNoEffect.ql

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,27 @@ predicate definedInIfDef(Function f) {
9191
)
9292
}
9393

94+
/**
95+
* Holds if `call` has the form `B::f()` or `q.B::f()`, where `B` is a base
96+
* class of the class containing `call`.
97+
*
98+
* This is most often used for calling base-class functions from within
99+
* overrides. Those functions may have no side effect in the current
100+
* implementation, but we should not advise callers to rely on this. That would
101+
* break encapsulation.
102+
*/
103+
predicate baseCall(FunctionCall call) {
104+
call.getNameQualifier().getQualifyingElement() =
105+
call.getEnclosingFunction().getDeclaringType().(Class).getABaseClass+()
106+
}
107+
94108
from PureExprInVoidContext peivc, Locatable parent,
95109
Locatable info, string info_text, string tail
96110
where // EQExprs are covered by CompareWhereAssignMeant.ql
97111
not peivc instanceof EQExpr and
98112
// as is operator==
99113
not peivc.(FunctionCall).getTarget().hasName("operator==") and
100-
// An assignment operator may have no side effects in its current
101-
// implementation, but we should not advise callers to rely on this. That
102-
// would break encapsulation.
103-
not peivc.(FunctionCall).getTarget().hasName("operator=") and
114+
not baseCall(peivc) and
104115
not accessInInitOfForStmt(peivc) and
105116
not peivc.isCompilerGenerated() and
106117
not exists(Macro m | peivc = m.getAnInvocation().getAnExpandedElement()) and

cpp/ql/src/semmle/code/cpp/NameQualifiers.qll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,10 @@ class NameQualifier extends NameQualifiableElement, @namequalifier {
6767
* the latter is qualified by `N1`.
6868
*/
6969
class NameQualifiableElement extends Element, @namequalifiableelement {
70-
/** Gets the name qualifier associated with this element. */
70+
/**
71+
* Gets the name qualifier associated with this element. For example, the
72+
* name qualifier of `N::f()` is `N`.
73+
*/
7174
NameQualifier getNameQualifier() {
7275
namequalifiers(unresolveElement(result),underlyingElement(this),_,_)
7376
}

cpp/ql/test/query-tests/Likely Bugs/Likely Typos/ExprHasNoEffect/ExprHasNoEffect.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
| test.c:27:9:27:10 | 33 | This expression has no effect. | test.c:27:9:27:10 | 33 | |
2828
| test.cpp:24:3:24:3 | call to operator++ | This expression has no effect (because $@ has no external side effects). | test.cpp:9:14:9:23 | operator++ | operator++ |
2929
| test.cpp:25:3:25:3 | call to operator++ | This expression has no effect (because $@ has no external side effects). | test.cpp:9:14:9:23 | operator++ | operator++ |
30+
| test.cpp:62:5:62:5 | call to operator= | This expression has no effect (because $@ has no external side effects). | test.cpp:47:14:47:22 | operator= | operator= |
31+
| test.cpp:65:5:65:5 | call to operator= | This expression has no effect (because $@ has no external side effects). | test.cpp:55:7:55:7 | operator= | operator= |
3032
| volatile.c:9:5:9:5 | c | This expression has no effect. | volatile.c:9:5:9:5 | c | |
3133
| volatile.c:12:5:12:9 | access to array | This expression has no effect. | volatile.c:12:5:12:9 | access to array | |
3234
| volatile.c:16:5:16:7 | * ... | This expression has no effect. | volatile.c:16:5:16:7 | * ... | |

0 commit comments

Comments
 (0)