llvm / clangir

A new (MLIR based) high-level IR for clang.
https://clangir.org
Other
312 stars 86 forks source link

Miss destruction in switch statements #587

Open wenpen opened 2 months ago

wenpen commented 2 months ago

The St destruction of following code won't be called.

#include <cstdio>

struct St{
  St() {
    puts("Ctor");
  }
  ~St(){
    puts("Dtor");
  }
};

int f(int a) {
  switch(a) {
    case 1:{
      St a;
      return 1;
      int x=1;
    }
  }
  return 0;
}

int main() {
  f(1);
}

emit-cir-flag output:

  cir.func @_Z1fi(%arg0: !s32i loc(fused[#loc13, #loc14])) -> !s32i extra(#fn_attr) {
    %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init] {alignment = 4 : i64} loc(#loc38)
    %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"] {alignment = 4 : i64} loc(#loc12)
    cir.store %arg0, %0 : !s32i, !cir.ptr<!s32i> loc(#loc15)
    cir.br ^bb1 loc(#loc39)
  ^bb1:  // pred: ^bb0
    %2 = cir.load %0 : !cir.ptr<!s32i>, !s32i loc(#loc18)
    cir.switch.flat %2 : !s32i, ^bb6 [
      1: ^bb2
    ] loc(#loc16)
  ^bb2:  // pred: ^bb1
    cir.br ^bb3 loc(#loc40)
  ^bb3:  // pred: ^bb2
    %3 = cir.alloca !ty_22St22, !cir.ptr<!ty_22St22>, ["a", init] {alignment = 1 : i64} loc(#loc41)
    %4 = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init] {alignment = 4 : i64} loc(#loc42)
    cir.call @_ZN2StC2Ev(%3) : (!cir.ptr<!ty_22St22>) -> () loc(#loc22)
    %5 = cir.const #cir.int<1> : !s32i loc(#loc25)
    cir.store %5, %1 : !s32i, !cir.ptr<!s32i> loc(#loc43)
    %6 = cir.load %1 : !cir.ptr<!s32i>, !s32i loc(#loc43)
    cir.return %6 : !s32i loc(#loc43)
  ^bb4:  // no predecessors
    %7 = cir.const #cir.int<1> : !s32i loc(#loc24)
    cir.store %7, %4 : !s32i, !cir.ptr<!s32i> loc(#loc42)
    cir.call @_ZN2StD2Ev(%3) : (!cir.ptr<!ty_22St22>) -> () loc(#loc36)
    cir.br ^bb5 loc(#loc20)
  ^bb5:  // pred: ^bb4
    cir.br ^bb6 loc(#loc16)
  ^bb6:  // 2 preds: ^bb1, ^bb5
    cir.br ^bb7 loc(#loc17)
  ^bb7:  // pred: ^bb6
    %8 = cir.const #cir.int<0> : !s32i loc(#loc27)
    cir.store %8, %1 : !s32i, !cir.ptr<!s32i> loc(#loc44)
    %9 = cir.load %1 : !cir.ptr<!s32i>, !s32i loc(#loc44)
    cir.return %9 : !s32i loc(#loc44)
  } loc(#loc37)
Lancern commented 2 months ago

This is a variant of #348 .

bcardosolopes commented 2 months ago

@Lancern is right. I have some on going work there I need to be resumed, should take care of this too.

bcardosolopes commented 2 months ago

@wenpen if you are looking for issues to work on, I advice against picking this one right now, it involves many parts of CIRGen is quite complex, I'd go for more simple stuff until you get more familiarity with the different parts.

wenpen commented 2 months ago

Just found this issue when construct test case, thank you for advice, I will keep focusing on my unfinished work :)