Skip to content

translate-c: Function-local extern variable is missing namespace qualifier when referenced in for loop decl #22671

@haydenridd

Description

@haydenridd

Zig Version

0.14.0 (commit bf6ee7c)

Steps to Reproduce and Observed Behavior

translate-c behavior surrounding extern variables with "in-function" typedefs has been improved in 19687 and 20828. However, it appears one more corner case remains surrounding use of these types of variables within for loops.

In extern_typedef_varables_in_functions.c which is used to test this behavior:

const int ev = 40;

static int func(void)
{
  typedef int test_type_t;
  extern const test_type_t ev;
  // Ensure mangled name is also being used for conditions and loops, see #20828
  if (ev == 0);
  while (ev == 0);
  do; while (ev == 0);
  return ev + 2;
}

int main()
{
  if (func() != 42)
    return 1;
  return 0;
}

// run-translated-c
// c_frontend=clang

If the following lines are added to func:

for (int i = ev; i < 40; i++)
    ;
for (int i = 0; i < ev; i++)
    ;
for (int i = 0; i < 40; i += ev)
    ;

The translated Zig mis-translates into the following:

{
    var i: c_int = ev;
    _ = &i;
    while (i < @as(c_int, 40)) : (i += 1) {}
}
{
    var i: c_int = 0;
    _ = &i;
    while (i < ev) : (i += 1) {}
}
{
    var i: c_int = 0;
    _ = &i;
    while (i < @as(c_int, 40)) : (i += @as(c_int, @bitCast(ev))) {}
}

The variable ev is still referenced un-mangled, and it should be referenced as ExternLocal_ev.ev. I'm struggling to come up with a test that adequately enforces this behavior as the above example, despite the mis-translation, does successfully compile due to needing const int ev = 40; to fulfill the extern variable in the same translation unit.

Expected Behavior

See above, the variable ev should be translated as ExternLocal_ev.ev in all cases.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions