diff --git a/.clang-tidy b/.clang-tidy
new file mode 100644
index 0000000000000000000000000000000000000000..d5935e488ae916935d56e2ecc13a44ec2a5e3597
--- /dev/null
+++ b/.clang-tidy
@@ -0,0 +1,4 @@
+# maybe-* checks are only available on OneFlow custom clang-tidy and clangd
+Checks: '-*, maybe-*'
+# TODO: treat all maybe warnings as errors when existing warnings are all fixed
+WarningsAsErrors: 'maybe-unused'
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index a45142400980c0fb43fe1685a46dd66079cfa201..78f718010b12445ab339cc421070bdf6785a1c0e 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -92,8 +92,8 @@ jobs:
run: |
exit 1
- static_analysis_with_clang_plug_in:
- name: Static analysis with Clang plug-in
+ static_analysis_with_clang:
+ name: Static analysis with clang
runs-on: ubuntu-20.04
if: github.event.pull_request.draft == false && contains(github.event.pull_request.requested_reviewers.*.login, 'oneflow-ci-bot')
steps:
@@ -104,48 +104,36 @@ jobs:
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Install dependencies
run: |
- wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
- sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-12 main"
sudo apt-get update
- sudo apt-get install -y llvm-12 llvm-12-dev llvm-12-tools clang-12 libclang-common-12-dev libclang-12-dev \
- libopenblas-dev nasm python3-pip ninja-build
- - name: Set environment variables
- run: |
- set -x
- echo "CC=clang-12" >> $GITHUB_ENV
- echo "CXX=clang++-12" >> $GITHUB_ENV
- - name: Build Clang plug-in
+ sudo apt-get install -y libopenblas-dev nasm python3-pip ninja-build
+ - name: Download OneFlow custom clang-tidy
run: |
- cd tools/clang-plugin
- mkdir build
- cd build
- cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCP_LLVM_INSTALL_DIR=/usr/lib/llvm-12
- make -j$(nproc)
- clang_plugin_path="${PWD}/lib/libCheckUnusedMaybe.so"
- ldd ${clang_plugin_path}
- echo "clang_plugin_path=${clang_plugin_path}" >> $GITHUB_ENV
- - name: Build (third party)
+ wget https://github.com/oneflow-inc/llvm-project/releases/download/latest/clang-tidy
+ wget https://raw.githubusercontent.com/oneflow-inc/llvm-project/maybe/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
+ chmod +x clang-tidy run-clang-tidy.py
+ - name: Build third party libs and generate files
run: |
mkdir build
cd build
- # clang-12 produces many warnings on oneflow, -w to suppress them
+ # clang-tidy has builtin includes, but doesn't work here
+ # https://clang.llvm.org/docs/LibTooling.html#builtin-includes
cmake .. -C ../cmake/caches/international/cpu.cmake \
-DCMAKE_BUILD_TYPE=Release \
- -DBUILD_TESTING=ON \
- -DTHIRD_PARTY=ON \
- -DONEFLOW=OFF \
- -DCMAKE_CXX_FLAGS="-w"
- cmake --build . -j$(nproc)
- - name: Check unused Maybe (by building OneFlow with Clang plug-in)
+ -DBUILD_TESTING=ON
+ cmake --build . -j$(nproc) --target of_git_version oneflow_deps generate_functional of_cfgobj generate_py_cfg
+ - name: Run Maybe-related checks by clang-tidy
run: |
cd build
+ rm CMakeCache.txt
cmake .. -C ../cmake/caches/international/cpu.cmake \
+ -DCMAKE_C_COMPILER=clang-12 \
+ -DCMAKE_CXX_COMPILER=clang++-12 \
+ -DCMAKE_CXX_FLAGS="-isystem /usr/lib/llvm-12/lib/clang/12.0.1/include/" \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_TESTING=ON \
- -DTHIRD_PARTY=OFF \
- -DONEFLOW=ON \
- -DCMAKE_CXX_FLAGS="-w -fplugin=${{ env.clang_plugin_path }}"
- cmake --build . -j$(nproc)
+ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
+ cd ..
+ ./run-clang-tidy.py -clang-tidy-binary ./clang-tidy -p build -quiet
wait_for_gpu_slot:
name: Wait for GPU slots
diff --git a/tools/clang-plugin/.clang-format b/tools/clang-plugin/.clang-format
deleted file mode 100644
index 9b3aa8b7213b2d3b534a08907a44773b4f9c1f1a..0000000000000000000000000000000000000000
--- a/tools/clang-plugin/.clang-format
+++ /dev/null
@@ -1 +0,0 @@
-BasedOnStyle: LLVM
diff --git a/tools/clang-plugin/.gitignore b/tools/clang-plugin/.gitignore
deleted file mode 100644
index 413e4569814c747c7a382135190c70f87b45952f..0000000000000000000000000000000000000000
--- a/tools/clang-plugin/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-build/
-build-*/
-.cache/
-compile_commands.json
diff --git a/tools/clang-plugin/CMakeLists.txt b/tools/clang-plugin/CMakeLists.txt
deleted file mode 100644
index 7e5b98a2c237299003141265813f25bf69657e38..0000000000000000000000000000000000000000
--- a/tools/clang-plugin/CMakeLists.txt
+++ /dev/null
@@ -1,66 +0,0 @@
-cmake_minimum_required(VERSION 3.10)
-project(clang-plugins CXX)
-
-set(CP_LLVM_INSTALL_DIR "" CACHE PATH "LLVM installation directory")
-
-# A bit of a sanity checking
-set(CP_LLVM_INCLUDE_DIR "${CP_LLVM_INSTALL_DIR}/include/llvm")
-if(NOT EXISTS "${CP_LLVM_INCLUDE_DIR}")
-message(FATAL_ERROR
- "${CP_LLVM_INCLUDE_DIR} does not exist, CP_LLVM_INSTALL_DIR (${CP_LLVM_INSTALL_DIR}) is invalid")
-endif()
-
-set(CP_LLVM_CMAKE_FILE "${CP_LLVM_INSTALL_DIR}/lib/cmake/clang/ClangConfig.cmake")
-if(NOT EXISTS "${CP_LLVM_CMAKE_FILE}")
-message(FATAL_ERROR
- " CP_LLVM_CMAKE_FILE (${CP_LLVM_CMAKE_FILE}) is invalid.")
-endif()
-
-#===============================================================================
-# 2. LOAD CLANG CONFIGURATION
-# For more: http://llvm.org/docs/CMake.html#embedding-llvm-in-your-project
-#===============================================================================
-list(APPEND CMAKE_PREFIX_PATH "${CP_LLVM_INSTALL_DIR}/lib/cmake/llvm/")
-list(APPEND CMAKE_PREFIX_PATH "${CP_LLVM_INSTALL_DIR}/lib/cmake/clang/")
-
-find_package(Clang REQUIRED CONFIG)
-
-# Sanity check. As Clang does not expose e.g. `CLANG_VERSION_MAJOR` through
-# AddClang.cmake, we have to use LLVM_VERSION_MAJOR instead.
-# TODO: Revisit when next version is released.
-if(NOT "12" VERSION_EQUAL "${LLVM_VERSION_MAJOR}")
- message(FATAL_ERROR "Found LLVM ${LLVM_VERSION_MAJOR}, but need LLVM 12")
-endif()
-
-message(STATUS "Found Clang ${LLVM_PACKAGE_VERSION}")
-message(STATUS "Using ClangConfig.cmake in: ${CP_LLVM_INSTALL_DIR}")
-
-message("CLANG STATUS:
- Includes (clang) ${CLANG_INCLUDE_DIRS}
- Includes (llvm) ${LLVM_INCLUDE_DIRS}"
-)
-
-# Set the LLVM and Clang header and library paths
-include_directories(SYSTEM "${LLVM_INCLUDE_DIRS};${CLANG_INCLUDE_DIRS}")
-
-#===============================================================================
-# 3. BUILD CONFIGURATION
-#===============================================================================
-# Use the same C++ standard as LLVM does
-set(CMAKE_CXX_STANDARD 14 CACHE STRING "")
-
-# -fvisibility-inlines-hidden is set when building LLVM and on Darwin warnings
-# are triggered if llvm-tutor is built without this flag (though otherwise it
-# builds fine). For consistency, add it here too.
-include(CheckCXXCompilerFlag)
-check_cxx_compiler_flag("-fvisibility-inlines-hidden" SUPPORTS_FVISIBILITY_INLINES_HIDDEN_FLAG)
-if (${SUPPORTS_FVISIBILITY_INLINES_HIDDEN_FLAG} EQUAL "1")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden")
-endif()
-
-# Set the build directories
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
-set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
-
-add_subdirectory(CheckUnusedMaybe)
-
diff --git a/tools/clang-plugin/CheckUnusedMaybe/CMakeLists.txt b/tools/clang-plugin/CheckUnusedMaybe/CMakeLists.txt
deleted file mode 100644
index 15a321fa4d317817e942f0247a24899e22d8b11f..0000000000000000000000000000000000000000
--- a/tools/clang-plugin/CheckUnusedMaybe/CMakeLists.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-add_library(CheckUnusedMaybe SHARED CheckUnusedMaybe.cpp)
-
-# On Darwin (unlike on Linux), undefined symbols in shared objects are not
-# allowed at the end of the link-edit. The plugins defined here:
-# - _are_ shared objects
-# - reference symbols from LLVM shared libraries, i.e. symbols which are
-# undefined until those shared objects are loaded in memory (and hence
-# _undefined_ during static linking)
-# The build will fail with errors like this:
-# "Undefined symbols for architecture x86_64"
-# with various LLVM symbols being undefined. Since those symbols are later
-# loaded and resolved at runtime, these errors are false positives.
-# This behaviour can be modified via the '-undefined' OS X linker flag as
-# follows.
-target_link_libraries(
- CheckUnusedMaybe
- "$<$<PLATFORM_ID:Darwin>:-undefined dynamic_lookup>"
- )
diff --git a/tools/clang-plugin/CheckUnusedMaybe/CheckUnusedMaybe.cpp b/tools/clang-plugin/CheckUnusedMaybe/CheckUnusedMaybe.cpp
deleted file mode 100644
index 899e185f8c5bb2ff12b3c4bc1af197c0a63224c3..0000000000000000000000000000000000000000
--- a/tools/clang-plugin/CheckUnusedMaybe/CheckUnusedMaybe.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/RecursiveASTVisitor.h"
-#include "clang/AST/Stmt.h"
-#include "clang/Frontend/CompilerInstance.h"
-#include "clang/Frontend/FrontendAction.h"
-#include "clang/Frontend/FrontendPluginRegistry.h"
-#include "clang/Tooling/Tooling.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/CrashRecoveryContext.h"
-
-using namespace clang;
-
-class CheckUnusedMaybeVisitor
- : public RecursiveASTVisitor<CheckUnusedMaybeVisitor> {
-public:
- explicit CheckUnusedMaybeVisitor(ASTContext *Context) : Context(Context) {
- {
- auto skip_filenames_env =
- llvm::StringRef(std::getenv("ONEFLOW_MAYBE_CHECK_SKIP_FN"));
- if (!skip_filenames_env.empty()) {
- skip_filenames_env.split(skip_filenames, ";");
- for (const auto &x : skip_filenames) {
- llvm::outs() << "skip: " << x << "\n";
- }
- }
- }
- {
- auto only_filenames_env =
- llvm::StringRef(std::getenv("ONEFLOW_MAYBE_CHECK_ONLY_FN"));
- if (!only_filenames_env.empty()) {
- only_filenames_env.split(only_filenames, ";");
- for (const auto &x : only_filenames) {
- llvm::outs() << "only: " << x << "\n";
- }
- }
- }
- }
-
- virtual bool VisitCompoundStmt(CompoundStmt *stmt) {
- if (!only_filenames.empty()) {
- bool skip = true;
- for (const auto &x : only_filenames) {
- if (Context->getSourceManager()
- .getFilename(stmt->getBeginLoc())
- .contains(x)) {
- skip = false;
- }
- }
- if (skip) {
- return true;
- }
- }
-
- for (const auto &x : skip_filenames) {
- if (Context->getSourceManager()
- .getFilename(stmt->getBeginLoc())
- .contains(x)) {
- return true;
- }
- }
-
- for (const auto &x : stmt->children()) {
- std::string typeStr;
- if (ExprWithCleanups *expr = dyn_cast<ExprWithCleanups>(x)) {
- typeStr = expr->getType().getAsString();
- }
- if (CallExpr *call = dyn_cast<CallExpr>(x)) {
- llvm::CrashRecoveryContext CRC;
- CRC.RunSafely([&call, &typeStr, this]() {
- QualType returnType;
- if (auto *callee = call->getDirectCallee()) {
- returnType = callee->getReturnType();
- } else {
- returnType = call->getCallReturnType(*this->Context);
- }
- if (!returnType.isNull() && returnType->isClassType()) {
- typeStr = returnType.getAsString();
- }
- });
- }
- if (typeStr.substr(0, 12) == "class Maybe<" ||
- typeStr.substr(0, 6) == "Maybe<") {
- DiagnosticsEngine &DE = Context->getDiagnostics();
- unsigned DiagID =
- DE.getCustomDiagID(DiagnosticsEngine::Error,
- "This function returns Maybe but the return "
- "value is ignored. Wrap it with JUST(..)?");
- auto DB = DE.Report(x->getBeginLoc(), DiagID);
- DB.AddSourceRange(
- clang::CharSourceRange::getCharRange(x->getSourceRange()));
- }
- }
- return true;
- }
-
-private:
- ASTContext *Context;
- llvm::SmallVector<llvm::StringRef, 10> skip_filenames;
- llvm::SmallVector<llvm::StringRef, 10> only_filenames;
-};
-
-class CheckUnusedMaybeConsumer : public clang::ASTConsumer {
-public:
- explicit CheckUnusedMaybeConsumer(ASTContext *Context) : Visitor(Context) {}
-
- void HandleTranslationUnit(clang::ASTContext &Context) override {
- Visitor.TraverseDecl(Context.getTranslationUnitDecl());
- }
-
-private:
- CheckUnusedMaybeVisitor Visitor;
-};
-
-class CheckUnusedMaybeAction : public clang::PluginASTAction {
-public:
- virtual std::unique_ptr<clang::ASTConsumer>
- CreateASTConsumer(clang::CompilerInstance &Compiler,
- llvm::StringRef InFile) override {
- return std::make_unique<CheckUnusedMaybeConsumer>(
- &Compiler.getASTContext());
- }
-
- bool ParseArgs(const CompilerInstance &CI,
- const std::vector<std::string> &args) override {
- return true;
- }
-
- // Automatically run the plugin after the main AST action
- ActionType getActionType() override { return AddAfterMainAction; }
-};
-
-static FrontendPluginRegistry::Add<CheckUnusedMaybeAction>
- X("check-unused-maybe", "Check unused maybe");
diff --git a/tools/clang-plugin/CheckUnusedMaybe/unused_maybe_example.cpp b/tools/clang-plugin/CheckUnusedMaybe/unused_maybe_example.cpp
deleted file mode 100644
index f61664629ef43f1236186491bef20431fa33059b..0000000000000000000000000000000000000000
--- a/tools/clang-plugin/CheckUnusedMaybe/unused_maybe_example.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-template <class T> class Maybe {};
-
-Maybe<void> a() { return Maybe<void>(); }
-
-int main() {
- a();
- return 0;
-}