This changes to address the PR : 55207
We update the volatility on the LValue by looking at the LHS cast operation qualifier and propagate the RValue volatile-ness from the CGF data structure .
Differential D157890
Propagate the volatile qualifier of exp to store /load operations . umesh.kalappa0 on Aug 14 2023, 8:42 AM. Authored by
Details This changes to address the PR : 55207 We update the volatility on the LValue by looking at the LHS cast operation qualifier and propagate the RValue volatile-ness from the CGF data structure .
Diff Detail
Unit Tests Event TimelineComment Actions Using a function-wide "isVolatileCastStmt" will almost certainly break in more complex cases (consider, for example, the case where the address of a load itself contains loads). Comment Actions The fix to EmitCastLValue looks correct and sufficient. All of this business with isVolatileCastStmt should be removed. Comment Actions Slight correction: I guess a NoOp cast can *remove* qualifiers, too. We should just unconditionally use the volatile qualifier from the result type of the cast instead of only *adding* it. Comment Actions @efriedma ,thank you for the pointers and we thought of propagating this info from VisitCast ,but that needs various api change and how about the reset "isVolatileCastStmt " to false after use in "VisitCast" ,that resolve this complex address load issue . or any other suggestions you have in mind ? Comment Actions @rjmccall ,we need "isVolatileCastStmt" for the RHS that has the cast like stated in the testcase and "EmitCastLValue" not handle the RValue . Comment Actions @rjmccall ,thank you and you right here but adding unconditionally can assert the case where either cast doesn't have the volatile qualifier nor result type doesn't have the same and if we remove the volatile-ness from LValue ,then it doesn't make sense to add right ? Comment Actions Oh, I think I understand the underlying issue with the RHS here, and it was something I was overlooking it before. Clang's r-value emitters aggressively recurse through LValueToRValue conversions, essentially sinking the load into the emission of the wrapped l-value expression. This is good to do because there are some common situations (especially in C++) where expressions are formally l-values but we can emit them more efficiently if we know there's going to be an immediate load. When we're sinking loads that way, it's usually okay to also recurse through a NoOp conversion. But we can't do that if there's a change in qualification that'll affect how the load is emitted, which mostly means a change in volatile. Using a "global" flag on the CGF object is still the wrong way to solve this. The r-value emitters need to detect that a cast materially changes qualification (I think this just means volatile) and, if so, emit the expression as an l-value and then load from it rather than aggressively recursing through the cast. You'll need to do this same logic in all of the r-value emitters: scalar, complex, and (probably) aggregate. You should be able to write a common helper function that says whether a CastExpr has a material qualification difference. Comment Actions Agree global flag is not the right way and refactor the changes for scalar/aggregate and complex and
tried to differentiate by QualType of declnode and expression with no success ,hence we go-ahead if the exp has volatile then we choose the other path . Comment Actions CE->isGLValue() && CE->getType().isVolatileQualified() != CE->getSubExpr()->getType().isVolatileQualified() Comment Actions Thank you @rjmccall for the pointers and same doesn't work with the case like static_cast<volatile _Complex float &>(cf) = static_cast<volatile _Complex float&>(cf) + 1; CXXStaticCastExpr 0x55556c405410 'volatile _Complex float' lvalue static_cast<volatile _Complex float &> <NoOp> `-ImplicitCastExpr 0x55556c4053f8 'volatile _Complex float' lvalue <NoOp> part_of_explicit_cast `-DeclRefExpr 0x55556c4053c8 '_Complex float' lvalue Var 0x55556c404fb8 'cf' '_Complex float' Comment Actions @rjmccall ,is that changes looks good to land on master or do you have any other comments ?
|
This is not a good name for this. Maybe changesVolatileQualification?
Also, please move this down after all the methods that are just getting and setting stored properties of the CastExpr — right before getTargetFieldForToUnionCast seems like the right place.
We should probably consider giving qualification conversions their own CastKind instead of folding them into NoOp. (You don't need to do that in this patch, I'm just saying that this seems like a poor choice of representation.)