| author | |
| committer | |
| log | 715370a10a1d8cd2b553e6b1b8a328a637707375 |
| tree | 236486855f464d90aa1ba328ac37bc1e251bccdf |
| parent | 4683de1e918c708ded3b111ae43fc702d28b1d52 |
4 files changed, 47 insertions(+), 1 deletions(-)
lib/std/c/builtins.zig+6| ... | @@ -188,3 +188,9 @@ pub fn __builtin_memcpy( | ... | @@ -188,3 +188,9 @@ pub fn __builtin_memcpy( |
| 188 | pub fn __builtin_expect(expr: c_long, c: c_long) callconv(.Inline) c_long { | 188 | pub fn __builtin_expect(expr: c_long, c: c_long) callconv(.Inline) c_long { |
| 189 | return expr; | 189 | return expr; |
| 190 | } | 190 | } |
| 191 | |||
| 192 | // __builtin_alloca_with_align is not currently implemented. | ||
| 193 | // It is used in a run-translated-c test and a test-translate-c test to ensure that non-implemented | ||
| 194 | // builtins are correctly demoted. If you implement __builtin_alloca_with_align, please update the | ||
| 195 | // run-translated-c test and the test-translate-c test to use a different non-implemented builtin. | ||
| 196 | // pub fn __builtin_alloca_with_align(size: usize, alignment: usize) callconv(.Inline) *c_void {} |
src/translate_c.zig+22-1| ... | @@ -11,6 +11,7 @@ const math = std.math; | ... | @@ -11,6 +11,7 @@ const math = std.math; |
| 11 | const ast = @import("translate_c/ast.zig"); | 11 | const ast = @import("translate_c/ast.zig"); |
| 12 | const Node = ast.Node; | 12 | const Node = ast.Node; |
| 13 | const Tag = Node.Tag; | 13 | const Tag = Node.Tag; |
| 14 | const c_builtins = std.c.builtins; | ||
| 14 | 15 | ||
| 15 | const CallingConvention = std.builtin.CallingConvention; | 16 | const CallingConvention = std.builtin.CallingConvention; |
| 16 | 17 | ||
| ... | @@ -1526,7 +1527,7 @@ fn transImplicitCastExpr( | ... | @@ -1526,7 +1527,7 @@ fn transImplicitCastExpr( |
| 1526 | return maybeSuppressResult(c, scope, result_used, ne); | 1527 | return maybeSuppressResult(c, scope, result_used, ne); |
| 1527 | }, | 1528 | }, |
| 1528 | .BuiltinFnToFnPtr => { | 1529 | .BuiltinFnToFnPtr => { |
| 1529 | return transExpr(c, scope, sub_expr, result_used); | 1530 | return transBuiltinFnExpr(c, scope, sub_expr, result_used); |
| 1530 | }, | 1531 | }, |
| 1531 | .ToVoid => { | 1532 | .ToVoid => { |
| 1532 | // Should only appear in the rhs and lhs of a ConditionalOperator | 1533 | // Should only appear in the rhs and lhs of a ConditionalOperator |
| ... | @@ -1542,6 +1543,22 @@ fn transImplicitCastExpr( | ... | @@ -1542,6 +1543,22 @@ fn transImplicitCastExpr( |
| 1542 | } | 1543 | } |
| 1543 | } | 1544 | } |
| 1544 | 1545 | ||
| 1546 | fn isBuiltinDefined(name: []const u8) bool { | ||
| 1547 | inline for (std.meta.declarations(c_builtins)) |decl| { | ||
| 1548 | if (std.mem.eql(u8, name, decl.name)) return true; | ||
| 1549 | } | ||
| 1550 | return false; | ||
| 1551 | } | ||
| 1552 | |||
| 1553 | fn transBuiltinFnExpr(c: *Context, scope: *Scope, expr: *const clang.Expr, used: ResultUsed) TransError!Node { | ||
| 1554 | const node = try transExpr(c, scope, expr, used); | ||
| 1555 | if (node.castTag(.identifier)) |ident| { | ||
| 1556 | const name = ident.data; | ||
| 1557 | if (!isBuiltinDefined(name)) return fail(c, error.UnsupportedTranslation, expr.getBeginLoc(), "TODO implement function '{s}' in std.c.builtins", .{name}); | ||
| 1558 | } | ||
| 1559 | return node; | ||
| 1560 | } | ||
| 1561 | |||
| 1545 | fn transBoolExpr( | 1562 | fn transBoolExpr( |
| 1546 | c: *Context, | 1563 | c: *Context, |
| 1547 | scope: *Scope, | 1564 | scope: *Scope, |
| ... | @@ -4759,6 +4776,10 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N | ... | @@ -4759,6 +4776,10 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N |
| 4759 | }, | 4776 | }, |
| 4760 | .Identifier => { | 4777 | .Identifier => { |
| 4761 | const mangled_name = scope.getAlias(slice); | 4778 | const mangled_name = scope.getAlias(slice); |
| 4779 | if (mem.startsWith(u8, mangled_name, "__builtin_") and !isBuiltinDefined(mangled_name)) { | ||
| 4780 | try m.fail(c, "TODO implement function '{s}' in std.c.builtins", .{mangled_name}); | ||
| 4781 | return error.ParseError; | ||
| 4782 | } | ||
| 4762 | return Tag.identifier.create(c.arena, builtin_typedef_map.get(mangled_name) orelse mangled_name); | 4783 | return Tag.identifier.create(c.arena, builtin_typedef_map.get(mangled_name) orelse mangled_name); |
| 4763 | }, | 4784 | }, |
| 4764 | .LParen => { | 4785 | .LParen => { |
test/run_translated_c.zig+12| ... | @@ -1221,4 +1221,16 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { | ... | @@ -1221,4 +1221,16 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { |
| 1221 | \\ return 0; | 1221 | \\ return 0; |
| 1222 | \\} | 1222 | \\} |
| 1223 | , ""); | 1223 | , ""); |
| 1224 | |||
| 1225 | // See __builtin_alloca_with_align comment in std.c.builtins | ||
| 1226 | cases.add("use of unimplemented builtin in unused function does not prevent compilation", | ||
| 1227 | \\#include <stdlib.h> | ||
| 1228 | \\void unused() { | ||
| 1229 | \\ __builtin_alloca_with_align(1, 8); | ||
| 1230 | \\} | ||
| 1231 | \\int main(void) { | ||
| 1232 | \\ if (__builtin_sqrt(1.0) != 1.0) abort(); | ||
| 1233 | \\ return 0; | ||
| 1234 | \\} | ||
| 1235 | , ""); | ||
| 1224 | } | 1236 | } |
test/translate_c.zig+7| ... | @@ -3418,4 +3418,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -3418,4 +3418,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 3418 | \\pub const MAY_NEED_PROMOTION_HEX = @import("std").meta.promoteIntLiteral(c_int, 0x80000000, .hexadecimal); | 3418 | \\pub const MAY_NEED_PROMOTION_HEX = @import("std").meta.promoteIntLiteral(c_int, 0x80000000, .hexadecimal); |
| 3419 | \\pub const MAY_NEED_PROMOTION_OCT = @import("std").meta.promoteIntLiteral(c_int, 0o20000000000, .octal); | 3419 | \\pub const MAY_NEED_PROMOTION_OCT = @import("std").meta.promoteIntLiteral(c_int, 0o20000000000, .octal); |
| 3420 | }); | 3420 | }); |
| 3421 | |||
| 3422 | // See __builtin_alloca_with_align comment in std.c.builtins | ||
| 3423 | cases.add("demote un-implemented builtins", | ||
| 3424 | \\#define FOO(X) __builtin_alloca_with_align((X), 8) | ||
| 3425 | , &[_][]const u8{ | ||
| 3426 | \\pub const FOO = @compileError("TODO implement function '__builtin_alloca_with_align' in std.c.builtins"); | ||
| 3427 | }); | ||
| 3421 | } | 3428 | } |