[clang] [analyzer] Model concrete floating-point values (PR #214098)

Balázs Benics via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 21 10:01:27 PDT 2026


================
@@ -275,6 +275,34 @@ class SValBuilder {
                      integer->getType()->isUnsignedIntegerOrEnumerationType()));
   }
 
+  /// Whether a nonloc::ConcreteFloat may hold \p V.
+  ///
+  /// Infinities and NaNs are not modeled: the semantics of which depend on
+  /// IEC 60559 conformance which is not readily available to the analyzer, so
+  /// we leave these as unknowns. NaNs we can never model, since LangRef
+  /// dictates their bit patterns are non-deterministic. Subnormals are not
+  /// modeled because their semantics depend on hardware and compiler denormal
+  /// modes which the analyzer cannot see. IBM double-double is also not modeled
+  /// because some of its operations are inaccurately emulated.
+  static bool isModeledFloatValue(const llvm::APFloat &V) {
+    return V.isFinite() && !V.isDenormal() &&
+           llvm::APFloat::SemanticsToEnum(V.getSemantics()) !=
+               llvm::APFloat::S_PPCDoubleDouble;
+  }
+
+  /// Create a concrete floating-point value. The value must satisfy
+  /// \c isModeledFloatValue.
+  nonloc::ConcreteFloat makeFloatVal(const FloatingLiteral *F) {
+    assert(isModeledFloatValue(F->getValue()) &&
+           "ConcreteFloat must be normal and finite");
+    return nonloc::ConcreteFloat(BasicVals.getFloatValue(F->getValue()));
+  }
+
+  nonloc::ConcreteFloat makeFloatVal(const llvm::APFloat &F) {
+    assert(isModeledFloatValue(F) && "ConcreteFloat must be normal and finite");
+    return nonloc::ConcreteFloat(BasicVals.getFloatValue(F));
+  }
----------------
steakhal wrote:

I was thinking if the callsites anyway must check if they satisfy `isModeledFloatValue`, why don't we wrap this and return std::optional and nullopt on failure?

https://github.com/llvm/llvm-project/pull/214098


More information about the cfe-commits mailing list