[clang] 443b46e - [analyzer] Fix assertion in getAPSIntType

via cfe-commits cfe-commits at lists.llvm.org
Sun Dec 11 15:58:33 PST 2022


Author: einvbri
Date: 2022-12-11T17:56:51-06:00
New Revision: 443b46e6d3139c1306caddd06efa674dcea9f38f

URL: https://github.com/llvm/llvm-project/commit/443b46e6d3139c1306caddd06efa674dcea9f38f
DIFF: https://github.com/llvm/llvm-project/commit/443b46e6d3139c1306caddd06efa674dcea9f38f.diff

LOG: [analyzer] Fix assertion in getAPSIntType

getAPSIntType crashes when analzying a simple case that uses a fixed
point type. getAPSIntType needs to handle fixed point types differently
to get sign information. LIT and Unittests were added since there were
 none previously added.

   clang: <root>/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h:155:
      clang::ento::APSIntType clang::ento::BasicValueFactory::getAPSIntType(clang::QualType) const:
      Assertion `T->isIntegralOrEnumerationType() || Loc::isLocType(T)' failed.

    Program received signal SIGABRT, Aborted.
    0x00007ffff66e2387 in raise () from /lib64/libc.so.6
    (gdb) bt
        at <root>/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h:155
        at <root>/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h:172
          LHS=0x108965a0, op=clang::BO_Shr, RHS=..., resultTy=...) at
          <root>/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp:213
          (this=0x1088e460, state=..., op=clang::BO_Shr, lhs=..., rhs=..., resultTy=...)
          at <root>/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp:681

Reviewed By: steakhal

Differential Revision: https://reviews.llvm.org/D139759

Added: 
    clang/test/Analysis/fixed-point.c
    clang/unittests/StaticAnalyzer/APSIntTypeTest.cpp

Modified: 
    clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
    clang/unittests/StaticAnalyzer/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
index 59bfbe3dea77b..ec503b41b381a 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
@@ -152,9 +152,15 @@ class BasicValueFactory {
       T = AT->getValueType();
     }
 
-    assert(T->isIntegralOrEnumerationType() || Loc::isLocType(T));
-    return APSIntType(Ctx.getIntWidth(T),
-                      !T->isSignedIntegerOrEnumerationType());
+    if (T->isIntegralOrEnumerationType() || Loc::isLocType(T)) {
+      return APSIntType(Ctx.getIntWidth(T),
+                        !T->isSignedIntegerOrEnumerationType());
+    } else {
+      // implicitly handle case of T->isFixedPointType()
+      return APSIntType(Ctx.getIntWidth(T), T->isUnsignedFixedPointType());
+    }
+
+    llvm_unreachable("Unsupported type in getAPSIntType!");
   }
 
   /// Convert - Create a new persistent APSInt with the same value as 'From'

diff  --git a/clang/test/Analysis/fixed-point.c b/clang/test/Analysis/fixed-point.c
new file mode 100644
index 0000000000000..e8c7a4039510c
--- /dev/null
+++ b/clang/test/Analysis/fixed-point.c
@@ -0,0 +1,65 @@
+// RUN: %clang_analyze_cc1 -ffixed-point \
+// RUN:   -analyzer-checker=core,debug.ExprInspection -verify %s
+
+// expected-no-diagnostics
+
+// Check that getAPSIntType does not crash
+// when using fixed point types.
+
+enum Kind { en_0 = 1 };
+
+void _enum(int c) {
+  (void)((enum Kind) c >> 4);
+}
+
+void _inttype(int c) {
+  (void)(c >> 4);
+}
+
+void _accum(int c) {
+  (void)((_Accum) c >> 4);
+}
+
+void _fract(int c) {
+  (void)((_Fract) c >> 4);
+}
+
+void _long_fract(int c) {
+  (void)((long _Fract) c >> 4);
+}
+
+void _unsigned_accum(int c) {
+  (void)((unsigned _Accum) c >> 4);
+}
+
+void _short_unsigned_accum(int c) {
+  (void)((short unsigned _Accum) c >> 4);
+}
+
+void _unsigned_fract(int c) {
+  (void)((unsigned _Fract) c >> 4);
+}
+
+void sat_accum(int c) {
+  (void)((_Sat _Accum) c >> 4);
+}
+
+void sat_fract(int c) {
+  (void)((_Sat _Fract) c >> 4);
+}
+
+void sat_long_fract(int c) {
+  (void)((_Sat long _Fract) c >> 4);
+}
+
+void sat_unsigned_accum(int c) {
+  (void)((_Sat unsigned _Accum) c >> 4);
+}
+
+void sat_short_unsigned_accum(int c) {
+  (void)((_Sat short unsigned _Accum) c >> 4);
+}
+
+void sat_unsigned_fract(int c) {
+  (void)((_Sat unsigned _Fract) c >> 4);
+}

diff  --git a/clang/unittests/StaticAnalyzer/APSIntTypeTest.cpp b/clang/unittests/StaticAnalyzer/APSIntTypeTest.cpp
new file mode 100644
index 0000000000000..19adb1b77c675
--- /dev/null
+++ b/clang/unittests/StaticAnalyzer/APSIntTypeTest.cpp
@@ -0,0 +1,57 @@
+//===- unittest/StaticAnalyzer/APSIntTest.cpp - getAPSIntType  test --===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/TargetInfo.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+
+namespace {
+
+TEST(getAPSIntTypeTest, APSIntTypeTests) {
+  std::unique_ptr<clang::ASTUnit> AST = clang::tooling::buildASTFromCode("");
+  clang::ASTContext &Context = AST->getASTContext();
+  llvm::BumpPtrAllocator Arena;
+  clang::ento::BasicValueFactory BVF{Context, Arena};
+
+  clang::ento::APSIntType Ty = BVF.getAPSIntType(Context.LongAccumTy);
+  EXPECT_TRUE(Ty.getBitWidth() == Context.getTargetInfo().getLongAccumWidth());
+  EXPECT_FALSE(Ty.isUnsigned());
+
+  Ty = BVF.getAPSIntType(Context.UnsignedLongAccumTy);
+  EXPECT_TRUE(Ty.getBitWidth() == Context.getTargetInfo().getLongAccumWidth());
+  EXPECT_TRUE(Ty.isUnsigned());
+
+  Ty = BVF.getAPSIntType(Context.LongFractTy);
+  EXPECT_TRUE(Ty.getBitWidth() == Context.getTargetInfo().getLongFractWidth());
+  EXPECT_FALSE(Ty.isUnsigned());
+
+  Ty = BVF.getAPSIntType(Context.UnsignedLongFractTy);
+  EXPECT_TRUE(Ty.getBitWidth() == Context.getTargetInfo().getLongFractWidth());
+  EXPECT_TRUE(Ty.isUnsigned());
+
+  Ty = BVF.getAPSIntType(Context.SignedCharTy);
+  EXPECT_TRUE(Ty.getBitWidth() == Context.getTargetInfo().getCharWidth());
+  EXPECT_FALSE(Ty.isUnsigned());
+
+  Ty = BVF.getAPSIntType(Context.UnsignedCharTy);
+  EXPECT_TRUE(Ty.getBitWidth() == Context.getTargetInfo().getCharWidth());
+  EXPECT_TRUE(Ty.isUnsigned());
+
+  Ty = BVF.getAPSIntType(Context.LongTy);
+  EXPECT_TRUE(Ty.getBitWidth() == Context.getTargetInfo().getLongWidth());
+  EXPECT_FALSE(Ty.isUnsigned());
+
+  Ty = BVF.getAPSIntType(Context.UnsignedLongTy);
+  EXPECT_TRUE(Ty.getBitWidth() == Context.getTargetInfo().getLongWidth());
+  EXPECT_TRUE(Ty.isUnsigned());
+}
+
+} // end namespace

diff  --git a/clang/unittests/StaticAnalyzer/CMakeLists.txt b/clang/unittests/StaticAnalyzer/CMakeLists.txt
index b72b035780a1d..775f0f8486b8f 100644
--- a/clang/unittests/StaticAnalyzer/CMakeLists.txt
+++ b/clang/unittests/StaticAnalyzer/CMakeLists.txt
@@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS
 
 add_clang_unittest(StaticAnalysisTests
   AnalyzerOptionsTest.cpp
+  APSIntTypeTest.cpp
   BugReportInterestingnessTest.cpp
   CallDescriptionTest.cpp
   CallEventTest.cpp


        


More information about the cfe-commits mailing list