diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2017-03-15 15:55:43 +0100 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2017-03-15 18:10:09 +0100 |
commit | 22d5a8f058610ec6e331f38106e34732c422b678 (patch) | |
tree | b5d651ddadde918d6e46240be72dd9905f469e8a /src/codegen/helpers.rs | |
parent | 16bd8b71fc8d2d2be793553dfc164776db058f64 (diff) |
ir: Generate non-finite floating point constants properly.
Diffstat (limited to 'src/codegen/helpers.rs')
-rw-r--r-- | src/codegen/helpers.rs | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/src/codegen/helpers.rs b/src/codegen/helpers.rs index 811d87c5..608f3f9e 100644 --- a/src/codegen/helpers.rs +++ b/src/codegen/helpers.rs @@ -158,17 +158,38 @@ pub mod ast_ty { .build_lit(aster::AstBuilder::new().lit().byte_str(string)) } - pub fn float_expr(f: f64) -> P<ast::Expr> { + pub fn float_expr(ctx: &BindgenContext, + f: f64) + -> Result<P<ast::Expr>, ()> { use aster::symbol::ToSymbol; - let mut string = f.to_string(); - // So it gets properly recognised as a floating point constant. - if !string.contains('.') { - string.push('.'); + if f.is_finite() { + let mut string = f.to_string(); + + // So it gets properly recognised as a floating point constant. + if !string.contains('.') { + string.push('.'); + } + + let kind = ast::LitKind::FloatUnsuffixed(string.as_str().to_symbol()); + return Ok(aster::AstBuilder::new().expr().lit().build_lit(kind)) + } + + let prefix = ctx.trait_prefix(); + if f.is_nan() { + return Ok(quote_expr!(ctx.ext_cx(), ::$prefix::f64::NAN)); + } + + if f.is_infinite() { + return Ok(if f.is_sign_positive() { + quote_expr!(ctx.ext_cx(), ::$prefix::f64::INFINITY) + } else { + quote_expr!(ctx.ext_cx(), ::$prefix::f64::NEG_INFINITY) + }); } - let kind = ast::LitKind::FloatUnsuffixed(string.as_str().to_symbol()); - aster::AstBuilder::new().expr().lit().build_lit(kind) + warn!("Unknown non-finite float number: {:?}", f); + return Err(()); } pub fn arguments_from_signature(signature: &FunctionSig, |