@@ -244,6 +244,16 @@ private module Cached {
244244 )
245245 }
246246
247+ /**
248+ * Gets a `glvalue` expression whose unconverted result is the same as the
249+ * unconverted result of `e`.
250+ */
251+ pragma [ inline]
252+ private Expr getAGLValueCategoryExpr ( Expr e ) {
253+ result .isGLValueCategory ( ) and
254+ result .getUnconverted ( ) = e .getUnconverted ( )
255+ }
256+
247257 /** Holds if `node` should be an `IndirectOperand` that maps `node.asExpr()` to `e`. */
248258 private predicate exprNodeShouldBeIndirectOperand ( IndirectOperand node , Expr e , int n ) {
249259 exists ( ArgumentOperand operand | isIndirectOperandOfArgument ( node , operand , e , n ) |
@@ -262,13 +272,13 @@ private module Cached {
262272 // The qualifier is associated with both `*x` and the lvalue-to-rvalue
263273 // conversion of `x`. Only `*x` is a glvalue and should map to the
264274 // indirect qualifier node; the converted `x` is a pointer prvalue and
265- // should map to the direct qualifier node. Restricting `e` to only be
266- // expressions for which `e.isGLValueCategory()` holds ensures that `*x`
267- // is the result of calling `asExpr()` while `asIndirectExpr()` gives
268- // `x` .
275+ // should map to the direct qualifier node. So we require that the fully
276+ // converted qualifier (i.e., the expression with `n = 0`) is a glvalue,
277+ // and then map every expression in the conversion chain with the same
278+ // unconverted expression to the indirect node .
269279 operand .isGLValue ( ) and
270280 operand instanceof ThisArgumentOperand and
271- e . isGLValueCategory ( )
281+ isIndirectOperandOfArgument ( node , operand , getAGLValueCategoryExpr ( e ) , 0 )
272282 or
273283 // When an argument (qualifier or positional) is a prvalue and the
274284 // parameter (qualifier or positional) is a (const) reference, IR
0 commit comments