diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h @@ -152,7 +152,8 @@ T = AT->getValueType(); } - assert(T->isIntegralOrEnumerationType() || Loc::isLocType(T)); + assert(T->isIntegralOrEnumerationType() || T->isFixedPointType() || + Loc::isLocType(T)); return APSIntType(Ctx.getIntWidth(T), !T->isSignedIntegerOrEnumerationType()); } diff --git a/clang/test/Analysis/fixed-point.c b/clang/test/Analysis/fixed-point.c new file mode 100644 --- /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 en_t { en_0 = 1 }; + +void _enum(int c) { + (void)((enum en_t) 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); +}