rsmith accepted this revision.
rsmith added a comment.
This revision is now accepted and ready to land.

Just some minor nits.



================
Comment at: docs/ReleaseNotes.rst:186
+
+  Just like other ``-fsanitize=integer`` checks, these issues are **not**
+  undefined behaviour. But they are not *always* intentional, and are somewhat
----------------
This seems inaccurate: `-fsanitize=signed-integer-overflow` is part of 
`-fsanitize=integer` and catches UB. Maybe "Like some other [...]"


================
Comment at: docs/ReleaseNotes.rst:190-191
+  but the ``-fsanitize=implicit-integer-sign-change`` check
+  (as is ``-fsanitize=implicit-integer-truncation`` check)
+  is enabled by ``-fsanitize=integer``.
 
----------------
This is a bit hard to read. Maybe reverse the order of these two lines.


================
Comment at: lib/CodeGen/CGExprScalar.cpp:1036
+    return;
+  // That's it. We can't rule out any more cases with the data we have.
+
----------------
lebedev.ri wrote:
> rsmith wrote:
> > rsmith wrote:
> > > lebedev.ri wrote:
> > > > rsmith wrote:
> > > > > I don't like the overlap between the implicit truncation check and 
> > > > > this check. I think you should aim for exactly one of those checks to 
> > > > > fire for any given integer conversion. There are the following cases:
> > > > > 
> > > > >  * Dst is smaller than Src: if the value changes at all (with sign 
> > > > > change or without), then the truncation check already catches it, and 
> > > > > catching it here does not seem useful
> > > > >  * Dst is the same size as Src or larger: sign change is the only 
> > > > > problem, and is only possible if exactly one of Src and Dst is signed
> > > > > 
> > > > > So I think you should bail out of this function if either Src and Dst 
> > > > > are both unsigned or both are signed, and also if Src is larger than 
> > > > > Dst (because we treat that case as a lossy truncation rather than as 
> > > > > a sign change).
> > > > > 
> > > > > And when you do emit a check here, the only thing you need to check 
> > > > > is if the signed value is negative (if so, you definitely changed the 
> > > > > sign, and if not, you definitely didn't -- except in the truncation 
> > > > > cases that the truncation sanitizer catches).
> > > > To be clear: we want to skip emitting in those cases if the other check 
> > > > (truncation) is enabled, right?
> > > > It does seem to make sense, (and i did thought about that a bit), but i 
> > > > need to think about it more..
> > > I think we want to skip emitting those checks always (regardless of 
> > > whether the other sanitizer is enabled). One way to think of it: this 
> > > sanitizer checks for non-truncating implicit integer conversions that 
> > > change the value of the result. The other sanitizer checks for truncating 
> > > implicit integer conversions that change the value of the result.
> > > 
> > > I don't see any point in allowing the user to ask to sanitize 
> > > sign-changing truncation but not other value-changing truncations. That 
> > > would lead to this:
> > > ```
> > > int a = 0x17fffffff; // no sanitizer warning
> > > int b = 0x180000000; // sanitizer warning
> > > int c = 0x1ffffffff; // sanitizer warning
> > > int d = 0x200000000; // no sanitizer warning
> > > ```
> > > ... which I think makes no sense.
> > Hmm, wait, the "truncation" sanitizer doesn't catch this:
> > 
> > `int a = 0x80000000u;`
> > 
> > ... does it? (Because it looks for cases where the value doesn't 
> > round-trip, not for cases where the value was changed by the truncation.)
> > 
> > 
> > I've thought a bit more about the user model and use cases for these 
> > sanitizers, and I think what we want is:
> > 
> >  * a sanitizer that checks for implicit conversions with data loss (the 
> > existing truncation sanitizer)
> >  * a sanitizer that checks for implicit conversions that change the value, 
> > where either the source or destination was signed (approximately what this 
> > sanitizer is doing)
> > 
> > The difference between that and what you have here is that I think the new 
> > sanitizer should catch all of these cases:
> > 
> > ```
> > int a = 0x17fffffff;
> > int b = 0x180000000;
> > int c = 0x1ffffffff;
> > int d = 0x200000000;
> > ```
> > 
> > ... because while the initializations of `a` and `d` don't change the sign 
> > of the result, that's only because they wrap around *past* a sign change.
> > 
> > So, I think what you have here is fine for the SrcBits <= DstBits case, but 
> > for the SrcBits > DstBits case, you should also check whether the value is 
> > the same as the original (that is, perform the truncation check).
> > 
> > In order to avoid duplicating work when both sanitizers are enabled, it'd 
> > make sense to combine the two sanitizer functions into a single function 
> > and reuse the checks.
> Yep, makes sense. I don't think i have followed the recommendations to the 
> letter,
> but i think the end result is not worse than suggested. Added tests shows how 
> it works now.
OK, so to be clear I'm following:

 * Any implicit conversion that truncates and changes the value triggers the 
truncation sanitizer (unsigned if both source and destination are unsigned, 
signed otherwise)
 * Any implicit conversion that results in a sign change triggers the sign 
change sanitizer
 * Any implicit conversion that triggers both sanitizers produces a single 
warning classified as ICCK_SignedIntegerTruncationOrSignChange (eg, the 
truncation changed the value, and the sign changed -- possibly multiple times 
-- when dropping bits)

That seems fine to me.


================
Comment at: lib/CodeGen/CGExprScalar.cpp:1071
+    // So which 'lt' predicate for the comparison do we have to use?
+    // NOTE: if it is unsigned, then the comparison is naturally always 
'false'.
+    llvm::ICmpInst::Predicate Pred =
----------------
Just emit `i1 false` directly in this case. `IRBuilder` generally only 
constant-folds values for you if all the operands are constant, and sanitizers 
are often used at -O0, so there's no guarantee that anyone else will clean this 
up.


================
Comment at: lib/CodeGen/CGExprScalar.cpp:1091-1103
+  //    Truth table:
+  //      /-----------------|-----------------|-----------------\
+  //      | src is negative | dst is negative | no sign change? |
+  //      |-----------------|-----------------|-----------------|
+  //      | false           | false           | true            |
+  //      |-----------------|-----------------|-----------------|
+  //      | false           | true            | false (!)       |
----------------
Do we really need this comment? This seems kinda obvious.


Repository:
  rC Clang

https://reviews.llvm.org/D50250



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

Reply via email to