[clang] [HLSL] Reuse temporaries of aggregate types in list initialization (PR #191605)

Tex Riddell via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 16 13:56:07 PDT 2026


================
@@ -5728,6 +5728,18 @@ class InitListTransformer {
         Ty->isHLSLAttributedResourceType())
       return castInitializer(E);
 
+    // If this is an aggregate type and a prvalue, create an xvalue temporary
+    // so the member accesses will be xvalues. Wrap it in OpaqueExpr top make
+    // sure codegen will not generate duplicate copies.
+    if (E->isPRValue() && Ty->isAggregateType()) {
+      ExprResult TmpExpr = S.TemporaryMaterializationConversion(E);
+      if (TmpExpr.isInvalid())
+        return false;
+      E = TmpExpr.get();
+      E = new (Ctx) OpaqueValueExpr(E->getBeginLoc(), Ty, E->getValueKind(),
+                                    E->getObjectKind(), E);
----------------
tex3d wrote:

I didn't know enough on my own to see any problems with this change, but I wasn't confident enough in this area to be sure it would always be generally correct.

However, I conversed with Claude about the change, and the one nit it had was that this `OpaqueValueExpr` is constructed using the desugared `Ty` instead of `E->getType()`, which is what would normally be done to preserve the sugared type for diagnostics and other tooling like AST matchers / static analyzers / tree dumpers. It said:
"The safer pattern would be E->getType() (after the conversion), which preserves sugar while still being canonically equivalent. That's what most other OpaqueValueExpr construction sites in Clang do."

```suggestion
      E = new (Ctx) OpaqueValueExpr(E->getBeginLoc(), E->getType(),
                                    E->getValueKind(), E->getObjectKind(), E);
```

https://github.com/llvm/llvm-project/pull/191605


More information about the cfe-commits mailing list