[PATCH] D45417: [analyzer] Don't crash on printing ConcreteInt of size >64 bits

Aleksei Sidorin via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sun Apr 8 10:43:05 PDT 2018


a.sidorin created this revision.
a.sidorin added reviewers: NoQ, dcoughlin, xazax.hun.
Herald added subscribers: cfe-commits, rnkovacs, szepet.
Herald added a reviewer: george.karpenkov.

Printing of ConcreteInts with size >64 bits resulted in assertion failure in get[Z|S]ExtValue() :`getActiveBits() <= 64 && "Too many bits for uint64_t"' failed'`. This patch fixes the issue.

Patch by Ivan Sidorenko!


Repository:
  rC Clang

https://reviews.llvm.org/D45417

Files:
  lib/StaticAnalyzer/Core/SVals.cpp
  test/Analysis/egraph-dump-int128.c


Index: test/Analysis/egraph-dump-int128.c
===================================================================
--- /dev/null
+++ test/Analysis/egraph-dump-int128.c
@@ -0,0 +1,7 @@
+// RUN: rm -fR %t.dir
+// RUN: mkdir -p %t.dir
+// RUN: env TMPDIR=%t.dir TEMP=%t.dir TMP=%t.dir %clang_analyze_cc1 -analyzer-checker=debug.ViewExplodedGraph %s
+
+unsigned __int128 get_big_value() {
+  return (unsigned __int128)5 << 64; // Do not crash
+}
Index: lib/StaticAnalyzer/Core/SVals.cpp
===================================================================
--- lib/StaticAnalyzer/Core/SVals.cpp
+++ lib/StaticAnalyzer/Core/SVals.cpp
@@ -301,12 +301,21 @@
   switch (getSubKind()) {
     case nonloc::ConcreteIntKind: {
       const nonloc::ConcreteInt& C = castAs<nonloc::ConcreteInt>();
-      if (C.getValue().isUnsigned())
-        os << C.getValue().getZExtValue();
-      else
-        os << C.getValue().getSExtValue();
-      os << ' ' << (C.getValue().isUnsigned() ? 'U' : 'S')
-         << C.getValue().getBitWidth() << 'b';
+      bool IsSigned = C.getValue().isSigned();
+      // FIXME: We can just call C.getValue().print() for all cases, but it has
+      //        rather slow performance (see implementation of toString()).
+      //        Let's call it only for integer values > 64 bits.
+      if (C.getValue().getBitWidth() <= llvm::APInt::APINT_BITS_PER_WORD) {
+        // NOTE: don't use ternary here! Otherwise, unsigned value will be
+        // always printed due to implicit type conversion.
+        if (IsSigned)
+          os << C.getValue().getSExtValue();
+        else
+          os << C.getValue().getZExtValue();
+      } else {
+        C.getValue().print(os, IsSigned);
+      }
+      os << ' ' << (IsSigned ? 'S' : 'U') << C.getValue().getBitWidth() << 'b';
       break;
     }
     case nonloc::SymbolValKind:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D45417.141557.patch
Type: text/x-patch
Size: 1840 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180408/6fe5766f/attachment-0001.bin>


More information about the cfe-commits mailing list