================
@@ -372,6 +372,21 @@ void FactsGenerator::VisitUnaryOperator(const
UnaryOperator *UO) {
killAndFlowOrigin(*UO, *SubExpr);
return;
}
+ case UO_PreInc:
+ case UO_PostInc:
+ case UO_PreDec:
+ case UO_PostDec: {
+ // Incrementing/decrementing a pointer keeps it in the same allocation, so
+ // the result carries the operand's loans. The operand is always an lvalue;
+ // peel its storage origin when the result is a prvalue (post-inc/dec, or
+ // any form in C).
+ if (!UO->getType()->isPointerType())
+ return;
+ OriginList *SubList = getOriginsList(*UO->getSubExpr());
+ flow(getOriginsList(*UO),
+ UO->isGLValue() ? SubList : SubList->peelOuterOrigin(),
/*Kill=*/true);
----------------
Xazax-hun wrote:
Actually, `getRValueOrigins` is doing the opposite. It peels off the lvalue's
origin.
Here, SubList is always an lvalue, so it always has an origin length of 2. In
case the operator itself produces an lvalue we can just propagate, in case it
produces an rvalue, we peel.
`getRValueOrigins` on the other hand peels when the passed in expression is an
lvalue.
https://github.com/llvm/llvm-project/pull/204477
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits