[clang] 0ffbbce - Don't take the expression range into account when looking for widening

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 1 17:42:23 PDT 2020


Author: Richard Smith
Date: 2020-09-01T17:42:12-07:00
New Revision: 0ffbbce78de60f4f4d03d6ef97fe2f3bb4275e08

URL: https://github.com/llvm/llvm-project/commit/0ffbbce78de60f4f4d03d6ef97fe2f3bb4275e08
DIFF: https://github.com/llvm/llvm-project/commit/0ffbbce78de60f4f4d03d6ef97fe2f3bb4275e08.diff

LOG: Don't take the expression range into account when looking for widening
of a unary - expression.

This fixes an issue where we'd produce bogus diagnostics, and also
should recover ~0.3% compile time.

Added: 
    

Modified: 
    clang/lib/Sema/SemaChecking.cpp
    clang/test/Sema/unary-minus-integer-impcast.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 2e07c8f63b79..f2b70be1d431 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -12064,13 +12064,13 @@ static void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
             << E->getType());
   }
 
-  IntRange MinSourceRange =
+  IntRange SourceTypeRange =
+      IntRange::forTargetOfCanonicalType(S.Context, Source);
+  IntRange LikelySourceRange =
       GetExprRange(S.Context, E, S.isConstantEvaluated(), /*Approximate*/ true);
-  IntRange MaxSourceRange =
-      GetExprRange(S.Context, E, S.isConstantEvaluated(), /*Approximate*/ false);
   IntRange TargetRange = IntRange::forTargetOfCanonicalType(S.Context, Target);
 
-  if (MinSourceRange.Width > TargetRange.Width) {
+  if (LikelySourceRange.Width > TargetRange.Width) {
     // If the source is a constant, use a default-on diagnostic.
     // TODO: this should happen for bitfield stores, too.
     Expr::EvalResult Result;
@@ -12103,9 +12103,7 @@ static void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
     return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_integer_precision);
   }
 
-  // Only warn here if E can't possibly reach the target range, not only if
-  // it's not likely to be in that range.
-  if (TargetRange.Width > MaxSourceRange.Width) {
+  if (TargetRange.Width > SourceTypeRange.Width) {
     if (auto *UO = dyn_cast<UnaryOperator>(E))
       if (UO->getOpcode() == UO_Minus)
         if (Source->isUnsignedIntegerType()) {
@@ -12118,8 +12116,9 @@ static void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
         }
   }
 
-  if (TargetRange.Width == MinSourceRange.Width && !TargetRange.NonNegative &&
-      MinSourceRange.NonNegative && Source->isSignedIntegerType()) {
+  if (TargetRange.Width == LikelySourceRange.Width &&
+      !TargetRange.NonNegative && LikelySourceRange.NonNegative &&
+      Source->isSignedIntegerType()) {
     // Warn when doing a signed to signed conversion, warn if the positive
     // source value is exactly the width of the target type, which will
     // cause a negative value to be stored.
@@ -12144,9 +12143,9 @@ static void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
     // Fall through for non-constants to give a sign conversion warning.
   }
 
-  if ((TargetRange.NonNegative && !MinSourceRange.NonNegative) ||
-      (!TargetRange.NonNegative && MinSourceRange.NonNegative &&
-       MinSourceRange.Width == TargetRange.Width)) {
+  if ((TargetRange.NonNegative && !LikelySourceRange.NonNegative) ||
+      (!TargetRange.NonNegative && LikelySourceRange.NonNegative &&
+       LikelySourceRange.Width == TargetRange.Width)) {
     if (S.SourceMgr.isInSystemMacro(CC))
       return;
 

diff  --git a/clang/test/Sema/unary-minus-integer-impcast.c b/clang/test/Sema/unary-minus-integer-impcast.c
index 0eb440175881..894ceff9a40f 100644
--- a/clang/test/Sema/unary-minus-integer-impcast.c
+++ b/clang/test/Sema/unary-minus-integer-impcast.c
@@ -17,4 +17,7 @@ void test(void) {
 #else
 // expected-warning at -4 {{implicit conversion changes signedness: 'unsigned int' to 'long'}}
 #endif
+
+  unsigned m;
+  int n = -(m & 0xff); // no warning
 }


        


More information about the cfe-commits mailing list