Skip to content

Commit 4419ce5

Browse files
authored
Merge pull request #85528 from hnrklssn/diag-verify-fixes
[DiagnosticVerifier] improve output for expansions in clang attributes
2 parents d0f8cce + 69f6f47 commit 4419ce5

File tree

10 files changed

+114
-22
lines changed

10 files changed

+114
-22
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8786,7 +8786,9 @@ SourceFile &ClangImporter::Implementation::getClangSwiftAttrSourceFile(
87868786
auto bufferID = sourceMgr.addMemBufferCopy(attributeText);
87878787

87888788
auto info = GeneratedSourceInfo{GeneratedSourceInfo::AttributeFromClang,
8789-
CharSourceRange(),
8789+
// NB: This source range is not used by the diagnostic engine,
8790+
// but it is traversed by DiagnostciVerifier.
8791+
CharSourceRange(MappedDecl->getStartLoc(), 0),
87908792
sourceMgr.getRangeForBuffer(bufferID)};
87918793
info.astNode = static_cast<void *>(module);
87928794
info.clangNode = MappedDecl->getClangNode();

lib/Frontend/DiagnosticVerifier.cpp

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "swift/Basic/ColorUtils.h"
2121
#include "swift/Basic/SourceManager.h"
2222
#include "swift/Parse/Lexer.h"
23+
#include "llvm/ADT/ArrayRef.h"
2324
#include "llvm/ADT/STLExtras.h"
2425
#include "llvm/Support/FileSystem.h"
2526
#include "llvm/Support/FormatVariadic.h"
@@ -386,19 +387,23 @@ static void autoApplyFixes(SourceManager &SM, unsigned BufferID,
386387
bool DiagnosticVerifier::verifyUnknown(
387388
std::vector<CapturedDiagnosticInfo> &CapturedDiagnostics) const {
388389
bool HadError = false;
389-
for (unsigned i = 0, e = CapturedDiagnostics.size(); i != e; ++i) {
390-
if (CapturedDiagnostics[i].Loc.isValid())
390+
auto CapturedDiagIter = CapturedDiagnostics.begin();
391+
while (CapturedDiagIter != CapturedDiagnostics.end()) {
392+
if (CapturedDiagIter->Loc.isValid()) {
393+
++CapturedDiagIter;
391394
continue;
395+
}
392396

393397
HadError = true;
394398
std::string Message =
395399
("unexpected " +
396-
getDiagKindString(CapturedDiagnostics[i].Classification) +
397-
" produced: " + CapturedDiagnostics[i].Message)
400+
getDiagKindString(CapturedDiagIter->Classification) +
401+
" produced: " + CapturedDiagIter->Message)
398402
.str();
399403

400404
auto diag = SM.GetMessage({}, llvm::SourceMgr::DK_Error, Message, {}, {});
401405
printDiagnostic(diag);
406+
CapturedDiagIter = CapturedDiagnostics.erase(CapturedDiagIter);
402407
}
403408

404409
if (HadError) {
@@ -414,23 +419,35 @@ bool DiagnosticVerifier::verifyUnknown(
414419
bool DiagnosticVerifier::verifyUnrelated(
415420
std::vector<CapturedDiagnosticInfo> &CapturedDiagnostics) const {
416421
bool HadError = false;
417-
for (unsigned i = 0, e = CapturedDiagnostics.size(); i != e; ++i) {
418-
SourceLoc Loc = CapturedDiagnostics[i].Loc;
419-
if (!Loc.isValid())
422+
auto CapturedDiagIter = CapturedDiagnostics.begin();
423+
while (CapturedDiagIter != CapturedDiagnostics.end()) {
424+
SourceLoc Loc = CapturedDiagIter->Loc;
425+
if (!Loc.isValid()) {
426+
++CapturedDiagIter;
420427
// checked by verifyUnknown
421428
continue;
429+
}
422430

423431
HadError = true;
424432
std::string Message =
425433
("unexpected " +
426-
getDiagKindString(CapturedDiagnostics[i].Classification) +
427-
" produced: " + CapturedDiagnostics[i].Message)
434+
getDiagKindString(CapturedDiagIter->Classification) +
435+
" produced: " + CapturedDiagIter->Message)
428436
.str();
429437

430438
auto diag = SM.GetMessage(Loc, llvm::SourceMgr::DK_Error, Message, {}, {});
431439
printDiagnostic(diag);
432440

433-
auto FileName = SM.getIdentifierForBuffer(SM.findBufferContainingLoc(Loc));
441+
unsigned TopmostBufferID = SM.findBufferContainingLoc(Loc);
442+
while (const GeneratedSourceInfo *GSI =
443+
SM.getGeneratedSourceInfo(TopmostBufferID)) {
444+
SourceLoc ParentLoc = GSI->originalSourceRange.getStart();
445+
if (ParentLoc.isInvalid())
446+
break;
447+
TopmostBufferID = SM.findBufferContainingLoc(ParentLoc);
448+
Loc = ParentLoc;
449+
}
450+
auto FileName = SM.getIdentifierForBuffer(TopmostBufferID);
434451
auto noteDiag =
435452
SM.GetMessage(Loc, llvm::SourceMgr::DK_Note,
436453
("file '" + FileName +
@@ -441,6 +458,7 @@ bool DiagnosticVerifier::verifyUnrelated(
441458
"ignore diagnostics in this file"),
442459
{}, {});
443460
printDiagnostic(noteDiag);
461+
CapturedDiagIter = CapturedDiagnostics.erase(CapturedDiagIter);
444462
}
445463

446464
return HadError;
@@ -476,7 +494,14 @@ void DiagnosticVerifier::printDiagnostic(const llvm::SMDiagnostic &Diag) const {
476494
ColoredStream coloredStream{stream};
477495
raw_ostream &out = UseColor ? coloredStream : stream;
478496
llvm::SourceMgr &Underlying = SM.getLLVMSourceMgr();
479-
Underlying.PrintMessage(out, Diag);
497+
if (Diag.getFilename().empty()) {
498+
llvm::SMDiagnostic SubstDiag(
499+
*Diag.getSourceMgr(), Diag.getLoc(), "<empty-filename>",
500+
Diag.getLineNo(), Diag.getColumnNo(), Diag.getKind(), Diag.getMessage(),
501+
Diag.getLineContents(), Diag.getRanges(), Diag.getFixIts());
502+
Underlying.PrintMessage(out, SubstDiag);
503+
} else
504+
Underlying.PrintMessage(out, Diag);
480505

481506
SourceLoc Loc = SourceLoc::getFromPointer(Diag.getLoc().getPointer());
482507
if (Loc.isInvalid())
@@ -1402,9 +1427,9 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) {
14021427

14031428
// Diagnostics attached to generated sources originating in this
14041429
// buffer also count as part of this buffer for this purpose.
1405-
const GeneratedSourceInfo *GSI =
1406-
SM.getGeneratedSourceInfo(CapturedDiagIter->SourceBufferID.value());
1407-
if (!GSI || llvm::find(GSI->ancestors, BufferID) == GSI->ancestors.end()) {
1430+
unsigned scratch;
1431+
llvm::ArrayRef<unsigned> ancestors = SM.getAncestors(CapturedDiagIter->SourceBufferID.value(), scratch);
1432+
if (llvm::find(ancestors, BufferID) == ancestors.end()) {
14081433
++CapturedDiagIter;
14091434
continue;
14101435
}

test/Frontend/DiagnosticVerifier/broken-c-module.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,9 @@
66
// RUN: not %target-typecheck-verify-swift -I %S/Inputs/broken-c-module 2>&1 | %FileCheck %s --implicit-check-not error: --implicit-check-not note: --implicit-check-not warning:
77

88
// CHECK: <unknown>:0: error: fatal error encountered while in -verify mode
9-
// CHECK: [[@LINE+7]]:8: error: unexpected error produced: could not build
9+
// CHECK: [[@LINE+5]]:8: error: unexpected error produced: could not build
1010
// CHECK: error: unexpected note produced: in file included from <module-includes>:1:
1111
// CHECK: note: file '<module-includes>' is not parsed for 'expected' statements. Use '-verify-additional-file <module-includes>' to enable, or '-verify-ignore-unrelated' to ignore diagnostics in this file
1212
// CHECK: error: unexpected error produced: expected function body after function declarator
1313
// CHECK: note: file '{{.*}}broken_c.h' is not parsed for 'expected' statements. Use '-verify-additional-file {{.*}}broken_c.h' to enable, or '-verify-ignore-unrelated' to ignore diagnostics in this file
14-
// CHECK: note: diagnostic produced elsewhere: in file included from <module-includes>
15-
// CHECK: broken_c.h:2:11: error: diagnostic produced elsewhere: expected function body after function declarator
1614
import BrokenCModule
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: not %target-swift-frontend -typecheck -verify %t/test.swift -I %t -plugin-path %swift-plugin-dir -Rmacro-expansions 2>&1 | \
5+
// RUN: %FileCheck %s --implicit-check-not error: --implicit-check-not note: --implicit-check-not warning: --implicit-check-not remark: --match-full-lines --sanitize TEST_H=%t%{fs-sep}test.h
6+
7+
//--- test.h
8+
void foo(int len, int *p) __attribute__((
9+
swift_attr("@_SwiftifyImport(.countedBy(pointer: .param(2), count: \"len\"))")));
10+
11+
//--- test.swift
12+
import TestClang
13+
14+
func bar(x: UnsafeMutableBufferPointer<CInt>) {
15+
foo(x) // trigger macro expansion
16+
}
17+
18+
//--- module.modulemap
19+
module TestClang {
20+
header "test.h"
21+
export *
22+
}
23+
24+
// CHECK: @__swiftmacro_So3foo15_SwiftifyImportfMp_.swift:1:1: error: unexpected remark produced: macro content: |/// This is an auto-generated wrapper for safer interop|
25+
// CHECK: TEST_H:1:25: note: in expansion from here
26+
// CHECK: TEST_H:1:25: note: file 'TEST_H' is not parsed for 'expected' statements. Use '-verify-additional-file TEST_H' to enable, or '-verify-ignore-unrelated' to ignore diagnostics in this file
27+
// CHECK: <empty-filename>:1:1: error: unexpected note produced: in expansion of macro '_SwiftifyImport' on global function 'foo' here
28+
// // CHECK-NEXT: @_SwiftifyImport(.countedBy(pointer: .param(2), count: "len"))
29+
// CHECK: TEST_H:1:6: note: in expansion from here
30+
// CHECK: TEST_H:1:6: note: file 'TEST_H' is not parsed for 'expected' statements. Use '-verify-additional-file TEST_H' to enable, or '-verify-ignore-unrelated' to ignore diagnostics in this file
31+
32+
// CHECK: @__swiftmacro_So3foo15_SwiftifyImportfMp_.swift:2:1: error: unexpected remark produced: macro content: |@_alwaysEmitIntoClient @_disfavoredOverload public func foo(_ p: UnsafeMutableBufferPointer<Int32>) {|
33+
// CHECK: TEST_H:1:25: note: in expansion from here
34+
// CHECK: TEST_H:1:25: note: file 'TEST_H' is not parsed for 'expected' statements. Use '-verify-additional-file TEST_H' to enable, or '-verify-ignore-unrelated' to ignore diagnostics in this file
35+
// CHECK: <empty-filename>:1:1: error: unexpected note produced: in expansion of macro '_SwiftifyImport' on global function 'foo' here
36+
// CHECK-NEXT: @_SwiftifyImport(.countedBy(pointer: .param(2), count: "len"))
37+
// CHECK: TEST_H:1:6: note: in expansion from here
38+
// CHECK: TEST_H:1:6: note: file 'TEST_H' is not parsed for 'expected' statements. Use '-verify-additional-file TEST_H' to enable, or '-verify-ignore-unrelated' to ignore diagnostics in this file
39+
40+
// CHECK: @__swiftmacro_So3foo15_SwiftifyImportfMp_.swift:3:1: error: unexpected remark produced: macro content: | let len = Int32(exactly: p.count)!|
41+
// CHECK: TEST_H:1:25: note: in expansion from here
42+
// CHECK: TEST_H:1:25: note: file 'TEST_H' is not parsed for 'expected' statements. Use '-verify-additional-file TEST_H' to enable, or '-verify-ignore-unrelated' to ignore diagnostics in this file
43+
// CHECK: <empty-filename>:1:1: error: unexpected note produced: in expansion of macro '_SwiftifyImport' on global function 'foo' here
44+
// CHECK-NEXT: @_SwiftifyImport(.countedBy(pointer: .param(2), count: "len"))
45+
// CHECK: TEST_H:1:6: note: in expansion from here
46+
// CHECK: TEST_H:1:6: note: file 'TEST_H' is not parsed for 'expected' statements. Use '-verify-additional-file TEST_H' to enable, or '-verify-ignore-unrelated' to ignore diagnostics in this file
47+
48+
// CHECK: @__swiftmacro_So3foo15_SwiftifyImportfMp_.swift:4:1: error: unexpected remark produced: macro content: | return unsafe foo(len, p.baseAddress!)|
49+
// CHECK: TEST_H:1:25: note: in expansion from here
50+
// CHECK: TEST_H:1:25: note: file 'TEST_H' is not parsed for 'expected' statements. Use '-verify-additional-file TEST_H' to enable, or '-verify-ignore-unrelated' to ignore diagnostics in this file
51+
// CHECK: <empty-filename>:1:1: error: unexpected note produced: in expansion of macro '_SwiftifyImport' on global function 'foo' here
52+
// CHECK-NEXT: @_SwiftifyImport(.countedBy(pointer: .param(2), count: "len"))
53+
// CHECK: TEST_H:1:6: note: in expansion from here
54+
// CHECK: TEST_H:1:6: note: file 'TEST_H' is not parsed for 'expected' statements. Use '-verify-additional-file TEST_H' to enable, or '-verify-ignore-unrelated' to ignore diagnostics in this file
55+
56+
// CHECK: @__swiftmacro_So3foo15_SwiftifyImportfMp_.swift:5:1: error: unexpected remark produced: macro content: |}|
57+
// CHECK: TEST_H:1:25: note: in expansion from here
58+
// CHECK: TEST_H:1:25: note: file 'TEST_H' is not parsed for 'expected' statements. Use '-verify-additional-file TEST_H' to enable, or '-verify-ignore-unrelated' to ignore diagnostics in this file
59+
// CHECK: <empty-filename>:1:1: error: unexpected note produced: in expansion of macro '_SwiftifyImport' on global function 'foo' here
60+
// CHECK-NEXT: @_SwiftifyImport(.countedBy(pointer: .param(2), count: "len"))
61+
// CHECK: TEST_H:1:6: note: in expansion from here
62+
// CHECK: TEST_H:1:6: note: file 'TEST_H' is not parsed for 'expected' statements. Use '-verify-additional-file TEST_H' to enable, or '-verify-ignore-unrelated' to ignore diagnostics in this file

test/Frontend/DiagnosticVerifier/verify.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,3 @@ fn(()) // expected-error {{argument passed to call that takes no arguments}}
3434
let x: Array<Int, Int>
3535
// CHECK: error: unexpected note produced: generic struct 'Array' declared here
3636
// CHECK: note: file 'Swift.Array' is not parsed for 'expected' statements. Use '-verify-additional-file Swift.Array' to enable, or '-verify-ignore-unrelated' to ignore diagnostics in this file
37-
// CHECK: note: diagnostic produced elsewhere: generic struct 'Array' declared here

test/Frontend/DiagnosticVerifier/verify2.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ extension Crap {} // expected-error {{non-nominal type 'Crap' (aka '() -> ()') c
4444

4545
// CHECK: error: unexpected note produced: 'Bool' declared here
4646
// CHECK: note: file 'Swift.Bool' is not parsed for 'expected' statements. Use '-verify-additional-file Swift.Bool' to enable, or '-verify-ignore-unrelated' to ignore diagnostics in this file
47-
// CHECK: note: diagnostic produced elsewhere: 'Bool' declared here
4847

4948
// Verify the serialized diags have the right magic at the top.
5049
// CHECK-SERIALIZED: DIA

test/Inputs/clang-importer-sdk/usr/include/ObjCConcurrency.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ MAIN_ACTOR MAIN_ACTOR __attribute__((__swift_attr__("@MainActor"))) @protocol Tr
233233

234234
SENDABLE @interface SendableClass : NSObject @end
235235

236+
// expected-expansion@+3:13{{
237+
// expected-note@1 5{{conformance of 'NonSendableClass' to 'Sendable' has been explicitly marked unavailable here}}
238+
// }}
236239
NONSENDABLE @interface NonSendableClass : NSObject @end // expected-note {{class 'NonSendableClass' does not conform to the 'Sendable' protocol}}
237240

238241
ASSUME_NONSENDABLE_BEGIN

test/Interop/Cxx/templates/function-template-typechecker-errors.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
// RUN: not %target-typecheck-verify-swift -verify-ignore-unrelated -I %S/Inputs -enable-experimental-cxx-interop 2>&1 | %FileCheck %s
2-
1+
// RUN: not %target-typecheck-verify-swift -verify-ignore-unrelated -verify-ignore-unknown -I %S/Inputs -enable-experimental-cxx-interop 2>&1 | %FileCheck %s
32
// README: If you just added support for protocol composition to the
43
// ClangTypeConverter, please update this test to use a different type that we
54
// don't support so the error messages here are still tested.

test/Macros/accessor_macros.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ struct MyBrokenStruct {
102102
/*
103103
expected-expansion@-2:25{{
104104
expected-error@1:1{{variable already has a getter}}
105+
expected-error@5:1{{variable already has a setter}}
105106
}}
106107
*/
107108
// CHECK-DIAGS: variable already has a getter

test/Macros/expand_peers_hang.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ macro HangingMacro() = #externalMacro(module: "MacroDefinition", type: "HangingM
1111
class Foo {
1212
init() {}
1313

14+
// expected-expansion@+5:32{{
15+
// expected-error@1{{unexpected token '}' in expanded member list}}
16+
// expected-error@2{{expected declaration}}
17+
// }}
1418
// expected-note@+1 2{{in expansion of macro 'HangingMacro' on property 'result' here}}
1519
@HangingMacro var result: Int // This comment makes it hang.
1620
}

0 commit comments

Comments
 (0)