r199405 - [analyzer] Shitfing a constant value by its bit width is undefined.

Jordan Rose jordan_rose at apple.com
Thu Jan 16 10:02:23 PST 2014


Author: jrose
Date: Thu Jan 16 12:02:23 2014
New Revision: 199405

URL: http://llvm.org/viewvc/llvm-project?rev=199405&view=rev
Log:
[analyzer] Shitfing a constant value by its bit width is undefined.

Citation: C++11 [expr.shift]p1 (and the equivalent text in C11).

This fixes PR18073, but the right thing to do (as noted in the FIXME) is to
have a real checker for too-large shifts.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
    cfe/trunk/test/Analysis/bitwise-ops.c

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BasicValueFactory.cpp?rev=199405&r1=199404&r2=199405&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BasicValueFactory.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BasicValueFactory.cpp Thu Jan 16 12:02:23 2014
@@ -177,7 +177,7 @@ BasicValueFactory::evalAPSInt(BinaryOper
 
       uint64_t Amt = V2.getZExtValue();
 
-      if (Amt > V1.getBitWidth())
+      if (Amt >= V1.getBitWidth())
         return NULL;
 
       return &getValue( V1.operator<<( (unsigned) Amt ));
@@ -195,7 +195,7 @@ BasicValueFactory::evalAPSInt(BinaryOper
 
       uint64_t Amt = V2.getZExtValue();
 
-      if (Amt > V1.getBitWidth())
+      if (Amt >= V1.getBitWidth())
         return NULL;
 
       return &getValue( V1.operator>>( (unsigned) Amt ));

Modified: cfe/trunk/test/Analysis/bitwise-ops.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/bitwise-ops.c?rev=199405&r1=199404&r2=199405&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/bitwise-ops.c (original)
+++ cfe/trunk/test/Analysis/bitwise-ops.c Thu Jan 16 12:02:23 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -triple x86_64-apple-darwin13 -Wno-shift-count-overflow -verify %s
 
 void clang_analyzer_eval(int);
 #define CHECK(expr) if (!(expr)) return; clang_analyzer_eval(expr)
@@ -11,4 +11,22 @@ void testPersistentConstraints(int x, in
   // False positives due to SValBuilder giving up on certain kinds of exprs.
   CHECK(1 - x); // expected-warning{{UNKNOWN}}
   CHECK(x & y); // expected-warning{{UNKNOWN}}
+}
+
+int testConstantShifts_PR18073(int which) {
+  // FIXME: We should have a checker that actually specifically checks bitwise
+  // shifts against the width of the LHS's /static/ type, rather than just
+  // having BasicValueFactory return "undefined" when dealing with two constant
+  // operands.
+  switch (which) {
+  case 1:
+    return 0ULL << 63; // no-warning
+  case 2:
+    return 0ULL << 64; // expected-warning{{The result of the '<<' expression is undefined}}
+  case 3:
+    return 0ULL << 65; // expected-warning{{The result of the '<<' expression is undefined}}
+
+  default:
+    return 0;
+  }
 }
\ No newline at end of file





More information about the cfe-commits mailing list