@@ -166,10 +166,13 @@ private predicate referenceFromVariableAccess(VariableAccess va, Expr reference)
166166 )
167167}
168168
169- private predicate valueMayEscapeAt ( Expr e ) {
169+ private predicate addressMayEscapeAt ( Expr e ) {
170170 exists ( Call call |
171171 e = call .getAnArgument ( ) .getFullyConverted ( ) and
172172 not stdIdentityFunction ( call .getTarget ( ) )
173+ or
174+ e = call .getQualifier ( ) .getFullyConverted ( ) and
175+ e .getUnderlyingType ( ) instanceof PointerType
173176 )
174177 or
175178 exists ( AssignExpr assign | e = assign .getRValue ( ) .getFullyConverted ( ) )
@@ -187,8 +190,8 @@ private predicate valueMayEscapeAt(Expr e) {
187190 exists ( AsmStmt asm | e = asm .getAChild ( ) .( Expr ) .getFullyConverted ( ) )
188191}
189192
190- private predicate valueMayEscapeMutablyAt ( Expr e ) {
191- valueMayEscapeAt ( e ) and
193+ private predicate addressMayEscapeMutablyAt ( Expr e ) {
194+ addressMayEscapeAt ( e ) and
192195 exists ( Type t | t = e .getType ( ) .getUnderlyingType ( ) |
193196 exists ( PointerType pt |
194197 pt = t
@@ -207,6 +210,22 @@ private predicate valueMayEscapeMutablyAt(Expr e) {
207210 )
208211}
209212
213+ private predicate lvalueMayEscapeAt ( Expr e ) {
214+ // A call qualifier, like `q` in `q.f()`, is special in that the address of
215+ // `q` escapes even though `q` is not a pointer or a reference.
216+ exists ( Call call |
217+ e = call .getQualifier ( ) .getFullyConverted ( ) and
218+ e .getType ( ) .getUnspecifiedType ( ) instanceof Class
219+ )
220+ }
221+
222+ private predicate lvalueMayEscapeMutablyAt ( Expr e ) {
223+ lvalueMayEscapeAt ( e ) and
224+ // A qualifier of a call to a const member function is converted to a const
225+ // class type.
226+ not e .getType ( ) .isConst ( )
227+ }
228+
210229private predicate addressFromVariableAccess ( VariableAccess va , Expr e ) {
211230 pointerFromVariableAccess ( va , e )
212231 or
@@ -253,8 +272,11 @@ private module EscapesTree_Cached {
253272 */
254273 cached
255274 predicate variableAddressEscapesTree ( VariableAccess va , Expr e ) {
256- valueMayEscapeAt ( e ) and
275+ addressMayEscapeAt ( e ) and
257276 addressFromVariableAccess ( va , e )
277+ or
278+ lvalueMayEscapeAt ( e ) and
279+ lvalueFromVariableAccess ( va , e )
258280 }
259281
260282 /**
@@ -283,8 +305,11 @@ private module EscapesTree_Cached {
283305 */
284306 cached
285307 predicate variableAddressEscapesTreeNonConst ( VariableAccess va , Expr e ) {
286- valueMayEscapeMutablyAt ( e ) and
308+ addressMayEscapeMutablyAt ( e ) and
287309 addressFromVariableAccess ( va , e )
310+ or
311+ lvalueMayEscapeMutablyAt ( e ) and
312+ lvalueFromVariableAccess ( va , e )
288313 }
289314
290315 /**
0 commit comments