[PATCH] D117496: [clang][dataflow] Add transfer function for addrof

Gábor Horváth via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 17 23:02:45 PST 2022


xazax.hun accepted this revision.
xazax.hun added a comment.
This revision is now accepted and ready to land.

The address-of part looks good to me. However, just realized that I'm not convinced whether the dereference operator, or references, in general, are correctly handled.



================
Comment at: clang/lib/Analysis/FlowSensitive/Transfer.cpp:190
       Env.setValue(Loc, Env.takeOwnership(std::make_unique<ReferenceValue>(
                             SubExprVal->getPointeeLoc())));
+      break;
----------------
I know this is not strictly related to this patch, but why do we actually need do `getPointeeLoc` here? I'd expect `UO_Deref` to be a noop for all intents and purposes.

E.g. for a snippet like: 
```
int f(int *p) {
    return *p;
}
```

The AST looks like:
```
  `-CompoundStmt 0x5565d151d038 <col:15, line:4:1>
    `-ReturnStmt 0x5565d151d028 <line:3:5, col:13>
      `-ImplicitCastExpr 0x5565d151d010 <col:12, col:13> 'int' <LValueToRValue>
        `-UnaryOperator 0x5565d151cff8 <col:12, col:13> 'int' lvalue prefix '*' cannot overflow
          `-ImplicitCastExpr 0x5565d151cfe0 <col:13> 'int *' <LValueToRValue>
            `-DeclRefExpr 0x5565d151cfc0 <col:13> 'int *' lvalue ParmVar 0x5565d151ce00 'p' 'int *'
```

I'd expect any actual dereference to happen in the `LValueToRValue` cast.
The reason is, this is how references can be handled. E.g.:
```
void f(int &p) {
    int &q = p;
    int r = p;
}
```

Has the AST:
```
    |-DeclStmt 0x55d49a1f00b0 <line:3:5, col:15>
    | `-VarDecl 0x55d49a1effd0 <col:5, col:14> col:10 q 'int &' cinit
    |   `-DeclRefExpr 0x55d49a1f0038 <col:14> 'int' lvalue ParmVar 0x55d49a1efe00 'p' 'int &'
    `-DeclStmt 0x55d49a1f0180 <line:4:5, col:14>
      `-VarDecl 0x55d49a1f00e0 <col:5, col:13> col:9 r 'int' cinit
        `-ImplicitCastExpr 0x55d49a1f0168 <col:13> 'int' <LValueToRValue>
          `-DeclRefExpr 0x55d49a1f0148 <col:13> 'int' lvalue ParmVar 0x55d49a1efe00 'p' 'int &'
```

The reason why you know when should you propagate the reference or the pointee of the reference from the subexpression is because of the `LValueToRValue` cast. So you already need to do the "dereference" operator there to correctly handle references. And if you already do that, I see no reason to duplicate this logic here for pointers. Do I miss something?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117496/new/

https://reviews.llvm.org/D117496



More information about the cfe-commits mailing list