Skip to content

Commit aff3643

Browse files
committed
Improve wording of some errors around bitfields
1 parent c6549dc commit aff3643

9 files changed

Lines changed: 86 additions & 35 deletions

File tree

compiler/src/dmd/dsymbolsem.d

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3174,10 +3174,12 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
31743174
if (dsym.semanticRun >= PASS.semanticdone)
31753175
return;
31763176

3177-
if (dsym.isAnonymous() && dsym._init)
3177+
const bool isAnonymous = dsym.isAnonymous();
3178+
if (isAnonymous && dsym._init)
31783179
{
31793180
.error(dsym.loc, "anonymous bitfield cannot have default initializer");
31803181
dsym._init = null;
3182+
dsym.errors = true;
31813183
}
31823184

31833185
visit(cast(VarDeclaration)dsym);
@@ -3201,18 +3203,22 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
32013203
if (!dsym.type.isIntegral())
32023204
{
32033205
// C11 6.7.2.1-5
3204-
error(dsym.loc, "bitfield type `%s` is not an integer type", dsym.type.toChars());
3206+
if (isAnonymous)
3207+
error(dsym.loc, "anonymous bitfield cannot be of non-integral type `%s`", dsym.type.toChars());
3208+
else
3209+
error(dsym.loc, "bitfield `%s` cannot be of non-integral type `%s`", dsym.toChars(), dsym.type.toChars());
32053210
dsym.errors = true;
3211+
return;
32063212
}
32073213
if (!width.isIntegerExp())
32083214
{
32093215
error(width.loc, "bitfield width `%s` is not an integer constant", dsym.width.toChars());
32103216
dsym.errors = true;
32113217
}
32123218
const uwidth = width.toInteger(); // uwidth is unsigned
3213-
if (uwidth == 0 && !dsym.isAnonymous())
3219+
if (uwidth == 0 && !isAnonymous)
32143220
{
3215-
error(width.loc, "bitfield `%s` has zero width", dsym.toChars());
3221+
error(dsym.loc, "bitfield `%s` cannot have zero width", dsym.toChars());
32163222
dsym.errors = true;
32173223
}
32183224
const sz = dsym.type.size();
@@ -3221,7 +3227,10 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
32213227
const max_width = sz * 8;
32223228
if (uwidth > max_width)
32233229
{
3224-
error(width.loc, "width `%lld` of bitfield `%s` does not fit in type `%s`", cast(long)uwidth, dsym.toChars(), dsym.type.toChars());
3230+
if (isAnonymous)
3231+
error(width.loc, "width `%lld` of anonymous bitfield does not fit in type `%s`", cast(long)uwidth, dsym.type.toChars());
3232+
else
3233+
error(width.loc, "width `%lld` of bitfield `%s` does not fit in type `%s`", cast(long)uwidth, dsym.toChars(), dsym.type.toChars());
32253234
dsym.errors = true;
32263235
}
32273236
dsym.fieldWidth = cast(uint)uwidth;
@@ -7046,10 +7055,20 @@ bool determineFields(AggregateDeclaration ad)
70467055
{
70477056
if (ad == tvs.sym)
70487057
{
7058+
if (ad.type.ty == Terror || ad.errors)
7059+
return 1; // failed already
7060+
70497061
const(char)* psz = (v.type.toBasetype().ty == Tsarray) ? "static array of " : "";
7050-
.error(ad.loc, "%s `%s` cannot have field `%s` with %ssame struct type", ad.kind, ad.toPrettyChars, v.toChars(), psz);
7051-
ad.type = Type.terror;
7052-
ad.errors = true;
7062+
if (!v.isAnonymous())
7063+
.error(v.loc, "%s `%s` cannot have field `%s` with %ssame struct type", ad.kind, ad.toPrettyChars, v.toChars(), psz);
7064+
else
7065+
.error(v.loc, "%s `%s` cannot have anonymous field with %ssame struct type", ad.kind, ad.toPrettyChars, psz);
7066+
// Don't cache errors from speculative semantic
7067+
if (!global.gag)
7068+
{
7069+
ad.type = Type.terror;
7070+
ad.errors = true;
7071+
}
70537072
return 1;
70547073
}
70557074
}
@@ -8439,10 +8458,9 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
84398458
uint memalignsize = target.fieldalign(t); // size of member for alignment purposes
84408459
if (log) printf(" memsize: %u memalignsize: %u\n", memsize, memalignsize);
84418460

