NoQ accepted this revision.
NoQ added inline comments.

================
Comment at: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp:734
   //        expressions which we currently do not know how to negate.
-  const RangeSet *getRangeForMinusSymbol(ProgramStateRef State, SymbolRef Sym) 
{
+  Optional<RangeSet> getRangeForInvertedSub(SymbolRef Sym) {
     if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(Sym)) {
----------------
vsavchenko wrote:
> ASDenysPetrov wrote:
> > vsavchenko wrote:
> > > ASDenysPetrov wrote:
> > > > As for me, I'd call this like `getRangeForNegatedSymSymExpr`, since you 
> > > > do Negate operation inside.
> > > I'm not super happy about my name either, but I feel like it describes it 
> > > better than the previous name and your version.  That function doesn't 
> > > work for any `SymSymExpr` and it doesn't simply negate whatever we gave 
> > > it.  It works specifically for symbolic subtractions and this is the 
> > > information I want to be reflected in the name.
> > Oh, I just assumed //...Sub// at the end as a //subexpression// but you 
> > mean //subtraction//. What I'm trying to say is that we can rename it like 
> > `getRangeFor...`//the expression which this function can handle//. E.g. 
> > `getRangeForNegatedSubtractionSymSymExpr`. My point is in a speaking name.
> > 
> > I think //invertion// is not something appropriate in terms of applying 
> > minus operator. I think invertion of zero should be something opposite but 
> > not a zero. Because when you would like to implement the function which 
> > turns [A, B] into [MIN, A)U(B, MAX], what would be the name of it? I think 
> > this is an //invertion//.
> > 
> > But this is not a big deal, it's just my thoughts.
> My thought process here was that we are trying to get range for `A - B` and 
> there is also information on `B - A`, so we can get something for `A - B` 
> based on that.  So, it doesn't really matter what it does under the hood with 
> ranges, it matters what its semantics are.  Here I called `B - A` //an 
> inverted subtraction//.
> I don't really know what would be the best name, but I thought that this one 
> makes more sense.
> Because when you would like to implement the function which turns [A, B] into 
> [MIN, A)U(B, MAX], what would be the name of it? I think this is an 
> //invertion//.

https://en.wikipedia.org/wiki/Complement_(set_theory)
https://en.wikipedia.org/wiki/Inverse_function

"Negated subtraction" is definitely my favorite so far. "Mirrored" might be a 
good layman term as well.


================
Comment at: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp:467-470
+/// Available representations for the arguments are:
+///   * RangeSet
+///   * Optional<RangeSet>
+///   * RangeSet *
----------------
vsavchenko wrote:
> xazax.hun wrote:
> > NoQ wrote:
> > > Why do we have these representations in the first place?
> > > 
> > > It sounds like you're treating null pointers / empty optionals 
> > > equivalently to full ranges (i.e., intersecting with them has no effect). 
> > > How hard would it be to simply construct an actual full range in all the 
> > > places in which we currently have empty optionals?
> > +1
> > 
> > I also find this confusing. Should I interpret a None as a full or empty 
> > range? Does this depend on the context or a general rule? Is there any 
> > reason we need to handle nullable pointers or could we actually make call 
> > sites more uniform to get rid of some of the complexity here?
> > It sounds like you're treating null pointers / empty optionals equivalently 
> > to full ranges (i.e., intersecting with them has no effect)
> It is not actually true.  Empty optionals is the information that "this range 
> information is not available for this symbol".  It is true that intersecting 
> with them has no effect, but they are semantically different in other 
> aspects.  
> 
> Currently solver RELIES on the information that whether the range is 
> available or not (see my previous comment), and we simply couldn't get rid of 
> this behavior as part of NFC.
> 
> > How hard would it be to simply construct an actual full range in all the 
> > places in which we currently have empty optionals?
> It is not hard architecturally, but it WILL make the change functional and 
> possibly impact the performance.
> 
> > Should I interpret a None as a full or empty range?
> Neither of those.  That is the problem right now, that we rely on different 
> sources of information for the ranges and behave differently depending on 
> whether one piece of information is available or not.
> 
> > Does this depend on the context or a general rule?
> Semantics are always the same - this info is not available.
> 
> > Is there any reason we need to handle nullable pointers?
> `State->get<XYZ>(abc)` returns a nullable pointer meaning optional object, it 
> is hard to avoid it especially because we currently behave very differently 
> when this information is not available.
> 
> > ...could we actually make call sites more uniform to get rid of some of the 
> > complexity here?
> Yes we can, but later on. See the explanations above and in my other comment.
> it WILL make the change functional and possibly impact the performance

Mmm, yeah, i guess the necessity to construct a full range and then do the 
possibly O(N) intersection when it'll do nothing most of the time is indeed 
daunting.

Maybe we should implement full ranges as a special case in the `RangeSet` 
class? Like, don't actually construct the single range, just remember the type; 
special-case all operations on such sets to perform trivially in O(1), etc.?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D82381



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

Reply via email to