Fix #21189 - wrong/missing error line when source file isn't regular (#21190)

This commit is contained in:
Dennis 2025-04-10 01:19:58 +02:00 committed by GitHub
parent 3070fc288a
commit 0aee4697bd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 39 additions and 30 deletions

View file

@ -442,7 +442,7 @@ private struct ErrorInfo
this.kind = kind;
}
const SourceLoc loc; // location of error
const SourceLoc loc; // location of error
Classification headerColor; // color to set `header` output to
const(char)* p1; // additional message prefix
const(char)* p2; // additional message prefix
@ -731,13 +731,9 @@ private void verrorPrint(const(char)* format, va_list ap, ref ErrorInfo info)
!loc.filename.startsWith(".d-mixin-") &&
!global.params.mixinOut.doOutput)
{
import dmd.root.filename : FileName;
if (auto text = cast(const(char[])) global.fileManager.getFileContents(FileName(loc.filename)))
{
tmp.reset();
printErrorLineContext(tmp, text, loc.fileOffset);
fputs(tmp.peekChars(), stderr);
}
tmp.reset();
printErrorLineContext(tmp, loc.fileContent, loc.fileOffset);
fputs(tmp.peekChars(), stderr);
}
old_loc = loc;
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
import dmd.root.utf : utf_decodeChar;
if (offset >= text.length)
return; // Out of bounds (can happen in pre-processed C files currently)
return; // Out of bounds (missing source content in SourceLoc)
// Scan backwards for beginning of line
size_t s = offset;

View file

@ -383,12 +383,14 @@ struct SourceLoc final
uint32_t line;
uint32_t column;
uint32_t fileOffset;
_d_dynamicArray< const char > fileContent;
const char* toChars(bool showColumns = Loc::showColumns, MessageStyle messageStyle = Loc::messageStyle) const;
SourceLoc() :
filename(),
line(),
column(),
fileOffset()
fileOffset(),
fileContent()
{
}
};

View file

@ -421,6 +421,7 @@ struct SourceLoc
uint32_t line;
uint32_t column;
uint32_t fileOffset;
DString fileContent;
};
struct Loc

View file

@ -132,7 +132,7 @@ class Lexer
// debug printf("Lexer::Lexer(%p)\n", base);
// debug printf("lexer.filename = %s\n", filename);
token = Token.init;
this.baseLoc = newBaseLoc(filename, endoffset);
this.baseLoc = newBaseLoc(filename, base[0 .. endoffset]);
this.linnum = 1;
this.base = base;
this.end = base + endoffset;
@ -224,7 +224,7 @@ class Lexer
inTokenStringConstant = 0;
lastDocLine = 0;
baseLoc = newBaseLoc("#defines", slice.length);
baseLoc = newBaseLoc("#defines", slice);
scanloc = baseLoc.getLoc(0);
}

View file