8442-
if (bfd.fieldWidth == 0 && !anon)
8443-
error(bfd.loc, "named bit fields cannot have 0 width");
8444-
if (bfd.fieldWidth > memsize * 8)
8445-
error(bfd.loc, "bit field width %d is larger than type", bfd.fieldWidth);
8461+
// Handled in dsymbolSemantic as errors
8462+
assert(bfd.fieldWidth != 0 || anon, "named bit fields cannot have 0 width");
8463+
assert(bfd.fieldWidth <= memsize * 8, "bit field width is larger than type");
84468464

84478465
const style = target.c.bitFieldStyle;
84488466
if (style != TargetC.BitFieldStyle.MS && style != TargetC.BitFieldStyle.Gcc_Clang)

compiler/src/dmd/semantic2.d

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,8 +351,14 @@ private extern(C++) final class Semantic2Visitor : Visitor
351351
if (!bounds.contains(value))
352352
{
353353
const uwidth = bfd.fieldWidth;
354-
error(ei.loc, "bitfield initializer `%s` does not fit in %d bit%s",
355-
ei.exp.toChars(), cast(int) uwidth, uwidth == 1 ? "".ptr : "s".ptr);
354+
error(ei.loc, "default initializer `%s` is not representable as bitfield type `%s:%lld`",
355+
ei.exp.toChars(), bfd.type.toBasetype().toChars(), cast(long)uwidth);
356+
if (isUnsigned)
357+
errorSupplemental(bfd.loc, "bitfield `%s` default initializer must be a value between `%llu..%llu`",
358+
bfd.toChars(), bounds.imin.value, bounds.imax.value);
359+
else
360+
errorSupplemental(bfd.loc, "bitfield `%s` default initializer must be a value between `%lld..%lld`",
361+
bfd.toChars(), bounds.imin.value, bounds.imax.value);
356362
}
357363
}
358364

