@@ -183,11 +183,14 @@ private predicate referenceFromVariableAccess(VariableAccess va, Expr reference)
183183 )
184184}
185185
186- private predicate valueMayEscapeAt ( Expr e ) {
186+ private predicate addressMayEscapeAt ( Expr e ) {
187187 exists ( Call call |
188188 e = call .getAnArgument ( ) .getFullyConverted ( ) and
189189 not stdIdentityFunction ( call .getTarget ( ) ) and
190190 not stdAddressOf ( call .getTarget ( ) )
191+ or
192+ e = call .getQualifier ( ) .getFullyConverted ( ) and
193+ e .getUnderlyingType ( ) instanceof PointerType
191194 )
192195 or
193196 exists ( AssignExpr assign | e = assign .getRValue ( ) .getFullyConverted ( ) )
@@ -205,8 +208,8 @@ private predicate valueMayEscapeAt(Expr e) {
205208 exists ( AsmStmt asm | e = asm .getAChild ( ) .( Expr ) .getFullyConverted ( ) )
206209}
207210
208- private predicate valueMayEscapeMutablyAt ( Expr e ) {
209- valueMayEscapeAt ( e ) and
211+ private predicate addressMayEscapeMutablyAt ( Expr e ) {
212+ addressMayEscapeAt ( e ) and
210213 exists ( Type t | t = e .getType ( ) .getUnderlyingType ( ) |
211214 exists ( PointerType pt |
212215 pt = t
@@ -225,6 +228,22 @@ private predicate valueMayEscapeMutablyAt(Expr e) {
225228 )
226229}
227230
231+ private predicate lvalueMayEscapeAt ( Expr e ) {
232+ // A call qualifier, like `q` in `q.f()`, is special in that the address of
233+ // `q` escapes even though `q` is not a pointer or a reference.
234+ exists ( Call call |
235+ e = call .getQualifier ( ) .getFullyConverted ( ) and
236+ e .getType ( ) .getUnspecifiedType ( ) instanceof Class
237+ )
238+ }
239+
240+ private predicate lvalueMayEscapeMutablyAt ( Expr e ) {
241+ lvalueMayEscapeAt ( e ) and
242+ // A qualifier of a call to a const member function is converted to a const
243+ // class type.
244+ not e .getType ( ) .isConst ( )
245+ }
246+
228247private predicate addressFromVariableAccess ( VariableAccess va , Expr e ) {
229248 pointerFromVariableAccess ( va , e )
230249 or
@@ -271,8 +290,11 @@ private module EscapesTree_Cached {
271290 */
272291 cached
273292 predicate variableAddressEscapesTree ( VariableAccess va , Expr e ) {
274- valueMayEscapeAt ( e ) and
293+ addressMayEscapeAt ( e ) and
275294 addressFromVariableAccess ( va , e )
295+ or
296+ lvalueMayEscapeAt ( e ) and
297+ lvalueFromVariableAccess ( va , e )
276298 }
277299
278300 /**
@@ -301,8 +323,11 @@ private module EscapesTree_Cached {
301323 */
302324 cached
303325 predicate variableAddressEscapesTreeNonConst ( VariableAccess va , Expr e ) {
304- valueMayEscapeMutablyAt ( e ) and
326+ addressMayEscapeMutablyAt ( e ) and
305327 addressFromVariableAccess ( va , e )
328+ or
329+ lvalueMayEscapeMutablyAt ( e ) and
330+ lvalueFromVariableAccess ( va , e )
306331 }
307332
308333 /**
0 commit comments