vsavchenko added a comment. > // 1. `VisitSymbolCast`. > // Get a range for main `reg_$0<int x>` - [-2147483648, 2147483647] > // Cast main range to `short` - [-2147483648, 2147483647] -> [-32768, > 32767]. > // Now we get a valid range for further bifurcation - [-32768, 32767].
That's a great example, thanks for putting it together. I can see your point now! Please, rebase your change and make use of `ConstraintAssignor`, and rework `VisitSymbolCast`. ================ Comment at: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h:293-296 + SymbolRef Sym = Operand; + while (isa<SymbolCast>(Sym)) + Sym = cast<SymbolCast>(Sym)->Operand; + return Sym; ---------------- ASDenysPetrov wrote: > vsavchenko wrote: > > ASDenysPetrov wrote: > > > vsavchenko wrote: > > > > > > > Do you think the recursive call is better than the loop? But, I guess, I > > > see your point. You option could be safer if we had another > > > implementation of the virtual method. Or you think such alike cast symbol > > > is possible in the future? Well, for now `ignoreCasts` doesn't make sense > > > to any other `Expr` successors. > > Oh, wait, why is it even virtual? I don't think that it should be virtual. > > Are similar functions in `Expr` virtual? > > And I think that this implementation should live in `SymExpr` directly. > > Then it would look like: > > ``` > > if (const SymbolCast *ThisAsCast = dyn_cast<SymbolCast>(this)) { > > return ThisAsCast->ignoreCasts(); > > } > > return this; > > ``` > Yes, `SymExpr` is an abstract class. And because of limitations and > dependency of inheritance we are not able to know the implementaion of > `SymbolCast`. Unfortunately, this is not a CRTP. Re-read my comment, please. ================ Comment at: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp:1203 + if (!Opts.ShouldSupportSymbolicIntegerCasts) + return VisitSymExpr(Sym); + ---------------- ASDenysPetrov wrote: > vsavchenko wrote: > > ASDenysPetrov wrote: > > > vsavchenko wrote: > > > > ASDenysPetrov wrote: > > > > > vsavchenko wrote: > > > > > > Why do you use `VisitSymExpr` here? You want to interrupt all > > > > > > `Visits or... I'm not sure I fully understand. > > > > > Here we want to delegate the reasoning to another handler as we don't > > > > > support non-integral cast yet. > > > > You are not delegating it here. `Visit` includes a runtime dispatch > > > > that calls a correct `VisitTYPE` method. Here you call `VisitSymExpr` > > > > directly, which is one of the `VisitTYPE` methods. No dispatch will > > > > happen, and since we use `VisitSymExpr` as the last resort (it's the > > > > most base class, if we got there, we don't actually support the > > > > expression), you interrupt the `Visit` and go directly to "the last > > > > resort". > > > > > > > > See the problem now? > > > OK. I reject this idea before. If we call `Visit` inside > > > `VisitSymbolCast`, we will go into recursive loop, because it will return > > > us back to `VisitSymbolCast` as we have passed `Sym` as is. (This is > > > theoretically, I didn't check in practice.) Or I'm missing smth? > > > I choosed `VisitSymExpr` here because all kinds of `SymbolCast` were > > > previously handled here. So I decided to pass all unsupproted forms of > > > casts there. > > Did I suggest to `Visit(Sym)`? Of course it is going to end up in a loop! > > Why isn't it `Visit(Sym->getOperand())` here? Before we started producing > > casts, casts were transparent. This logic would fit perfectly with that. > > were transparent. > Not exactly. There are still some cases when symbols are not equal to there > roots(aka Operands). Such cases were handled by `VisitSymExpr` which uses > `infer(Sym->getType());` instead of getOperand`. So this needs a sort of > think twice. Also I see a problem with `EquivalenceClass`'es. Consider next: > ``` > int x, y; > if(x == y) > if ((char)x == 2) > if(y == 259) > // Here we shall update `(char)x` and find this branch infeasible. > ``` > Also such cases like: > ``` > if(x == (short)y) > // What we should do(store) with(in) `EquivalenceClass`es. > ``` > Currently, I have an obscure vision of the solution. > There are still some cases when symbols are not equal to there roots(aka > Operands) Right now we don't have casts, this is what we do currently. However faulty it is, it is the existing solution and we should respect that. > Also I see a problem with EquivalenceClass'es. Because of the current situation with casts (or more precisely with their lack), `EquivalenceClass`es do not get merged for symbols with different types. It is as simple as that. You can find similar tests in `equality_tracking.c`. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103096/new/ https://reviews.llvm.org/D103096 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits