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.
This commit is contained in:
Iain Buclaw 2025-04-15 15:19:13 +02:00
parent 369461d074
commit 074b2b0f91
3 changed files with 13 additions and 5 deletions

View file

@ -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);

View file

@ -0,0 +1,2 @@
// { dg-do compile }
import pr119799c;

View file

@ -0,0 +1 @@
static struct {} s119799;