rjmccall added inline comments.
================ Comment at: clang/lib/Sema/SemaExpr.cpp:677 + E->getType().isDestructedType() == QualType::DK_nontrivial_c_struct) + Cleanup.setExprNeedsCleanups(true); + ---------------- ahatanak wrote: > rjmccall wrote: > > ahatanak wrote: > > > rjmccall wrote: > > > > ahatanak wrote: > > > > > rjmccall wrote: > > > > > > Why only when the l-value is volatile? > > > > > I was trying to avoid emitting `ExprWithCleanups` when it wasn't > > > > > needed and it seemed that it wasn't needed for non-volatile types. > > > > > I'm not sure it's important, so I've removed the check for volatile. > > > > > Also, `ExprWithCleanups` shouldn't' be emitted when this is in file > > > > > scope, so I fixed that too. > > > > Hmm, not sure about this file-scope thing, since the combination of C++ > > > > dynamic initializers and statement-expressions means we can have > > > > pretty unrestricted code there. > > > I should have explained why this was needed, but I wanted to prevent > > > emitting `ExprWithCleanups` in the following example: > > > > > > ``` > > > struct A { > > > id f0; > > > }; > > > > > > typedef struct A A; > > > > > > A g = (A){ .f0 = 0 }; > > > ``` > > > > > > The l-value to r-value conversion happens here because compound literals > > > are l-values. Since `g` is a global of a non-trivial C struct type, we > > > shouldn't try to push a cleanup and destruct the object. > > > > > > We don't have to think about the C++ case since the line below checks the > > > type is a non-trivial C type. I didn't think about statement expressions, > > > but they aren't allowed in file scope, so I guess that's not a problem > > > either. > > I would hope that the constant-evaluator here might be smart enough to > > ignore some elidable temporaries. > Do you mean the constant-evaluator should evaluate initializers that are > `ExprWithCleanups` to constants in a case like this? It's possible to do so > by seeing whether the sub-expression of `ExprWithCleanups` is constant, but > it looks like we also have to set the `CleanupInfo::CleanupsHaveSideEffects` > flag to false when it's a file scope expression so that > `ConstExprEmitter::VisitExprWithCleanups` can constant-fold the > `ExprWithCleanups` initializer. In this case, what we're doing is eliding a "temporary" (really an object with wider lifetime, but if the object isn't referenceable, we can compile as-if the object is really temporary) and therefore bypassing the need for a cleanup entirely. I wouldn't expect the AST to change to reflect that this is possible, just the constant evaluator. Basically, it needs to look through `ExprWithCleanups`; we probably already peephole the `LValueToRValue(CompoundLiteralExpr)` combination. We do try to do constant-evaluation on local initializers as well as an optimization, and abstractly that should also work with these constructs. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D66094/new/ https://reviews.llvm.org/D66094 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits