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 | |
parent | 16bd8b71fc8d2d2be793553dfc164776db058f64 (diff) |
ir: Generate non-finite floating point constants properly.
Diffstat (limited to 'src/codegen')
-rw-r--r-- | src/codegen/helpers.rs | 35 | ||||
-rw-r--r-- | src/codegen/mod.rs | 10 |
2 files changed, 35 insertions, 10 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, diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 2e404a5c..17769144 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -470,8 +470,12 @@ impl CodeGenerator for Var { } } VarType::Float(f) => { - const_item.build(helpers::ast_ty::float_expr(f)) - .build(ty) + match helpers::ast_ty::float_expr(ctx, f) { + Ok(expr) => { + const_item.build(expr).build(ty) + } + Err(..) => return, + } } VarType::Char(c) => { const_item @@ -2419,7 +2423,7 @@ impl ToRustTy for TemplateInstantiation { .map(|(arg, _)| arg.to_rust_ty(ctx)) .collect::<Vec<_>>(); - path.segments.last_mut().unwrap().parameters = if + path.segments.last_mut().unwrap().parameters = if template_args.is_empty() { None } else { |