Merge pull request #8608 from LemonBoy/fix-8602

translate-c: Prevent mistranslation of fp literals
This commit is contained in:
Andrew Kelley 2021-04-24 19:55:13 -04:00 committed by GitHub
commit 6951889f6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 47 additions and 4 deletions

View File

@ -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 {

View File

@ -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))

View File

@ -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();

View File

@ -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);

View File

@ -3028,7 +3028,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\void call() {
\\ fn_int(3.0f);
\\ fn_int(3.0);
\\ fn_int(3.0L);
\\ fn_int('ABCD');
\\ fn_f32(3);
\\ fn_f64(3);
@ -3053,7 +3052,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub export fn call() void {
\\ fn_int(@floatToInt(c_int, 3.0));
\\ fn_int(@floatToInt(c_int, 3.0));
\\ fn_int(@floatToInt(c_int, 3.0));
\\ fn_int(@as(c_int, 1094861636));
\\ fn_f32(@intToFloat(f32, @as(c_int, 3)));
\\ fn_f64(@intToFloat(f64, @as(c_int, 3)));