Skip to content

Commit d515537

Browse files
authored
Fix dlang/dmd!21189 - wrong/missing error line when source file isn't regular (dlang/dmd!21190)
1 parent 150a17e commit d515537

8 files changed

Lines changed: 39 additions & 30 deletions

File tree

dmd/errors.d

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ private struct ErrorInfo
442442
this.kind = kind;
443443
}
444444

445-
const SourceLoc loc; // location of error
445+
const SourceLoc loc; // location of error
446446
Classification headerColor; // color to set `header` output to
447447
const(char)* p1; // additional message prefix
448448
const(char)* p2; // additional message prefix
@@ -731,13 +731,9 @@ private void verrorPrint(const(char)* format, va_list ap, ref ErrorInfo info)
731731
!loc.filename.startsWith(".d-mixin-") &&
732732
!global.params.mixinOut.doOutput)
733733
{
734-
import dmd.root.filename : FileName;
735-
if (auto text = cast(const(char[])) global.fileManager.getFileContents(FileName(loc.filename)))
736-
{
737-
tmp.reset();
738-
printErrorLineContext(tmp, text, loc.fileOffset);
739-
fputs(tmp.peekChars(), stderr);
740-
}
734+
tmp.reset();
735+
printErrorLineContext(tmp, loc.fileContent, loc.fileOffset);
736+
fputs(tmp.peekChars(), stderr);
741737
}
742738
old_loc = loc;
743739
fflush(stderr); // ensure it gets written out in case of compiler aborts
@@ -750,7 +746,7 @@ private void printErrorLineContext(ref OutBuffer buf, const(char)[] text, size_t
750746
import dmd.root.utf : utf_decodeChar;
751747

752748
if (offset >= text.length)
753-
return; // Out of bounds (can happen in pre-processed C files currently)
749+
return; // Out of bounds (missing source content in SourceLoc)
754750

755751
// Scan backwards for beginning of line
756752
size_t s = offset;

dmd/frontend.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,12 +383,14 @@ struct SourceLoc final
383383
uint32_t line;
384384
uint32_t column;
385385
uint32_t fileOffset;
386+
_d_dynamicArray< const char > fileContent;
386387
const char* toChars(bool showColumns = Loc::showColumns, MessageStyle messageStyle = Loc::messageStyle) const;
387388
SourceLoc() :
388389
filename(),
389390
line(),
390391
column(),
391-
fileOffset()
392+
fileOffset(),
393+
fileContent()
392394
{
393395
}
394396
};

dmd/globals.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ struct SourceLoc
421421
uint32_t line;
422422
uint32_t column;
423423
uint32_t fileOffset;
424+
DString fileContent;
424425
};
425426

426427
struct Loc

dmd/lexer.d

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class Lexer
132132
// debug printf("Lexer::Lexer(%p)\n", base);
133133
// debug printf("lexer.filename = %s\n", filename);
134134
token = Token.init;
135-
this.baseLoc = newBaseLoc(filename, endoffset);
135+
this.baseLoc = newBaseLoc(filename, base[0 .. endoffset]);
136136
this.linnum = 1;
137137
this.base = base;
138138
this.end = base + endoffset;
@@ -224,7 +224,7 @@ class Lexer
224224
inTokenStringConstant = 0;
225225
lastDocLine = 0;
226226

227-
baseLoc = newBaseLoc("#defines", slice.length);
227+
baseLoc = newBaseLoc("#defines", slice);
228228
scanloc = baseLoc.getLoc(0);
229229
}
230230

dmd/location.d

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ nothrow:
6464
extern (C++) static Loc singleFilename(const char* filename)
6565
{
6666
Loc result;
67-
locFileTable ~= new BaseLoc(filename.toDString, locIndex, 0, [0]);
67+
locFileTable ~= new BaseLoc(filename.toDString, null, locIndex, 0, [0]);
6868
result.index = locIndex++;
6969
return result;
7070
}
@@ -235,16 +235,20 @@ struct SourceLoc
235235
uint column; /// column number (starts at 1)
236236
uint fileOffset; /// byte index into file
237237

238+
/// Index `fileOffset` into this to to obtain source code context of this location
239+
const(char)[] fileContent;
240+
238241
// aliases for backwards compatibility
239242
alias linnum = line;
240243
alias charnum = column;
241244

242-
this(const(char)[] filename, uint line, uint column, uint fileOffset = 0) nothrow @nogc pure @safe
245+
this(const(char)[] filename, uint line, uint column, uint fileOffset = 0, const(char)[] fileContent = null) nothrow @nogc pure @safe
243246
{
244247
this.filename = filename;
245248
this.line = line;
246249
this.column = column;
247250
this.fileOffset = fileOffset;
251+
this.fileContent = fileContent;
248252
}
249253

