authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-05-27 16:43:21+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-05-29 12:07:29+03:00
log0274e2f1fd3b7a81344080d532cfd2d384427cd2
treef2e882f35401602799e46b76990a9e9403e3c909
parent36b4658752257a27b1d7db5a4396132784801997

translate-c: check variable types being demoted to opaque


2 files changed, 22 insertions(+), 3 deletions(-)

src/translate_c.zig+7-2
......@@ -793,6 +793,10 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co
793793 var is_extern = storage_class == .Extern and !has_init;
794794 var is_export = !is_extern and storage_class != .Static;
795795
796 if (!is_extern and qualTypeWasDemotedToOpaque(c, qual_type)) {
797 return failDecl(c, var_decl_loc, var_name, "non-extern variable has opaque type", .{});
798 }
799
796800 const type_node = transQualTypeMaybeInitialized(c, scope, qual_type, decl_init, var_decl_loc) catch |err| switch (err) {
797801 error.UnsupportedTranslation, error.UnsupportedType => {
798802 return failDecl(c, var_decl_loc, var_name, "unable to resolve variable type", .{});
......@@ -1839,6 +1843,7 @@ fn transDeclStmtOne(
18391843 .Var => {
18401844 const var_decl = @ptrCast(*const clang.VarDecl, decl);
18411845 const decl_init = var_decl.getInit();
1846 const loc = decl.getLocation();
18421847
18431848 const qual_type = var_decl.getTypeSourceInfo_getType();
18441849 const name = try c.str(@ptrCast(*const clang.NamedDecl, var_decl).getName_bytes_begin());
......@@ -1848,12 +1853,12 @@ fn transDeclStmtOne(
18481853 // This is actually a global variable, put it in the global scope and reference it.
18491854 // `_ = mangled_name;`
18501855 return visitVarDecl(c, var_decl, mangled_name);
1856 } else if (qualTypeWasDemotedToOpaque(c, qual_type)) {
1857 return fail(c, error.UnsupportedTranslation, loc, "local variable has opaque type", .{});
18511858 }
18521859
18531860 const is_static_local = var_decl.isStaticLocal();
18541861 const is_const = qual_type.isConstQualified();
1855
1856 const loc = decl.getLocation();
18571862 const type_node = try transQualTypeMaybeInitialized(c, scope, qual_type, decl_init, loc);
18581863
18591864 var init_node = if (decl_init) |expr|
test/translate_c.zig+15-1
......@@ -6,6 +6,20 @@ const CrossTarget = std.zig.CrossTarget;
66pub fn addCases(cases: *tests.TranslateCContext) void {
77 const default_enum_type = if (builtin.abi == .msvc) "c_int" else "c_uint";
88
9 cases.add("variables check for opaque demotion",
10 \\struct A {
11 \\ _Atomic int a;
12 \\} a;
13 \\int main(void) {
14 \\ struct A a;
15 \\}
16 , &[_][]const u8{
17 \\pub const struct_A = opaque {};
18 \\pub const a = @compileError("non-extern variable has opaque type");
19 ,
20 \\pub extern fn main() c_int;
21 });
22
923 cases.add("field access is grouped if necessary",
1024 \\unsigned long foo(unsigned long x) {
1125 \\ return ((union{unsigned long _x}){x})._x;
......@@ -3587,7 +3601,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
35873601 \\ struct my_struct S = {.a = 1, .b = 2};
35883602 \\}
35893603 , &[_][]const u8{
3590 \\warning: cannot initialize opaque type
3604 \\warning: local variable has opaque type
35913605 ,
35923606 \\warning: unable to translate function, demoted to extern
35933607 \\pub extern fn initialize() void;