From b81854e34e444042c454abaef3684d1c1d32eae4 Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Thu, 7 Sep 2023 16:14:53 +0100 Subject: [PATCH] Lazily IR-declare global variables Analogous to #4420. --- gen/declarations.cpp | 7 +++++-- tests/codegen/avr.d | 2 ++ tests/codegen/wasi.d | 2 -- tests/fail_compilation/global_var_collision.d | 11 ++++++++++- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/gen/declarations.cpp b/gen/declarations.cpp index d98652a2ebb..1e51651212b 100644 --- a/gen/declarations.cpp +++ b/gen/declarations.cpp @@ -236,9 +236,12 @@ class CodegenVisitor : public Visitor { decl->toPrettyChars()); LOG_SCOPE; - if (decl->ir->isDefined()) { + if (decl->ir->isDefined()) + return; + + // skip external declarations (IR-declared lazily) + if (decl->storage_class & STCextern) return; - } if (decl->type->ty == TY::Terror) { decl->error("had semantic errors when compiling"); diff --git a/tests/codegen/avr.d b/tests/codegen/avr.d index c473cc7dc12..1e0c4073dff 100644 --- a/tests/codegen/avr.d +++ b/tests/codegen/avr.d @@ -11,3 +11,5 @@ version (D_SoftFloat) {} else static assert(0); int definedGlobal = 123; // CHECK: @_D3avr14declaredGlobali = external global i32 extern int declaredGlobal; + +int dummyRef() { return declaredGlobal; } // make sure `declaredGlobal` is IR-declared diff --git a/tests/codegen/wasi.d b/tests/codegen/wasi.d index 2e33d5b4e24..28e67ed037a 100644 --- a/tests/codegen/wasi.d +++ b/tests/codegen/wasi.d @@ -15,8 +15,6 @@ version (CRuntime_WASI) {} else static assert(0); // CHECK: @_D4wasi13definedGlobali = global i32 123 int definedGlobal = 123; -// CHECK: @_D4wasi14declaredGlobali = external global i32 -extern int declaredGlobal; // make sure the ModuleInfo ref is emitted into the __minfo section: diff --git a/tests/fail_compilation/global_var_collision.d b/tests/fail_compilation/global_var_collision.d index 89be7c930be..641131fba98 100644 --- a/tests/fail_compilation/global_var_collision.d +++ b/tests/fail_compilation/global_var_collision.d @@ -1,8 +1,17 @@ +// It should compile fine when not referencing the colliding external global: +// RUN: %ldc -c %s -d-version=DontReference + +// But fail if referenced: // RUN: not %ldc -c %s 2>&1 | FileCheck %s extern(C) extern int myGlobal; -// CHECK: global_var_collision.d(9): Error: Global variable type does not match previous declaration with same mangled name: `myGlobal` +version (DontReference) {} else +{ + int dummyRef() { return myGlobal; } +} + +// CHECK: global_var_collision.d([[@LINE+4]]): Error: Global variable type does not match previous declaration with same mangled name: `myGlobal` // CHECK-NEXT: Previous IR type: i32, mutable, thread-local // CHECK-NEXT: New IR type: i64, const, non-thread-local pragma(mangle, myGlobal.mangleof)