[PATCH] D66014: [analyzer] Avoid unnecessary enum range check on LValueToRValue casts

Kristóf Umann via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 23 07:20:17 PDT 2019


This revision was automatically updated to reflect the committed changes.
Closed by commit rL369760: [analyzer] Avoid unnecessary enum range check on LValueToRValue casts (authored by Szelethus, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D66014?vs=215433&id=216842#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D66014

Files:
  cfe/trunk/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
  cfe/trunk/test/Analysis/enum-cast-out-of-range.c
  cfe/trunk/test/Analysis/enum-cast-out-of-range.cpp


Index: cfe/trunk/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
===================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
@@ -91,6 +91,22 @@
 
 void EnumCastOutOfRangeChecker::checkPreStmt(const CastExpr *CE,
                                              CheckerContext &C) const {
+
+  // Only perform enum range check on casts where such checks are valid.  For
+  // all other cast kinds (where enum range checks are unnecessary or invalid),
+  // just return immediately.  TODO: The set of casts whitelisted for enum
+  // range checking may be incomplete.  Better to add a missing cast kind to
+  // enable a missing check than to generate false negatives and have to remove
+  // those later.
+  switch (CE->getCastKind()) {
+  case CK_IntegralCast:
+    break;
+
+  default:
+    return;
+    break;
+  }
+
   // Get the value of the expression to cast.
   const llvm::Optional<DefinedOrUnknownSVal> ValueToCast =
       C.getSVal(CE->getSubExpr()).getAs<DefinedOrUnknownSVal>();
Index: cfe/trunk/test/Analysis/enum-cast-out-of-range.c
===================================================================
--- cfe/trunk/test/Analysis/enum-cast-out-of-range.c
+++ cfe/trunk/test/Analysis/enum-cast-out-of-range.c
@@ -0,0 +1,34 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:   -analyzer-checker=core,alpha.cplusplus.EnumCastOutOfRange \
+// RUN:   -verify %s
+
+enum En_t {
+  En_0 = -4,
+  En_1,
+  En_2 = 1,
+  En_3,
+  En_4 = 4
+};
+
+void unscopedUnspecifiedCStyle() {
+  enum En_t Below = (enum En_t)(-5);    // expected-warning {{not in the valid range}}
+  enum En_t NegVal1 = (enum En_t)(-4);  // OK.
+  enum En_t NegVal2 = (enum En_t)(-3);  // OK.
+  enum En_t InRange1 = (enum En_t)(-2); // expected-warning {{not in the valid range}}
+  enum En_t InRange2 = (enum En_t)(-1); // expected-warning {{not in the valid range}}
+  enum En_t InRange3 = (enum En_t)(0);  // expected-warning {{not in the valid range}}
+  enum En_t PosVal1 = (enum En_t)(1);   // OK.
+  enum En_t PosVal2 = (enum En_t)(2);   // OK.
+  enum En_t InRange4 = (enum En_t)(3);  // expected-warning {{not in the valid range}}
+  enum En_t PosVal3 = (enum En_t)(4);   // OK.
+  enum En_t Above = (enum En_t)(5);     // expected-warning {{not in the valid range}}
+}
+
+enum En_t unused;
+void unusedExpr() {
+  // Following line is not something that EnumCastOutOfRangeChecker should
+  // evaluate.  Checker should either ignore this line or process it without
+  // producing any warnings.  However, compilation will (and should) still
+  // generate a warning having nothing to do with this checker.
+  unused; // expected-warning {{expression result unused}}
+}
Index: cfe/trunk/test/Analysis/enum-cast-out-of-range.cpp
===================================================================
--- cfe/trunk/test/Analysis/enum-cast-out-of-range.cpp
+++ cfe/trunk/test/Analysis/enum-cast-out-of-range.cpp
@@ -150,7 +150,15 @@
   scoped_specified_t InvalidAfterRangeEnd = (scoped_specified_t)(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}}
 }
 
-void rangeContstrained1(int input) {
+unscoped_unspecified_t unused;
+void unusedExpr() {
+  // following line is not something that EnumCastOutOfRangeChecker should evaluate.  checker should either ignore this line
+  // or process it without producing any warnings.  However, compilation will (and should) still generate a warning having
+  // nothing to do with this checker.
+  unused; // expected-warning {{expression result unused}}
+}
+
+void rangeConstrained1(int input) {
   if (input > -5 && input < 5)
     auto value = static_cast<scoped_specified_t>(input); // OK. Being conservative, this is a possibly good value.
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D66014.216842.patch
Type: text/x-patch
Size: 3886 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190823/022ae210/attachment-0001.bin>


More information about the cfe-commits mailing list