aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2022-05-30 16:01:05 +0300
committerGitHub <noreply@github.com>2022-05-30 16:01:05 +0300
commitf846dc420fff629572caa1175bfa64e5fcffaeb5 (patch)
treef2e882f35401602799e46b76990a9e9403e3c909 /src
parentee651c3cd358f40f60db0bbcd82ffde99aed9b88 (diff)
parent0274e2f1fd3b7a81344080d532cfd2d384427cd2 (diff)
downloadzig-f846dc420fff629572caa1175bfa64e5fcffaeb5.tar.gz
zig-f846dc420fff629572caa1175bfa64e5fcffaeb5.zip
Merge pull request #10474 from TwoClocks/master
translate-c: fix for #10461. Check child records for opaque types
Diffstat (limited to 'src')
-rw-r--r--src/translate_c.zig20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/translate_c.zig b/src/translate_c.zig
index 8c4bd5e9bf..3bbe1e6f46 100644
--- a/src/translate_c.zig
+++ b/src/translate_c.zig
@@ -793,6 +793,10 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co
var is_extern = storage_class == .Extern and !has_init;
var is_export = !is_extern and storage_class != .Static;
+ if (!is_extern and qualTypeWasDemotedToOpaque(c, qual_type)) {
+ return failDecl(c, var_decl_loc, var_name, "non-extern variable has opaque type", .{});
+ }
+
const type_node = transQualTypeMaybeInitialized(c, scope, qual_type, decl_init, var_decl_loc) catch |err| switch (err) {
error.UnsupportedTranslation, error.UnsupportedType => {
return failDecl(c, var_decl_loc, var_name, "unable to resolve variable type", .{});
@@ -1839,6 +1843,7 @@ fn transDeclStmtOne(
.Var => {
const var_decl = @ptrCast(*const clang.VarDecl, decl);
const decl_init = var_decl.getInit();
+ const loc = decl.getLocation();
const qual_type = var_decl.getTypeSourceInfo_getType();
const name = try c.str(@ptrCast(*const clang.NamedDecl, var_decl).getName_bytes_begin());
@@ -1848,12 +1853,12 @@ fn transDeclStmtOne(
// This is actually a global variable, put it in the global scope and reference it.
// `_ = mangled_name;`
return visitVarDecl(c, var_decl, mangled_name);
+ } else if (qualTypeWasDemotedToOpaque(c, qual_type)) {
+ return fail(c, error.UnsupportedTranslation, loc, "local variable has opaque type", .{});
}
const is_static_local = var_decl.isStaticLocal();
const is_const = qual_type.isConstQualified();
-
- const loc = decl.getLocation();
const type_node = try transQualTypeMaybeInitialized(c, scope, qual_type, decl_init, loc);
var init_node = if (decl_init) |expr|
@@ -4831,7 +4836,16 @@ fn qualTypeWasDemotedToOpaque(c: *Context, qt: clang.QualType) bool {
const record_decl = record_ty.getDecl();
const canonical = @ptrToInt(record_decl.getCanonicalDecl());
- return c.opaque_demotes.contains(canonical);
+ if (c.opaque_demotes.contains(canonical)) return true;
+
+ // check all childern for opaque types.
+ var it = record_decl.field_begin();
+ const end_it = record_decl.field_end();
+ while (it.neq(end_it)) : (it = it.next()) {
+ const field_decl = it.deref();
+ if (qualTypeWasDemotedToOpaque(c, field_decl.getType())) return true;
+ }
+ return false;
},
.Enum => {
const enum_ty = @ptrCast(*const clang.EnumType, ty);