[clang] [CIR] Upstream support for address of and dereference (PR #134317)
Andy Kaylor via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 4 10:57:45 PDT 2025
================
@@ -193,8 +334,23 @@ LValue CIRGenFunction::emitUnaryOpLValue(const UnaryOperator *e) {
switch (op) {
case UO_Deref: {
- cgm.errorNYI(e->getSourceRange(), "UnaryOp dereference");
- return LValue();
+ QualType t = e->getSubExpr()->getType()->getPointeeType();
+ assert(!t.isNull() && "CodeGenFunction::EmitUnaryOpLValue: Illegal type");
+
+ assert(!cir::MissingFeatures::lvalueBaseInfo());
+ assert(!cir::MissingFeatures::opTBAA());
+ Address addr = emitPointerWithAlignment(e->getSubExpr());
+
+ // Tag 'load' with deref attribute.
+ if (auto loadOp =
+ dyn_cast<cir::LoadOp>(addr.getPointer().getDefiningOp())) {
+ loadOp.setIsDerefAttr(mlir::UnitAttr::get(&getMLIRContext()));
----------------
andykaylor wrote:
That's a good question. You're correct that the intent is to describe a static property of the source code. Perhaps the dialect documentation needs some clarification on this point. At the time that the CIR is generated in the front end, I think there is likely to be a direct correspondence here. The pointer loaded _is_ being dereferenced. We just emitted it in the call to `emitPointerWithAlignment()` on line 342. Of course, after some CIR-to-CIR transformation, this might not be the case.
In any event, I believe this is intended to be used for static analysis. For example, it distinguishes loads of `alloca` values to reference local variables, from loads of user pointers. For example, consider this code:
```
1 void foo(int *p1) {
2 int *p2;
3 *p1 = 2;
4 p2 = p1;
5 }
```
There are `cir.load` operations generated for lines 3 and 4. Both are immediately used in `cir.store` operations, but only the one for line 3 gets marked with the `deref` attribute.
https://godbolt.org/z/WP69hqvxj
I'm not sure exactly what the static analysis does with this information. Perhaps @bcardosolopes could provide more information.
BTW, I see that we miss applying the `deref` attribute if there is a cast on the pointer being dereferenced. I'll open an issue for that.
https://github.com/llvm/llvm-project/pull/134317
More information about the cfe-commits
mailing list