translate-c: demote usage of un-implemented builtins

This commit is contained in:
Evan Haas
2021-03-07 20:47:13 -08:00
committed by Veikka Tuominen
parent 4683de1e91
commit 715370a10a
4 changed files with 47 additions and 1 deletions

View File

@@ -188,3 +188,9 @@ pub fn __builtin_memcpy(
pub fn __builtin_expect(expr: c_long, c: c_long) callconv(.Inline) c_long {
return expr;
}
// __builtin_alloca_with_align is not currently implemented.
// It is used in a run-translated-c test and a test-translate-c test to ensure that non-implemented
// builtins are correctly demoted. If you implement __builtin_alloca_with_align, please update the
// run-translated-c test and the test-translate-c test to use a different non-implemented builtin.
// pub fn __builtin_alloca_with_align(size: usize, alignment: usize) callconv(.Inline) *c_void {}

View File

@@ -11,6 +11,7 @@ const math = std.math;
const ast = @import("translate_c/ast.zig");
const Node = ast.Node;
const Tag = Node.Tag;
const c_builtins = std.c.builtins;
const CallingConvention = std.builtin.CallingConvention;
@@ -1526,7 +1527,7 @@ fn transImplicitCastExpr(
return maybeSuppressResult(c, scope, result_used, ne);
},
.BuiltinFnToFnPtr => {
return transExpr(c, scope, sub_expr, result_used);
return transBuiltinFnExpr(c, scope, sub_expr, result_used);
},
.ToVoid => {
// Should only appear in the rhs and lhs of a ConditionalOperator
@@ -1542,6 +1543,22 @@ fn transImplicitCastExpr(
}
}
fn isBuiltinDefined(name: []const u8) bool {
inline for (std.meta.declarations(c_builtins)) |decl| {
if (std.mem.eql(u8, name, decl.name)) return true;
}
return false;
}
fn transBuiltinFnExpr(c: *Context, scope: *Scope, expr: *const clang.Expr, used: ResultUsed) TransError!Node {
const node = try transExpr(c, scope, expr, used);
if (node.castTag(.identifier)) |ident| {
const name = ident.data;
if (!isBuiltinDefined(name)) return fail(c, error.UnsupportedTranslation, expr.getBeginLoc(), "TODO implement function '{s}' in std.c.builtins", .{name});
}
return node;
}
fn transBoolExpr(
c: *Context,
scope: *Scope,
@@ -4759,6 +4776,10 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N
},
.Identifier => {
const mangled_name = scope.getAlias(slice);
if (mem.startsWith(u8, mangled_name, "__builtin_") and !isBuiltinDefined(mangled_name)) {
try m.fail(c, "TODO implement function '{s}' in std.c.builtins", .{mangled_name});
return error.ParseError;
}
return Tag.identifier.create(c.arena, builtin_typedef_map.get(mangled_name) orelse mangled_name);
},
.LParen => {

View File

@@ -1221,4 +1221,16 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
\\ return 0;
\\}
, "");
// See __builtin_alloca_with_align comment in std.c.builtins
cases.add("use of unimplemented builtin in unused function does not prevent compilation",
\\#include <stdlib.h>
\\void unused() {
\\ __builtin_alloca_with_align(1, 8);
\\}
\\int main(void) {
\\ if (__builtin_sqrt(1.0) != 1.0) abort();
\\ return 0;
\\}
, "");
}

View File

@@ -3418,4 +3418,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const MAY_NEED_PROMOTION_HEX = @import("std").meta.promoteIntLiteral(c_int, 0x80000000, .hexadecimal);
\\pub const MAY_NEED_PROMOTION_OCT = @import("std").meta.promoteIntLiteral(c_int, 0o20000000000, .octal);
});
// See __builtin_alloca_with_align comment in std.c.builtins
cases.add("demote un-implemented builtins",
\\#define FOO(X) __builtin_alloca_with_align((X), 8)
, &[_][]const u8{
\\pub const FOO = @compileError("TODO implement function '__builtin_alloca_with_align' in std.c.builtins");
});
}