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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits