manas added inline comments.

================
Comment at: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp:1397
+        (LHS.To() < 0 && RHS.To() < 0 && Max > 0) ||
+        (LHS.To() < 0 && RHS.To() < 0 && Max > 0)) {
+      return {RangeFactory, Tmin, Tmax};
----------------
vsavchenko wrote:
> This clause is exactly the same as the previous one, it is a mistake.
> And I think we should have a test that could've shown that.
> Also, since you are checking for overflows for both the beginning and the 
> end, we should have tests where both overflow.
Understood! I will add tests to check each OR part of these conditionals in 
these cases.


================
Comment at: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp:1401-1402
+
+    // FIXME: This case in particular is resulting in failed assertion.
+    Range First = Range(Tmin, Max);
+    Range Second = Range(Min, Tmax);
----------------
vsavchenko wrote:
> vsavchenko wrote:
> > manas wrote:
> > > I changed the logic from using getCrucialPoints (which I mentioned in the 
> > > e-mail thread) to simple checks to determine overflows using signedness. 
> > > But the failed assertions again popped up. And I was unable to pin-point 
> > > the issue here. Can someone help me?
> > > 
> > > Although, I am thinking of revising the above logic by using bitwise 
> > > methods to detect overflows.
> > This is actually one place that I won't expect an assertion failure.
> > Can we get a bit more detail on it?  Is it again `From > To` (which will 
> > indeed be weird) or something different?
> > 
> > NOTE: Asking for help (either here or on StackOverflow) is a lot like 
> > filing a bug report, try to put as much information as possible, try to 
> > structure this information so it is easy to follow.  It's also good to tell 
> > people what you tried, instead of saying that you tried something and it 
> > didn't work.
> OK, I downloaded your patch and ran the debugger.
> 
> It complains about different bit-width for ranges that the analyzer tries to 
> intersect.  What I checked next: what are those ranges, so I took `begin()` 
> from one of them and checked what are `From` and `To` there.
> Here is one of them:
> ```
> (const llvm::APSInt) $8 = {
>   llvm::APInt = {
>     U = {
>       VAL = 22
>       pVal = 0x0000000000000016
>     }
>     BitWidth = 4022311424
>   }
>   IsUnsigned = true
> }
> ```
> Woah, this `BitWidth` seems ridiculous!  What does it tell us?  It definitely 
> didn't get there as part of any reasonable logic, right?  So, what can it be 
> instead?  Only one answer here - garbage.  We have some sort of memory issue 
> with integers that we use as part of our ranges!  So, let's see what type of 
> information `Range` class actually stores:
> ```
> class Range {
> public:
>   Range(const llvm::APSInt &From, const llvm::APSInt &To) : Impl(&From, &To) {
>     assert(From <= To);
>   }
> 
> ...
> 
> private:
>   std::pair<const llvm::APSInt *, const llvm::APSInt *> Impl;
> };
> ```
> 
> What we have here is a pair of pointers, and you have:
> ```
>   llvm::APSInt Min = LHS.From() + RHS.From();
>   llvm::APSInt Max = LHS.To() + RHS.To();
>   llvm::APSInt Tmin = ValueFactory.getMinValue(ResultType);
>   llvm::APSInt Tmax = ValueFactory.getMaxValue(ResultType);
> ```
> These are ALL stack variables. So, pointer to those point to adequate data 
> ONLY while we are inside of our functions.  When we call another function, 
> these pointers point into some data from some other function in the call 
> stack, it doesn't point to anything even remotely resembling `llvm::APSInt` 
> and we get `BitWidth = 4022311424`.
> 
> OK, we figured out the problem, what about a solution?  If you look at other 
> implementations, you can notice a couple of interesting things.
> When you do:
> ```
> llvm::APSInt Tmin = ValueFactory.getMinValue(ResultType);
> ```
> other code does something like:
> ```
> const llvm::APSInt &Tmin = ValueFactory.getMinValue(ResultType);
> ```
> Or when you do:
> ```
> Range Second = Range(Min, Tmax);
> ```
> The sibling code does:
> ```
> return {RangeFactory, ValueFactory.getValue(Min), ValueFactory.getValue(Max)};
> ```
> 
> It looks like `ValueFactory` is the key here!  It actually manages the 
> lifetime of those integers for you and, whenever you ask it about values, it 
> gives you `llvm::APSInt &` (note the reference part) that will have the 
> correct lifetime.
> 
> I hope this gives you some insight into how you can debug things like this on 
> your own and how you can reason about what you see.
> 
> Another piece of advice is to look around, other `VisitBinaryOperator` 
> methods have all the information you actually needed.  If you don't 
> understand why we need `ValueFactory`, - experiment, ask us!  It's bad to 
> just ignore it.
Got it! I am working on fixing this. 


================
Comment at: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp:1405-1406
+    RangeSet ResultRangeSet = RangeFactory.getRangeSet(First);
+    RangeSet ResultRangeSet2 = RangeFactory.add(ResultRangeSet, Second);
+    return ResultRangeSet2;
+  }
----------------
vsavchenko wrote:
> Why not just `return RangeFactory.add(ResultRangeSet, Second)`?
> 
> NOTE: variables with integers in their names is a big no-no.
Right! I assumed I have to refactor this part so I used this temporarily.


================
Comment at: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp:1409-1415
+  if ((LHS.From() > 0 && RHS.From() > 0 && Min < 0) ||
+      (LHS.From() < 0 && RHS.From() < 0 && Min > 0) ||
+      (LHS.To() > 0 && RHS.To() > 0 && Max < 0) ||
+      (LHS.To() < 0 && RHS.To() < 0 && Max > 0)) {
+    // return [Tmin, Tmax]
+    return {RangeFactory, Tmin, Tmax};
+  }
----------------
vsavchenko wrote:
> I thought we talked quite a lot that there is nothing bad with overflows and 
> here we have that if ANY overflow happened, we bail out and don't give any 
> result.
Understood! Should I replace it with code returning EmptySet()?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103440/new/

https://reviews.llvm.org/D103440

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to