Skip to content
This repository was archived by the owner on Jan 26, 2024. It is now read-only.

Commit 567e894

Browse files
committed
merge main into amd-stg-open
Change-Id: If90c1680d0ff6e188ba39d498f325045da7d863d
2 parents db8fc31 + 9f88727 commit 567e894

File tree

127 files changed

+1846
-803
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

127 files changed

+1846
-803
lines changed

clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "StaticAccessedThroughInstanceCheck.h"
1010
#include "clang/AST/ASTContext.h"
1111
#include "clang/ASTMatchers/ASTMatchFinder.h"
12+
#include "llvm/ADT/StringRef.h"
1213

1314
using namespace clang::ast_matchers;
1415

@@ -54,7 +55,7 @@ void StaticAccessedThroughInstanceCheck::check(
5455

5556
const Expr *BaseExpr = MemberExpression->getBase();
5657

57-
// Do not warn for overlaoded -> operators.
58+
// Do not warn for overloaded -> operators.
5859
if (isa<CXXOperatorCallExpr>(BaseExpr))
5960
return;
6061

@@ -70,6 +71,10 @@ void StaticAccessedThroughInstanceCheck::check(
7071
std::string BaseTypeName =
7172
BaseType.getAsString(PrintingPolicyWithSupressedTag);
7273

74+
// Do not warn for CUDA built-in variables.
75+
if (StringRef(BaseTypeName).startswith("__cuda_builtin_"))
76+
return;
77+
7378
SourceLocation MemberExprStartLoc = MemberExpression->getBeginLoc();
7479
auto Diag =
7580
diag(MemberExprStartLoc, "static member accessed through instance");

clang-tools-extra/clangd/IncludeCleaner.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ class ReferencedLocationCrawler
3939
return true;
4040
}
4141

42+
bool VisitFunctionDecl(FunctionDecl *FD) {
43+
// Function definition will require redeclarations to be included.
44+
if (FD == FD->getDefinition())
45+
add(FD);
46+
return true;
47+
}
48+
4249
bool VisitCXXConstructExpr(CXXConstructExpr *CCE) {
4350
add(CCE->getConstructor());
4451
return true;

clang-tools-extra/clangd/JSONTransport.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
#include "support/Cancellation.h"
1111
#include "support/Logger.h"
1212
#include "support/Shutdown.h"
13+
#include "support/ThreadCrashReporter.h"
1314
#include "llvm/ADT/SmallString.h"
1415
#include "llvm/Support/Errno.h"
1516
#include "llvm/Support/Error.h"
17+
#include "llvm/Support/Threading.h"
1618
#include <system_error>
1719

1820
namespace clang {
@@ -109,6 +111,11 @@ class JSONTransport : public Transport {
109111
return llvm::errorCodeToError(
110112
std::error_code(errno, std::system_category()));
111113
if (readRawMessage(JSON)) {
114+
ThreadCrashReporter ScopedReporter([&JSON]() {
115+
auto &OS = llvm::errs();
116+
OS << "Signalled while processing message:\n";
117+
OS << JSON << "\n";
118+
});
112119
if (auto Doc = llvm::json::parse(JSON)) {
113120
vlog(Pretty ? "<<< {0:2}\n" : "<<< {0}\n", *Doc);
114121
if (!handleMessage(std::move(*Doc), Handler))

clang-tools-extra/clangd/TUScheduler.cpp

+51
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
#include "support/Logger.h"
5959
#include "support/MemoryTree.h"
6060
#include "support/Path.h"
61+
#include "support/ThreadCrashReporter.h"
6162
#include "support/Threading.h"
6263
#include "support/Trace.h"
6364
#include "clang/Frontend/CompilerInvocation.h"
@@ -76,6 +77,7 @@
7677
#include "llvm/Support/FormatVariadic.h"
7778
#include "llvm/Support/Path.h"
7879
#include "llvm/Support/Threading.h"
80+
#include "llvm/Support/raw_ostream.h"
7981
#include <algorithm>
8082
#include <atomic>
8183
#include <chrono>
@@ -902,6 +904,40 @@ void ASTWorker::runWithAST(
902904
startTask(Name, std::move(Task), /*Update=*/None, Invalidation);
903905
}
904906

907+
/// To be called from ThreadCrashReporter's signal handler.
908+
static void crashDumpCompileCommand(llvm::raw_ostream &OS,
909+
const tooling::CompileCommand &Command) {
910+
OS << " Filename: " << Command.Filename << "\n";
911+
OS << " Directory: " << Command.Directory << "\n";
912+
OS << " Command Line:";
913+
for (auto &Arg : Command.CommandLine) {
914+
OS << " " << Arg;
915+
}
916+
OS << "\n";
917+
}
918+
919+
/// To be called from ThreadCrashReporter's signal handler.
920+
static void crashDumpFileContents(llvm::raw_ostream &OS,
921+
const std::string &Contents) {
922+
// Avoid flooding the terminal with source code by default, but allow clients
923+
// to opt in. Use an env var to preserve backwards compatibility of the
924+
// command line interface, while allowing it to be set outside the clangd
925+
// launch site for more flexibility.
926+
if (getenv("CLANGD_CRASH_DUMP_SOURCE")) {
927+
OS << " Contents:\n";
928+
OS << Contents << "\n";
929+
}
930+
}
931+
932+
/// To be called from ThreadCrashReporter's signal handler.
933+
static void crashDumpParseInputs(llvm::raw_ostream &OS,
934+
const ParseInputs &FileInputs) {
935+
auto &Command = FileInputs.CompileCommand;
936+
crashDumpCompileCommand(OS, Command);
937+
OS << " Version: " << FileInputs.Version << "\n";
938+
crashDumpFileContents(OS, FileInputs.Contents);
939+
}
940+
905941
void PreambleThread::build(Request Req) {
906942
assert(Req.CI && "Got preamble request with null compiler invocation");
907943
const ParseInputs &Inputs = Req.Inputs;
@@ -932,6 +968,11 @@ void PreambleThread::build(Request Req) {
932968
FileName, Inputs.Version, LatestBuild->Version);
933969
}
934970

971+
ThreadCrashReporter ScopedReporter([&Inputs]() {
972+
llvm::errs() << "Signalled while building preamble\n";
973+
crashDumpParseInputs(llvm::errs(), Inputs);
974+
});
975+
935976
LatestBuild = clang::clangd::buildPreamble(
936977
FileName, *Req.CI, Inputs, StoreInMemory,
937978
[this, Version(Inputs.Version)](ASTContext &Ctx,
@@ -1288,6 +1329,11 @@ void ASTWorker::run() {
12881329
Status.ASTActivity.Name = CurrentRequest->Name;
12891330
});
12901331
WithContext WithProvidedContext(ContextProvider(FileName));
1332+
ThreadCrashReporter ScopedReporter([this]() {
1333+
const char *Name = CurrentRequest ? CurrentRequest->Name.c_str() : "";
1334+
llvm::errs() << "Signalled during AST worker action: " << Name << "\n";
1335+
crashDumpParseInputs(llvm::errs(), FileInputs);
1336+
});
12911337
CurrentRequest->Action();
12921338
}
12931339

@@ -1613,6 +1659,11 @@ void TUScheduler::runWithPreamble(llvm::StringRef Name, PathRef File,
16131659
Ctx = Context::current().derive(kFileBeingProcessed,
16141660
std::string(File)),
16151661
Action = std::move(Action), this]() mutable {
1662+
ThreadCrashReporter ScopedReporter([&Name, &Contents, &Command]() {
1663+
llvm::errs() << "Signalled during preamble action: " << Name << "\n";
1664+
crashDumpCompileCommand(llvm::errs(), Command);
1665+
crashDumpFileContents(llvm::errs(), Contents);
1666+
});
16161667
std::shared_ptr<const PreambleData> Preamble;
16171668
if (Consistency == PreambleConsistency::Stale) {
16181669
// Wait until the preamble is built for the first time, if preamble

clang-tools-extra/clangd/support/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ add_clang_library(clangdSupport
2424
MemoryTree.cpp
2525
Path.cpp
2626
Shutdown.cpp
27+
ThreadCrashReporter.cpp
2728
Threading.cpp
2829
ThreadsafeFS.cpp
2930
Trace.cpp
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//===--- ThreadCrashReporter.cpp - Thread local signal handling --*- C++-*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "support/ThreadCrashReporter.h"
10+
#include "llvm/Support/Signals.h"
11+
#include "llvm/Support/ThreadLocal.h"
12+
#include <atomic>
13+
14+
namespace clang {
15+
namespace clangd {
16+
17+
static thread_local ThreadCrashReporter *CurrentReporter = nullptr;
18+
19+
void ThreadCrashReporter::runCrashHandlers() {
20+
// No signal handling is done here on top of what AddSignalHandler() does:
21+
// on Windows the signal handling is implmented via
22+
// SetUnhandledExceptionFilter() which is thread-directed, and on Unix
23+
// platforms the handlers are only called for KillSigs out of which only
24+
// SIGQUIT seems to be process-directed and would be delivered to any thread
25+
// that is not blocking it, but if the thread it gets delivered to has a
26+
// ThreadCrashReporter installed during the interrupt — it seems reasonable to
27+
// let it run and print the thread's context information.
28+
29+
// Call the reporters in LIFO order.
30+
ThreadCrashReporter *Reporter = CurrentReporter;
31+
while (Reporter) {
32+
Reporter->Callback();
33+
Reporter = Reporter->Next;
34+
}
35+
}
36+
37+
ThreadCrashReporter::ThreadCrashReporter(SignalCallback ThreadLocalCallback)
38+
: Callback(std::move(ThreadLocalCallback)), Next(nullptr) {
39+
this->Next = CurrentReporter;
40+
CurrentReporter = this;
41+
// Don't reorder subsequent operations: whatever comes after might crash and
42+
// we want the the crash handler to see the reporter values we just set.
43+
std::atomic_signal_fence(std::memory_order_seq_cst);
44+
}
45+
46+
ThreadCrashReporter::~ThreadCrashReporter() {
47+
assert(CurrentReporter == this);
48+
CurrentReporter = this->Next;
49+
// Don't reorder subsequent operations: whatever comes after might crash and
50+
// we want the the crash handler to see the reporter values we just set.
51+
std::atomic_signal_fence(std::memory_order_seq_cst);
52+
}
53+
54+
} // namespace clangd
55+
} // namespace clang
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//===--- ThreadCrashReporter.h - Thread local signal handling ----*- C++-*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_THREADCRASHREPORTER_H
10+
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_THREADCRASHREPORTER_H
11+
12+
#include "llvm/ADT/FunctionExtras.h"
13+
14+
namespace clang {
15+
namespace clangd {
16+
17+
/// Allows setting per-thread abort/kill signal callbacks, to print additional
18+
/// information about the crash depending on which thread got signalled.
19+
class ThreadCrashReporter {
20+
public:
21+
using SignalCallback = llvm::unique_function<void(void)>;
22+
23+
/// Registers the callback as the first one in thread-local callback chain.
24+
///
25+
/// Asserts if the current thread's callback is already set. The callback is
26+
/// likely to be invoked in a signal handler. Most LLVM signal handling is not
27+
/// strictly async-signal-safe. However reporters should avoid accessing data
28+
/// structures likely to be in a bad state on crash.
29+
ThreadCrashReporter(SignalCallback ThreadLocalCallback);
30+
/// Resets the current thread's callback to nullptr.
31+
~ThreadCrashReporter();
32+
33+
/// Moves are disabled to ease nesting and escaping considerations.
34+
ThreadCrashReporter(ThreadCrashReporter &&RHS) = delete;
35+
ThreadCrashReporter(const ThreadCrashReporter &) = delete;
36+
ThreadCrashReporter &operator=(ThreadCrashReporter &&) = delete;
37+
ThreadCrashReporter &operator=(const ThreadCrashReporter &) = delete;
38+
39+
/// Calls all currently-active ThreadCrashReporters for the current thread.
40+
///
41+
/// To be called from sys::AddSignalHandler() callback. Any signal filtering
42+
/// is the responsibility of the caller. While this function is intended to be
43+
/// called from signal handlers, it is not strictly async-signal-safe - see
44+
/// constructor comment.
45+
///
46+
/// When several reporters are nested, the callbacks are called in LIFO order.
47+
static void runCrashHandlers();
48+
49+
private:
50+
SignalCallback Callback;
51+
/// Points to the next reporter up the stack.
52+
ThreadCrashReporter *Next;
53+
};
54+
55+
} // namespace clangd
56+
} // namespace clang
57+
58+
#endif
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Overflow the recursive json parser, prevent `yes` error due to broken pipe and `clangd` SIGSEGV from being treated as a failure.
2+
# RUN: (yes '[' || :) | head -n 50000 | (clangd --input-style=delimited 2>&1 || :) | FileCheck %s
3+
# CHECK: Signalled while processing message:
4+
# CHECK-NEXT: [
5+
# CHECK-NEXT: [

clang-tools-extra/clangd/tool/ClangdMain.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "refactor/Rename.h"
2525
#include "support/Path.h"
2626
#include "support/Shutdown.h"
27+
#include "support/ThreadCrashReporter.h"
2728
#include "support/ThreadsafeFS.h"
2829
#include "support/Trace.h"
2930
#include "clang/Format/Format.h"
@@ -679,6 +680,13 @@ int main(int argc, char *argv[]) {
679680

680681
llvm::InitializeAllTargetInfos();
681682
llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
683+
llvm::sys::AddSignalHandler(
684+
[](void *) {
685+
ThreadCrashReporter::runCrashHandlers();
686+
// Ensure ThreadCrashReporter and PrintStackTrace output is visible.
687+
llvm::errs().flush();
688+
},
689+
nullptr);
682690
llvm::sys::SetInterruptFunction(&requestShutdown);
683691
llvm::cl::SetVersionPrinter([](llvm::raw_ostream &OS) {
684692
OS << versionString() << "\n"

clang-tools-extra/clangd/unittests/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ add_unittest(ClangdUnitTests ClangdTests
8888
TestIndex.cpp
8989
TestTU.cpp
9090
TestWorkspace.cpp
91+
ThreadCrashReporterTests.cpp
9192
TidyProviderTests.cpp
9293
TypeHierarchyTests.cpp
9394
URITests.cpp

clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,19 @@ TEST(IncludeCleaner, ReferencedLocations) {
7979
"struct ^X { ^X(int) {} int ^foo(); };",
8080
"auto x = X(42); auto y = x.foo();",
8181
},
82+
// Function
83+
{
84+
"void ^foo();",
85+
"void foo() {}",
86+
},
87+
{
88+
"void foo() {}",
89+
"void foo();",
90+
},
91+
{
92+
"inline void ^foo() {}",
93+
"void bar() { foo(); }",
94+
},
8295
// Static function
8396
{
8497
"struct ^X { static bool ^foo(); }; bool X::^foo() {}",

0 commit comments

Comments
 (0)