Merge pull request #754 from jbj/copy-assignment-no-effect

C++: Exclude assignment operator in ExprHasNoEffect
This commit is contained in:
Dave Bartolomeo
2019-01-23 00:46:17 -08:00
committed by GitHub
3 changed files with 61 additions and 1 deletions

View File

@@ -91,12 +91,27 @@ predicate definedInIfDef(Function f) {
)
}
/**
* Holds if `call` has the form `B::f()` or `q.B::f()`, where `B` is a base
* class of the class containing `call`.
*
* This is most often used for calling base-class functions from within
* overrides. Those functions may have no side effect in the current
* implementation, but we should not advise callers to rely on this. That would
* break encapsulation.
*/
predicate baseCall(FunctionCall call) {
call.getNameQualifier().getQualifyingElement() =
call.getEnclosingFunction().getDeclaringType().(Class).getABaseClass+()
}
from PureExprInVoidContext peivc, Locatable parent,
Locatable info, string info_text, string tail
where // EQExprs are covered by CompareWhereAssignMeant.ql
not peivc instanceof EQExpr and
// as is operator==
not peivc.(FunctionCall).getTarget().hasName("operator==") and
not baseCall(peivc) and
not accessInInitOfForStmt(peivc) and
not peivc.isCompilerGenerated() and
not exists(Macro m | peivc = m.getAnInvocation().getAnExpandedElement()) and

View File

@@ -67,7 +67,10 @@ class NameQualifier extends NameQualifiableElement, @namequalifier {
* the latter is qualified by `N1`.
*/
class NameQualifiableElement extends Element, @namequalifiableelement {
/** Gets the name qualifier associated with this element. */
/**
* Gets the name qualifier associated with this element. For example, the
* name qualifier of `N::f()` is `N`.
*/
NameQualifier getNameQualifier() {
namequalifiers(unresolveElement(result),underlyingElement(this),_,_)
}