250254
this(Loc loc) nothrow @nogc @trusted
@@ -300,15 +304,15 @@ private size_t fileTableIndex(uint index) nothrow @nogc
300304
* Create a new source location map for a file
301305
* Params:
302306
* filename = source file name
303-
* size = space to reserve for locations, equal to the file size in bytes
307+
* fileContent = content of source file
304308
* Returns: new BaseLoc
305309
*/
306-
BaseLoc* newBaseLoc(const(char)* filename, size_t size) nothrow
310+
BaseLoc* newBaseLoc(const(char)* filename, const(char)[] fileContent) nothrow
307311
{
308-
locFileTable ~= new BaseLoc(filename.toDString, locIndex, 1, [0]);
312+
locFileTable ~= new BaseLoc(filename.toDString, fileContent, locIndex, 1, [0]);
309313
// Careful: the endloc of a FuncDeclaration can
310314
// point to 1 past the very last byte in the file, so account for that
311-
locIndex += size + 1;
315+
locIndex += fileContent.length + 1;
312316
return locFileTable[$ - 1];
313317
}
314318

@@ -354,6 +358,7 @@ struct BaseLoc
354358
@safe nothrow:
355359

356360
const(char)[] filename; /// Source file name
361+
const(char)[] fileContents; /// Source file contents
357362
uint startIndex; /// Subtract this from Loc.index to get file offset
358363
int startLine = 1; /// Line number at index 0
359364
uint[] lines; /// For each line, the file offset at which it starts. At index 0 there's always a 0 entry.
@@ -384,11 +389,11 @@ struct BaseLoc
384389
{
385390
auto fname = filename.toDString;
386391
if (substitutions.length == 0)
387-
substitutions ~= BaseLoc(this.filename, 0, 0);
392+
substitutions ~= BaseLoc(this.filename, null, 0, 0);
388393

389394
if (fname.length == 0)
390395
fname = substitutions[$ - 1].filename;
391-
substitutions ~= BaseLoc(fname, offset, cast(int) (line - lines.length + startLine - 2));
396+
substitutions ~= BaseLoc(fname, null, offset, cast(int) (line - lines.length + startLine - 2));
392397
}
393398

394399
/// Returns: `loc` modified by substitutions from #file / #line directives
@@ -408,7 +413,7 @@ struct BaseLoc
408413
private SourceLoc getSourceLoc(uint offset) @nogc
409414
{
410415
const i = getLineIndex(offset);
411-
const sl = SourceLoc(filename, cast(int) (i + startLine), cast(int) (1 + offset - lines[i]), offset);
416+
const sl = SourceLoc(filename, cast(int) (i + startLine), cast(int) (1 + offset - lines[i]), offset, fileContents);
412417
return substitute(sl);
413418
}
414419

tests/dmd/compilable/pragmapack.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* REQUIRED_ARGS: -wi
1+
/* REQUIRED_ARGS: -wi -verrors=simple
22
TEST_OUTPUT:
33
---
44
compilable/pragmapack.c(101): Warning: current pack attribute is default

tests/dmd/fail_compilation/fail_pretty_errors.d

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
1-
/*
1+
/*
22
REQUIRED_ARGS: -verrors=context
33
TEST_OUTPUT:
44
---
5-
fail_compilation/fail_pretty_errors.d(27): Error: undefined identifier `a`
5+
fail_compilation/fail_pretty_errors.d(29): Error: undefined identifier `a`
66
a = 1;
77
^
8-
fail_compilation/fail_pretty_errors.d-mixin-32(32): Error: undefined identifier `b`
9-
fail_compilation/fail_pretty_errors.d(37): Error: cannot implicitly convert expression `5` of type `int` to `string`
8+
fail_compilation/fail_pretty_errors.d-mixin-34(34): Error: undefined identifier `b`
9+
b = 1;
10+
^
11+
fail_compilation/fail_pretty_errors.d(39): Error: cannot implicitly convert expression `5` of type `int` to `string`
1012
string x = 5;
1113
^
12-
fail_compilation/fail_pretty_errors.d(42): Error: mixin `fail_pretty_errors.testMixin2.mixinTemplate!()` error instantiating
14+
fail_compilation/fail_pretty_errors.d(44): Error: mixin `fail_pretty_errors.testMixin2.mixinTemplate!()` error instantiating
1315
mixin mixinTemplate;
1416
^
15-
fail_compilation/fail_pretty_errors.d(48): Error: invalid array operation `"" + ""` (possible missing [])
17+
fail_compilation/fail_pretty_errors.d(50): Error: invalid array operation `"" + ""` (possible missing [])
1618
auto x = ""+"";
1719
^
18-
fail_compilation/fail_pretty_errors.d(48): did you mean to concatenate (`"" ~ ""`) instead ?
19-
fail_compilation/fail_pretty_errors.d(51): Error: cannot implicitly convert expression `1111` of type `int` to `byte`
20+
fail_compilation/fail_pretty_errors.d(50): did you mean to concatenate (`"" ~ ""`) instead ?
21+
fail_compilation/fail_pretty_errors.d(53): Error: cannot implicitly convert expression `1111` of type `int` to `byte`
2022
byte ɑ = 1111;
2123
^
2224
---

tests/dmd/fail_compilation/failcstuff6.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
// check dsymbolSemantic analysis of C files
22
/* TEST_OUTPUT:
3+
REQUIRED_ARGS: -verrors=context
34
---
45
fail_compilation/failcstuff6.c(56): Error: enum member `failcstuff6.test_overflow.boom` initialization with `2147483647+1` causes overflow for type `int`
6+
boom,
7+
^
58
---
69
*/
710

0 commit comments

Comments
 (0)