https://gcc.gnu.org/g:074b2b0f91f948fe3488ada91ec6a8576c684dea

commit r15-9485-g074b2b0f91f948fe3488ada91ec6a8576c684dea
Author: Iain Buclaw <ibuc...@gdcproject.org>
Date:   Tue Apr 15 15:19:13 2025 +0200

    d: Fix internal compiler error: in visit, at d/decl.cc:838 [PR119799]
    
    This was caused by a check in the D front-end disallowing static
    VAR_DECLs with a size `0'.
    
    While empty structs in D are give the size `1', the same symbol coming
    from ImportC modules do infact have no size, so allow C variables to
    pass the check as well as array objects.
    
            PR d/119799
    
    gcc/d/ChangeLog:
    
            * decl.cc (DeclVisitor::visit (VarDeclaration *)): Check front-end
            type size before building the VAR_DECL.  Allow C symbols to have a
            size of `0'.
    
    gcc/testsuite/ChangeLog:
    
            * gdc.dg/import-c/pr119799.d: New test.
            * gdc.dg/import-c/pr119799c.c: New test.

Diff:
---
 gcc/d/decl.cc                             | 15 ++++++++++-----
 gcc/testsuite/gdc.dg/import-c/pr119799.d  |  2 ++
 gcc/testsuite/gdc.dg/import-c/pr119799c.c |  1 +
 3 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index 136f78b32ff0..9ddf7cf1540c 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -791,6 +791,12 @@ public:
       }
     else if (d->isDataseg ())
       {
+       /* When the front-end type size is invalid, an error has already been
+          given for the declaration or type.  */
+       dinteger_t size = dmd::size (d->type, d->loc);
+       if (size == SIZE_INVALID)
+         return;
+
        tree decl = get_symbol_decl (d);
 
        /* Only need to build the VAR_DECL for extern declarations.  */
@@ -804,9 +810,7 @@ public:
          return;
 
        /* How big a symbol can be should depend on back-end.  */
-       tree size = build_integer_cst (dmd::size (d->type, d->loc),
-                                      build_ctype (Type::tsize_t));
-       if (!valid_constant_size_p (size))
+       if (!valid_constant_size_p (build_integer_cst (size, size_type_node)))
          {
            error_at (make_location_t (d->loc), "size is too large");
            return;
@@ -835,8 +839,9 @@ public:
          }
 
        /* Frontend should have already caught this.  */
-       gcc_assert (!integer_zerop (size)
-                   || d->type->toBasetype ()->isTypeSArray ());
+       gcc_assert ((size != 0 && size != SIZE_INVALID)
+                   || d->type->toBasetype ()->isTypeSArray ()
+                   || d->isCsymbol ());
 
        d_finish_decl (decl);
 
diff --git a/gcc/testsuite/gdc.dg/import-c/pr119799.d 
b/gcc/testsuite/gdc.dg/import-c/pr119799.d
new file mode 100644
index 000000000000..d8b0fa22fe1f
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/import-c/pr119799.d
@@ -0,0 +1,2 @@
+// { dg-do compile }
+import pr119799c;
diff --git a/gcc/testsuite/gdc.dg/import-c/pr119799c.c 
b/gcc/testsuite/gdc.dg/import-c/pr119799c.c
new file mode 100644
index 000000000000..b80e856f75f7
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/import-c/pr119799c.c
@@ -0,0 +1 @@
+static struct {} s119799;

Reply via email to