leonardchan created this revision.
leonardchan added reviewers: phosek, mcgrathr, jakehehrlich.
leonardchan added a project: clang.
This patch contains changes and a test for checking that fixed point types can
be converted between all other valid types. Fixed point types can be converted
between floating point types, integral types, and other fixed point types.
This is a child of https://reviews.llvm.org/D46963
Repository:
rC Clang
https://reviews.llvm.org/D46979
Files:
include/clang/AST/OperationKinds.def
lib/AST/Expr.cpp
lib/AST/ExprConstant.cpp
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprAgg.cpp
lib/CodeGen/CGExprComplex.cpp
lib/CodeGen/CGExprConstant.cpp
lib/CodeGen/CGExprScalar.cpp
lib/Edit/RewriteObjCFoundationAPI.cpp
lib/Sema/SemaExpr.cpp
lib/StaticAnalyzer/Core/ExprEngineC.cpp
test/Frontend/fixed_point_all_conversions.c
Index: test/Frontend/fixed_point_all_conversions.c
===
--- /dev/null
+++ test/Frontend/fixed_point_all_conversions.c
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -Werror %s
+
+// Test for conversions between fixed point types and all other valid types.
+
+// Conversion from one type to another type
+#define CONVERT(FROM_TYPE, FROM_ID, TO_TYPE, TO_ID) \
+ TO_TYPE FROM_ID ## _to_ ## TO_ID (FROM_TYPE x) { return x; }
+
+// Conversion between 2 types
+#define CONVERT_COMBINATION(TYPE1, ID1, TYPE2, ID2) \
+ CONVERT(TYPE1, ID1, TYPE2, ID2) \
+ CONVERT(TYPE2, ID2, TYPE1, ID1)
+
+// Conversion between one type and floating point types
+#define CONVERT_BETWEEN_FLOATS(TYPE, ID) \
+ CONVERT_COMBINATION(TYPE, ID, float, Float) \
+ CONVERT_COMBINATION(TYPE, ID, double, Double)
+
+// Conversion between one type and an integral type with differant signage
+#define CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, INT_TYPE, INT_ID) \
+ CONVERT_COMBINATION(TYPE, ID, INT_TYPE, INT_ID) \
+ CONVERT_COMBINATION(TYPE, ID, signed INT_TYPE, Signed ## INT_ID) \
+ CONVERT_COMBINATION(TYPE, ID, unsigned INT_TYPE, Unsigned ## INT_ID)
+
+// Conversion between one type and all integral types
+#define CONVERT_BETWEEN_INTEGRALS(TYPE, ID) \
+ CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, char, Char) \
+ CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, short, Short) \
+ CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, int, Int) \
+ CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, long, Long) \
+ CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, long long, LongLong)
+
+// Conversion between one type and a fixed point type with different saturation
+#define CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, FIXED_TYPE, FIXED_ID) \
+ CONVERT_COMBINATION(TYPE, ID, FIXED_TYPE, FIXED_ID) \
+ CONVERT_COMBINATION(TYPE, ID, _Sat FIXED_TYPE, Sat ## FIXED_ID)
+
+// Conversion between one type and a fixed point type with different signage
+#define CONVERT_BETWEEN_FIXED_POINT_WITH_SIGN(TYPE, ID, FIXED_TYPE, FIXED_ID) \
+ CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, FIXED_TYPE, FIXED_ID) \
+ CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, signed FIXED_TYPE, Signed ## FIXED_ID) \
+ CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, unsigned FIXED_TYPE, Unsigned ## FIXED_ID)
+
+// Convert between one type and all fixed point types.
+// Add "Type" to the end of the ID to avoid multiple definitions of a function
+// if the Type is a fixed point type.
+#define CONVERT_BETWEEN_FIXED_POINT(TYPE, ID) \
+ CONVERT_BETWEEN_FIXED_POINT_WITH_SIGN(TYPE, ID, _Fract, FractType) \
+ CONVERT_BETWEEN_FIXED_POINT_WITH_SIGN(TYPE, ID, _Accum, AccumType)
+
+// Convert between one type and all other types
+#define CONVERT_BETWEEN_ALL_TYPES(TYPE, ID) \
+ CONVERT_BETWEEN_FLOATS(TYPE, ID) \
+ CONVERT_BETWEEN_INTEGRALS(TYPE, ID) \
+ CONVERT_BETWEEN_FIXED_POINT(TYPE, ID)
+
+#define CONVERT_FIXED_POINT_TYPE_WITH_SAT(TYPE, ID) \
+ CONVERT_BETWEEN_ALL_TYPES(TYPE, ID) \
+ CONVERT_BETWEEN_ALL_TYPES(_Sat TYPE, Sat ## ID)
+
+#define CONVERT_FIXED_POINT_TYPE(TYPE, ID) \
+ CONVERT_FIXED_POINT_TYPE_WITH_SAT(TYPE, ID) \
+ CONVERT_FIXED_POINT_TYPE_WITH_SAT(signed TYPE, Signed ## ID) \
+ CONVERT_FIXED_POINT_TYPE_WITH_SAT(unsigned TYPE, Unsigned ## ID)
+
+CONVERT_FIXED_POINT_TYPE(short _Fract, ShortFract);
+CONVERT_FIXED_POINT_TYPE(_Fract, Fract);
+CONVERT_FIXED_POINT_TYPE(long _Fract, LongFract);
+
+CONVERT_FIXED_POINT_TYPE(short _Accum, ShortAccum);
+CONVERT_FIXED_POINT_TYPE(_Accum, Accum);
+CONVERT_FIXED_POINT_TYPE(long _Accum, LongAccum);
Index: lib/StaticAnalyzer/Core/ExprEngineC.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -321,6 +321,7 @@
const LocationContext *LCtx = Pred->getLocationContext();
switch (CastE->getCastKind()) {
+ case CK_FloatingToFixedPoint: llvm_unreachable("CK_FloatingToFixedPoint");
case CK_FixedPointToFloating: llvm_unreachable("Unimplemented logic for CK_FixedPointToFloating");
case