[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