compiler/test/fail_compilation/biterrors2.d

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
fail_compilation/biterrors2.d(100): Error: variable `biterrors2.a` - bitfield must be member of struct, union, or class
55
int a : 2;
66
^
7-
fail_compilation/biterrors2.d(104): Error: bitfield `b` has zero width
7+
fail_compilation/biterrors2.d(104): Error: bitfield `b` cannot have zero width
88
int b:0;
9-
^
10-
fail_compilation/biterrors2.d(105): Error: bitfield type `float` is not an integer type
9+
^
10+
fail_compilation/biterrors2.d(105): Error: bitfield `c` cannot be of non-integral type `float`
1111
float c:3;
1212
^
1313
---
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
* TEST_OUTPUT:
3+
---
4+
fail_compilation/biterrors6.d(10): Error: anonymous bitfield cannot be of non-integral type `noreturn`
5+
fail_compilation/biterrors6.d(11): Error: width `-1` of anonymous bitfield does not fit in type `int`
6+
---
7+
*/
8+
struct S
9+
{
10+
noreturn : -1;
11+
int : -1;
12+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/*
2+
* TEST_OUTPUT:
3+
---
4+
fail_compilation/biterrors7.d(10): Error: struct `biterrors7.S` cannot have anonymous field with same struct type
5+
fail_compilation/biterrors7.d(10): Error: anonymous bitfield cannot be of non-integral type `S`
6+
---
7+
*/
8+
struct S
9+
{
10+
S : S();
11+
}

compiler/test/fail_compilation/bitfields2.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/* TEST_OUTPUT:
22
---
3-
fail_compilation/bitfields2.c(103): Error: bitfield type `float` is not an integer type
3+
fail_compilation/bitfields2.c(103): Error: bitfield `a` cannot be of non-integral type `float`
44
fail_compilation/bitfields2.c(104): Error: bitfield width `3.0` is not an integer constant
5-
fail_compilation/bitfields2.c(105): Error: bitfield `c` has zero width
5+
fail_compilation/bitfields2.c(105): Error: bitfield `c` cannot have zero width
66
fail_compilation/bitfields2.c(106): Error: width `60` of bitfield `d` does not fit in type `int`
77
---
88
*/

compiler/test/fail_compilation/fail20779.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
/*
44
TEST_OUTPUT:
55
---
6-
fail_compilation/fail20779.d(12): Error: struct `fail20779.X` cannot have field `x` with same struct type
6+
fail_compilation/fail20779.d(14): Error: struct `fail20779.X` cannot have field `x` with same struct type
77
---
88
*/
99

compiler/test/fail_compilation/fail22384.d

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
11
/*
22
TEST_OUTPUT:
33
---
4-
fail_compilation/fail22384.d(32): Error: bitfield `z` has zero width
5-
fail_compilation/fail22384.d(36): Error: bitfield type `float` is not an integer type
6-
fail_compilation/fail22384.d(36): Error: bitfield `f` has zero width
7-
fail_compilation/fail22384.d(37): Error: bitfield type `float` is not an integer type
8-
fail_compilation/fail22384.d(38): Error: bitfield type `float` is not an integer type
9-
fail_compilation/fail22384.d(39): Error: bitfield type `float` is not an integer type
10-
fail_compilation/fail22384.d(44): Error: anonymous bitfield cannot have default initializer
11-
fail_compilation/fail22384.d(21): Error: bitfield initializer `4294967295u` does not fit in 4 bits
12-
fail_compilation/fail22384.d(26): Error: bitfield initializer `E.B` does not fit in 2 bits
13-
fail_compilation/fail22384.d(30): Error: bitfield initializer `4` does not fit in 3 bits
14-
fail_compilation/fail22384.d(31): Error: bitfield initializer `65` does not fit in 7 bits
15-
fail_compilation/fail22384.d(43): Error: cannot implicitly convert expression `4.2F` of type `float` to `int`
16-
fail_compilation/fail22384.d(45): Error: bitfield initializer `65` does not fit in 7 bits
17-
fail_compilation/fail22384.d(46): Error: cannot implicitly convert expression `42` of type `int` to `bool`
4+
fail_compilation/fail22384.d(36): Error: bitfield `z` cannot have zero width
5+
fail_compilation/fail22384.d(40): Error: bitfield `f` cannot be of non-integral type `float`
6+
fail_compilation/fail22384.d(41): Error: bitfield `f2` cannot be of non-integral type `float`
7+
fail_compilation/fail22384.d(42): Error: bitfield `f3` cannot be of non-integral type `float`
8+
fail_compilation/fail22384.d(43): Error: bitfield `f4` cannot be of non-integral type `float`
9+
fail_compilation/fail22384.d(48): Error: anonymous bitfield cannot have default initializer
10+
fail_compilation/fail22384.d(25): Error: default initializer `4294967295u` is not representable as bitfield type `uint:4`
11+
fail_compilation/fail22384.d(25): bitfield `d` default initializer must be a value between `0..15`
12+
fail_compilation/fail22384.d(30): Error: default initializer `E.B` is not representable as bitfield type `int:2`
13+
fail_compilation/fail22384.d(30): bitfield `b` default initializer must be a value between `-2..1`
14+
fail_compilation/fail22384.d(34): Error: default initializer `4` is not representable as bitfield type `int:3`
15+
fail_compilation/fail22384.d(34): bitfield `x` default initializer must be a value between `-4..3`
16+
fail_compilation/fail22384.d(35): Error: default initializer `65` is not representable as bitfield type `int:7`
17+
fail_compilation/fail22384.d(35): bitfield `y` default initializer must be a value between `-64..63`
18+
fail_compilation/fail22384.d(47): Error: cannot implicitly convert expression `4.2F` of type `float` to `int`
19+
fail_compilation/fail22384.d(49): Error: default initializer `65` is not representable as bitfield type `int:7`
20+
fail_compilation/fail22384.d(49): bitfield `j` default initializer must be a value between `-64..63`
21+
fail_compilation/fail22384.d(50): Error: cannot implicitly convert expression `42` of type `int` to `bool`
1822
---
1923
*/
2024
struct S {

compiler/test/fail_compilation/fail8691.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
TEST_OUTPUT:
33
---
4-
fail_compilation/fail8691.d(7): Error: struct `fail8691.Foo` cannot have field `f` with static array of same struct type
4+
fail_compilation/fail8691.d(9): Error: struct `fail8691.Foo` cannot have field `f` with static array of same struct type
55
---
66
*/
77
struct Foo

0 commit comments

Comments
 (0)