Skip to content

Commit 3cf6297

Browse files
committed
Preprocessor+Parser: detect system headers and don't apply indirect include rule to them
1 parent f22c28e commit 3cf6297

File tree

6 files changed

+14
-9
lines changed

6 files changed

+14
-9
lines changed

src/Compilation.zig

+9-7
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,7 @@ pub fn addSourceFromReader(
529529
path: []const u8,
530530
contents: []u8,
531531
included_automatically: bool,
532+
system_header_file: bool,
532533
) !Source {
533534
const duped_path = try comp.gpa.dupe(u8, path);
534535
errdefer comp.gpa.free(duped_path);
@@ -618,6 +619,7 @@ pub fn addSourceFromReader(
618619
.id = source_id,
619620
.path = duped_path,
620621
.included_automatically = included_automatically,
622+
.system_header_file = system_header_file,
621623
.buf = if (i == contents.len) contents else try comp.gpa.realloc(contents, i),
622624
.splice_locs = splice_locs,
623625
};
@@ -637,11 +639,11 @@ pub fn addSourceFromBuffer(comp: *Compilation, path: []const u8, buf: []const u8
637639
const contents = try comp.gpa.alloc(u8, buf.len);
638640
errdefer comp.gpa.free(contents);
639641

640-
return comp.addSourceFromReader(reader, path, contents, true);
642+
return comp.addSourceFromReader(reader, path, contents, true, false);
641643
}
642644

643645
/// Caller retains ownership of `path`
644-
pub fn addSourceFromPath(comp: *Compilation, path: []const u8) !Source {
646+
pub fn addSourceFromPath(comp: *Compilation, path: []const u8, system_header_file: bool) !Source {
645647
if (comp.sources.get(path)) |some| return some;
646648

647649
if (mem.indexOfScalar(u8, path, 0) != null) {
@@ -657,7 +659,7 @@ pub fn addSourceFromPath(comp: *Compilation, path: []const u8) !Source {
657659
const contents = try comp.gpa.alloc(u8, size);
658660
errdefer comp.gpa.free(contents);
659661

660-
return comp.addSourceFromReader(reader, path, contents, false);
662+
return comp.addSourceFromReader(reader, path, contents, false, system_header_file);
661663
}
662664

663665
pub fn findInclude(comp: *Compilation, tok: Token, filename: []const u8, search_cwd: bool) !?Source {
@@ -669,7 +671,7 @@ pub fn findInclude(comp: *Compilation, tok: Token, filename: []const u8, search_
669671
std.fs.path.join(fib.allocator(), &.{ some, filename }) catch break :blk
670672
else
671673
std.fs.path.join(fib.allocator(), &.{ ".", filename }) catch break :blk;
672-
if (comp.addSourceFromPath(path)) |some|
674+
if (comp.addSourceFromPath(path, false)) |some|
673675
return some
674676
else |err| switch (err) {
675677
error.OutOfMemory => return error.OutOfMemory,
@@ -679,7 +681,7 @@ pub fn findInclude(comp: *Compilation, tok: Token, filename: []const u8, search_
679681
for (comp.include_dirs.items) |dir| {
680682
fib.end_index = 0;
681683
const path = std.fs.path.join(fib.allocator(), &.{ dir, filename }) catch continue;
682-
if (comp.addSourceFromPath(path)) |some|
684+
if (comp.addSourceFromPath(path, false)) |some|
683685
return some
684686
else |err| switch (err) {
685687
error.OutOfMemory => return error.OutOfMemory,
@@ -689,7 +691,7 @@ pub fn findInclude(comp: *Compilation, tok: Token, filename: []const u8, search_
689691
for (comp.system_include_dirs.items) |dir| {
690692
fib.end_index = 0;
691693
const path = std.fs.path.join(fib.allocator(), &.{ dir, filename }) catch continue;
692-
if (comp.addSourceFromPath(path)) |some|
694+
if (comp.addSourceFromPath(path, true)) |some|
693695
return some
694696
else |err| switch (err) {
695697
error.OutOfMemory => return error.OutOfMemory,
@@ -785,7 +787,7 @@ test "addSourceFromReader" {
785787
const contents = try comp.gpa.alloc(u8, 1024);
786788

787789
var reader = std.io.fixedBufferStream(str).reader();
788-
const source = try comp.addSourceFromReader(reader, "path", contents, false);
790+
const source = try comp.addSourceFromReader(reader, "path", contents, false, false);
789791

790792
try std.testing.expectEqualStrings(expected, source.buf);
791793
try std.testing.expectEqual(warning_count, @intCast(u32, comp.diag.list.items.len));

src/Parser.zig

+1
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ fn checkIndirectInclude(p: *Parser, usage_tok: TokenIndex, source_tok: TokenInde
392392
if (locs[usage_tok].id == .generated) return;
393393
if (locs[usage_tok].id == locs[source_tok].id) return; // in same file
394394
const usage_src = p.pp.comp.getSource(locs[usage_tok].id);
395+
if (usage_src.system_header_file) return; // do not apply rule to system header files
395396
if (usage_src.direct_includes.get(locs[source_tok].id) != null) return; // directly included
396397

397398
try p.errTok(.indirect_use_of_ident, usage_tok);

src/Preprocessor.zig

+1
Original file line numberDiff line numberDiff line change
@@ -1195,6 +1195,7 @@ fn checkIndirectInclude(pp: *Preprocessor, source_loc: Source.Location) !void {
11951195
if (source.included_automatically) return; // macro is included automatically and always visible
11961196
if (pp.expansion_source_loc.id == source_loc.id) return; // in same file
11971197
const usage_src = pp.comp.getSource(pp.expansion_source_loc.id);
1198+
if (usage_src.system_header_file) return; // do not apply rule to system header files
11981199
if (usage_src.direct_includes.get(source_loc.id) != null) return; // directly included
11991200

12001201
try pp.comp.diag.add(.{ .tag = .indirect_use_of_ident, .loc = pp.expansion_source_loc }, &.{});

src/Source.zig

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ buf: []const u8,
2424
id: Id,
2525
/// True if this source is included in the preprocessor without an explicit #include
2626
included_automatically: bool = false,
27+
system_header_file: bool = false,
2728
invalid_utf8_loc: ?Location = null,
2829
/// each entry represents a byte position within `buf` where a backslash+newline was deleted
2930
/// from the original raw buffer. The same position can appear multiple times if multiple

src/main.zig

+1-1
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ pub fn parseArgs(comp: *Compilation, std_out: anytype, sources: *std.ArrayList(S
236236
try comp.diag.add(.{ .tag = .cli_unknown_arg, .extra = .{ .str = arg } }, &.{});
237237
}
238238
} else {
239-
const file = comp.addSourceFromPath(arg) catch |err| {
239+
const file = comp.addSourceFromPath(arg, false) catch |err| {
240240
return fatal(comp, "{s} when trying to add source file", .{@errorName(err)});
241241
};
242242
try sources.append(file);

test/runner.zig

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ pub fn main() !void {
8686
defer case_node.end();
8787
progress.refresh();
8888

89-
const file = comp.addSourceFromPath(path) catch |err| {
89+
const file = comp.addSourceFromPath(path, false) catch |err| {
9090
fail_count += 1;
9191
progress.log("could not add source '{s}': {s}\n", .{ path, @errorName(err) });
9292
continue;

0 commit comments

Comments
 (0)