mirror of
https://github.com/ziglang/zig.git
synced 2025-12-24 07:03:11 +00:00
translate-c: Prevent mistranslation of fp literals
When trying to retrieve 80bit fp values from clang using getValueAsApproximateDouble we'd eventually hit the ceiling value and return infinity, an invalid value for a fp literal. Add some logic to prevent this error and warn the user. Closes #8602
This commit is contained in:
parent
4ec6d174ad
commit
7c3896e6cd
@ -104,6 +104,16 @@ pub const APFloat = opaque {
|
||||
extern fn ZigClangAPFloat_toString(*const APFloat, precision: c_uint, maxPadding: c_uint, truncateZero: bool) [*:0]const u8;
|
||||
};
|
||||
|
||||
pub const APFloatBaseSemantics = extern enum {
|
||||
IEEEhalf,
|
||||
BFloat,
|
||||
IEEEsingle,
|
||||
IEEEdouble,
|
||||
x86DoubleExtended,
|
||||
IEEEquad,
|
||||
PPCDoubleDouble,
|
||||
};
|
||||
|
||||
pub const APInt = opaque {
|
||||
pub const getLimitedValue = ZigClangAPInt_getLimitedValue;
|
||||
extern fn ZigClangAPInt_getLimitedValue(*const APInt, limit: u64) u64;
|
||||
@ -455,6 +465,12 @@ pub const FileID = opaque {};
|
||||
pub const FloatingLiteral = opaque {
|
||||
pub const getValueAsApproximateDouble = ZigClangFloatingLiteral_getValueAsApproximateDouble;
|
||||
extern fn ZigClangFloatingLiteral_getValueAsApproximateDouble(*const FloatingLiteral) f64;
|
||||
|
||||
pub const getBeginLoc = ZigClangIntegerLiteral_getBeginLoc;
|
||||
extern fn ZigClangIntegerLiteral_getBeginLoc(*const FloatingLiteral) SourceLocation;
|
||||
|
||||
pub const getRawSemantics = ZigClangFloatingLiteral_getRawSemantics;
|
||||
extern fn ZigClangFloatingLiteral_getRawSemantics(*const FloatingLiteral) APFloatBaseSemantics;
|
||||
};
|
||||
|
||||
pub const ForStmt = opaque {
|
||||
|
||||
@ -3547,9 +3547,22 @@ fn transCPtrCast(
|
||||
}
|
||||
}
|
||||
|
||||
fn transFloatingLiteral(c: *Context, scope: *Scope, stmt: *const clang.FloatingLiteral, used: ResultUsed) TransError!Node {
|
||||
fn transFloatingLiteral(c: *Context, scope: *Scope, expr: *const clang.FloatingLiteral, used: ResultUsed) TransError!Node {
|
||||
switch (expr.getRawSemantics()) {
|
||||
.IEEEhalf, // f16
|
||||
.IEEEsingle, // f32
|
||||
.IEEEdouble, // f64
|
||||
=> {},
|
||||
else => |format| return fail(
|
||||
c,
|
||||
error.UnsupportedTranslation,
|
||||
expr.getBeginLoc(),
|
||||
"unsupported floating point constant format {}",
|
||||
.{format},
|
||||
),
|
||||
}
|
||||
// TODO use something more accurate
|
||||
var dbl = stmt.getValueAsApproximateDouble();
|
||||
var dbl = expr.getValueAsApproximateDouble();
|
||||
const is_negative = dbl < 0;
|
||||
if (is_negative) dbl = -dbl;
|
||||
const str = if (dbl == std.math.floor(dbl))
|
||||
|
||||
@ -2528,6 +2528,11 @@ double ZigClangFloatingLiteral_getValueAsApproximateDouble(const ZigClangFloatin
|
||||
return casted->getValueAsApproximateDouble();
|
||||
}
|
||||
|
||||
ZigClangAPFloatBase_Semantics ZigClangFloatingLiteral_getRawSemantics(const ZigClangFloatingLiteral *self) {
|
||||
auto casted = reinterpret_cast<const clang::FloatingLiteral *>(self);
|
||||
return static_cast<ZigClangAPFloatBase_Semantics>(casted->getRawSemantics());
|
||||
}
|
||||
|
||||
enum ZigClangStringLiteral_StringKind ZigClangStringLiteral_getKind(const struct ZigClangStringLiteral *self) {
|
||||
auto casted = reinterpret_cast<const clang::StringLiteral *>(self);
|
||||
return (ZigClangStringLiteral_StringKind)casted->getKind();
|
||||
|
||||
@ -881,6 +881,16 @@ enum ZigClangAPFloat_roundingMode {
|
||||
ZigClangAPFloat_roundingMode_Invalid = -1,
|
||||
};
|
||||
|
||||
enum ZigClangAPFloatBase_Semantics {
|
||||
ZigClangAPFloatBase_Semantics_IEEEhalf,
|
||||
ZigClangAPFloatBase_Semantics_BFloat,
|
||||
ZigClangAPFloatBase_Semantics_IEEEsingle,
|
||||
ZigClangAPFloatBase_Semantics_IEEEdouble,
|
||||
ZigClangAPFloatBase_Semantics_x87DoubleExtended,
|
||||
ZigClangAPFloatBase_Semantics_IEEEquad,
|
||||
ZigClangAPFloatBase_Semantics_PPCDoubleDouble,
|
||||
};
|
||||
|
||||
enum ZigClangStringLiteral_StringKind {
|
||||
ZigClangStringLiteral_StringKind_Ascii,
|
||||
ZigClangStringLiteral_StringKind_Wide,
|
||||
@ -1142,6 +1152,7 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangDeclStmt_getBeginLoc(const st
|
||||
ZIG_EXTERN_C unsigned ZigClangAPFloat_convertToHexString(const struct ZigClangAPFloat *self, char *DST,
|
||||
unsigned HexDigits, bool UpperCase, enum ZigClangAPFloat_roundingMode RM);
|
||||
ZIG_EXTERN_C double ZigClangFloatingLiteral_getValueAsApproximateDouble(const ZigClangFloatingLiteral *self);
|
||||
ZIG_EXTERN_C ZigClangAPFloatBase_Semantics ZigClangFloatingLiteral_getRawSemantics(const ZigClangFloatingLiteral *self);
|
||||
|
||||
ZIG_EXTERN_C enum ZigClangStringLiteral_StringKind ZigClangStringLiteral_getKind(const struct ZigClangStringLiteral *self);
|
||||
ZIG_EXTERN_C uint32_t ZigClangStringLiteral_getCodeUnit(const struct ZigClangStringLiteral *self, size_t i);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user