[committed] d: Fix internal compiler error: in visit, at d/decl.cc:838 [PR119799]

Message ID 20250415133259.1113366-1-ibuclaw@gdcproject.org
State New
Headers
Series [committed] d: Fix internal compiler error: in visit, at d/decl.cc:838 [PR119799] |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-arm-bootstrap fail Patch failed to apply

Commit Message

Iain Buclaw April 15, 2025, 1:32 p.m. UTC
  Hi,

This patch fixes the ICE in 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 given 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.

Bootstrapped and regression tested on x86_64-linux-gnu/-m32, and
committed to mainline.  Will backport as necessary once gcc-14/13/12
release branches have been regtested too.

Regards,
Iain.

---
	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.
---
 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(-)
 create mode 100644 gcc/testsuite/gdc.dg/import-c/pr119799.d
 create mode 100644 gcc/testsuite/gdc.dg/import-c/pr119799c.c
  

Patch

diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index 136f78b32ff..9ddf7cf1540 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 00000000000..d8b0fa22fe1
--- /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 00000000000..b80e856f75f
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/import-c/pr119799c.c
@@ -0,0 +1 @@ 
+static struct {} s119799;