@@ -214,7 +214,10 @@ CVarSet
214214 return PVConstraintFromType (TypE);
215215 }
216216 // NULL
217- } else if (isNULLExpression (E, *Context)) {
217+ // Special handling for casts of null is required to enable rewriting
218+ // statements such as int *x = (int*) 0. If this was handled as a
219+ // normal null expression, the cast would never be visited.
220+ } else if (!isa<ExplicitCastExpr>(E) && isNULLExpression (E, *Context)) {
218221 return EmptyCSet;
219222 // Implicit cast, e.g., T* from T[] or int (*)(int) from int (int),
220223 // but also weird int->int * conversions (and back)
@@ -254,14 +257,29 @@ CVarSet
254257 CVarSet Ret = EmptyCSet;
255258 if (ExplicitCastExpr *ECE = dyn_cast<ExplicitCastExpr>(E)) {
256259 assert (ECE->getType () == TypE);
257- // Is cast internally safe? Return WILD if not
258260 Expr *TmpE = ECE->getSubExpr ();
259- if (TypE->isPointerType () && !isCastSafe (TypE, TmpE->getType ()))
261+ // Is cast internally safe? Return WILD if not.
262+ // If the cast is NULL, it will otherwise seem invalid, but we want to
263+ // handle it as usual so the type in the cast can be rewritten.
264+ if (!isNULLExpression (ECE, *Context) && TypE->isPointerType ()
265+ && !isCastSafe (TypE, TmpE->getType ())) {
260266 Ret = getInvalidCastPVCons (E);
261267 // NB: Expression ECE itself handled in
262268 // ConstraintBuilder::FunctionVisitor
263- else
264- Ret = getExprConstraintVars (TmpE);
269+ } else {
270+ CVarSet Vars = getExprConstraintVars (TmpE);
271+ // PVConstraint introduced for explicit cast so they can be rewritten.
272+ // Pretty much the same idea as CompoundLiteralExpr.
273+ PVConstraint *P = getRewritablePVConstraint (ECE);
274+ Ret = {P};
275+ // ConstraintVars for TmpE when ECE is NULL will be WILD, so
276+ // constraining GEQ these vars would be the cast always be WILD.
277+ if (!isNULLExpression (ECE, *Context)) {
278+ PersistentSourceLoc PL = PersistentSourceLoc::mkPSL (ECE, *Context);
279+ constrainConsVarGeq (Ret, Vars, Info.getConstraints (), &PL,
280+ Same_to_Same, false , &Info);
281+ }
282+ }
265283 }
266284 // x = y, x+y, x+=y, etc.
267285 else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
@@ -520,9 +538,7 @@ CVarSet
520538 CVarSet T;
521539 CVarSet Vars = getExprConstraintVars (CLE->getInitializer ());
522540
523- PVConstraint *P =
524- new PVConstraint (CLE->getType (), nullptr , CLE->getStmtClassName (),
525- Info, *Context, nullptr );
541+ PVConstraint *P = getRewritablePVConstraint (CLE);
526542 T = {P};
527543
528544 PersistentSourceLoc PL = PersistentSourceLoc::mkPSL (CLE, *Context);
@@ -581,11 +597,12 @@ CVarSet
581597 return Persist;
582598}
583599
600+
584601void ConstraintResolver::storePersistentConstraints (clang::Expr *E,
585602 CVarSet &Vars) {
586- auto PSL = PersistentSourceLoc::mkPSL (E, *Context);
587603 // Store only if the PSL is valid.
588- if (PSL.valid ()) {
604+ auto PSL = PersistentSourceLoc::mkPSL (E, *Context);
605+ if (PSL.valid () && Rewriter::isRewritable (E->getBeginLoc ())){
589606 CVarSet &Persist = Info.getPersistentConstraintVars (E, Context);
590607 Persist.insert (Vars.begin (), Vars.end ());
591608 }
@@ -679,6 +696,18 @@ CVarSet ConstraintResolver::getBaseVarPVConstraint(DeclRefExpr *Decl) {
679696 return Ret;
680697}
681698
699+ // Construct a PVConstraint for an expression that can safely be used when
700+ // rewriting the expression later on. This is done by making the constraint WILD
701+ // if the expression is inside a macro.
702+ PVConstraint *ConstraintResolver::getRewritablePVConstraint (Expr *E) {
703+ PVConstraint *P = new PVConstraint (E->getType (), nullptr ,
704+ E->getStmtClassName (), Info, *Context,
705+ nullptr );
706+ CVarSet Tmp = {P};
707+ Info.constrainWildIfMacro (Tmp, E->getExprLoc ());
708+ return P;
709+ }
710+
682711bool
683712ConstraintResolver::containsValidCons (CVarSet &CVs) {
684713 bool RetVal = false ;
0 commit comments