================
@@ -768,6 +768,59 @@ void InitializeOpenCLFeatureTestMacros(const TargetInfo 
&TI,
   Builder.defineMacro("__opencl_c_int64");
 }
 
+std::string ConstructFixedPointLiteral(llvm::APFixedPoint Val,
+                                       llvm::StringRef Suffix) {
+  if (Val.isSigned() && Val == llvm::APFixedPoint::getMin(Val.getSemantics())) 
{
+    // When representing the min value of a signed fixed point type in source
+    // code, we cannot simply write `-<lowest value>`. For example, the min
+    // value of a `short _Fract` cannot be written as `-1.0hr`. This is because
+    // the parser will read this (and really any negative numerical literal) as
+    // a UnaryOperator that owns a FixedPointLiteral with a positive value
+    // rather than just a FixedPointLiteral with a negative value. Compiling
+    // `-1.0hr` results in an overflow to the maximal value of that fixed point
+    // type. The correct way to represent a signed min value is to instead 
split
+    // it into two halves, like `(-0.5hr-0.5hr)` which is what the standard
+    // defines SFRACT_MIN as.
+    std::string Literal;
+    std::string HalfStr = ConstructFixedPointLiteral(Val.shr(1), Suffix);
+    Literal.push_back('(');
+    Literal += HalfStr;
----------------
MaskRay wrote:

Returning `SmallString`  and using `Twine` to concatenate strings is slightly 
more efficient.

https://github.com/llvm/llvm-project/pull/81207
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to