Skip to content

C Frontend doesn't handle extern declarations in nested scope correctly #1867

Closed
@hannes-steffenhagen-diffblue

Description

Given a C program like this

#include <stdio.h>

int some_global = 10;

void shadow()
{
  int some_global = 5;
  printf("local: %d\n", some_global);
  {
    extern int some_global;
    ++some_global;
    printf("global: %d\n", some_global);
  }
  printf("local: %d\n", some_global);
  {
    extern int some_global;
    ++some_global;
    printf("global: %d\n", some_global);
  }
}

int main(void)
{
  shadow();
}

The correct output is

local: 5
global: 11
local: 5
global: 12

i.e. the local variable declaration should shadow the global variable, and the extern declaration should shadow the local variable with the global variable.

But the goto function generated for shadow is

shadow /* shadow */
        // 3 file main.c line 7 function shadow
        signed int shadow$$1$$some_global;
        // 4 file main.c line 7 function shadow
        shadow$$1$$some_global = 5;
        // 5 file main.c line 8 function shadow
        printf("local: %d\n", shadow$$1$$some_global);
        // 6 no location
        SKIP
        // 7 file main.c line 11 function shadow
        shadow$$1$$some_global = shadow$$1$$some_global + 1;
        // 8 file main.c line 12 function shadow
        printf("global: %d\n", shadow$$1$$some_global);
        // 9 file main.c line 14 function shadow
        printf("local: %d\n", shadow$$1$$some_global);
        // 10 no location
        SKIP
        // 11 file main.c line 17 function shadow
        shadow$$1$$some_global = shadow$$1$$some_global + 1;
        // 12 file main.c line 18 function shadow
        printf("global: %d\n", shadow$$1$$some_global);
        // 13 file main.c line 20 function shadow
        dead shadow$$1$$some_global;
        // 14 file main.c line 20 function shadow
        END_FUNCTION

In this case, the extern declaration seemingly gets ignored and the assignments that should've been made to the global variable are made to the local variable instead.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions