Author: adams381 Date: 2026-05-14T10:40:21-05:00 New Revision: cc4efa3992b11d85a7a57f58fc88a2bbde91a8b8
URL: https://github.com/llvm/llvm-project/commit/cc4efa3992b11d85a7a57f58fc88a2bbde91a8b8 DIFF: https://github.com/llvm/llvm-project/commit/cc4efa3992b11d85a7a57f58fc88a2bbde91a8b8.diff LOG: [CIR] Lower static locals in C++ ctor and dtor bodies (#197089) Static locals declared inside a C++ constructor or destructor body were hitting `errorNYI("C++ constructors static var context")` (and the dtor variant) in `CIRGenModule::getOrCreateStaticVarDecl`, even though the rest of the static-local plumbing was already in place. The fix is to mirror what classic CodeGen does at `CGDecl.cpp:328-334` — pick `GlobalDecl(cd, Ctor_Base)` for ctors and `GlobalDecl(dd, Dtor_Base)` for dtors instead of erroring. Hit this trying to compile a couple of SPEC CPU 2026 benchmarks with `-fclangir`: `flightdm` has a `static constexpr std::array` inside `FGCondition::FGCondition`, and `gmsh` has a similar shape in `MetaEl.cpp`. The minimum repro is the obvious one: ```c++ struct Foo { Foo() { static int x = 42; (void)x; } }; Foo f; ``` The new test cross-checks against OGCG so we catch any drift — both backends emit `@_ZZN4CtorC1EvE1x = linkonce_odr global i32 42, comdat, align 4` and the dtor analogue. Both CIR test suites pass cleanly (`check-clang-cir-codegen` and `check-clang-cir`). Added: clang/test/CIR/CodeGen/static-local-in-ctor.cpp Modified: clang/lib/CIR/CodeGen/CIRGenDecl.cpp Removed: ################################################################################ diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp index 2bf90e99eb7d3..c2a0dd80407ca 100644 --- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp @@ -487,10 +487,10 @@ CIRGenModule::getOrCreateStaticVarDecl(const VarDecl &d, } GlobalDecl gd; - if (isa<CXXConstructorDecl>(dc)) - errorNYI(d.getSourceRange(), "C++ constructors static var context"); - else if (isa<CXXDestructorDecl>(dc)) - errorNYI(d.getSourceRange(), "C++ destructors static var context"); + if (const auto *cd = dyn_cast<CXXConstructorDecl>(dc)) + gd = GlobalDecl(cd, Ctor_Base); + else if (const auto *dd = dyn_cast<CXXDestructorDecl>(dc)) + gd = GlobalDecl(dd, Dtor_Base); else if (const auto *fd = dyn_cast<FunctionDecl>(dc)) gd = GlobalDecl(fd); else { diff --git a/clang/test/CIR/CodeGen/static-local-in-ctor.cpp b/clang/test/CIR/CodeGen/static-local-in-ctor.cpp new file mode 100644 index 0000000000000..6056d3a2cbfe1 --- /dev/null +++ b/clang/test/CIR/CodeGen/static-local-in-ctor.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s +// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s +// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll +// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s + +struct Ctor { + Ctor() { + static int x = 42; + (void)x; + } +}; + +struct Dtor { + ~Dtor() { + static int y = 7; + (void)y; + } +}; + +void use() { Ctor c; Dtor d; } + + +// Static local inside the constructor body. + +// CIR-DAG: cir.global linkonce_odr comdat @_ZZN4CtorC1EvE1x = #cir.int<42> : !s32i {alignment = 4 : i64} +// LLVM-DAG: @_ZZN4CtorC1EvE1x = linkonce_odr global i32 42, comdat, align 4 + + +// Static local inside the destructor body. + +// CIR-DAG: cir.global linkonce_odr comdat @_ZZN4DtorD1EvE1y = #cir.int<7> : !s32i {alignment = 4 : i64} +// LLVM-DAG: @_ZZN4DtorD1EvE1y = linkonce_odr global i32 7, comdat, align 4 + + +// The static local is loaded by cir.get_global inside the base-subobject +// constructor / destructor body (Itanium ABI emits both C1/C2 and D1/D2; +// both reference the same static). + +// CIR: cir.func{{.*}}@_ZN4CtorC2Ev +// CIR: cir.get_global @_ZZN4CtorC1EvE1x : !cir.ptr<!s32i> + +// CIR: cir.func{{.*}}@_ZN4DtorD2Ev +// CIR: cir.get_global @_ZZN4DtorD1EvE1y : !cir.ptr<!s32i> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
