Skip to content

Loop body should be emitted in different scope #1218

@Lancern

Description

@Lancern

In the comments of CIRGenStmt.cpp:

// https://en.cppreference.com/w/cpp/language/for
// While in C++, the scope of the init-statement and the scope of
// statement are one and the same, in C the scope of statement is
// nested within the scope of init-statement.
bool useCurrentScope =
CGM.getASTContext().getLangOpts().CPlusPlus ? true : false;

I believe the comment's statement is actually wrong. The referenced page says:

  • The scope of init-statement and the scope of condition are the same.
  • The scope of statement and the scope of expression are disjoint and nested within the scope of init-statement and condition.

Thus in C++ the scope of statement should be in a scope nested within the scope of init-statement, but not in the same scope with init-statement.

For the following C++ code:

void test() {
  for (int i = 0; i < 10; ++i) {
    int x = 42;
    use(x);
  }
}

ClangIR currently emits the following CIR:

cir.func @_Z4testv() {
  cir.scope {
    %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["i", init]
    %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init]
    // ...
    cir.for : cond {
      // ...
    } body {
      // ...
    } step {
      // ...
    }
  }
  cir.return
}

I actually expect it to be:

cir.func @_Z4testv() {
  cir.scope {
    %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["i", init]
    // ...
    cir.for : cond {
      // ...
    } body {
      cir.scope {
        %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init]
        // ...
      }
    } step {
      // ...
    }
  }
  cir.return
}

Note the difference of the places of the alloca operation for local variable x.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions