@@ -25,7 +25,7 @@ predicate pointerThis(Expr e) {
2525 // `f(...)`
2626 // (includes `this = ...`, where `=` is overloaded so a `FunctionCall`)
2727 exists ( FunctionCall fc | fc = e and callOnThis ( fc ) |
28- exists ( fc . getTarget ( ) . getBlock ( ) ) implies returnsPointerThis ( fc .getTarget ( ) )
28+ returnsPointerThis ( fc .getTarget ( ) )
2929 ) or
3030
3131 // `this = ...` (where `=` is not overloaded, so an `AssignExpr`)
@@ -38,22 +38,33 @@ predicate dereferenceThis(Expr e) {
3838 // `f(...)`
3939 // (includes `*this = ...`, where `=` is overloaded so a `FunctionCall`)
4040 exists ( FunctionCall fc | fc = e and callOnThis ( fc ) |
41- exists ( fc . getTarget ( ) . getBlock ( ) ) implies returnsDereferenceThis ( fc .getTarget ( ) )
41+ returnsDereferenceThis ( fc .getTarget ( ) )
4242 ) or
4343
4444 // `*this = ...` (where `=` is not overloaded, so an `AssignExpr`)
4545 dereferenceThis ( e .( AssignExpr ) .getLValue ( ) )
4646}
4747
48+ /**
49+ * Holds if all `return` statements in `f` return `this`, possibly indirectly.
50+ * This includes functions whose body is not in the database.
51+ */
4852predicate returnsPointerThis ( Function f ) {
49- forex ( ReturnStmt s | s .getEnclosingFunction ( ) = f |
53+ f .getType ( ) .getUnspecifiedType ( ) instanceof PointerType and
54+ forall ( ReturnStmt s | s .getEnclosingFunction ( ) = f and reachable ( s ) |
5055 // `return this`
5156 pointerThis ( s .getExpr ( ) )
5257 )
5358}
5459
60+ /**
61+ * Holds if all `return` statements in `f` return a reference to `*this`,
62+ * possibly indirectly. This includes functions whose body is not in the
63+ * database.
64+ */
5565predicate returnsDereferenceThis ( Function f ) {
56- forex ( ReturnStmt s | s .getEnclosingFunction ( ) = f |
66+ f .getType ( ) .getUnspecifiedType ( ) instanceof ReferenceType and
67+ forall ( ReturnStmt s | s .getEnclosingFunction ( ) = f and reachable ( s ) |
5768 // `return *this`
5869 dereferenceThis ( s .getExpr ( ) )
5970 )
@@ -72,7 +83,6 @@ predicate assignOperatorWithWrongType(Operator op, string msg) {
7283predicate assignOperatorWithWrongResult ( Operator op , string msg ) {
7384 op .hasName ( "operator=" )
7485 and not returnsDereferenceThis ( op )
75- and exists ( op .getBlock ( ) )
7686 and not op .getType ( ) instanceof VoidType
7787 and not assignOperatorWithWrongType ( op , _)
7888 and msg = "Assignment operator in class " + op .getDeclaringType ( ) .getName ( ) + " does not return a reference to *this."
0 commit comments