Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
#include "UndelegatedConstructorCheck.h"
#include "UnhandledExceptionAtNewCheck.h"
#include "UnhandledSelfAssignmentCheck.h"
#include "UninitializedThreadLocalCheck.h"
#include "UnintendedCharOstreamOutputCheck.h"
#include "UniquePtrArrayMismatchCheck.h"
#include "UnsafeFunctionsCheck.h"
Expand Down
1 change: 1 addition & 0 deletions clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ add_clang_library(clangTidyBugproneModule STATIC
InaccurateEraseCheck.cpp
IncorrectEnableIfCheck.cpp
IncorrectEnableSharedFromThisCheck.cpp
UninitializedThreadLocalCheck.cpp
UnintendedCharOstreamOutputCheck.cpp
ReturnConstRefFromParameterCheck.cpp
SuspiciousStringviewDataUsageCheck.cpp
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//===--- UninitializedThreadLocalCheck.cpp - clang-tidy
//--------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "UninitializedThreadLocalCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/Lex/Lexer.h"

using namespace clang::ast_matchers;

namespace clang::tidy::bugprone {

UninitializedThreadLocalCheck::UninitializedThreadLocalCheck(
StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context) {}

void UninitializedThreadLocalCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
declRefExpr(
// Fast check -- bail out quickly before slower filters
to(varDecl(hasThreadStorageDuration(),
hasDeclContext(functionDecl()))),
forCallable(decl().bind("ctx")),
to(varDecl(unless(hasDeclContext(equalsBoundNode("ctx"))))))
.bind("declref"),
this);
}

void UninitializedThreadLocalCheck::check(
const MatchFinder::MatchResult &Result) {
const auto *E = Result.Nodes.getNodeAs<DeclRefExpr>("declref");
diag(E->getLocation(),
"variable '%0' might not have been initialized on the current thread. "
"To guarantee prior initialization on the same thread that performs the "
"access, consider capturing the address of the variable in the same "
"block as its initialization, then use the captured address to the "
"desired code.")
<< E;
}

} // namespace clang::tidy::bugprone
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//===--- UninitializedThreadLocalCheck.cpp - Clang tidy tool --------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNINITIALIZEDTHREADLOCALCHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNINITIALIZEDTHREADLOCALCHECK_H

#include "../ClangTidyCheck.h"

namespace clang::tidy::runtime {

// Finds accesses to thread_local variables that might occur prior to
// initialization.
class UninitializedThreadLocalCheck : public ClangTidyCheck {
public:
UninitializedThreadLocalCheck(StringRef Name, ClangTidyContext *Context);

bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
return LangOpts.CPlusPlus;
}
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;

private:
};

} // namespace clang::tidy::runtime

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNINITIALIZEDTHREADLOCALCHECK_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// RUN: %check_clang_tidy %s bugprone-uninitialized-thread-local %t

thread_local int global_tls = 1;

int main() {
thread_local int local_tls = 2;
{
++global_tls; // no warning
++local_tls; // no warning
}
auto f = []() {
return local_tls + global_tls;
// CHECK-MESSAGES: [[@LINE-1]]:12: warning: variable 'local_tls' might not have been initialized on the current thread.
};
return f();
}
Loading