[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