@ -64,7 +64,7 @@ nothrow:
extern (C++) static Loc singleFilename(const char* filename)
{
Loc result;
locFileTable ~= new BaseLoc(filename.toDString, locIndex, 0, [0]);
locFileTable ~= new BaseLoc(filename.toDString, null, locIndex, 0, [0]);
result.index = locIndex++;
return result;
}
@ -235,16 +235,20 @@ struct SourceLoc
uint column; /// column number (starts at 1)
uint fileOffset; /// byte index into file
/// Index `fileOffset` into this to to obtain source code context of this location
const(char)[] fileContent;
// aliases for backwards compatibility
alias linnum = line;
alias charnum = column;
this(const(char)[] filename, uint line, uint column, uint fileOffset = 0) nothrow @nogc pure @safe
this(const(char)[] filename, uint line, uint column, uint fileOffset = 0, const(char)[] fileContent = null) nothrow @nogc pure @safe
{
this.filename = filename;
this.line = line;
this.column = column;
this.fileOffset = fileOffset;
this.fileContent = fileContent;
}
this(Loc loc) nothrow @nogc @trusted
@ -300,15 +304,15 @@ private size_t fileTableIndex(uint index) nothrow @nogc
* Create a new source location map for a file
* Params:
* filename = source file name
* size = space to reserve for locations, equal to the file size in bytes
* fileContent = content of source file
* Returns: new BaseLoc
*/
BaseLoc* newBaseLoc(const(char)* filename, size_t size) nothrow
BaseLoc* newBaseLoc(const(char)* filename, const(char)[] fileContent) nothrow
{
locFileTable ~= new BaseLoc(filename.toDString, locIndex, 1, [0]);
locFileTable ~= new BaseLoc(filename.toDString, fileContent, locIndex, 1, [0]);
// Careful: the endloc of a FuncDeclaration can
// point to 1 past the very last byte in the file, so account for that
locIndex += size + 1;
locIndex += fileContent.length + 1;
return locFileTable[$ - 1];
}
@ -354,6 +358,7 @@ struct BaseLoc
@safe nothrow:
const(char)[] filename; /// Source file name
const(char)[] fileContents; /// Source file contents
uint startIndex; /// Subtract this from Loc.index to get file offset
int startLine = 1; /// Line number at index 0
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
{
auto fname = filename.toDString;
if (substitutions.length == 0)
substitutions ~= BaseLoc(this.filename, 0, 0);
substitutions ~= BaseLoc(this.filename, null, 0, 0);
if (fname.length == 0)
fname = substitutions[$ - 1].filename;
substitutions ~= BaseLoc(fname, offset, cast(int) (line - lines.length + startLine - 2));
substitutions ~= BaseLoc(fname, null, offset, cast(int) (line - lines.length + startLine - 2));
}
/// Returns: `loc` modified by substitutions from #file / #line directives
@ -408,7 +413,7 @@ struct BaseLoc
private SourceLoc getSourceLoc(uint offset) @nogc
{
const i = getLineIndex(offset);
const sl = SourceLoc(filename, cast(int) (i + startLine), cast(int) (1 + offset - lines[i]), offset);
const sl = SourceLoc(filename, cast(int) (i + startLine), cast(int) (1 + offset - lines[i]), offset, fileContents);
return substitute(sl);
}

View file

@ -1,4 +1,4 @@
/* REQUIRED_ARGS: -wi
/* REQUIRED_ARGS: -wi -verrors=simple
TEST_OUTPUT:
---
compilable/pragmapack.c(101): Warning: current pack attribute is default

View file

@ -1,22 +1,24 @@
/*
/*
REQUIRED_ARGS: -verrors=context
TEST_OUTPUT:
---
fail_compilation/fail_pretty_errors.d(27): Error: undefined identifier `a`
fail_compilation/fail_pretty_errors.d(29): Error: undefined identifier `a`
a = 1;
^
fail_compilation/fail_pretty_errors.d-mixin-32(32): Error: undefined identifier `b`
fail_compilation/fail_pretty_errors.d(37): Error: cannot implicitly convert expression `5` of type `int` to `string`
fail_compilation/fail_pretty_errors.d-mixin-34(34): Error: undefined identifier `b`
b = 1;
^
fail_compilation/fail_pretty_errors.d(39): Error: cannot implicitly convert expression `5` of type `int` to `string`
string x = 5;
^
fail_compilation/fail_pretty_errors.d(42): Error: mixin `fail_pretty_errors.testMixin2.mixinTemplate!()` error instantiating
fail_compilation/fail_pretty_errors.d(44): Error: mixin `fail_pretty_errors.testMixin2.mixinTemplate!()` error instantiating
mixin mixinTemplate;
^
fail_compilation/fail_pretty_errors.d(48): Error: invalid array operation `"" + ""` (possible missing [])
fail_compilation/fail_pretty_errors.d(50): Error: invalid array operation `"" + ""` (possible missing [])
auto x = ""+"";
^
fail_compilation/fail_pretty_errors.d(48): did you mean to concatenate (`"" ~ ""`) instead ?
fail_compilation/fail_pretty_errors.d(51): Error: cannot implicitly convert expression `1111` of type `int` to `byte`
fail_compilation/fail_pretty_errors.d(50): did you mean to concatenate (`"" ~ ""`) instead ?
fail_compilation/fail_pretty_errors.d(53): Error: cannot implicitly convert expression `1111` of type `int` to `byte`
byte ɑ = 1111;
^
---

View file

@ -1,7 +1,10 @@
// check dsymbolSemantic analysis of C files
/* TEST_OUTPUT:
REQUIRED_ARGS: -verrors=context
---
fail_compilation/failcstuff6.c(56): Error: enum member `failcstuff6.test_overflow.boom` initialization with `2147483647+1` causes overflow for type `int`
boom,
^
---
*/