Initial check in
Bug: 137197907
diff --git a/src/llvm-project/clang-tools-extra/test/.clang-format b/src/llvm-project/clang-tools-extra/test/.clang-format
new file mode 100644
index 0000000..4799b66
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/.clang-format
@@ -0,0 +1,2 @@
+BasedOnStyle: LLVM
+ColumnLimit: 0
diff --git a/src/llvm-project/clang-tools-extra/test/CMakeLists.txt b/src/llvm-project/clang-tools-extra/test/CMakeLists.txt
new file mode 100644
index 0000000..adeb036
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/CMakeLists.txt
@@ -0,0 +1,113 @@
+# Test runner infrastructure for Clang-based tools. This configures the Clang
+# test trees for use by Lit, and delegates to LLVM's lit test handlers.
+#
+# Note that currently we don't support stand-alone builds of Clang, you must
+# be building Clang from within a combined LLVM+Clang checkout..
+
+set(CLANG_TOOLS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
+set(CLANG_TOOLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/..")
+
+if (CMAKE_CFG_INTDIR STREQUAL ".")
+ set(LLVM_BUILD_MODE ".")
+else ()
+ set(LLVM_BUILD_MODE "%(build_mode)s")
+endif ()
+
+string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} CLANG_TOOLS_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
+
+llvm_canonicalize_cmake_booleans(
+ CLANG_ENABLE_STATIC_ANALYZER
+ CLANGD_BUILD_XPC_SUPPORT)
+
+configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+ )
+
+configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
+ )
+
+option(CLANG_TOOLS_TEST_USE_VG "Run Clang tools' tests under Valgrind" OFF)
+if(CLANG_TOOLS_TEST_USE_VG)
+ set(CLANG_TOOLS_TEST_EXTRA_ARGS ${CLANG_TEST_EXTRA_ARGS} "--vg")
+endif()
+
+set(CLANG_TOOLS_TEST_DEPS
+ # For the clang-apply-replacements test that uses clang-rename.
+ clang-rename
+
+ # For the clang-doc tests that emit bitcode files.
+ llvm-bcanalyzer
+
+ # Individual tools we test.
+ clang-apply-replacements
+ clang-change-namespace
+ clang-doc
+ clang-include-fixer
+ clang-move
+ clang-query
+ clang-reorder-fields
+ find-all-symbols
+ modularize
+ pp-trace
+
+ # Unit tests
+ ExtraToolsUnitTests
+
+ # For the clang-tidy libclang integration test.
+ c-index-test
+ # clang-tidy tests require it.
+ clang-headers
+
+ clang-tidy
+)
+
+if(CLANGD_BUILD_XPC_SUPPORT)
+ list(APPEND CLANG_TOOLS_TEST_DEPS clangd-xpc-test-client)
+endif()
+
+set(CLANGD_TEST_DEPS
+ clangd
+ ClangdTests
+ # clangd-related tools which don't have tests, add them to the test to make
+ # sure we don't introduce new changes that break their compilations.
+ clangd-indexer
+ dexp
+ )
+
+# Add lit test dependencies.
+set(LLVM_UTILS_DEPS
+ FileCheck count not
+)
+foreach(dep ${LLVM_UTILS_DEPS})
+ if(TARGET ${dep})
+ list(APPEND CLANGD_TEST_DEPS ${dep})
+ endif()
+endforeach()
+
+foreach(clangd_dep ${CLANGD_TEST_DEPS})
+ list(APPEND CLANG_TOOLS_TEST_DEPS
+ ${clangd_dep})
+endforeach()
+
+add_lit_testsuite(check-clang-tools "Running the Clang extra tools' regression tests"
+ ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS ${CLANG_TOOLS_TEST_DEPS}
+ ARGS ${CLANG_TOOLS_TEST_EXTRA_ARGS}
+ )
+
+set_target_properties(check-clang-tools PROPERTIES FOLDER "Clang extra tools' tests")
+
+# Setup an individual test for building and testing clangd-only stuff.
+# Note: all clangd tests have been covered in check-clang-tools, this is a
+# convenient target for clangd developers.
+# Exclude check-clangd from check-all.
+set(EXCLUDE_FROM_ALL ON)
+add_lit_testsuite(check-clangd "Running the Clangd regression tests"
+ ${CMAKE_CURRENT_BINARY_DIR}/Unit/clangd;${CMAKE_CURRENT_BINARY_DIR}/clangd
+ DEPENDS ${CLANGD_TEST_DEPS}
+)
+set_target_properties(check-clangd PROPERTIES FOLDER "Clangd tests")
+set(EXCLUDE_FROM_ALL OFF)
diff --git a/src/llvm-project/clang-tools-extra/test/Unit/lit.cfg b/src/llvm-project/clang-tools-extra/test/Unit/lit.cfg
new file mode 100644
index 0000000..b40e1ca
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/Unit/lit.cfg
@@ -0,0 +1,37 @@
+# -*- Python -*-
+
+import platform
+
+import lit.formats
+
+config.name = "Extra Tools Unit Tests"
+config.suffixes = [] # Seems not to matter for google tests?
+
+# Test Source and Exec root dirs both point to the same directory where google
+# test binaries are built.
+
+config.test_source_root = config.extra_tools_obj_dir
+config.test_exec_root = config.test_source_root
+
+# All GoogleTests are named to have 'Tests' as their suffix. The '.' option is
+# a special value for GoogleTest indicating that it should look through the
+# entire testsuite recursively for tests (alternatively, one could provide a
+# ;-separated list of subdirectories).
+config.test_format = lit.formats.GoogleTest('.', 'Tests')
+
+if platform.system() == 'Darwin':
+ shlibpath_var = 'DYLD_LIBRARY_PATH'
+elif platform.system() == 'Windows':
+ shlibpath_var = 'PATH'
+else:
+ shlibpath_var = 'LD_LIBRARY_PATH'
+
+# Point the dynamic loader at dynamic libraries in 'lib'.
+shlibpath = os.path.pathsep.join((config.shlibdir, config.llvm_libs_dir,
+ config.environment.get(shlibpath_var,'')))
+
+# Win32 seeks DLLs along %PATH%.
+if sys.platform in ['win32', 'cygwin'] and os.path.isdir(config.shlibdir):
+ shlibpath = os.path.pathsep.join((config.shlibdir, shlibpath))
+
+config.environment[shlibpath_var] = shlibpath
diff --git a/src/llvm-project/clang-tools-extra/test/Unit/lit.site.cfg.in b/src/llvm-project/clang-tools-extra/test/Unit/lit.site.cfg.in
new file mode 100644
index 0000000..69a5cd5
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/Unit/lit.site.cfg.in
@@ -0,0 +1,9 @@
+@LIT_SITE_CFG_IN_HEADER@
+
+config.extra_tools_obj_dir = "@CLANG_TOOLS_BINARY_DIR@/unittests"
+config.extra_tools_src_dir = "@CLANG_TOOLS_SOURCE_DIR@/unittests"
+config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
+config.shlibdir = "@SHLIBDIR@"
+config.target_triple = "@TARGET_TRIPLE@"
+
+lit_config.load_config(config, "@CLANG_TOOLS_SOURCE_DIR@/test/Unit/lit.cfg")
diff --git a/src/llvm-project/clang-tools-extra/test/change-namespace/Inputs/fake-std.h b/src/llvm-project/clang-tools-extra/test/change-namespace/Inputs/fake-std.h
new file mode 100644
index 0000000..24d3f97
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/change-namespace/Inputs/fake-std.h
@@ -0,0 +1,5 @@
+namespace std {
+ class STD {};
+}
+
+using namespace std;
diff --git a/src/llvm-project/clang-tools-extra/test/change-namespace/lambda-function.cpp b/src/llvm-project/clang-tools-extra/test/change-namespace/lambda-function.cpp
new file mode 100644
index 0000000..452983e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/change-namespace/lambda-function.cpp
@@ -0,0 +1,37 @@
+// RUN: clang-change-namespace -old_namespace "na::nb" -new_namespace "x::y" --file_pattern ".*" %s -- -std=c++11 | sed 's,// CHECK.*,,' | FileCheck %s
+
+template <class T>
+class function;
+template <class R, class... ArgTypes>
+class function<R(ArgTypes...)> {
+public:
+ template <typename Functor>
+ function(Functor f) {}
+ R operator()(ArgTypes...) const {}
+};
+
+namespace x {
+// CHECK: namespace x {
+class X {};
+}
+
+namespace na {
+namespace nb {
+// CHECK: namespace x {
+// CHECK-NEXT: namespace y {
+void f(function<void(int)> func, int param) { func(param); }
+void g() { f([](int x) {}, 1); }
+
+// x::X in function type parameter list will have translation unit context, so
+// we simply replace it with fully-qualified name.
+using TX = function<x::X(x::X)>;
+// CHECK: using TX = function<X(x::X)>;
+
+class A {};
+using TA = function<A(A)>;
+// CHECK: using TA = function<A(A)>;
+
+// CHECK: } // namespace y
+// CHECK-NEXT: } // namespace x
+}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/change-namespace/macro.cpp b/src/llvm-project/clang-tools-extra/test/change-namespace/macro.cpp
new file mode 100644
index 0000000..ba47de6
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/change-namespace/macro.cpp
@@ -0,0 +1,29 @@
+// RUN: cp %S/macro.cpp %T/macro.cpp
+// RUN: echo "#define USING using na::nc::X" > %T/macro.h
+//
+// RUN: clang-change-namespace -old_namespace "na::nb" -new_namespace "x::y" --file_pattern "macro.cpp" --i %T/macro.cpp --
+// RUN: FileCheck -input-file=%T/macro.cpp -check-prefix=CHECK-CC %s
+// RUN: FileCheck -input-file=%T/macro.h -check-prefix=CHECK-HEADER %s
+//
+// RUN: cp %S/macro.cpp %T/macro.cpp
+// RUN: echo "#define USING using na::nc::X" > %T/macro.h
+// RUN: clang-change-namespace -old_namespace "na::nb" -new_namespace "x::y" --file_pattern ".*" --i %T/macro.cpp --
+// RUN: FileCheck -input-file=%T/macro.cpp -check-prefix=CHECK-CC %s
+// RUN: FileCheck -input-file=%T/macro.h -check-prefix=CHECK-CHANGED-HEADER %s
+#include "macro.h"
+namespace na { namespace nc { class X{}; } }
+
+namespace na {
+namespace nb {
+USING;
+}
+}
+// CHECK-CC: namespace x {
+// CHECK-CC: namespace y {
+// CHECK-CC: USING;
+// CHECK-CC: } // namespace y
+// CHECK-CC: } // namespace x
+
+// CHECK-HEADER: #define USING using na::nc::X
+
+// CHECK-CHANGED-HEADER: #define USING using ::na::nc::X
diff --git a/src/llvm-project/clang-tools-extra/test/change-namespace/simple-move.cpp b/src/llvm-project/clang-tools-extra/test/change-namespace/simple-move.cpp
new file mode 100644
index 0000000..ea3c3d3
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/change-namespace/simple-move.cpp
@@ -0,0 +1,10 @@
+// RUN: clang-change-namespace -old_namespace "na::nb" -new_namespace "x::y" --file_pattern ".*" %s -- | sed 's,// CHECK.*,,' | FileCheck %s
+// CHECK: namespace x {
+// CHECK-NEXT: namespace y {
+namespace na {
+namespace nb {
+class A {};
+// CHECK: } // namespace y
+// CHECK-NEXT: } // namespace x
+}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/change-namespace/white-list.cpp b/src/llvm-project/clang-tools-extra/test/change-namespace/white-list.cpp
new file mode 100644
index 0000000..48e3a78
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/change-namespace/white-list.cpp
@@ -0,0 +1,19 @@
+// RUN: echo "^std::.*$" > %T/white-list.txt
+// RUN: clang-change-namespace -old_namespace "na::nb" -new_namespace "x::y" --file_pattern ".*" --whitelist_file %T/white-list.txt %s -- | sed 's,// CHECK.*,,' | FileCheck %s
+
+#include "Inputs/fake-std.h"
+
+// CHECK: namespace x {
+// CHECK-NEXT: namespace y {
+namespace na {
+namespace nb {
+void f() {
+ std::STD x1;
+ STD x2;
+// CHECK: {{^}} std::STD x1;{{$}}
+// CHECK-NEXT: {{^}} STD x2;{{$}}
+}
+// CHECK: } // namespace y
+// CHECK-NEXT: } // namespace x
+}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/ClangRenameClassReplacements.cpp b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/ClangRenameClassReplacements.cpp
new file mode 100644
index 0000000..2b478bb
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/ClangRenameClassReplacements.cpp
@@ -0,0 +1,11 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/fixes
+// RUN: cat %s > %t.cpp
+// RUN: clang-rename -offset=254 -new-name=Bar -export-fixes=%t/fixes/clang-rename.yaml %t.cpp --
+// RUN: clang-apply-replacements %t
+// RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
+
+class Foo {}; // CHECK: class Bar {};
+
+// Use grep -FUbo 'Foo' <file> to get the correct offset of Cla when changing
+// this file.
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/basic/basic.h b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/basic/basic.h
new file mode 100644
index 0000000..4850968
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/basic/basic.h
@@ -0,0 +1,32 @@
+#ifndef BASIC_H
+#define BASIC_H
+
+
+class Parent {
+public:
+ virtual void func() {}
+};
+
+class Derived : public Parent {
+public:
+ virtual void func() {}
+ // CHECK: virtual void func() override {}
+};
+
+extern void ext(int (&)[5], const Parent &);
+
+void func(int t) {
+ int ints[5];
+ for (unsigned i = 0; i < 5; ++i) {
+ int &e = ints[i];
+ e = t;
+ // CHECK: for (auto & elem : ints) {
+ // CHECK-NEXT: elem = t;
+ }
+
+ Derived d;
+
+ ext(ints, d);
+}
+
+#endif // BASIC_H
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/basic/file1.yaml b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/basic/file1.yaml
new file mode 100644
index 0000000..3a5375e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/basic/file1.yaml
@@ -0,0 +1,25 @@
+---
+MainSourceFile: source1.cpp
+Diagnostics:
+ - DiagnosticName: test-basic
+ Message: Fix
+ FilePath: $(path)/basic.h
+ FileOffset: 242
+ Replacements:
+ - FilePath: $(path)/basic.h
+ Offset: 242
+ Length: 26
+ ReplacementText: 'auto & elem : ints'
+ - FilePath: $(path)/basic.h
+ Offset: 276
+ Length: 22
+ ReplacementText: ''
+ - FilePath: $(path)/basic.h
+ Offset: 298
+ Length: 1
+ ReplacementText: elem
+ - FilePath: $(path)/../basic/basic.h
+ Offset: 148
+ Length: 0
+ ReplacementText: 'override '
+...
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/basic/file2.yaml b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/basic/file2.yaml
new file mode 100644
index 0000000..8f6f65a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/basic/file2.yaml
@@ -0,0 +1,13 @@
+---
+MainSourceFile: source2.cpp
+Diagnostics:
+ - DiagnosticName: test-basic
+ Message: Fix
+ FilePath: $(path)/basic.h
+ FileOffset: 148
+ Replacements:
+ - FilePath: $(path)/../basic/basic.h
+ Offset: 298
+ Length: 1
+ ReplacementText: elem
+...
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/conflict/common.h b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/conflict/common.h
new file mode 100644
index 0000000..630a39a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/conflict/common.h
@@ -0,0 +1,17 @@
+#ifndef COMMON_H
+#define COMMON_H
+
+extern void ext(int (&)[5]);
+
+void func(int t) {
+ int ints[5];
+ for (unsigned i = 0; i < 5; ++i) {
+ ints[i] = t;
+ }
+
+ int *i = 0;
+
+ ext(ints);
+}
+
+#endif // COMMON_H
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/conflict/expected.txt b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/conflict/expected.txt
new file mode 100644
index 0000000..b66f577a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/conflict/expected.txt
@@ -0,0 +1,12 @@
+The new replacement overlaps with an existing replacement.
+New replacement: $(path)/common.h: 106:+26:"int & elem : ints"
+Existing replacement: $(path)/common.h: 106:+26:"auto & i : ints"
+The new replacement overlaps with an existing replacement.
+New replacement: $(path)/common.h: 140:+7:"i"
+Existing replacement: $(path)/common.h: 140:+7:"elem"
+The new replacement overlaps with an existing replacement.
+New replacement: $(path)/common.h: 169:+0:"(int*)"
+Existing replacement: $(path)/common.h: 160:+12:""
+The new replacement overlaps with an existing replacement.
+New replacement: $(path)/common.h: 169:+1:"nullptr"
+Existing replacement: $(path)/common.h: 160:+12:""
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/conflict/file1.yaml b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/conflict/file1.yaml
new file mode 100644
index 0000000..8505273
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/conflict/file1.yaml
@@ -0,0 +1,21 @@
+---
+MainSourceFile: source1.cpp
+Diagnostics:
+ - DiagnosticName: test-conflict
+ Message: Fix
+ FilePath: $(path)/common.h
+ FileOffset: 106
+ Replacements:
+ - FilePath: $(path)/common.h
+ Offset: 106
+ Length: 26
+ ReplacementText: 'auto & i : ints'
+ - FilePath: $(path)/common.h
+ Offset: 140
+ Length: 7
+ ReplacementText: i
+ - FilePath: $(path)/common.h
+ Offset: 160
+ Length: 12
+ ReplacementText: ''
+...
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/conflict/file2.yaml b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/conflict/file2.yaml
new file mode 100644
index 0000000..32b35ac
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/conflict/file2.yaml
@@ -0,0 +1,21 @@
+---
+MainSourceFile: source2.cpp
+Diagnostics:
+ - DiagnosticName: test-conflict
+ Message: Fix
+ FilePath: $(path)/common.h
+ FileOffset: 106
+ Replacements:
+ - FilePath: $(path)/common.h
+ Offset: 106
+ Length: 26
+ ReplacementText: 'int & elem : ints'
+ - FilePath: $(path)/common.h
+ Offset: 140
+ Length: 7
+ ReplacementText: elem
+ - FilePath: $(path)/common.h
+ Offset: 169
+ Length: 1
+ ReplacementText: nullptr
+...
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/conflict/file3.yaml b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/conflict/file3.yaml
new file mode 100644
index 0000000..88543e0
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/conflict/file3.yaml
@@ -0,0 +1,13 @@
+---
+MainSourceFile: source1.cpp
+Diagnostics:
+ - DiagnosticName: test-conflict
+ Message: Fix
+ FilePath: $(path)/common.h
+ FileOffset: 169
+ Replacements:
+ - FilePath: $(path)/common.h
+ Offset: 169
+ Length: 0
+ ReplacementText: "(int*)"
+...
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/crlf/crlf.cpp b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/crlf/crlf.cpp
new file mode 100644
index 0000000..26f7996
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/crlf/crlf.cpp
@@ -0,0 +1,6 @@
+
+// This file intentionally uses a CRLF newlines!
+
+void foo() {
+ int *x = 0;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/crlf/crlf.cpp.expected b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/crlf/crlf.cpp.expected
new file mode 100644
index 0000000..ad8e907
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/crlf/crlf.cpp.expected
@@ -0,0 +1,6 @@
+
+// This file intentionally uses a CRLF newlines!
+
+void foo() {
+ int *x = nullptr;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/crlf/file1.yaml b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/crlf/file1.yaml
new file mode 100644
index 0000000..06b058e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/crlf/file1.yaml
@@ -0,0 +1,13 @@
+---
+MainSourceFile: source1.cpp
+Diagnostics:
+ - DiagnosticName: test-crlf
+ Message: Fix
+ FilePath: $(path)/crlf.cpp
+ FileOffset: 79
+ Replacements:
+ - FilePath: $(path)/crlf.cpp
+ Offset: 79
+ Length: 1
+ ReplacementText: nullptr
+...
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/format/no.cpp b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/format/no.cpp
new file mode 100644
index 0000000..5bc9081
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/format/no.cpp
@@ -0,0 +1,6 @@
+class C {};
+
+void f() { // This comment necessary to prevent formatting as void f() { ... }
+ C *a = new C();
+ // CHECK: {{^\ \ auto\ a\ \=\ new\ C\(\);}}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/format/no.yaml b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/format/no.yaml
new file mode 100644
index 0000000..3118cc6
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/format/no.yaml
@@ -0,0 +1,13 @@
+---
+MainSourceFile: no.cpp
+Diagnostics:
+ - DiagnosticName: test-no
+ Message: Fix
+ FilePath: $(path)/no.cpp
+ FileOffset: 94
+ Replacements:
+ - FilePath: $(path)/no.cpp
+ Offset: 94
+ Length: 3
+ ReplacementText: 'auto '
+...
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/format/yes.cpp b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/format/yes.cpp
new file mode 100644
index 0000000..8f600c3
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/format/yes.cpp
@@ -0,0 +1,22 @@
+class MyType012345678901234567890123456789 {};
+
+void g(int, int*, int, int*, int, int*, int);
+
+void f() {
+ MyType012345678901234567890123456789 *a =
+ new MyType012345678901234567890123456789();
+ // CHECK: {{^\ \ auto\ a\ \=\ new\ MyType012345678901234567890123456789\(\);}}
+
+ int iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii;
+ int jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj;
+ int kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk;
+ int mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm;
+ g(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii, 0, jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj,
+ 0, kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk, 0, mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm);
+ // CHECK: g(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii, nullptr,
+ // CHECK-NEXT: jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj, nullptr,
+ // CHECK-NEXT: kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk, nullptr,
+ // CHECK-NEXT: mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm);
+
+ delete a;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/format/yes.yaml b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/format/yes.yaml
new file mode 100644
index 0000000..6ded4db
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/format/yes.yaml
@@ -0,0 +1,27 @@
+# These replacements are out of order on purpose to test that they get sorted
+# so that formatting happens correctly.
+---
+MainSourceFile: yes.cpp
+Diagnostics:
+ - DiagnosticName: test-yes
+ Message: Fix
+ FilePath: $(path)/yes.cpp
+ FileOffset: 494
+ Replacements:
+ - FilePath: $(path)/yes.cpp
+ Offset: 494
+ Length: 1
+ ReplacementText: nullptr
+ - FilePath: $(path)/yes.cpp
+ Offset: 410
+ Length: 1
+ ReplacementText: nullptr
+ - FilePath: $(path)/yes.cpp
+ Offset: 454
+ Length: 1
+ ReplacementText: nullptr
+ - FilePath: $(path)/yes.cpp
+ Offset: 108
+ Length: 38
+ ReplacementText: 'auto '
+...
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/identical/file1.yaml b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/identical/file1.yaml
new file mode 100644
index 0000000..cf273c4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/identical/file1.yaml
@@ -0,0 +1,14 @@
+---
+MainSourceFile: identical.cpp
+Diagnostics:
+ - DiagnosticName: test-identical-insertion
+ Message: Fix
+ FilePath: $(path)/identical.cpp
+ FileOffset: 12
+ Replacements:
+ - FilePath: $(path)/identical.cpp
+ Offset: 12
+ Length: 0
+ ReplacementText: '0'
+...
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/identical/file2.yaml b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/identical/file2.yaml
new file mode 100644
index 0000000..cf273c4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/identical/file2.yaml
@@ -0,0 +1,14 @@
+---
+MainSourceFile: identical.cpp
+Diagnostics:
+ - DiagnosticName: test-identical-insertion
+ Message: Fix
+ FilePath: $(path)/identical.cpp
+ FileOffset: 12
+ Replacements:
+ - FilePath: $(path)/identical.cpp
+ Offset: 12
+ Length: 0
+ ReplacementText: '0'
+...
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/identical/identical.cpp b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/identical/identical.cpp
new file mode 100644
index 0000000..bc740fa
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/identical/identical.cpp
@@ -0,0 +1,2 @@
+class MyType {};
+// CHECK: class MyType0 {};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/invalid-files/invalid-files.yaml b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/invalid-files/invalid-files.yaml
new file mode 100644
index 0000000..f84964d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/invalid-files/invalid-files.yaml
@@ -0,0 +1,12 @@
+---
+MainSourceFile: ''
+Replacements:
+ - FilePath: idontexist.h
+ Offset: 2669
+ Length: 0
+ ReplacementText: ' override'
+ - FilePath: idontexist.h
+ Offset: 2669
+ Length: 0
+ ReplacementText: ' override'
+...
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/order-dependent/expected.txt b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/order-dependent/expected.txt
new file mode 100644
index 0000000..cf38b34
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/order-dependent/expected.txt
@@ -0,0 +1,3 @@
+The new insertion has the same insert location as an existing replacement.
+New replacement: $(path)/order-dependent.cpp: 12:+0:"1"
+Existing replacement: $(path)/order-dependent.cpp: 12:+0:"0"
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/order-dependent/file1.yaml b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/order-dependent/file1.yaml
new file mode 100644
index 0000000..a823438
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/order-dependent/file1.yaml
@@ -0,0 +1,13 @@
+---
+MainSourceFile: order-dependent.cpp
+Diagnostics:
+ - DiagnosticName: test-order-dependent-insertion
+ Message: Fix
+ FilePath: $(path)/order-dependent.cpp
+ FileOffset: 12
+ Replacements:
+ - FilePath: $(path)/order-dependent.cpp
+ Offset: 12
+ Length: 0
+ ReplacementText: '0'
+...
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/order-dependent/file2.yaml b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/order-dependent/file2.yaml
new file mode 100644
index 0000000..634d3ca
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/order-dependent/file2.yaml
@@ -0,0 +1,13 @@
+---
+MainSourceFile: order-dependent.cpp
+Diagnostics:
+ - DiagnosticName: test-order-dependent-insertion
+ Message: Fix
+ FilePath: $(path)/order-dependent.cpp
+ FileOffset: 12
+ Replacements:
+ - FilePath: $(path)/order-dependent.cpp
+ Offset: 12
+ Length: 0
+ ReplacementText: '1'
+...
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/order-dependent/order-dependent.cpp b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/order-dependent/order-dependent.cpp
new file mode 100644
index 0000000..5b98860
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/Inputs/order-dependent/order-dependent.cpp
@@ -0,0 +1 @@
+class MyType {};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/basic.cpp b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/basic.cpp
new file mode 100644
index 0000000..4f19a96
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/basic.cpp
@@ -0,0 +1,17 @@
+// RUN: mkdir -p %T/Inputs/basic
+// RUN: grep -Ev "// *[A-Z-]+:" %S/Inputs/basic/basic.h > %T/Inputs/basic/basic.h
+// RUN: sed "s#\$(path)#%/T/Inputs/basic#" %S/Inputs/basic/file1.yaml > %T/Inputs/basic/file1.yaml
+// RUN: sed "s#\$(path)#%/T/Inputs/basic#" %S/Inputs/basic/file2.yaml > %T/Inputs/basic/file2.yaml
+// RUN: clang-apply-replacements %T/Inputs/basic
+// RUN: FileCheck -input-file=%T/Inputs/basic/basic.h %S/Inputs/basic/basic.h
+//
+// Check that the yaml files are *not* deleted after running clang-apply-replacements without remove-change-desc-files.
+// RUN: ls -1 %T/Inputs/basic | FileCheck %s --check-prefix=YAML
+//
+// Check that the yaml files *are* deleted after running clang-apply-replacements with remove-change-desc-files.
+// RUN: grep -Ev "// *[A-Z-]+:" %S/Inputs/basic/basic.h > %T/Inputs/basic/basic.h
+// RUN: clang-apply-replacements -remove-change-desc-files %T/Inputs/basic
+// RUN: ls -1 %T/Inputs/basic | FileCheck %s --check-prefix=NO_YAML
+//
+// YAML: {{^file.\.yaml$}}
+// NO_YAML-NOT: {{^file.\.yaml$}}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/conflict.cpp b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/conflict.cpp
new file mode 100644
index 0000000..c1f2342
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/conflict.cpp
@@ -0,0 +1,17 @@
+// RUN: mkdir -p %T/Inputs/conflict
+// RUN: sed "s#\$(path)#%/S/Inputs/conflict#" %S/Inputs/conflict/file1.yaml > %T/Inputs/conflict/file1.yaml
+// RUN: sed "s#\$(path)#%/S/Inputs/conflict#" %S/Inputs/conflict/file2.yaml > %T/Inputs/conflict/file2.yaml
+// RUN: sed "s#\$(path)#%/S/Inputs/conflict#" %S/Inputs/conflict/file3.yaml > %T/Inputs/conflict/file3.yaml
+// RUN: sed "s#\$(path)#%/S/Inputs/conflict#" %S/Inputs/conflict/expected.txt > %T/Inputs/conflict/expected.txt
+// RUN: not clang-apply-replacements %T/Inputs/conflict > %T/Inputs/conflict/output.txt 2>&1
+// RUN: diff -b %T/Inputs/conflict/output.txt %T/Inputs/conflict/expected.txt
+//
+// Check that the yaml files are *not* deleted after running clang-apply-replacements without remove-change-desc-files even when there is a failure.
+// RUN: ls -1 %T/Inputs/conflict | FileCheck %s --check-prefix=YAML
+//
+// Check that the yaml files *are* deleted after running clang-apply-replacements with remove-change-desc-files even when there is a failure.
+// RUN: not clang-apply-replacements %T/Inputs/conflict -remove-change-desc-files > %T/Inputs/conflict/output.txt 2>&1
+// RUN: ls -1 %T/Inputs/conflict | FileCheck %s --check-prefix=NO_YAML
+//
+// YAML: {{^file.\.yaml$}}
+// NO_YAML-NOT: {{^file.\.yaml$}}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/crlf.cpp b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/crlf.cpp
new file mode 100644
index 0000000..15ba5b5
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/crlf.cpp
@@ -0,0 +1,5 @@
+// RUN: mkdir -p %T/Inputs/crlf
+// RUN: cat %S/Inputs/crlf/crlf.cpp > %T/Inputs/crlf/crlf.cpp
+// RUN: sed "s#\$(path)#%/T/Inputs/crlf#" %S/Inputs/crlf/file1.yaml > %T/Inputs/crlf/file1.yaml
+// RUN: clang-apply-replacements %T/Inputs/crlf
+// RUN: diff %T/Inputs/crlf/crlf.cpp %S/Inputs/crlf/crlf.cpp.expected
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/format.cpp b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/format.cpp
new file mode 100644
index 0000000..7de320d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/format.cpp
@@ -0,0 +1,15 @@
+// RUN: mkdir -p %T/Inputs/format
+//
+// yes.cpp requires formatting after replacements are applied. no.cpp does not.
+// The presence of no.cpp ensures that files that don't need formatting still
+// have their new state written to disk after applying replacements.
+//
+// RUN: grep -Ev "// *[A-Z-]+:" %S/Inputs/format/yes.cpp > %T/Inputs/format/yes.cpp
+// RUN: grep -Ev "// *[A-Z-]+:" %S/Inputs/format/no.cpp > %T/Inputs/format/no.cpp
+// RUN: sed "s#\$(path)#%/T/Inputs/format#" %S/Inputs/format/yes.yaml > %T/Inputs/format/yes.yaml
+// RUN: sed "s#\$(path)#%/T/Inputs/format#" %S/Inputs/format/no.yaml > %T/Inputs/format/no.yaml
+// RUN: clang-apply-replacements -format %T/Inputs/format
+// RUN: FileCheck --strict-whitespace -input-file=%T/Inputs/format/yes.cpp %S/Inputs/format/yes.cpp
+// RUN: FileCheck --strict-whitespace -input-file=%T/Inputs/format/no.cpp %S/Inputs/format/no.cpp
+//
+// RUN not clang-apply-replacements -format=blah %T/Inputs/format
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/identical.cpp b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/identical.cpp
new file mode 100644
index 0000000..ffbf2e3
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/identical.cpp
@@ -0,0 +1,6 @@
+// RUN: mkdir -p %T/Inputs/identical
+// RUN: grep -Ev "// *[A-Z-]+:" %S/Inputs/identical/identical.cpp > %T/Inputs/identical/identical.cpp
+// RUN: sed "s#\$(path)#%/T/Inputs/identical#" %S/Inputs/identical/file1.yaml > %T/Inputs/identical/file1.yaml
+// RUN: sed "s#\$(path)#%/T/Inputs/identical#" %S/Inputs/identical/file2.yaml > %T/Inputs/identical/file2.yaml
+// RUN: clang-apply-replacements %T/Inputs/identical
+// RUN: FileCheck -input-file=%T/Inputs/identical/identical.cpp %S/Inputs/identical/identical.cpp
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/invalid-files.cpp b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/invalid-files.cpp
new file mode 100644
index 0000000..b0eb9ef
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/invalid-files.cpp
@@ -0,0 +1,6 @@
+// RUN: mkdir -p %T/invalid-files
+// RUN: cp %S/Inputs/invalid-files/invalid-files.yaml %T/invalid-files/invalid-files.yaml
+// RUN: clang-apply-replacements %T/invalid-files
+//
+// Check that the yaml files are *not* deleted after running clang-apply-replacements without remove-change-desc-files.
+// RUN: ls %T/invalid-files/invalid-files.yaml
diff --git a/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/order-dependent.cpp b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/order-dependent.cpp
new file mode 100644
index 0000000..769f4f7
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-apply-replacements/order-dependent.cpp
@@ -0,0 +1,7 @@
+// RUN: mkdir -p %T/Inputs/order-dependent
+// RUN: grep -Ev "// *[A-Z-]+:" %S/Inputs/order-dependent/order-dependent.cpp > %T/Inputs/order-dependent/order-dependent.cpp
+// RUN: sed "s#\$(path)#%/T/Inputs/order-dependent#" %S/Inputs/order-dependent/file1.yaml > %T/Inputs/order-dependent/file1.yaml
+// RUN: sed "s#\$(path)#%/T/Inputs/order-dependent#" %S/Inputs/order-dependent/file2.yaml > %T/Inputs/order-dependent/file2.yaml
+// RUN: sed "s#\$(path)#%/T/Inputs/order-dependent#" %S/Inputs/order-dependent/expected.txt > %T/Inputs/order-dependent/expected.txt
+// RUN: not clang-apply-replacements %T/Inputs/order-dependent > %T/Inputs/order-dependent/output.txt 2>&1
+// RUN: diff -b %T/Inputs/order-dependent/output.txt %T/Inputs/order-dependent/expected.txt
diff --git a/src/llvm-project/clang-tools-extra/test/clang-doc/single-file-public.cpp b/src/llvm-project/clang-tools-extra/test/clang-doc/single-file-public.cpp
new file mode 100644
index 0000000..e53a645
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-doc/single-file-public.cpp
@@ -0,0 +1,49 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: echo "" > %t/compile_flags.txt
+// RUN: cp "%s" "%t/test.cpp"
+// RUN: clang-doc --doxygen --public --executor=standalone -p %t %t/test.cpp -output=%t/docs
+// RUN: cat %t/docs/Record.yaml | FileCheck %s --check-prefix=CHECK
+// RUN: rm -rf %t
+
+class Record {
+private:
+ void function_private();
+
+public:
+ void function_public();
+};
+
+void Record::function_private() {}
+
+void Record::function_public() {}
+
+// CHECK: ---
+// CHECK-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-NEXT: Name: 'Record'
+// CHECK-NEXT: DefLocation:
+// CHECK-NEXT: LineNumber: [[@LINE-16]]
+// CHECK-NEXT: Filename: '{{.*}}'
+// CHECK-NEXT: TagType: Class
+// CHECK-NEXT: ChildFunctions:
+// CHECK-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-NEXT: Name: 'function_public'
+// CHECK-NEXT: Namespace:
+// CHECK-NEXT: - Type: Record
+// CHECK-NEXT: Name: 'Record'
+// CHECK-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-NEXT: DefLocation:
+// CHECK-NEXT: LineNumber: [[@LINE-17]]
+// CHECK-NEXT: Filename: '{{.*}}'
+// CHECK-NEXT: Location:
+// CHECK-NEXT: - LineNumber: [[@LINE-25]]
+// CHECK-NEXT: Filename: '{{.*}}'
+// CHECK-NEXT: IsMethod: true
+// CHECK-NEXT: Parent:
+// CHECK-NEXT: Type: Record
+// CHECK-NEXT: Name: 'Record'
+// CHECK-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-NEXT: ReturnType:
+// CHECK-NEXT: Type:
+// CHECK-NEXT: Name: 'void'
+// CHECK-NEXT: ...
diff --git a/src/llvm-project/clang-tools-extra/test/clang-doc/single-file.cpp b/src/llvm-project/clang-tools-extra/test/clang-doc/single-file.cpp
new file mode 100644
index 0000000..8bde6f9
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-doc/single-file.cpp
@@ -0,0 +1,31 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: echo "" > %t/compile_flags.txt
+// RUN: cp "%s" "%t/test.cpp"
+// RUN: clang-doc --doxygen --executor=standalone -p %t %t/test.cpp -output=%t/docs
+// RUN: cat %t/docs/GlobalNamespace.yaml | FileCheck %s --check-prefix=CHECK
+// RUN: rm -rf %t
+
+void function(int x);
+
+void function(int x) {}
+
+// CHECK: ---
+// CHECK-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-NEXT: ChildFunctions:
+// CHECK-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-NEXT: Name: 'function'
+// CHECK-NEXT: DefLocation:
+// CHECK-NEXT: LineNumber: [[@LINE-8]]
+// CHECK-NEXT: Filename: '{{.*}}
+// CHECK-NEXT: Location:
+// CHECK-NEXT: - LineNumber: [[@LINE-13]]
+// CHECK-NEXT: Filename: '{{.*}}'
+// CHECK-NEXT: Params:
+// CHECK-NEXT: - Type:
+// CHECK-NEXT: Name: 'int'
+// CHECK-NEXT: Name: 'x'
+// CHECK-NEXT: ReturnType:
+// CHECK-NEXT: Type:
+// CHECK-NEXT: Name: 'void'
+// CHECK-NEXT:...
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/database_template.json b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/database_template.json
new file mode 100644
index 0000000..ceb499c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/database_template.json
@@ -0,0 +1,7 @@
+[
+{
+ "directory": "$test_dir/build",
+ "command": "clang++ -o test.o -I../include $test_dir/src/test.cpp",
+ "file": "$test_dir/src/test.cpp"
+}
+]
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/enum.h b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/enum.h
new file mode 100644
index 0000000..9ec3926
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/enum.h
@@ -0,0 +1,9 @@
+namespace a {
+enum E1 { Green, Red };
+
+enum class E2 { Yellow };
+
+class C {
+ enum E3 { Blue };
+};
+} // namespace a
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/function_test.cpp b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/function_test.cpp
new file mode 100644
index 0000000..5e86f59
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/function_test.cpp
@@ -0,0 +1,5 @@
+#include "function_test.h"
+
+void f() {}
+
+void A::f() {}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/function_test.h b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/function_test.h
new file mode 100644
index 0000000..810f803
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/function_test.h
@@ -0,0 +1,14 @@
+void f();
+
+inline int g() { return 0; }
+
+template<typename T>
+void h(T t) {}
+
+template<>
+void h(int t) {}
+
+class A {
+ public:
+ void f();
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/helper_decls_test.cpp b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/helper_decls_test.cpp
new file mode 100644
index 0000000..32d2a23
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/helper_decls_test.cpp
@@ -0,0 +1,97 @@
+#include "helper_decls_test.h"
+
+namespace {
+class HelperC1 {
+public:
+ static int I;
+};
+
+int HelperC1::I = 0;
+
+class HelperC2 {};
+
+class HelperC3 {
+ public:
+ static int I;
+};
+
+int HelperC3::I = 0;
+
+void HelperFun1() {}
+
+void HelperFun2() { HelperFun1(); }
+
+const int K1 = 1;
+} // namespace
+
+static const int K2 = 2;
+static void HelperFun3() { K2; }
+
+namespace a {
+
+static const int K3 = 3;
+static const int K4 = HelperC3::I;
+static const int K5 = 5;
+static const int K6 = 6;
+
+static void HelperFun4() {}
+static void HelperFun6() {}
+
+void Class1::f() { HelperFun2(); }
+
+void Class2::f() {
+ HelperFun1();
+ HelperFun3();
+}
+
+void Class3::f() { HelperC1::I; }
+
+void Class4::f() { HelperC2 c2; }
+
+void Class5::f() {
+ int Result = K1 + K2 + K3;
+ HelperFun4();
+}
+
+int Class6::f() {
+ int R = K4;
+ return R;
+}
+
+int Class7::f() {
+ int R = K6;
+ return R;
+}
+
+int Class7::g() {
+ HelperFun6();
+ return 1;
+}
+
+static int HelperFun5() {
+ int R = K5;
+ return R;
+}
+
+void Fun1() { HelperFun5(); }
+
+} // namespace a
+
+namespace b {
+namespace {
+void HelperFun7();
+
+class HelperC4;
+} // namespace
+
+void Fun3() {
+ HelperFun7();
+ HelperC4 *t;
+}
+
+namespace {
+void HelperFun7() {}
+
+class HelperC4 {};
+} // namespace
+} // namespace b
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/helper_decls_test.h b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/helper_decls_test.h
new file mode 100644
index 0000000..d8927c4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/helper_decls_test.h
@@ -0,0 +1,39 @@
+namespace a {
+class Class1 {
+ void f();
+};
+
+class Class2 {
+ void f();
+};
+
+class Class3 {
+ void f();
+};
+
+class Class4 {
+ void f();
+};
+
+class Class5 {
+ void f();
+};
+
+class Class6 {
+ int f();
+};
+
+class Class7 {
+ int f();
+ int g();
+};
+
+void Fun1();
+
+inline void Fun2() {}
+
+} // namespace a
+
+namespace b {
+void Fun3();
+} // namespace b
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/macro_helper_test.cpp b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/macro_helper_test.cpp
new file mode 100644
index 0000000..c2c1e1e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/macro_helper_test.cpp
@@ -0,0 +1,13 @@
+#include "macro_helper_test.h"
+
+#define DEFINE(name) \
+ namespace ns { \
+ static const bool t1 = false; \
+ bool t2_##name = t1; \
+ bool t3_##name = t1; \
+ } \
+ using ns::t2_##name;
+
+DEFINE(test)
+
+void f1() {}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/macro_helper_test.h b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/macro_helper_test.h
new file mode 100644
index 0000000..0ddfaae
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/macro_helper_test.h
@@ -0,0 +1,2 @@
+class A {};
+void f1();
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/multiple_class_test.cpp b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/multiple_class_test.cpp
new file mode 100644
index 0000000..5eb4bf3
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/multiple_class_test.cpp
@@ -0,0 +1,52 @@
+#include "multiple_class_test.h"
+
+using a::Move1;
+using namespace a;
+using A = a::Move1;
+static int g = 0;
+
+namespace a {
+int Move1::f() {
+ return 0;
+}
+} // namespace a
+
+namespace {
+using a::Move1;
+using namespace a;
+static int k = 0;
+} // namespace
+
+namespace b {
+using a::Move1;
+using namespace a;
+using T = a::Move1;
+int Move2::f() {
+ return 0;
+}
+} // namespace b
+
+namespace c {
+int Move3::f() {
+ using a::Move1;
+ using namespace b;
+ return 0;
+}
+
+int Move4::f() {
+ return k;
+}
+
+int EnclosingMove5::a = 1;
+
+int EnclosingMove5::Nested::f() {
+ return g;
+}
+
+int EnclosingMove5::Nested::b = 1;
+
+int NoMove::f() {
+ static int F = 0;
+ return g;
+}
+} // namespace c
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/multiple_class_test.h b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/multiple_class_test.h
new file mode 100644
index 0000000..113a261
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/multiple_class_test.h
@@ -0,0 +1,39 @@
+namespace a {
+class Move1 {
+public:
+ int f();
+};
+} // namespace a
+
+namespace b {
+class Move2 {
+public:
+ int f();
+};
+} // namespace b
+
+namespace c {
+class Move3 {
+public:
+ int f();
+};
+
+class Move4 {
+public:
+ int f();
+};
+
+class EnclosingMove5 {
+public:
+ class Nested {
+ int f();
+ static int b;
+ };
+ static int a;
+};
+
+class NoMove {
+public:
+ int f();
+};
+} // namespace c
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/template_class_test.cpp b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/template_class_test.cpp
new file mode 100644
index 0000000..8ad2dcb
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/template_class_test.cpp
@@ -0,0 +1,13 @@
+#include "template_class_test.h"
+
+template <typename T>
+void A<T>::g() {}
+
+template <typename T>
+template <typename U>
+void A<T>::k() {}
+
+template <typename T>
+int A<T>::c = 2;
+
+void B::f() {}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/template_class_test.h b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/template_class_test.h
new file mode 100644
index 0000000..d42a158
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/template_class_test.h
@@ -0,0 +1,30 @@
+#ifndef TEMPLATE_CLASS_TEST_H // comment 1
+#define TEMPLATE_CLASS_TEST_H
+
+template <typename T>
+class A {
+ public:
+ void f();
+ void g();
+ template <typename U> void h();
+ template <typename U> void k();
+ static int b;
+ static int c;
+};
+
+template <typename T>
+void A<T>::f() {}
+
+template <typename T>
+template <typename U>
+void A<T>::h() {}
+
+template <typename T>
+int A<T>::b = 2;
+
+class B {
+ public:
+ void f();
+};
+
+#endif // TEMPLATE_CLASS_TEST_H
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/test.cpp b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/test.cpp
new file mode 100644
index 0000000..fa777f0
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/test.cpp
@@ -0,0 +1,11 @@
+#include "test.h"
+#include "test2.h"
+
+namespace a {
+int Foo::f() {
+ return 0;
+}
+int Foo::f2(int a, int b) {
+ return a + b;
+}
+} // namespace a
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/test.h b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/test.h
new file mode 100644
index 0000000..8006c34
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/test.h
@@ -0,0 +1,10 @@
+#ifndef TEST_H // comment 1
+#define TEST_H
+namespace a {
+class Foo {
+public:
+ int f();
+ int f2(int a, int b);
+};
+} // namespace a
+#endif // TEST_H
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/type_alias.h b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/type_alias.h
new file mode 100644
index 0000000..7a900f6
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/type_alias.h
@@ -0,0 +1,11 @@
+typedef int Int1;
+using Int2 = int;
+
+template<class T>
+struct A {};
+
+template <class T> using B = A<T>;
+
+class C {
+ typedef int Int3;
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/var_test.cpp b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/var_test.cpp
new file mode 100644
index 0000000..9023abc
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/var_test.cpp
@@ -0,0 +1,6 @@
+#include "var_test.h"
+
+namespace a{
+int kGlobalInt = 1;
+const char *const kGlobalStr = "Hello";
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/var_test.h b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/var_test.h
new file mode 100644
index 0000000..1bfd54c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/Inputs/var_test.h
@@ -0,0 +1,11 @@
+namespace a {
+extern int kGlobalInt;
+extern const char *const kGlobalStr;
+}
+
+int kEvilInt = 2;
+
+inline void f1() {
+ int kGlobalInt = 3;
+ const char *const kGlobalStr = "Hello2";
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/move-class.cpp b/src/llvm-project/clang-tools-extra/test/clang-move/move-class.cpp
new file mode 100644
index 0000000..a30cb4d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/move-class.cpp
@@ -0,0 +1,43 @@
+// RUN: mkdir -p %T/clang-move/build
+// RUN: mkdir -p %T/clang-move/include
+// RUN: mkdir -p %T/clang-move/src
+// RUN: sed 's|$test_dir|%/T/clang-move|g' %S/Inputs/database_template.json > %T/clang-move/compile_commands.json
+// RUN: cp %S/Inputs/test.h %T/clang-move/include
+// RUN: cp %S/Inputs/test.cpp %T/clang-move/src
+// RUN: touch %T/clang-move/include/test2.h
+// RUN: cd %T/clang-move/build
+// RUN: clang-move -names="a::Foo" -new_cc=%T/clang-move/new_test.cpp -new_header=%T/clang-move/new_test.h -old_cc=../src/test.cpp -old_header=../include/test.h %T/clang-move/src/test.cpp
+// RUN: FileCheck -input-file=%T/clang-move/new_test.cpp -check-prefix=CHECK-NEW-TEST-CPP %s
+// RUN: FileCheck -input-file=%T/clang-move/new_test.h -check-prefix=CHECK-NEW-TEST-H %s
+// RUN: FileCheck -input-file=%T/clang-move/src/test.cpp -check-prefix=CHECK-OLD-TEST-EMPTY -allow-empty %s
+// RUN: FileCheck -input-file=%T/clang-move/include/test.h -check-prefix=CHECK-OLD-TEST-EMPTY -allow-empty %s
+//
+// RUN: cp %S/Inputs/test.h %T/clang-move/include
+// RUN: cp %S/Inputs/test.cpp %T/clang-move/src
+// RUN: cd %T/clang-move/build
+// RUN: clang-move -names="a::Foo" -new_cc=%T/clang-move/new_test.cpp -new_header=%T/clang-move/new_test.h -old_cc=%T/clang-move/src/test.cpp -old_header=%T/clang-move/include/test.h %T/clang-move/src/test.cpp
+// RUN: FileCheck -input-file=%T/clang-move/new_test.cpp -check-prefix=CHECK-NEW-TEST-CPP %s
+// RUN: FileCheck -input-file=%T/clang-move/new_test.h -check-prefix=CHECK-NEW-TEST-H %s
+// RUN: FileCheck -input-file=%T/clang-move/src/test.cpp -check-prefix=CHECK-OLD-TEST-EMPTY -allow-empty %s
+// RUN: FileCheck -input-file=%T/clang-move/include/test.h -check-prefix=CHECK-OLD-TEST-EMPTY -allow-empty %s
+//
+//
+// CHECK-NEW-TEST-H: #ifndef TEST_H // comment 1
+// CHECK-NEW-TEST-H: #define TEST_H
+// CHECK-NEW-TEST-H: namespace a {
+// CHECK-NEW-TEST-H: class Foo {
+// CHECK-NEW-TEST-H: public:
+// CHECK-NEW-TEST-H: int f();
+// CHECK-NEW-TEST-H: int f2(int a, int b);
+// CHECK-NEW-TEST-H: };
+// CHECK-NEW-TEST-H: } // namespace a
+// CHECK-NEW-TEST-H: #endif // TEST_H
+//
+// CHECK-NEW-TEST-CPP: #include "{{.*}}new_test.h"
+// CHECK-NEW-TEST-CPP: #include "test2.h"
+// CHECK-NEW-TEST-CPP: namespace a {
+// CHECK-NEW-TEST-CPP: int Foo::f() { return 0; }
+// CHECK-NEW-TEST-CPP: int Foo::f2(int a, int b) { return a + b; }
+// CHECK-NEW-TEST-CPP: } // namespace a
+//
+// CHECK-OLD-TEST-EMPTY: {{^}}{{$}}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/move-enum-decl.cpp b/src/llvm-project/clang-tools-extra/test/clang-move/move-enum-decl.cpp
new file mode 100644
index 0000000..42f6f99
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/move-enum-decl.cpp
@@ -0,0 +1,44 @@
+// RUN: mkdir -p %T/move-enum
+// RUN: cp %S/Inputs/enum.h %T/move-enum/enum.h
+// RUN: echo '#include "enum.h"' > %T/move-enum/enum.cpp
+// RUN: cd %T/move-enum
+//
+// -----------------------------------------------------------------------------
+// Test moving enum declarations.
+// -----------------------------------------------------------------------------
+// RUN: clang-move -names="a::E1" -new_cc=%T/move-enum/new_test.cpp -new_header=%T/move-enum/new_test.h -old_cc=%T/move-enum/enum.cpp -old_header=%T/move-enum/enum.h %T/move-enum/enum.cpp -- -std=c++11
+// RUN: FileCheck -input-file=%T/move-enum/new_test.h -check-prefix=CHECK-NEW-TEST-H-CASE1 %s
+// RUN: FileCheck -input-file=%T/move-enum/enum.h -check-prefix=CHECK-OLD-TEST-H-CASE1 %s
+//
+// CHECK-NEW-TEST-H-CASE1: namespace a {
+// CHECK-NEW-TEST-H-CASE1-NEXT: enum E1 { Green, Red };
+// CHECK-NEW-TEST-H-CASE1-NEXT: }
+
+// CHECK-OLD-TEST-H-CASE1-NOT: enum E1 { Green, Red };
+
+
+// -----------------------------------------------------------------------------
+// Test moving scoped enum declarations.
+// -----------------------------------------------------------------------------
+// RUN: cp %S/Inputs/enum.h %T/move-enum/enum.h
+// RUN: echo '#include "enum.h"' > %T/move-enum/enum.cpp
+// RUN: clang-move -names="a::E2" -new_cc=%T/move-enum/new_test.cpp -new_header=%T/move-enum/new_test.h -old_cc=%T/move-enum/enum.cpp -old_header=%T/move-enum/enum.h %T/move-enum/enum.cpp -- -std=c++11
+// RUN: FileCheck -input-file=%T/move-enum/new_test.h -check-prefix=CHECK-NEW-TEST-H-CASE2 %s
+// RUN: FileCheck -input-file=%T/move-enum/enum.h -check-prefix=CHECK-OLD-TEST-H-CASE2 %s
+
+// CHECK-NEW-TEST-H-CASE2: namespace a {
+// CHECK-NEW-TEST-H-CASE2-NEXT: enum class E2 { Yellow };
+// CHECK-NEW-TEST-H-CASE2-NEXT: }
+
+// CHECK-OLD-TEST-H-CASE2-NOT: enum class E2 { Yellow };
+
+
+// -----------------------------------------------------------------------------
+// Test not moving class-insided enum declarations.
+// -----------------------------------------------------------------------------
+// RUN: cp %S/Inputs/enum.h %T/move-enum/enum.h
+// RUN: echo '#include "enum.h"' > %T/move-enum/enum.cpp
+// RUN: clang-move -names="a::C::E3" -new_cc=%T/move-enum/new_test.cpp -new_header=%T/move-enum/new_test.h -old_cc=%T/move-enum/enum.cpp -old_header=%T/move-enum/enum.h %T/move-enum/enum.cpp -- -std=c++11
+// RUN: FileCheck -input-file=%T/move-enum/new_test.h -allow-empty -check-prefix=CHECK-EMPTY %s
+
+// CHECK-EMPTY: {{^}}{{$}}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/move-function.cpp b/src/llvm-project/clang-tools-extra/test/clang-move/move-function.cpp
new file mode 100644
index 0000000..0324b80
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/move-function.cpp
@@ -0,0 +1,70 @@
+// RUN: mkdir -p %T/move-function
+// RUN: cat %S/Inputs/function_test.h > %T/move-function/function_test.h
+// RUN: cat %S/Inputs/function_test.cpp > %T/move-function/function_test.cpp
+// RUN: cd %T/move-function
+// RUN: clang-move -names="g" -new_header=%T/move-function/new_function_test.h -old_header=../move-function/function_test.h %T/move-function/function_test.cpp --
+// RUN: FileCheck -input-file=%T/move-function/new_function_test.h -check-prefix=CHECK-NEW-TEST-H-CASE1 %s
+//
+// CHECK-NEW-TEST-H-CASE1: #ifndef {{.*}}NEW_FUNCTION_TEST_H
+// CHECK-NEW-TEST-H-CASE1: #define {{.*}}NEW_FUNCTION_TEST_H
+// CHECK-NEW-TEST-H-CASE1: {{[[:space:]]+}}
+// CHECK-NEW-TEST-H-CASE1: inline int g() { return 0; }
+// CHECK-NEW-TEST-H-CASE1: {{[[:space:]]+}}
+// CHECK-NEW-TEST-H-CASE1: #endif // {{.*}}NEW_FUNCTION_TEST_H
+//
+// RUN: cp %S/Inputs/function_test* %T/move-function
+// RUN: clang-move -names="h" -new_header=%T/move-function/new_function_test.h -old_header=../move-function/function_test.h %T/move-function/function_test.cpp --
+// RUN: FileCheck -input-file=%T/move-function/new_function_test.h -check-prefix=CHECK-NEW-TEST-H-CASE2 %s
+//
+// CHECK-NEW-TEST-H-CASE2: #ifndef {{.*}}NEW_FUNCTION_TEST_H
+// CHECK-NEW-TEST-H-CASE2: #define {{.*}}NEW_FUNCTION_TEST_H
+// CHECK-NEW-TEST-H-CASE2: {{[[:space:]]+}}
+// CHECK-NEW-TEST-H-CASE2: template <typename T> void h(T t) {}
+// CHECK-NEW-TEST-H-CASE2: {{[[:space:]]+}}
+// CHECK-NEW-TEST-H-CASE2: template <> void h(int t) {}
+// CHECK-NEW-TEST-H-CASE2: {{[[:space:]]+}}
+// CHECK-NEW-TEST-H-CASE2: #endif // {{.*}}NEW_FUNCTION_TEST_H
+//
+// RUN: cp %S/Inputs/function_test* %T/move-function
+// RUN: clang-move -names="f" -new_header=%T/move-function/new_function_test.h -new_cc=%T/move-function/new_function_test.cpp -old_header=../move-function/function_test.h -old_cc=../move-function/function_test.cpp %T/move-function/function_test.cpp --
+// RUN: FileCheck -input-file=%T/move-function/new_function_test.h -check-prefix=CHECK-NEW-TEST-H-CASE3 %s
+// RUN: FileCheck -input-file=%T/move-function/new_function_test.cpp -check-prefix=CHECK-NEW-TEST-CPP-CASE3 %s
+//
+// CHECK-NEW-TEST-H-CASE3: #ifndef {{.*}}NEW_FUNCTION_TEST_H
+// CHECK-NEW-TEST-H-CASE3: #define {{.*}}NEW_FUNCTION_TEST_H
+// CHECK-NEW-TEST-H-CASE3: {{[[:space:]]+}}
+// CHECK-NEW-TEST-H-CASE3: void f();
+// CHECK-NEW-TEST-H-CASE3: {{[[:space:]]+}}
+// CHECK-NEW-TEST-H-CASE3: #endif // {{.*}}NEW_FUNCTION_TEST_H
+// CHECK-NEW-TEST-CPP-CASE3: #include "{{.*}}new_function_test.h"
+// CHECK-NEW-TEST-CPP-CASE3: {{[[:space:]]+}}
+// CHECK-NEW-TEST-CPP-CASE3: void f() {}
+//
+// RUN: cat %S/Inputs/function_test.h > %T/move-function/function_test.h
+// RUN: cat %S/Inputs/function_test.cpp > %T/move-function/function_test.cpp
+// RUN: clang-move -names="A::f" -new_header=%T/move-function/new_function_test.h -new_cc=%T/move-function/new_function_test.cpp -old_header=../move-function/function_test.h -old_cc=../move-function/function_test.cpp %T/move-function/function_test.cpp -dump_result -- | FileCheck %s -check-prefix=CHECK-EMPTY
+//
+// CHECK-EMPTY: [{{[[:space:]]*}}]
+//
+// RUN: cat %S/Inputs/function_test.h > %T/move-function/function_test.h
+// RUN: cat %S/Inputs/function_test.cpp > %T/move-function/function_test.cpp
+// RUN: clang-move -names="f,A" -new_header=%T/move-function/new_function_test.h -new_cc=%T/move-function/new_function_test.cpp -old_header=../move-function/function_test.h -old_cc=../move-function/function_test.cpp %T/move-function/function_test.cpp --
+// RUN: FileCheck -input-file=%T/move-function/new_function_test.h -check-prefix=CHECK-NEW-TEST-H-CASE4 %s
+// RUN: FileCheck -input-file=%T/move-function/new_function_test.cpp -check-prefix=CHECK-NEW-TEST-CPP-CASE4 %s
+
+// CHECK-NEW-TEST-H-CASE4: #ifndef {{.*}}NEW_FUNCTION_TEST_H
+// CHECK-NEW-TEST-H-CASE4: #define {{.*}}NEW_FUNCTION_TEST_H
+// CHECK-NEW-TEST-H-CASE4: {{[[:space:]]+}}
+// CHECK-NEW-TEST-H-CASE4: void f();
+// CHECK-NEW-TEST-H-CASE4: {{[[:space:]]+}}
+// CHECK-NEW-TEST-H-CASE4: class A {
+// CHECK-NEW-TEST-H-CASE4: public:
+// CHECK-NEW-TEST-H-CASE4: void f();
+// CHECK-NEW-TEST-H-CASE4: };
+// CHECK-NEW-TEST-H-CASE4: {{[[:space:]]+}}
+// CHECK-NEW-TEST-H-CASE4: #endif // {{.*}}NEW_FUNCTION_TEST_H
+// CHECK-NEW-TEST-CPP-CASE4: #include "{{.*}}new_function_test.h"
+// CHECK-NEW-TEST-CPP-CASE4: {{[[:space:]]+}}
+// CHECK-NEW-TEST-CPP-CASE4: void f() {}
+// CHECK-NEW-TEST-CPP-CASE4: {{[[:space:]]+}}
+// CHECK-NEW-TEST-CPP-CASE4: void A::f() {}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/move-multiple-classes.cpp b/src/llvm-project/clang-tools-extra/test/clang-move/move-multiple-classes.cpp
new file mode 100644
index 0000000..821d567
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/move-multiple-classes.cpp
@@ -0,0 +1,104 @@
+// RUN: mkdir -p %T/move-multiple-classes
+// RUN: cp %S/Inputs/multiple_class_test* %T/move-multiple-classes/
+// RUN: cd %T/move-multiple-classes
+// RUN: clang-move -names="c::EnclosingMove5::Nested" -new_cc=%T/move-multiple-classes/new_multiple_class_test.cpp -new_header=%T/move-multiple-classes/new_multiple_class_test.h -old_cc=%T/move-multiple-classes/multiple_class_test.cpp -old_header=../move-multiple-classes/multiple_class_test.h -dump_result %T/move-multiple-classes/multiple_class_test.cpp -- -std=c++11| FileCheck %s -check-prefix=CHECK-EMPTY
+// RUN: clang-move -names="a::Move1, b::Move2,c::Move3,c::Move4,c::EnclosingMove5" -new_cc=%T/move-multiple-classes/new_multiple_class_test.cpp -new_header=%T/move-multiple-classes/new_multiple_class_test.h -old_cc=%T/move-multiple-classes/multiple_class_test.cpp -old_header=../move-multiple-classes/multiple_class_test.h %T/move-multiple-classes/multiple_class_test.cpp -- -std=c++11
+// RUN: FileCheck -input-file=%T/move-multiple-classes/new_multiple_class_test.cpp -check-prefix=CHECK-NEW-TEST-CPP %s
+// RUN: FileCheck -input-file=%T/move-multiple-classes/new_multiple_class_test.h -check-prefix=CHECK-NEW-TEST-H %s
+// RUN: FileCheck -input-file=%T/move-multiple-classes/multiple_class_test.cpp -check-prefix=CHECK-OLD-TEST-CPP %s
+// RUN: FileCheck -input-file=%T/move-multiple-classes/multiple_class_test.h -check-prefix=CHECK-OLD-TEST-H %s
+//
+// CHECK-EMPTY: [{{[[:space:]]*}}]
+//
+// CHECK-OLD-TEST-H: namespace c {
+// CHECK-OLD-TEST-H: class NoMove {
+// CHECK-OLD-TEST-H: public:
+// CHECK-OLD-TEST-H: int f();
+// CHECK-OLD-TEST-H: };
+// CHECK-OLD-TEST-H: } // namespace c
+
+// CHECK-OLD-TEST-CPP: #include "{{.*}}multiple_class_test.h"
+// CHECK-OLD-TEST-CPP: using a::Move1;
+// CHECK-OLD-TEST-CPP: using namespace a;
+// CHECK-OLD-TEST-CPP: using A = a::Move1;
+// CHECK-OLD-TEST-CPP: static int g = 0;
+// CHECK-OLD-TEST-CPP: namespace {
+// CHECK-OLD-TEST-CPP: using a::Move1;
+// CHECK-OLD-TEST-CPP: using namespace a;
+// CHECK-OLD-TEST-CPP: } // namespace
+// CHECK-OLD-TEST-CPP: namespace b {
+// CHECK-OLD-TEST-CPP: using a::Move1;
+// CHECK-OLD-TEST-CPP: using namespace a;
+// CHECK-OLD-TEST-CPP: using T = a::Move1;
+// CHECK-OLD-TEST-CPP: } // namespace b
+// CHECK-OLD-TEST-CPP: namespace c {
+// CHECK-OLD-TEST-CPP: int NoMove::f() {
+// CHECK-OLD-TEST-CPP: static int F = 0;
+// CHECK-OLD-TEST-CPP: return g;
+// CHECK-OLD-TEST-CPP: }
+// CHECK-OLD-TEST-CPP: } // namespace c
+
+// CHECK-NEW-TEST-H: #ifndef {{.*}}NEW_MULTIPLE_CLASS_TEST_H
+// CHECK-NEW-TEST-H: #define {{.*}}NEW_MULTIPLE_CLASS_TEST_H
+// CHECK-NEW-TEST-H: namespace a {
+// CHECK-NEW-TEST-H: class Move1 {
+// CHECK-NEW-TEST-H: public:
+// CHECK-NEW-TEST-H: int f();
+// CHECK-NEW-TEST-H: };
+// CHECK-NEW-TEST-H: } // namespace a
+// CHECK-NEW-TEST-H: namespace b {
+// CHECK-NEW-TEST-H: class Move2 {
+// CHECK-NEW-TEST-H: public:
+// CHECK-NEW-TEST-H: int f();
+// CHECK-NEW-TEST-H: };
+// CHECK-NEW-TEST-H: } // namespace b
+// CHECK-NEW-TEST-H: namespace c {
+// CHECK-NEW-TEST-H: class Move3 {
+// CHECK-NEW-TEST-H: public:
+// CHECK-NEW-TEST-H: int f();
+// CHECK-NEW-TEST-H: };
+// CHECK-NEW-TEST-H: class Move4 {
+// CHECK-NEW-TEST-H: public:
+// CHECK-NEW-TEST-H: int f();
+// CHECK-NEW-TEST-H: };
+// CHECK-NEW-TEST-H: class EnclosingMove5 {
+// CHECK-NEW-TEST-H: public:
+// CHECK-NEW-TEST-H: class Nested {
+// CHECK-NEW-TEST-H: int f();
+// CHECK-NEW-TEST-H: static int b;
+// CHECK-NEW-TEST-H: };
+// CHECK-NEW-TEST-H: static int a;
+// CHECK-NEW-TEST-H: };
+// CHECK-NEW-TEST-H: } // namespace c
+// CHECK-NEW-TEST-H: #endif // {{.*}}NEW_MULTIPLE_CLASS_TEST_H
+
+// CHECK-NEW-TEST-CPP: #include "{{.*}}new_multiple_class_test.h"
+// CHECK-NEW-TEST-CPP: using a::Move1;
+// CHECK-NEW-TEST-CPP: using namespace a;
+// CHECK-NEW-TEST-CPP: using A = a::Move1;
+// CHECK-NEW-TEST-CPP: static int g = 0;
+// CHECK-NEW-TEST-CPP: namespace a {
+// CHECK-NEW-TEST-CPP: int Move1::f() { return 0; }
+// CHECK-NEW-TEST-CPP: } // namespace a
+// CHECK-NEW-TEST-CPP: namespace {
+// CHECK-NEW-TEST-CPP: using a::Move1;
+// CHECK-NEW-TEST-CPP: using namespace a;
+// CHECK-NEW-TEST-CPP: static int k = 0;
+// CHECK-NEW-TEST-CPP: } // namespace
+// CHECK-NEW-TEST-CPP: namespace b {
+// CHECK-NEW-TEST-CPP: using a::Move1;
+// CHECK-NEW-TEST-CPP: using namespace a;
+// CHECK-NEW-TEST-CPP: using T = a::Move1;
+// CHECK-NEW-TEST-CPP: int Move2::f() { return 0; }
+// CHECK-NEW-TEST-CPP: } // namespace b
+// CHECK-NEW-TEST-CPP: namespace c {
+// CHECK-NEW-TEST-CPP: int Move3::f() {
+// CHECK-NEW-TEST-CPP: using a::Move1;
+// CHECK-NEW-TEST-CPP: using namespace b;
+// CHECK-NEW-TEST-CPP: return 0;
+// CHECK-NEW-TEST-CPP: }
+// CHECK-NEW-TEST-CPP: int Move4::f() { return k; }
+// CHECK-NEW-TEST-CPP: int EnclosingMove5::a = 1;
+// CHECK-NEW-TEST-CPP: int EnclosingMove5::Nested::f() { return g; }
+// CHECK-NEW-TEST-CPP: int EnclosingMove5::Nested::b = 1;
+// CHECK-NEW-TEST-CPP: } // namespace c
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/move-template-class.cpp b/src/llvm-project/clang-tools-extra/test/clang-move/move-template-class.cpp
new file mode 100644
index 0000000..1a6a60b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/move-template-class.cpp
@@ -0,0 +1,86 @@
+// RUN: mkdir -p %T/move-template-class
+// RUN: cp %S/Inputs/template_class_test* %T/move-template-class
+// RUN: cd %T/move-template-class
+// RUN: clang-move -names="A,B" -new_cc=%T/move-template-class/new_template_class_test.cpp -new_header=%T/move-template-class/new_template_class_test.h -old_cc=%T/move-template-class/template_class_test.cpp -old_header=../move-template-class/template_class_test.h %T/move-template-class/template_class_test.cpp --
+// RUN: FileCheck -input-file=%T/move-template-class/template_class_test.cpp -check-prefix=CHECK-OLD-TEST-EMPTY -allow-empty %s
+// RUN: FileCheck -input-file=%T/move-template-class/template_class_test.h -check-prefix=CHECK-OLD-TEST-EMPTY -allow-empty %s
+// RUN: FileCheck -input-file=%T/move-template-class/new_template_class_test.cpp -check-prefix=CHECK-NEW-TEST-CPP-CASE1 %s
+// RUN: FileCheck -input-file=%T/move-template-class/new_template_class_test.h -check-prefix=CHECK-NEW-TEST-H-CASE1 %s
+//
+// RUN: cp %S/Inputs/template_class_test* %T/move-template-class
+// RUN: clang-move -names="A" -new_cc=%T/move-template-class/new_template_class_test.cpp -new_header=%T/move-template-class/new_template_class_test.h -old_cc=%T/move-template-class/template_class_test.cpp -old_header=../move-template-class/template_class_test.h %T/move-template-class/template_class_test.cpp --
+// RUN: FileCheck -input-file=%T/move-template-class/template_class_test.h -check-prefix=CHECK-OLD-TEST-H-CASE2 %s
+// RUN: FileCheck -input-file=%T/move-template-class/template_class_test.cpp -check-prefix=CHECK-OLD-TEST-CPP-CASE2 %s
+// RUN: FileCheck -input-file=%T/move-template-class/new_template_class_test.h -check-prefix=CHECK-NEW-TEST-H-CASE2 %s
+// RUN: FileCheck -input-file=%T/move-template-class/new_template_class_test.cpp -check-prefix=CHECK-NEW-TEST-CPP-CASE2 %s
+//
+//
+// CHECK-OLD-TEST-EMPTY: {{^}}{{$}}
+//
+// CHECK-NEW-TEST-H-CASE1: #ifndef TEMPLATE_CLASS_TEST_H // comment 1
+// CHECK-NEW-TEST-H-CASE1: #define TEMPLATE_CLASS_TEST_H
+// CHECK-NEW-TEST-H-CASE1: template <typename T>
+// CHECK-NEW-TEST-H-CASE1: class A {
+// CHECK-NEW-TEST-H-CASE1: public:
+// CHECK-NEW-TEST-H-CASE1: void f();
+// CHECK-NEW-TEST-H-CASE1: void g();
+// CHECK-NEW-TEST-H-CASE1: template <typename U> void h();
+// CHECK-NEW-TEST-H-CASE1: template <typename U> void k();
+// CHECK-NEW-TEST-H-CASE1: static int b;
+// CHECK-NEW-TEST-H-CASE1: static int c;
+// CHECK-NEW-TEST-H-CASE1: };
+// CHECK-NEW-TEST-H-CASE1: template <typename T>
+// CHECK-NEW-TEST-H-CASE1: void A<T>::f() {}
+// CHECK-NEW-TEST-H-CASE1: template <typename T>
+// CHECK-NEW-TEST-H-CASE1: template <typename U>
+// CHECK-NEW-TEST-H-CASE1: void A<T>::h() {}
+// CHECK-NEW-TEST-H-CASE1: template <typename T>
+// CHECK-NEW-TEST-H-CASE1: int A<T>::b = 2;
+// CHECK-NEW-TEST-H-CASE1: class B {
+// CHECK-NEW-TEST-H-CASE1: public:
+// CHECK-NEW-TEST-H-CASE1: void f();
+// CHECK-NEW-TEST-H-CASE1: };
+// CHECK-NEW-TEST-H-CASE1: #endif // TEMPLATE_CLASS_TEST_H
+//
+// CHECK-NEW-TEST-CPP-CASE1: #include "{{.*}}new_template_class_test.h"
+// CHECK-NEW-TEST-CPP-CASE1: template <typename T>
+// CHECK-NEW-TEST-CPP-CASE1: void A<T>::g() {}
+// CHECK-NEW-TEST-CPP-CASE1: template <typename T>
+// CHECK-NEW-TEST-CPP-CASE1: template <typename U>
+// CHECK-NEW-TEST-CPP-CASE1: void A<T>::k() {}
+// CHECK-NEW-TEST-CPP-CASE1: template <typename T>
+// CHECK-NEW-TEST-CPP-CASE1: int A<T>::c = 2;
+// CHECK-NEW-TEST-CPP-CASE1: void B::f() {}
+//
+// CHECK-OLD-TEST-H-CASE2: #ifndef TEMPLATE_CLASS_TEST_H // comment 1
+// CHECK-OLD-TEST-H-CASE2: #define TEMPLATE_CLASS_TEST_H
+// CHECK-OLD-TEST-H-CASE2: class B {
+// CHECK-OLD-TEST-H-CASE2: public:
+// CHECK-OLD-TEST-H-CASE2: void f();
+// CHECK-OLD-TEST-H-CASE2: };
+// CHECK-OLD-TEST-H-CASE2: #endif // TEMPLATE_CLASS_TEST_H
+//
+// CHECK-OLD-TEST-CPP-CASE2: #include "template_class_test.h"
+// CHECK-OLD-TEST-CPP-CASE2: void B::f() {}
+//
+// CHECK-NEW-TEST-H-CASE2: #ifndef {{.*}}NEW_TEMPLATE_CLASS_TEST_H
+// CHECK-NEW-TEST-H-CASE2: #define {{.*}}NEW_TEMPLATE_CLASS_TEST_H
+// CHECK-NEW-TEST-H-CASE2: template <typename T>
+// CHECK-NEW-TEST-H-CASE2: class A {
+// CHECK-NEW-TEST-H-CASE2: public:
+// CHECK-NEW-TEST-H-CASE2: void f();
+// CHECK-NEW-TEST-H-CASE2: void g();
+// CHECK-NEW-TEST-H-CASE2: template <typename U> void h();
+// CHECK-NEW-TEST-H-CASE2: template <typename U> void k();
+// CHECK-NEW-TEST-H-CASE2: static int b;
+// CHECK-NEW-TEST-H-CASE2: static int c;
+// CHECK-NEW-TEST-H-CASE2: };
+// CHECK-NEW-TEST-H-CASE2: template <typename T> void A<T>::f() {}
+// CHECK-NEW-TEST-H-CASE2: template <typename T> template <typename U> void A<T>::h() {}
+// CHECK-NEW-TEST-H-CASE2: template <typename T> int A<T>::b = 2;
+// CHECK-NEW-TEST-H-CASE2: #endif // {{.*}}NEW_TEMPLATE_CLASS_TEST_H
+//
+// CHECK-NEW-TEST-CPP-CASE2: #include "{{.*}}new_template_class_test.h"
+// CHECK-NEW-TEST-CPP-CASE2: template <typename T> void A<T>::g() {}
+// CHECK-NEW-TEST-CPP-CASE2: template <typename T> template <typename U> void A<T>::k() {}
+// CHECK-NEW-TEST-CPP-CASE2: template <typename T> int A<T>::c = 2;
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/move-type-alias.cpp b/src/llvm-project/clang-tools-extra/test/clang-move/move-type-alias.cpp
new file mode 100644
index 0000000..ab70237
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/move-type-alias.cpp
@@ -0,0 +1,52 @@
+// RUN: mkdir -p %T/move-type-alias
+// RUN: cp %S/Inputs/type_alias.h %T/move-type-alias/type_alias.h
+// RUN: echo '#include "type_alias.h"' > %T/move-type-alias/type_alias.cpp
+// RUN: cd %T/move-type-alias
+//
+// -----------------------------------------------------------------------------
+// Test moving typedef declarations.
+// -----------------------------------------------------------------------------
+// RUN: clang-move -names="Int1" -new_cc=%T/move-type-alias/new_test.cpp -new_header=%T/move-type-alias/new_test.h -old_cc=%T/move-type-alias/type_alias.cpp -old_header=%T/move-type-alias/type_alias.h %T/move-type-alias/type_alias.cpp -- -std=c++11
+// RUN: FileCheck -input-file=%T/move-type-alias/new_test.h -check-prefix=CHECK-NEW-TEST-H-CASE1 %s
+// RUN: FileCheck -input-file=%T/move-type-alias/type_alias.h -check-prefix=CHECK-OLD-TEST-H-CASE1 %s
+
+// CHECK-NEW-TEST-H-CASE1: typedef int Int1;
+
+// CHECK-OLD-TEST-H-CASE1-NOT: typedef int Int1;
+
+
+// -----------------------------------------------------------------------------
+// Test moving type alias declarations.
+// -----------------------------------------------------------------------------
+// RUN: cp %S/Inputs/type_alias.h %T/move-type-alias/type_alias.h
+// RUN: echo '#include "type_alias.h"' > %T/move-type-alias/type_alias.cpp
+// RUN: clang-move -names="Int2" -new_cc=%T/move-type-alias/new_test.cpp -new_header=%T/move-type-alias/new_test.h -old_cc=%T/move-type-alias/type_alias.cpp -old_header=%T/move-type-alias/type_alias.h %T/move-type-alias/type_alias.cpp -- -std=c++11
+// RUN: FileCheck -input-file=%T/move-type-alias/new_test.h -check-prefix=CHECK-NEW-TEST-H-CASE2 %s
+// RUN: FileCheck -input-file=%T/move-type-alias/type_alias.h -check-prefix=CHECK-OLD-TEST-H-CASE2 %s
+
+// CHECK-NEW-TEST-H-CASE2: using Int2 = int;
+
+// CHECK-OLD-TEST-H-CASE2-NOT: using Int2 = int;
+
+
+// -----------------------------------------------------------------------------
+// Test moving template type alias declarations.
+// -----------------------------------------------------------------------------
+// RUN: cp %S/Inputs/type_alias.h %T/move-type-alias/type_alias.h
+// RUN: echo '#include "type_alias.h"' > %T/move-type-alias/type_alias.cpp
+// RUN: clang-move -names="B" -new_cc=%T/move-type-alias/new_test.cpp -new_header=%T/move-type-alias/new_test.h -old_cc=%T/move-type-alias/type_alias.cpp -old_header=%T/move-type-alias/type_alias.h %T/move-type-alias/type_alias.cpp -- -std=c++11
+// RUN: FileCheck -input-file=%T/move-type-alias/new_test.h -check-prefix=CHECK-OLD-TEST-H-CASE3 %s
+
+// CHECK-NEW-TEST-H-CASE3: template<class T> using B = A<T>;
+// CHECK-OLD-TEST-H-CASE3-NOT: template<class T> using B = A<T>;
+
+
+// -----------------------------------------------------------------------------
+// Test not moving class-insided typedef declarations.
+// -----------------------------------------------------------------------------
+// RUN: cp %S/Inputs/type_alias.h %T/move-type-alias/type_alias.h
+// RUN: echo '#include "type_alias.h"' > %T/move-type-alias/type_alias.cpp
+// RUN: clang-move -names="C::Int3" -new_cc=%T/move-type-alias/new_test.cpp -new_header=%T/move-type-alias/new_test.h -old_cc=%T/move-type-alias/type_alias.cpp -old_header=%T/move-type-alias/type_alias.h %T/move-type-alias/type_alias.cpp -- -std=c++11
+// RUN: FileCheck -input-file=%T/move-type-alias/new_test.h -allow-empty -check-prefix=CHECK-EMPTY %s
+
+// CHECK-EMPTY: {{^}}{{$}}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/move-used-helper-decls.cpp b/src/llvm-project/clang-tools-extra/test/clang-move/move-used-helper-decls.cpp
new file mode 100644
index 0000000..45bd4be
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/move-used-helper-decls.cpp
@@ -0,0 +1,438 @@
+// RUN: mkdir -p %T/used-helper-decls
+// RUN: cp %S/Inputs/helper_decls_test* %T/used-helper-decls/
+// RUN: cd %T/used-helper-decls
+
+// ----------------------------------------------------------------------------
+// Test moving used helper function and its transively used functions.
+// ----------------------------------------------------------------------------
+// RUN: clang-move -names="a::Class1" -new_cc=%T/used-helper-decls/new_helper_decls_test.cpp -new_header=%T/used-helper-decls/new_helper_decls_test.h -old_cc=%T/used-helper-decls/helper_decls_test.cpp -old_header=../used-helper-decls/helper_decls_test.h %T/used-helper-decls/helper_decls_test.cpp -- -std=c++11
+// RUN: FileCheck -input-file=%T/used-helper-decls/new_helper_decls_test.cpp -check-prefix=CHECK-NEW-CLASS1-CPP %s
+// RUN: FileCheck -input-file=%T/used-helper-decls/helper_decls_test.cpp -check-prefix=CHECK-OLD-CLASS1-CPP %s
+
+// CHECK-NEW-CLASS1-CPP: #include "{{.*}}new_helper_decls_test.h"
+// CHECK-NEW-CLASS1-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS1-CPP-NEXT: namespace {
+// CHECK-NEW-CLASS1-CPP-NEXT: void HelperFun1() {}
+// CHECK-NEW-CLASS1-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS1-CPP-NEXT: void HelperFun2() { HelperFun1(); }
+// CHECK-NEW-CLASS1-CPP-NEXT: } // namespace
+// CHECK-NEW-CLASS1-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS1-CPP-NEXT: namespace a {
+// CHECK-NEW-CLASS1-CPP-NEXT: void Class1::f() { HelperFun2(); }
+// CHECK-NEW-CLASS1-CPP-NEXT: } // namespace a
+//
+// CHECK-OLD-CLASS1-CPP: void HelperFun1() {}
+// CHECK-OLD-CLASS1-CPP-NOT: void HelperFun2() { HelperFun1(); }
+// CHECK-OLD-CLASS1-CPP-NOT: void Class1::f() { HelperFun2(); }
+// CHECK-OLD-CLASS1-CPP: void Class2::f() {
+// CHECK-OLD-CLASS1-CPP: HelperFun1();
+
+
+// ----------------------------------------------------------------------------
+// Test moving used helper function and its transively used static variables.
+// ----------------------------------------------------------------------------
+// RUN: cp %S/Inputs/helper_decls_test* %T/used-helper-decls/
+// RUN: clang-move -names="a::Class2" -new_cc=%T/used-helper-decls/new_helper_decls_test.cpp -new_header=%T/used-helper-decls/new_helper_decls_test.h -old_cc=%T/used-helper-decls/helper_decls_test.cpp -old_header=../used-helper-decls/helper_decls_test.h %T/used-helper-decls/helper_decls_test.cpp -- -std=c++11
+// RUN: FileCheck -input-file=%T/used-helper-decls/new_helper_decls_test.cpp -check-prefix=CHECK-NEW-CLASS2-CPP %s
+// RUN: FileCheck -input-file=%T/used-helper-decls/helper_decls_test.cpp -check-prefix=CHECK-OLD-CLASS2-CPP %s
+
+// CHECK-NEW-CLASS2-CPP: #include "{{.*}}new_helper_decls_test.h"
+// CHECK-NEW-CLASS2-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS2-CPP-NEXT: namespace {
+// CHECK-NEW-CLASS2-CPP-NEXT: void HelperFun1() {}
+// CHECK-NEW-CLASS2-CPP-NEXT: } // namespace
+// CHECK-NEW-CLASS2-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS2-CPP-NEXT: static const int K2 = 2;
+// CHECK-NEW-CLASS2-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS2-CPP-NEXT: static void HelperFun3() { K2; }
+// CHECK-NEW-CLASS2-CPP-NEXT: namespace a {
+// CHECK-NEW-CLASS2-CPP-NEXT: void Class2::f() {
+// CHECK-NEW-CLASS2-CPP-NEXT: HelperFun1();
+// CHECK-NEW-CLASS2-CPP-NEXT: HelperFun3();
+// CHECK-NEW-CLASS2-CPP-NEXT: }
+// CHECK-NEW-CLASS2-CPP-NEXT: } // namespace a
+
+// CHECK-OLD-CLASS2-CPP: void HelperFun1() {}
+// CHECK-OLD-CLASS2-CPP: void HelperFun2() { HelperFun1(); }
+// CHECK-OLD-CLASS2-CPP: const int K1 = 1;
+// CHECK-OLD-CLASS2-CPP: static const int K2 = 2;
+// CHECK-OLD-CLASS2-CPP-NOT: static void HelperFun3() { K2; }
+// CHECK-OLD-CLASS2-CPP-NOT: void Class2::f() {
+// CHECK-OLD-CLASS2-CPP-NOT: HelperFun1();
+// CHECK-OLD-CLASS2-CPP-NOT: HelperFun3();
+// CHECK-OLD-CLASS2-CPP: void Class5::f() {
+// CHECK-OLD-CLASS2-CPP-NEXT: int Result = K1 + K2 + K3;
+
+
+// ----------------------------------------------------------------------------
+// Test using a static member variable of a helper class.
+// ----------------------------------------------------------------------------
+// RUN: cp %S/Inputs/helper_decls_test* %T/used-helper-decls/
+// RUN: clang-move -names="a::Class3" -new_cc=%T/used-helper-decls/new_helper_decls_test.cpp -new_header=%T/used-helper-decls/new_helper_decls_test.h -old_cc=%T/used-helper-decls/helper_decls_test.cpp -old_header=../used-helper-decls/helper_decls_test.h %T/used-helper-decls/helper_decls_test.cpp -- -std=c++11
+// RUN: FileCheck -input-file=%T/used-helper-decls/new_helper_decls_test.cpp -check-prefix=CHECK-NEW-CLASS3-CPP %s
+// RUN: FileCheck -input-file=%T/used-helper-decls/helper_decls_test.cpp -check-prefix=CHECK-OLD-CLASS3-CPP %s
+
+// CHECK-NEW-CLASS3-CPP: #include "{{.*}}new_helper_decls_test.h"
+// CHECK-NEW-CLASS3-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS3-CPP-NEXT: namespace {
+// CHECK-NEW-CLASS3-CPP-NEXT: class HelperC1 {
+// CHECK-NEW-CLASS3-CPP-NEXT: public:
+// CHECK-NEW-CLASS3-CPP-NEXT: static int I;
+// CHECK-NEW-CLASS3-CPP-NEXT: };
+// CHECK-NEW-CLASS3-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS3-CPP-NEXT: int HelperC1::I = 0;
+// CHECK-NEW-CLASS3-CPP-NEXT: } // namespace
+// CHECK-NEW-CLASS3-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS3-CPP-NEXT: namespace a {
+// CHECK-NEW-CLASS3-CPP-NEXT: void Class3::f() { HelperC1::I; }
+// CHECK-NEW-CLASS3-CPP-NEXT: } // namespace a
+
+// CHECK-OLD-CLASS3-CPP: namespace {
+// CHECK-OLD-CLASS3-CPP-NOT: class HelperC1 {
+// CHECK-OLD-CLASS3-CPP-NOT: public:
+// CHECK-OLD-CLASS3-CPP-NOT: static int I;
+// CHECK-OLD-CLASS3-CPP-NOT: };
+// CHECK-OLD-CLASS3-CPP-NOT: int HelperC1::I = 0;
+// CHECK-OLD-CLASS3-CPP: class HelperC2 {};
+
+
+// ----------------------------------------------------------------------------
+// Test moving helper classes.
+// ----------------------------------------------------------------------------
+// RUN: cp %S/Inputs/helper_decls_test* %T/used-helper-decls/
+// RUN: clang-move -names="a::Class4" -new_cc=%T/used-helper-decls/new_helper_decls_test.cpp -new_header=%T/used-helper-decls/new_helper_decls_test.h -old_cc=%T/used-helper-decls/helper_decls_test.cpp -old_header=../used-helper-decls/helper_decls_test.h %T/used-helper-decls/helper_decls_test.cpp -- -std=c++11
+// RUN: FileCheck -input-file=%T/used-helper-decls/new_helper_decls_test.cpp -check-prefix=CHECK-NEW-CLASS4-CPP %s
+// RUN: FileCheck -input-file=%T/used-helper-decls/helper_decls_test.cpp -check-prefix=CHECK-OLD-CLASS4-CPP %s
+
+// CHECK-NEW-CLASS4-CPP: #include "{{.*}}new_helper_decls_test.h"
+// CHECK-NEW-CLASS4-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS4-CPP-NEXT: namespace {
+// CHECK-NEW-CLASS4-CPP-NEXT: class HelperC2 {};
+// CHECK-NEW-CLASS4-CPP-NEXT: } // namespace
+// CHECK-NEW-CLASS4-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS4-CPP-NEXT: namespace a {
+// CHECK-NEW-CLASS4-CPP-NEXT: void Class4::f() { HelperC2 c2; }
+// CHECK-NEW-CLASS4-CPP-NEXT: } // namespace a
+
+// CHECK-OLD-CLASS4-CPP-NOT: class HelperC2 {};
+
+
+// ----------------------------------------------------------------------------
+// Test moving helper variables and helper functions together.
+// ----------------------------------------------------------------------------
+// RUN: cp %S/Inputs/helper_decls_test* %T/used-helper-decls/
+// RUN: clang-move -names="a::Class5" -new_cc=%T/used-helper-decls/new_helper_decls_test.cpp -new_header=%T/used-helper-decls/new_helper_decls_test.h -old_cc=%T/used-helper-decls/helper_decls_test.cpp -old_header=../used-helper-decls/helper_decls_test.h %T/used-helper-decls/helper_decls_test.cpp -- -std=c++11
+// RUN: FileCheck -input-file=%T/used-helper-decls/new_helper_decls_test.cpp -check-prefix=CHECK-NEW-CLASS5-CPP %s
+// RUN: FileCheck -input-file=%T/used-helper-decls/helper_decls_test.cpp -check-prefix=CHECK-OLD-CLASS5-CPP %s
+
+// CHECK-NEW-CLASS5-CPP: #include "{{.*}}new_helper_decls_test.h"
+// CHECK-NEW-CLASS5-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS5-CPP-NEXT: namespace {
+// CHECK-NEW-CLASS5-CPP-NEXT: const int K1 = 1;
+// CHECK-NEW-CLASS5-CPP-NEXT: } // namespace
+// CHECK-NEW-CLASS5-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS5-CPP-NEXT: static const int K2 = 2;
+// CHECK-NEW-CLASS5-CPP-NEXT: namespace a {
+// CHECK-NEW-CLASS5-CPP-NEXT: static const int K3 = 3;
+// CHECK-NEW-CLASS5-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS5-CPP-NEXT: static void HelperFun4() {}
+// CHECK-NEW-CLASS5-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS5-CPP-NEXT: void Class5::f() {
+// CHECK-NEW-CLASS5-CPP-NEXT: int Result = K1 + K2 + K3;
+// CHECK-NEW-CLASS5-CPP-NEXT: HelperFun4();
+// CHECK-NEW-CLASS5-CPP-NEXT: }
+// CHECK-NEW-CLASS5-CPP-NEXT: } // namespace a
+
+// CHECK-OLD-CLASS5-CPP-NOT: const int K1 = 1;
+// CHECK-OLD-CLASS5-CPP: static const int K2 = 2;
+// CHECK-OLD-CLASS5-CPP: static void HelperFun3() { K2; }
+// CHECK-OLD-CLASS5-CPP: static const int K4 = HelperC3::I;
+// CHECK-OLD-CLASS5-CPP-NOT: void Class5::f() {
+
+
+// ----------------------------------------------------------------------------
+// Test moving helper variables and their transively used helper classes.
+// ----------------------------------------------------------------------------
+// RUN: cp %S/Inputs/helper_decls_test* %T/used-helper-decls/
+// RUN: clang-move -names="a::Class6" -new_cc=%T/used-helper-decls/new_helper_decls_test.cpp -new_header=%T/used-helper-decls/new_helper_decls_test.h -old_cc=%T/used-helper-decls/helper_decls_test.cpp -old_header=../used-helper-decls/helper_decls_test.h %T/used-helper-decls/helper_decls_test.cpp -- -std=c++11
+// RUN: FileCheck -input-file=%T/used-helper-decls/new_helper_decls_test.cpp -check-prefix=CHECK-NEW-CLASS6-CPP %s
+// RUN: FileCheck -input-file=%T/used-helper-decls/helper_decls_test.cpp -check-prefix=CHECK-OLD-CLASS6-CPP %s
+
+// CHECK-NEW-CLASS6-CPP: #include "{{.*}}new_helper_decls_test.h"
+// CHECK-NEW-CLASS6-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS6-CPP-NEXT: namespace {
+// CHECK-NEW-CLASS6-CPP-NEXT: class HelperC3 {
+// CHECK-NEW-CLASS6-CPP-NEXT: public:
+// CHECK-NEW-CLASS6-CPP-NEXT: static int I;
+// CHECK-NEW-CLASS6-CPP-NEXT: };
+// CHECK-NEW-CLASS6-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS6-CPP-NEXT: int HelperC3::I = 0;
+// CHECK-NEW-CLASS6-CPP-NEXT: } // namespace
+// CHECK-NEW-CLASS6-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS6-CPP-NEXT: namespace a {
+// CHECK-NEW-CLASS6-CPP-NEXT: static const int K4 = HelperC3::I;
+// CHECK-NEW-CLASS6-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS6-CPP-NEXT: int Class6::f() {
+// CHECK-NEW-CLASS6-CPP-NEXT: int R = K4;
+// CHECK-NEW-CLASS6-CPP-NEXT: return R;
+// CHECK-NEW-CLASS6-CPP-NEXT: }
+// CHECK-NEW-CLASS6-CPP-NEXT: } // namespace a
+
+// CHECK-OLD-CLASS6-CPP-NOT: class HelperC3 {
+// CHECK-OLD-CLASS6-CPP-NOT: int HelperC3::I = 0;
+// CHECK-OLD-CLASS6-CPP-NOT: static const int K4 = HelperC3::I;
+
+
+// ----------------------------------------------------------------------------
+// Test moving classes where its methods use helpers.
+// ----------------------------------------------------------------------------
+// RUN: cp %S/Inputs/helper_decls_test* %T/used-helper-decls/
+// RUN: clang-move -names="a::Class7" -new_cc=%T/used-helper-decls/new_helper_decls_test.cpp -new_header=%T/used-helper-decls/new_helper_decls_test.h -old_cc=%T/used-helper-decls/helper_decls_test.cpp -old_header=../used-helper-decls/helper_decls_test.h %T/used-helper-decls/helper_decls_test.cpp -- -std=c++11
+// RUN: FileCheck -input-file=%T/used-helper-decls/new_helper_decls_test.cpp -check-prefix=CHECK-NEW-CLASS7-CPP %s
+// RUN: FileCheck -input-file=%T/used-helper-decls/helper_decls_test.cpp -check-prefix=CHECK-OLD-CLASS7-CPP %s
+
+// CHECK-NEW-CLASS7-CPP: #include "{{.*}}new_helper_decls_test.h"
+// CHECK-NEW-CLASS7-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS7-CPP-NEXT: namespace a {
+// CHECK-NEW-CLASS7-CPP-NEXT: static const int K6 = 6;
+// CHECK-NEW-CLASS7-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS7-CPP-NEXT: static void HelperFun6() {}
+// CHECK-NEW-CLASS7-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS7-CPP-NEXT: int Class7::f() {
+// CHECK-NEW-CLASS7-CPP-NEXT: int R = K6;
+// CHECK-NEW-CLASS7-CPP-NEXT: return R;
+// CHECK-NEW-CLASS7-CPP-NEXT: }
+// CHECK-NEW-CLASS7-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CLASS7-CPP-NEXT: int Class7::g() {
+// CHECK-NEW-CLASS7-CPP-NEXT: HelperFun6();
+// CHECK-NEW-CLASS7-CPP-NEXT: return 1;
+// CHECK-NEW-CLASS7-CPP-NEXT: }
+// CHECK-NEW-CLASS7-CPP-NEXT: } // namespace a
+//
+// CHECK-OLD-CLASS7-CPP-NOT: static const int K6 = 6;
+// CHECK-OLD-CLASS7-CPP-NOT: static void HelperFun6() {}
+// CHECK-OLD-CLASS7-CPP-NOT: int Class7::f() {
+// CHECK-OLD-CLASS7-CPP-NOT: int Class7::g() {
+
+
+// ----------------------------------------------------------------------------
+// Test moving helper function and its transively used helper variables.
+// ----------------------------------------------------------------------------
+// RUN: cp %S/Inputs/helper_decls_test* %T/used-helper-decls/
+// RUN: clang-move -names="a::Fun1" -new_cc=%T/used-helper-decls/new_helper_decls_test.cpp -new_header=%T/used-helper-decls/new_helper_decls_test.h -old_cc=%T/used-helper-decls/helper_decls_test.cpp -old_header=../used-helper-decls/helper_decls_test.h %T/used-helper-decls/helper_decls_test.cpp -- -std=c++11
+// RUN: FileCheck -input-file=%T/used-helper-decls/new_helper_decls_test.cpp -check-prefix=CHECK-NEW-FUN1-CPP %s
+// RUN: FileCheck -input-file=%T/used-helper-decls/helper_decls_test.cpp -check-prefix=CHECK-OLD-FUN1-CPP %s
+
+// CHECK-NEW-FUN1-CPP: #include "{{.*}}new_helper_decls_test.h"
+// CHECK-NEW-FUN1-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-FUN1-CPP-NEXT: namespace a {
+// CHECK-NEW-FUN1-CPP-NEXT: static const int K5 = 5;
+// CHECK-NEW-FUN1-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-FUN1-CPP-NEXT: static int HelperFun5() {
+// CHECK-NEW-FUN1-CPP-NEXT: int R = K5;
+// CHECK-NEW-FUN1-CPP-NEXT: return R;
+// CHECK-NEW-FUN1-CPP-NEXT: }
+// CHECK-NEW-FUN1-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-FUN1-CPP-NEXT: void Fun1() { HelperFun5(); }
+// CHECK-NEW-FUN1-CPP-NEXT: } // namespace a
+
+// CHECK-OLD-FUN1-CPP-NOT: static const int K5 = 5;
+// CHECK-OLD-FUN1-CPP-NOT: static int HelperFun5() {
+// CHECK-OLD-FUN1-CPP-NOT: void Fun1() { HelperFun5(); }
+
+
+// ----------------------------------------------------------------------------
+// Test no moving helpers when moving inline functions in header.
+// ----------------------------------------------------------------------------
+// RUN: cp %S/Inputs/helper_decls_test* %T/used-helper-decls/
+// RUN: clang-move -names="a::Fun2" -new_cc=%T/used-helper-decls/new_helper_decls_test.cpp -new_header=%T/used-helper-decls/new_helper_decls_test.h -old_cc=%T/used-helper-decls/helper_decls_test.cpp -old_header=../used-helper-decls/helper_decls_test.h %T/used-helper-decls/helper_decls_test.cpp -- -std=c++11
+// RUN: FileCheck -input-file=%T/used-helper-decls/new_helper_decls_test.cpp -check-prefix=CHECK-NEW-FUN2-CPP %s
+// RUN: FileCheck -input-file=%T/used-helper-decls/new_helper_decls_test.h -check-prefix=CHECK-NEW-FUN2-H %s
+// RUN: FileCheck -input-file=%T/used-helper-decls/helper_decls_test.h -check-prefix=CHECK-OLD-FUN2-H %s
+
+// CHECK-NEW-FUN2-H: namespace a {
+// CHECK-NEW-FUN2-H-NEXT: inline void Fun2() {}
+// CHECK-NEW-FUN2-H-NEXT: } // namespace a
+
+// CHECK-NEW-FUN2-CPP: #include "{{.*}}new_helper_decls_test.h"
+// CHECK-NEW-FUN2-CPP-SAME: {{[[:space:]]}}
+
+// CHECK-OLD-FUN2-H-NOT: inline void Fun2() {}
+
+// ----------------------------------------------------------------------------
+// Test moving used helper function and its transively used functions.
+// ----------------------------------------------------------------------------
+// RUN: cp %S/Inputs/helper_decls_test* %T/used-helper-decls/
+// RUN: clang-move -names="b::Fun3" -new_cc=%T/used-helper-decls/new_helper_decls_test.cpp -new_header=%T/used-helper-decls/new_helper_decls_test.h -old_cc=%T/used-helper-decls/helper_decls_test.cpp -old_header=../used-helper-decls/helper_decls_test.h %T/used-helper-decls/helper_decls_test.cpp -- -std=c++11
+// RUN: FileCheck -input-file=%T/used-helper-decls/new_helper_decls_test.cpp -check-prefix=CHECK-NEW-FUN3-CPP %s
+// RUN: FileCheck -input-file=%T/used-helper-decls/helper_decls_test.cpp -check-prefix=CHECK-OLD-FUN3-CPP %s
+
+// CHECK-NEW-FUN3-CPP: #include "{{.*}}new_helper_decls_test.h"
+// CHECK-NEW-FUN3-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-FUN3-CPP-NEXT: namespace b {
+// CHECK-NEW-FUN3-CPP-NEXT: namespace {
+// CHECK-NEW-FUN3-CPP-NEXT: void HelperFun7();
+// CHECK-NEW-FUN3-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-FUN3-CPP-NEXT: class HelperC4;
+// CHECK-NEW-FUN3-CPP-NEXT: } // namespace
+// CHECK-NEW-FUN3-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-FUN3-CPP-NEXT: void Fun3() {
+// CHECK-NEW-FUN3-CPP-NEXT: HelperFun7();
+// CHECK-NEW-FUN3-CPP-NEXT: HelperC4 *t;
+// CHECK-NEW-FUN3-CPP-NEXT: }
+// CHECK-NEW-FUN3-CPP-NEXT: namespace {
+// CHECK-NEW-FUN3-CPP-NEXT: void HelperFun7() {}
+// CHECK-NEW-FUN3-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-FUN3-CPP-NEXT: class HelperC4 {};
+// CHECK-NEW-FUN3-CPP-NEXT: } // namespace
+// CHECK-NEW-FUN3-CPP-NEXT: } // namespace b
+//
+// CHECK-OLD-FUN3-CPP-NOT: void HelperFun7();
+// CHECK-OLD-FUN3-CPP-NOT: void HelperFun7() {}
+// CHECK-OLD-FUN3-CPP-NOT: void Fun3() { HelperFun7(); }
+
+// ----------------------------------------------------------------------------
+// Test moving all symbols in headers.
+// ----------------------------------------------------------------------------
+// RUN: cp %S/Inputs/helper_decls_test* %T/used-helper-decls/
+// RUN: clang-move -names="a::Class1, a::Class2, a::Class3, a::Class4, a::Class5, a::Class5, a::Class6, a::Class7, a::Fun1, a::Fun2, b::Fun3" -new_cc=%T/used-helper-decls/new_helper_decls_test.cpp -new_header=%T/used-helper-decls/new_helper_decls_test.h -old_cc=%T/used-helper-decls/helper_decls_test.cpp -old_header=../used-helper-decls/helper_decls_test.h %T/used-helper-decls/helper_decls_test.cpp -- -std=c++11
+// RUN: FileCheck -input-file=%T/used-helper-decls/new_helper_decls_test.h -check-prefix=CHECK-NEW-H %s
+// RUN: FileCheck -input-file=%T/used-helper-decls/new_helper_decls_test.cpp -check-prefix=CHECK-NEW-CPP %s
+// RUN: FileCheck -input-file=%T/used-helper-decls/helper_decls_test.h -allow-empty -check-prefix=CHECK-EMPTY %s
+// RUN: FileCheck -input-file=%T/used-helper-decls/helper_decls_test.cpp -allow-empty -check-prefix=CHECK-EMPTY %s
+
+
+// CHECK-NEW-H: namespace a {
+// CHECK-NEW-H-NEXT: class Class1 {
+// CHECK-NEW-H-NEXT: void f();
+// CHECK-NEW-H-NEXT: };
+// CHECK-NEW-H-SAME: {{[[:space:]]}}
+// CHECK-NEW-H-NEXT: class Class2 {
+// CHECK-NEW-H-NEXT: void f();
+// CHECK-NEW-H-NEXT: };
+// CHECK-NEW-H-SAME: {{[[:space:]]}}
+// CHECK-NEW-H-NEXT: class Class3 {
+// CHECK-NEW-H-NEXT: void f();
+// CHECK-NEW-H-NEXT: };
+// CHECK-NEW-H-SAME: {{[[:space:]]}}
+// CHECK-NEW-H-NEXT: class Class4 {
+// CHECK-NEW-H-NEXT: void f();
+// CHECK-NEW-H-NEXT: };
+// CHECK-NEW-H-SAME: {{[[:space:]]}}
+// CHECK-NEW-H-NEXT: class Class5 {
+// CHECK-NEW-H-NEXT: void f();
+// CHECK-NEW-H-NEXT: };
+// CHECK-NEW-H-SAME: {{[[:space:]]}}
+// CHECK-NEW-H-NEXT: class Class6 {
+// CHECK-NEW-H-NEXT: int f();
+// CHECK-NEW-H-NEXT: };
+// CHECK-NEW-H-SAME: {{[[:space:]]}}
+// CHECK-NEW-H-NEXT: class Class7 {
+// CHECK-NEW-H-NEXT: int f();
+// CHECK-NEW-H-NEXT: int g();
+// CHECK-NEW-H-NEXT: };
+// CHECK-NEW-H-SAME: {{[[:space:]]}}
+// CHECK-NEW-H-NEXT: void Fun1();
+// CHECK-NEW-H-SAME: {{[[:space:]]}}
+// CHECK-NEW-H-NEXT: inline void Fun2() {}
+// CHECK-NEW-H-SAME: {{[[:space:]]}}
+// CHECK-NEW-H-NEXT: } // namespace a
+
+
+// CHECK-NEW-CPP: namespace {
+// CHECK-NEW-CPP-NEXT: class HelperC1 {
+// CHECK-NEW-CPP-NEXT: public:
+// CHECK-NEW-CPP-NEXT: static int I;
+// CHECK-NEW-CPP-NEXT: };
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: int HelperC1::I = 0;
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: class HelperC2 {};
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: class HelperC3 {
+// CHECK-NEW-CPP-NEXT: public:
+// CHECK-NEW-CPP-NEXT: static int I;
+// CHECK-NEW-CPP-NEXT: };
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: int HelperC3::I = 0;
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: void HelperFun1() {}
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: void HelperFun2() { HelperFun1(); }
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: const int K1 = 1;
+// CHECK-NEW-CPP-NEXT: } // namespace
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: static const int K2 = 2;
+// CHECK-NEW-CPP-NEXT: static void HelperFun3() { K2; }
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: namespace a {
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: static const int K3 = 3;
+// CHECK-NEW-CPP-NEXT: static const int K4 = HelperC3::I;
+// CHECK-NEW-CPP-NEXT: static const int K5 = 5;
+// CHECK-NEW-CPP-NEXT: static const int K6 = 6;
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: static void HelperFun4() {}
+// CHECK-NEW-CPP-NEXT: static void HelperFun6() {}
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: void Class1::f() { HelperFun2(); }
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: void Class2::f() {
+// CHECK-NEW-CPP-NEXT: HelperFun1();
+// CHECK-NEW-CPP-NEXT: HelperFun3();
+// CHECK-NEW-CPP-NEXT: }
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: void Class3::f() { HelperC1::I; }
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: void Class4::f() { HelperC2 c2; }
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: void Class5::f() {
+// CHECK-NEW-CPP-NEXT: int Result = K1 + K2 + K3;
+// CHECK-NEW-CPP-NEXT: HelperFun4();
+// CHECK-NEW-CPP-NEXT: }
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: int Class6::f() {
+// CHECK-NEW-CPP-NEXT: int R = K4;
+// CHECK-NEW-CPP-NEXT: return R;
+// CHECK-NEW-CPP-NEXT: }
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: int Class7::f() {
+// CHECK-NEW-CPP-NEXT: int R = K6;
+// CHECK-NEW-CPP-NEXT: return R;
+// CHECK-NEW-CPP-NEXT: }
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: int Class7::g() {
+// CHECK-NEW-CPP-NEXT: HelperFun6();
+// CHECK-NEW-CPP-NEXT: return 1;
+// CHECK-NEW-CPP-NEXT: }
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: static int HelperFun5() {
+// CHECK-NEW-CPP-NEXT: int R = K5;
+// CHECK-NEW-CPP-NEXT: return R;
+// CHECK-NEW-CPP-NEXT: }
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: void Fun1() { HelperFun5(); }
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: } // namespace a
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: namespace b {
+// CHECK-NEW-CPP-NEXT: namespace {
+// CHECK-NEW-CPP-NEXT: void HelperFun7();
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: class HelperC4;
+// CHECK-NEW-CPP-NEXT: } // namespace
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: void Fun3() {
+// CHECK-NEW-CPP-NEXT: HelperFun7();
+// CHECK-NEW-CPP-NEXT: HelperC4 *t;
+// CHECK-NEW-CPP-NEXT: }
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: namespace {
+// CHECK-NEW-CPP-NEXT: void HelperFun7() {}
+// CHECK-NEW-CPP-SAME: {{[[:space:]]}}
+// CHECK-NEW-CPP-NEXT: class HelperC4 {};
+// CHECK-NEW-CPP-NEXT: } // namespace
+// CHECK-NEW-CPP-NEXT: } // namespace b
+
+// CHECK-EMPTY: {{^}}{{$}}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/move-var.cpp b/src/llvm-project/clang-tools-extra/test/clang-move/move-var.cpp
new file mode 100644
index 0000000..4a3554c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/move-var.cpp
@@ -0,0 +1,46 @@
+// RUN: mkdir -p %T/move-var
+// RUN: cp %S/Inputs/var_test* %T/move-var
+// RUN: cd %T/move-var
+// RUN: clang-move -names="a::kGlobalInt" -new_header=%T/move-var/new_var_test.h -old_header=../move-var/var_test.h -old_cc=../move-var/var_test.cpp -new_cc=%T/move-var/new_var_test.cpp %T/move-var/var_test.cpp --
+// RUN: FileCheck -input-file=%T/move-var/var_test.h -check-prefix=CHECK-OLD-VAR-H-CASE1 %s
+// RUN: FileCheck -input-file=%T/move-var/var_test.cpp -check-prefix=CHECK-OLD-VAR-CPP-CASE1 %s
+// RUN: FileCheck -input-file=%T/move-var/new_var_test.h -check-prefix=CHECK-NEW-VAR-H-CASE1 %s
+// RUN: FileCheck -input-file=%T/move-var/new_var_test.cpp -check-prefix=CHECK-NEW-VAR-CPP-CASE1 %s
+
+// CHECK-OLD-VAR-H-CASE1-NOT: extern int kGlobalInt;
+// CHECK-OLD-VAR-H-CASE1: int kGlobalInt = 3;
+
+// CHECK-OLD-VAR-CPP-CASE1-NOT: int kGlobalInt = 1;
+
+// CHECK-NEW-VAR-H-CASE1: extern int kGlobalInt;
+// CHECK-NEW-VAR-H-CASE1-NOT: int kGlobalInt = 3;
+
+// CHECK-NEW-VAR-CPP-CASE1: int kGlobalInt = 1;
+
+
+// RUN: cp %S/Inputs/var_test* %T/move-var
+// RUN: clang-move -names="a::kGlobalStr" -new_header=%T/move-var/new_var_test.h -old_header=../move-var/var_test.h -old_cc=../move-var/var_test.cpp -new_cc=%T/move-var/new_var_test.cpp %T/move-var/var_test.cpp --
+// RUN: FileCheck -input-file=%T/move-var/var_test.h -check-prefix=CHECK-OLD-VAR-H-CASE2 %s
+// RUN: FileCheck -input-file=%T/move-var/var_test.cpp -check-prefix=CHECK-OLD-VAR-CPP-CASE2 %s
+// RUN: FileCheck -input-file=%T/move-var/new_var_test.h -check-prefix=CHECK-NEW-VAR-H-CASE2 %s
+// RUN: FileCheck -input-file=%T/move-var/new_var_test.cpp -check-prefix=CHECK-NEW-VAR-CPP-CASE2 %s
+
+// CHECK-OLD-VAR-H-CASE2-NOT: extern const char *const kGlobalStr;
+// CHECK-OLD-VAR-H-CASE2: const char *const kGlobalStr = "Hello2";
+
+// CHECK-OLD-VAR-CPP-CASE2-NOT: const char *const kGlobalStr = "Hello";
+
+// CHECK-NEW-VAR-H-CASE2: extern const char *const kGlobalStr;
+// CHECK-NEW-VAR-H-CASE2-NOT: const char *const kGlobalStr = "Hello2";
+
+// CHECK-NEW-VAR-CPP-CASE2: const char *const kGlobalStr = "Hello";
+
+
+// RUN: cp %S/Inputs/var_test* %T/move-var
+// RUN: clang-move -names="kEvilInt" -new_header=%T/move-var/new_var_test.h -old_header=../move-var/var_test.h -old_cc=../move-var/var_test.cpp -new_cc=%T/move-var/new_var_test.cpp %T/move-var/var_test.cpp --
+// RUN: FileCheck -input-file=%T/move-var/var_test.h -check-prefix=CHECK-OLD-VAR-H-CASE3 %s
+// RUN: FileCheck -input-file=%T/move-var/new_var_test.h -check-prefix=CHECK-NEW-VAR-H-CASE3 %s
+
+// CHECK-OLD-VAR-H-CASE3-NOT: int kEvilInt = 2;
+
+// CHECK-NEW-VAR-H-CASE3: int kEvilInt = 2;
diff --git a/src/llvm-project/clang-tools-extra/test/clang-move/no-move-macro-helpers.cpp b/src/llvm-project/clang-tools-extra/test/clang-move/no-move-macro-helpers.cpp
new file mode 100644
index 0000000..282eee0
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-move/no-move-macro-helpers.cpp
@@ -0,0 +1,43 @@
+// RUN: mkdir -p %T/no-move-macro-helper
+// RUN: cat %S/Inputs/macro_helper_test.h > %T/no-move-macro-helper/macro_helper_test.h
+// RUN: cat %S/Inputs/macro_helper_test.cpp > %T/no-move-macro-helper/macro_helper_test.cpp
+// RUN: cd %T/no-move-macro-helper
+//
+// -----------------------------------------------------------------------------
+// Test no moving helpers in macro.
+// -----------------------------------------------------------------------------
+// RUN: clang-move -names="A" -new_cc=%T/no-move-macro-helper/new_test.cpp -new_header=%T/no-move-macro-helper/new_test.h -old_cc=%T/no-move-macro-helper/macro_helper_test.cpp -old_header=%T/no-move-macro-helper/macro_helper_test.h %T/no-move-macro-helper/macro_helper_test.cpp -- -std=c++11
+// RUN: FileCheck -input-file=%T/no-move-macro-helper/new_test.h -check-prefix=CHECK-NEW-TEST-CASE1-H %s
+// RUN: FileCheck -input-file=%T/no-move-macro-helper/new_test.cpp -check-prefix=CHECK-NEW-TEST-CASE1-CPP %s
+// RUN: FileCheck -input-file=%T/no-move-macro-helper/macro_helper_test.h -check-prefix=CHECK-OLD-TEST-CASE1-H %s
+// RUN: FileCheck -input-file=%T/no-move-macro-helper/macro_helper_test.cpp -check-prefix=CHECK-OLD-TEST-CASE1-CPP %s
+
+// CHECK-NEW-TEST-CASE1-H: class A {};
+
+// CHECK-OLD-TEST-CASE1-H-NOT: class A {};
+
+// CHECK-OLD-TEST-CASE1-CPP: DEFINE(test)
+
+// CHECK-NEW-TEST-CASE1-CPP-NOT: DEFINE(test)
+
+
+// -----------------------------------------------------------------------------
+// Test moving all.
+// -----------------------------------------------------------------------------
+// RUN: cat %S/Inputs/macro_helper_test.h > %T/no-move-macro-helper/macro_helper_test.h
+// RUN: cat %S/Inputs/macro_helper_test.cpp > %T/no-move-macro-helper/macro_helper_test.cpp
+// RUN: clang-move -names="A, f1" -new_cc=%T/no-move-macro-helper/new_test.cpp -new_header=%T/no-move-macro-helper/new_test.h -old_cc=%T/no-move-macro-helper/macro_helper_test.cpp -old_header=%T/no-move-macro-helper/macro_helper_test.h %T/no-move-macro-helper/macro_helper_test.cpp -- -std=c++11
+//
+// RUN: FileCheck -input-file=%T/no-move-macro-helper/new_test.h -check-prefix=CHECK-NEW-TEST-CASE2-H %s
+// RUN: FileCheck -input-file=%T/no-move-macro-helper/new_test.cpp -check-prefix=CHECK-NEW-TEST-CASE2-CPP %s
+// RUN: FileCheck -input-file=%T/no-move-macro-helper/macro_helper_test.h -allow-empty -check-prefix=CHECK-EMPTY %s
+// RUN: FileCheck -input-file=%T/no-move-macro-helper/macro_helper_test.cpp -allow-empty -check-prefix=CHECK-EMPTY %s
+
+// CHECK-NEW-TEST-CASE2-H: class A {};
+// CHECK-NEW-TEST-CASE2-H-NEXT:void f1();
+
+
+// CHECK-NEW-TEST-CASE2-CPP: DEFINE(test)
+// CHECK-NEW-TEST-CASE2-CPP: void f1() {}
+
+// CHECK-EMPTY: {{^}}{{$}}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-query/Inputs/foo.script b/src/llvm-project/clang-tools-extra/test/clang-query/Inputs/foo.script
new file mode 100644
index 0000000..3bd1f0e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-query/Inputs/foo.script
@@ -0,0 +1,2 @@
+foo
+bar
diff --git a/src/llvm-project/clang-tools-extra/test/clang-query/errors.c b/src/llvm-project/clang-tools-extra/test/clang-query/errors.c
new file mode 100644
index 0000000..bbb7421
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-query/errors.c
@@ -0,0 +1,10 @@
+// RUN: not clang-query -c foo -c bar %s -- | FileCheck %s
+// RUN: not clang-query -f %S/Inputs/foo.script %s -- | FileCheck %s
+// RUN: not clang-query -f %S/Inputs/nonexistent.script %s -- 2>&1 | FileCheck --check-prefix=CHECK-NONEXISTENT %s
+// RUN: not clang-query -c foo -f foo %s -- 2>&1 | FileCheck --check-prefix=CHECK-BOTH %s
+
+// CHECK: unknown command: foo
+// CHECK-NOT: unknown command: bar
+
+// CHECK-NONEXISTENT: cannot open {{.*}}nonexistent.script
+// CHECK-BOTH: cannot specify both -c and -f
diff --git a/src/llvm-project/clang-tools-extra/test/clang-query/function-decl.c b/src/llvm-project/clang-tools-extra/test/clang-query/function-decl.c
new file mode 100644
index 0000000..f35cba0
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-query/function-decl.c
@@ -0,0 +1,4 @@
+// RUN: clang-query -c "match functionDecl()" %s -- | FileCheck %s
+
+// CHECK: function-decl.c:4:1: note: "root" binds here
+void foo(void) {}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/AggregatePartialInitialization.cpp b/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/AggregatePartialInitialization.cpp
new file mode 100644
index 0000000..9d09c81
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/AggregatePartialInitialization.cpp
@@ -0,0 +1,14 @@
+// RUN: clang-reorder-fields -record-name Foo -fields-order z,y,x %s -- | FileCheck %s
+
+// The order of fields should not change.
+class Foo {
+public:
+ int x; // CHECK: {{^ int x;}}
+ int y; // CHECK-NEXT: {{^ int y;}}
+ int z; // CHECK-NEXT: {{^ int z;}}
+};
+
+int main() {
+ Foo foo = { 0, 1 }; // CHECK: {{^ Foo foo = { 0, 1 };}}
+ return 0;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/CStructAmbiguousName.cpp b/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/CStructAmbiguousName.cpp
new file mode 100644
index 0000000..e1e6645
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/CStructAmbiguousName.cpp
@@ -0,0 +1,18 @@
+// RUN: clang-reorder-fields -record-name ::Foo -fields-order y,x %s -- | FileCheck %s
+
+struct Foo {
+ int x; // CHECK: {{^ double y;}}
+ double y; // CHECK-NEXT: {{^ int x;}}
+};
+
+namespace bar {
+struct Foo {
+ int x; // CHECK: {{^ int x;}}
+ double y; // CHECK-NEXT: {{^ double y;}}
+};
+} // end namespace bar
+
+int main() {
+ bar::Foo foo = { 1, 1.7 }; // CHECK: {{^ bar::Foo foo = { 1, 1.7 };}}
+ return 0;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/CStructFieldsOrder.cpp b/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/CStructFieldsOrder.cpp
new file mode 100644
index 0000000..2ed3578
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/CStructFieldsOrder.cpp
@@ -0,0 +1,16 @@
+// RUN: clang-reorder-fields -record-name ::bar::Foo -fields-order z,w,y,x %s -- | FileCheck %s
+
+namespace bar {
+struct Foo {
+ const int* x; // CHECK: {{^ double z;}}
+ int y; // CHECK-NEXT: {{^ int w;}}
+ double z; // CHECK-NEXT: {{^ int y;}}
+ int w; // CHECK-NEXT: {{^ const int\* x}}
+};
+} // end namespace bar
+
+int main() {
+ const int x = 13;
+ bar::Foo foo = { &x, 0, 1.29, 17 }; // CHECK: {{^ bar::Foo foo = { 1.29, 17, 0, &x };}}
+ return 0;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/ClassDerived.cpp b/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/ClassDerived.cpp
new file mode 100644
index 0000000..e7e9ac1
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/ClassDerived.cpp
@@ -0,0 +1,33 @@
+// RUN: clang-reorder-fields -record-name bar::Derived -fields-order z,y %s -- | FileCheck %s
+
+namespace bar {
+class Base {
+public:
+ Base(int nx, int np) : x(nx), p(np) {}
+ int x;
+ int p;
+};
+
+
+class Derived : public Base {
+public:
+ Derived(long ny);
+ Derived(char nz);
+private:
+ long y;
+ char z;
+};
+
+Derived::Derived(long ny) :
+ Base(ny, 0),
+ y(ny), // CHECK: {{^ z\(static_cast<char>\(ny\)\),}}
+ z(static_cast<char>(ny)) // CHECK-NEXT: {{^ y\(ny\)}}
+{}
+
+Derived::Derived(char nz) :
+ Base(1, 2),
+ y(nz), // CHECK: {{^ z\(x\),}}
+ z(x) // CHECK-NEXT: {{^ y\(nz\)}}
+{}
+
+} // namespace bar
diff --git a/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/ClassDifferentFieldsAccesses.cpp b/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/ClassDifferentFieldsAccesses.cpp
new file mode 100644
index 0000000..dd0a555
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/ClassDifferentFieldsAccesses.cpp
@@ -0,0 +1,16 @@
+// RUN: clang-reorder-fields -record-name Foo -fields-order z,y,x %s -- | FileCheck %s
+
+// The order of fields should not change.
+class Foo {
+public:
+ int x; // CHECK: {{^ int x;}}
+
+private:
+ int y; // CHECK: {{^ int y;}}
+ int z; // CHECK-NEXT: {{^ int z;}}
+};
+
+int main() {
+ Foo foo;
+ return 0;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/ClassMixedInitialization.cpp b/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/ClassMixedInitialization.cpp
new file mode 100644
index 0000000..888649a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/ClassMixedInitialization.cpp
@@ -0,0 +1,24 @@
+// RUN: clang-reorder-fields -record-name Foo -fields-order e,x,pi,s2,s1 %s -- -std=c++11 | FileCheck %s
+
+class Foo {
+public:
+ Foo();
+
+private:
+ int x; // CHECK: {{^ double e = 2.71;}}
+ const char *s1; // CHECK-NEXT: {{^ int x;}}
+ const char *s2; // CHECK-NEXT: {{^ double pi = 3.14;}}
+ double pi = 3.14; // CHECK-NEXT: {{^ const char \*s2;}}
+ double e = 2.71; // CHECK-NEXT: {{^ const char \*s1;}}
+};
+
+Foo::Foo():
+ x(12), // CHECK: {{^ x\(12\)}},
+ s1("abc"), // CHECK-NEXT: {{^ s2\("def"\)}},
+ s2("def") // CHECK-NEXT: {{^ s1\("abc"\)}}
+{}
+
+int main() {
+ Foo foo;
+ return 0;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/ClassSimpleCtor.cpp b/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/ClassSimpleCtor.cpp
new file mode 100644
index 0000000..6dc2722
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/ClassSimpleCtor.cpp
@@ -0,0 +1,24 @@
+// RUN: clang-reorder-fields -record-name Foo -fields-order s1,x,z,s2 %s -- | FileCheck %s
+
+class Foo {
+public:
+ Foo();
+
+private:
+ int x; // CHECK: {{^ const char \*s1;}}
+ const char *s1; // CHECK-NEXT: {{^ int x;}}
+ const char *s2; // CHECK-NEXT: {{^ double z;}}
+ double z; // CHECK-NEXT: {{^ const char \*s2;}}
+};
+
+Foo::Foo():
+ x(12), // CHECK: {{^ s1\("abc"\),}}
+ s1("abc"), // CHECK-NEXT: {{^ x\(12\),}}
+ s2("def"), // CHECK-NEXT: {{^ z\(3.14\),}}
+ z(3.14) // CHECK-NEXT: {{^ s2\("def"\)}}
+{}
+
+int main() {
+ Foo foo;
+ return 0;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/FieldDependencyWarning.cpp b/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/FieldDependencyWarning.cpp
new file mode 100644
index 0000000..bbe0e7f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/FieldDependencyWarning.cpp
@@ -0,0 +1,54 @@
+// RUN: clang-reorder-fields -record-name bar::Foo -fields-order y,z,c,x %s -- 2>&1 | FileCheck --check-prefix=CHECK-MESSAGES %s
+// FIXME: clang-reorder-fields should provide -verify mode to make writing these checks
+// easier and more accurate, for now we follow clang-tidy's approach.
+
+namespace bar {
+
+struct Dummy {
+ Dummy(int x, char c) : x(x), c(c) {}
+ int x;
+ char c;
+};
+
+class Foo {
+public:
+ Foo(int x, double y, char cin);
+ Foo(int nx);
+ Foo();
+ int x;
+ double y;
+ char c;
+ Dummy z;
+};
+
+static char bar(char c) {
+ return c + 1;
+}
+
+Foo::Foo() : x(), y(), c(), z(0, 'a') {}
+
+Foo::Foo(int x, double y, char cin) :
+ x(x),
+ y(y),
+ c(cin),
+ z(this->x, bar(c))
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: reordering field x after z makes x uninitialized when used in init expression
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: reordering field c after z makes c uninitialized when used in init expression
+{}
+
+Foo::Foo(int nx) :
+ x(nx),
+ y(x),
+ c(0),
+ z(bar(bar(x)), c)
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: reordering field x after y makes x uninitialized when used in init expression
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: reordering field x after z makes x uninitialized when used in init expression
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: reordering field c after z makes c uninitialized when used in init expression
+{}
+
+} // namespace bar
+
+int main() {
+ bar::Foo F(5, 12.8, 'c');
+ return 0;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/FieldDependencyWarningDerived.cpp b/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/FieldDependencyWarningDerived.cpp
new file mode 100644
index 0000000..bbc58ae
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/FieldDependencyWarningDerived.cpp
@@ -0,0 +1,36 @@
+// RUN: clang-reorder-fields -record-name bar::Derived -fields-order z,y %s -- 2>&1 | FileCheck --check-prefix=CHECK-MESSAGES %s
+// FIXME: clang-reorder-fields should provide -verify mode to make writing these checks
+// easier and more accurate, for now we follow clang-tidy's approach.
+
+namespace bar {
+struct Base {
+ int x;
+ int p;
+};
+
+class Derived : public Base {
+public:
+ Derived(long ny);
+ Derived(char nz);
+private:
+ long y;
+ char z;
+};
+
+Derived::Derived(long ny) :
+ Base(),
+ y(ny),
+ z(static_cast<char>(y))
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: reordering field y after z makes y uninitialized when used in init expression
+{}
+
+Derived::Derived(char nz) :
+ Base(),
+ y(nz),
+ // Check that base class fields are correctly ignored in reordering checks
+ // x has field index 1 and so would improperly warn if this wasn't the case since the command for this file swaps field indexes 1 and 2
+ z(x)
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:3: warning: reordering field x after z makes x uninitialized when used in init expression
+{}
+
+} // namespace bar
diff --git a/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/PlainCStructFieldsOrder.c b/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/PlainCStructFieldsOrder.c
new file mode 100644
index 0000000..5b4fe9e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-reorder-fields/PlainCStructFieldsOrder.c
@@ -0,0 +1,14 @@
+// RUN: clang-reorder-fields -record-name Foo -fields-order z,w,y,x %s -- | FileCheck %s
+
+struct Foo {
+ const int* x; // CHECK: {{^ double z;}}
+ int y; // CHECK-NEXT: {{^ int w;}}
+ double z; // CHECK-NEXT: {{^ int y;}}
+ int w; // CHECK-NEXT: {{^ const int\* x}}
+};
+
+int main() {
+ const int x = 13;
+ struct Foo foo = { &x, 0, 1.29, 17 }; // CHECK: {{^ struct Foo foo = { 1.29, 17, 0, &x };}}
+ return 0;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/a.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/a.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/a.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/b.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/b.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/b.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/clang-c/c.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/clang-c/c.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/clang-c/c.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/clang/b.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/clang/b.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/clang/b.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/cross-file-a.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/cross-file-a.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/cross-file-a.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/cross-file-b.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/cross-file-b.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/cross-file-b.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/cross-file-c.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/cross-file-c.h
new file mode 100644
index 0000000..342dd34
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/cross-file-c.h
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// The line number of the following include should match the location of the
+// corresponding comment in llvm-include-order.cpp
+#include "cross-file-b.h"
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/gtest/foo.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/gtest/foo.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/gtest/foo.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/i.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/i.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/i.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/j.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/j.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/j.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/llvm-c/d.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/llvm-c/d.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/llvm-c/d.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/llvm/a.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/llvm/a.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/llvm/a.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/s.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/s.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/s.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/system-header-simulation.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/system-header-simulation.h
new file mode 100644
index 0000000..0df5305
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/Headers/system-header-simulation.h
@@ -0,0 +1,24 @@
+#pragma clang system_header
+
+namespace std {
+
+template<class T, T v>
+struct integral_constant {
+ static constexpr T value = v;
+ typedef T value_type;
+ typedef integral_constant type;
+ constexpr operator value_type() const noexcept { return value; }
+};
+
+template <bool B>
+using bool_constant = integral_constant<bool, B>;
+using true_type = bool_constant<true>;
+using false_type = bool_constant<false>;
+
+template<class T>
+struct is_error_code_enum : false_type {};
+
+template<class T>
+void swap(T &a, T &b);
+}
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/absl/external-file.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/absl/external-file.h
new file mode 100644
index 0000000..11e2e4a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/absl/external-file.h
@@ -0,0 +1,6 @@
+namespace absl {
+namespace base_internal {
+void InternalFunction() {}
+} // namespace base_internal
+} //namespace absl
+void DirectAccess2() { absl::base_internal::InternalFunction(); }
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/absl/flags/internal-file.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/absl/flags/internal-file.h
new file mode 100644
index 0000000..c81cf9e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/absl/flags/internal-file.h
@@ -0,0 +1 @@
+#define USE_INTERNAL(x) absl::strings_internal::Internal##x()
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/absl/strings/internal-file.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/absl/strings/internal-file.h
new file mode 100644
index 0000000..6014278
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/absl/strings/internal-file.h
@@ -0,0 +1,33 @@
+namespace std {
+struct string {
+ string(const char *);
+ ~string();
+};
+} // namespace std
+
+namespace absl {
+std::string StringsFunction(std::string s1) { return s1; }
+class SomeContainer {};
+namespace strings_internal {
+void InternalFunction() {}
+template <class P> P InternalTemplateFunction(P a) {}
+} // namespace strings_internal
+
+namespace container_internal {
+struct InternalStruct {};
+} // namespace container_internal
+} // namespace absl
+
+// should not trigger warnings because inside Abseil files
+void DirectAcessInternal() {
+ absl::strings_internal::InternalFunction();
+ absl::strings_internal::InternalTemplateFunction<std::string>("a");
+}
+
+class FriendUsageInternal {
+ friend struct absl::container_internal::InternalStruct;
+};
+
+namespace absl {
+void OpeningNamespaceInternally() { strings_internal::InternalFunction(); }
+} // namespace absl
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/absl/time/time.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/absl/time/time.h
new file mode 100644
index 0000000..9d136a5d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/absl/time/time.h
@@ -0,0 +1,72 @@
+// Mimic the implementation of absl::Duration
+namespace absl {
+
+using int64_t = long long int;
+
+class Duration {
+public:
+ Duration &operator*=(int64_t r);
+ Duration &operator*=(float r);
+ Duration &operator*=(double r);
+ template <typename T> Duration &operator*=(T r);
+
+ Duration &operator/=(int64_t r);
+ Duration &operator/=(float r);
+ Duration &operator/=(double r);
+ template <typename T> Duration &operator/=(T r);
+};
+
+template <typename T> Duration operator*(Duration lhs, T rhs);
+template <typename T> Duration operator*(T lhs, Duration rhs);
+template <typename T> Duration operator/(Duration lhs, T rhs);
+
+class Time{};
+
+constexpr Duration Nanoseconds(long long);
+constexpr Duration Microseconds(long long);
+constexpr Duration Milliseconds(long long);
+constexpr Duration Seconds(long long);
+constexpr Duration Minutes(long long);
+constexpr Duration Hours(long long);
+
+template <typename T> struct EnableIfFloatImpl {};
+template <> struct EnableIfFloatImpl<float> { typedef int Type; };
+template <> struct EnableIfFloatImpl<double> { typedef int Type; };
+template <> struct EnableIfFloatImpl<long double> { typedef int Type; };
+template <typename T> using EnableIfFloat = typename EnableIfFloatImpl<T>::Type;
+
+template <typename T, EnableIfFloat<T> = 0> Duration Nanoseconds(T n);
+template <typename T, EnableIfFloat<T> = 0> Duration Microseconds(T n);
+template <typename T, EnableIfFloat<T> = 0> Duration Milliseconds(T n);
+template <typename T, EnableIfFloat<T> = 0> Duration Seconds(T n);
+template <typename T, EnableIfFloat<T> = 0> Duration Minutes(T n);
+template <typename T, EnableIfFloat<T> = 0> Duration Hours(T n);
+
+double ToDoubleHours(Duration d);
+double ToDoubleMinutes(Duration d);
+double ToDoubleSeconds(Duration d);
+double ToDoubleMilliseconds(Duration d);
+double ToDoubleMicroseconds(Duration d);
+double ToDoubleNanoseconds(Duration d);
+int64_t ToInt64Hours(Duration d);
+int64_t ToInt64Minutes(Duration d);
+int64_t ToInt64Seconds(Duration d);
+int64_t ToInt64Milliseconds(Duration d);
+int64_t ToInt64Microseconds(Duration d);
+int64_t ToInt64Nanoseconds(Duration d);
+
+// Relational Operators
+constexpr bool operator<(Duration lhs, Duration rhs);
+constexpr bool operator>(Duration lhs, Duration rhs);
+constexpr bool operator>=(Duration lhs, Duration rhs);
+constexpr bool operator<=(Duration lhs, Duration rhs);
+constexpr bool operator==(Duration lhs, Duration rhs);
+constexpr bool operator!=(Duration lhs, Duration rhs);
+
+// Additive Operators
+inline Time operator+(Time lhs, Duration rhs);
+inline Time operator+(Duration lhs, Time rhs);
+inline Time operator-(Time lhs, Duration rhs);
+inline Duration operator-(Time lhs, Time rhs);
+
+} // namespace absl
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/compilation-database/template.json b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/compilation-database/template.json
new file mode 100644
index 0000000..74275d9
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/compilation-database/template.json
@@ -0,0 +1,32 @@
+[
+{
+ "directory": "test_dir/a",
+ "command": "clang++ -o test.o test_dir/a/a.cpp",
+ "file": "test_dir/a/a.cpp"
+},
+{
+ "directory": "test_dir/a",
+ "command": "clang++ -o test.o test_dir/a/b.cpp",
+ "file": "test_dir/a/b.cpp"
+},
+{
+ "directory": "test_dir/",
+ "command": "clang++ -o test.o test_dir/b/b.cpp",
+ "file": "test_dir/b/b.cpp"
+},
+{
+ "directory": "test_dir/b",
+ "command": "clang++ -o test.o ../b/c.cpp",
+ "file": "test_dir/b/c.cpp"
+},
+{
+ "directory": "test_dir/b",
+ "command": "clang++ -I../include -o test.o ../b/d.cpp",
+ "file": "test_dir/b/d.cpp"
+},
+{
+ "directory": "test_dir/",
+ "command": "clang++ -o test.o test_dir/b/not-exist.cpp",
+ "file": "test_dir/b/not-exist.cpp"
+}
+]
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/config-files/.clang-tidy b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/config-files/.clang-tidy
new file mode 100644
index 0000000..942169f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/config-files/.clang-tidy
@@ -0,0 +1,2 @@
+Checks: 'from-parent'
+HeaderFilterRegex: 'parent'
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/config-files/1/.clang-tidy b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/config-files/1/.clang-tidy
new file mode 100644
index 0000000..800fd4e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/config-files/1/.clang-tidy
@@ -0,0 +1,2 @@
+Checks: 'from-child1'
+HeaderFilterRegex: 'child1'
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/explain-config/.clang-tidy b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/explain-config/.clang-tidy
new file mode 100644
index 0000000..4fbd09c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/explain-config/.clang-tidy
@@ -0,0 +1 @@
+Checks: '-*,modernize-use-nullptr'
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/file-filter/header1.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/file-filter/header1.h
new file mode 100644
index 0000000..ba9e3d1
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/file-filter/header1.h
@@ -0,0 +1 @@
+class A1 { A1(int); };
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/file-filter/header2.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/file-filter/header2.h
new file mode 100644
index 0000000..09bfeab
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/file-filter/header2.h
@@ -0,0 +1 @@
+class A2 { A2(int); };
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/file-filter/system/system-header.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/file-filter/system/system-header.h
new file mode 100644
index 0000000..98482c4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/file-filter/system/system-header.h
@@ -0,0 +1 @@
+class A0 { A0(int); };
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/a.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/a.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/a.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/cstdarg.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/cstdarg.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/cstdarg.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/cstdlib.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/cstdlib.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/cstdlib.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/j.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/j.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/j.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/r.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/r.h
new file mode 100644
index 0000000..56757a7
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/r.h
@@ -0,0 +1 @@
+void f() {}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/s.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/s.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/s.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/t.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/t.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/t.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/transitive.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/transitive.h
new file mode 100644
index 0000000..6dba769
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/system/transitive.h
@@ -0,0 +1,3 @@
+#include <r.h>
+#include <t.h>
+#include <s.h>
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/transitive2.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/transitive2.h
new file mode 100644
index 0000000..ea56788
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/fuchsia-restrict-system-includes/transitive2.h
@@ -0,0 +1,2 @@
+#include <s.h>
+#include <t.h>
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/google-namespaces.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/google-namespaces.h
new file mode 100644
index 0000000..f4d87f5b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/google-namespaces.h
@@ -0,0 +1,7 @@
+namespace {
+int x;
+}
+
+namespace spaaaace {
+class core;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/line-filter/header1.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/line-filter/header1.h
new file mode 100644
index 0000000..35d59ce
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/line-filter/header1.h
@@ -0,0 +1,3 @@
+class A1 { A1(int); };
+class B1 { B1(int); };
+class C1 { C1(int); };
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/line-filter/header2.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/line-filter/header2.h
new file mode 100644
index 0000000..bb12598
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/line-filter/header2.h
@@ -0,0 +1,3 @@
+class A2 { A2(int); };
+class B2 { B2(int); };
+class C2 { C2(int); };
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/line-filter/header3.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/line-filter/header3.h
new file mode 100644
index 0000000..b5198ca
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/line-filter/header3.h
@@ -0,0 +1 @@
+class A3 { A3(int); };
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/mock-libcxx/bin/clang b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/mock-libcxx/bin/clang
new file mode 100644
index 0000000..ed34c1f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/mock-libcxx/bin/clang
@@ -0,0 +1 @@
+This file is a placeholder to keep its parent directory in git.
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/mock-libcxx/include/c++/v1/mock_vector b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/mock-libcxx/include/c++/v1/mock_vector
new file mode 100644
index 0000000..3539526
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/mock-libcxx/include/c++/v1/mock_vector
@@ -0,0 +1,2 @@
+class vector {};
+typedef vector* vector_ptr;
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/assert.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/assert.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/assert.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/complex.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/complex.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/complex.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/ctype.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/ctype.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/ctype.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/errno.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/errno.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/errno.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/fenv.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/fenv.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/fenv.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/float.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/float.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/float.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/inttypes.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/inttypes.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/inttypes.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/iso646.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/iso646.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/iso646.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/limits.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/limits.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/limits.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/locale.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/locale.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/locale.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/math.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/math.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/math.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/setjmp.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/setjmp.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/setjmp.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/signal.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/signal.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/signal.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stdalign.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stdalign.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stdalign.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stdarg.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stdarg.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stdarg.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stdbool.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stdbool.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stdbool.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stddef.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stddef.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stddef.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stdint.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stdint.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stdint.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stdio.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stdio.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stdio.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stdlib.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stdlib.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/stdlib.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/string.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/string.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/string.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/tgmath.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/tgmath.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/tgmath.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/time.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/time.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/time.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/uchar.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/uchar.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/uchar.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/wchar.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/wchar.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/wchar.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/wctype.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/wctype.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-deprecated-headers/wctype.h
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-loop-convert/structures.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-loop-convert/structures.h
new file mode 100644
index 0000000..02d440c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-loop-convert/structures.h
@@ -0,0 +1,206 @@
+#ifndef STRUCTURES_H
+#define STRUCTURES_H
+
+extern "C" {
+extern int printf(const char *restrict, ...);
+}
+
+struct Val {int X; void g(); };
+
+struct MutableVal {
+ void constFun(int) const;
+ void nonConstFun(int, int);
+ void constFun(MutableVal &) const;
+ void constParamFun(const MutableVal &) const;
+ void nonConstParamFun(const MutableVal &);
+ int X;
+};
+
+struct NonTriviallyCopyable {
+ NonTriviallyCopyable() = default;
+ // Define this constructor to make this class non-trivially copyable.
+ NonTriviallyCopyable(const NonTriviallyCopyable& Ntc);
+ int X;
+};
+
+struct TriviallyCopyableButBig {
+ int X;
+ char Array[16];
+};
+
+struct S {
+ typedef MutableVal *iterator;
+ typedef const MutableVal *const_iterator;
+ const_iterator begin() const;
+ const_iterator end() const;
+ const_iterator cbegin() const;
+ const_iterator cend() const;
+ iterator begin();
+ iterator end();
+};
+
+struct T {
+ struct iterator {
+ int& operator*();
+ const int& operator*()const;
+ iterator& operator ++();
+ bool operator!=(const iterator &other);
+ void insert(int);
+ int X;
+ };
+ iterator begin();
+ iterator end();
+};
+
+struct U {
+ struct iterator {
+ Val& operator*();
+ const Val& operator*()const;
+ iterator& operator ++();
+ bool operator!=(const iterator &other);
+ Val *operator->();
+ };
+ iterator begin();
+ iterator end();
+ int X;
+};
+
+struct X {
+ S Ss;
+ T Tt;
+ U Uu;
+ S getS();
+};
+
+template<typename ElemType>
+class dependent {
+ public:
+ dependent<ElemType>();
+ struct iterator_base {
+ const ElemType& operator*()const;
+ iterator_base& operator ++();
+ bool operator!=(const iterator_base &other) const;
+ const ElemType *operator->() const;
+ };
+
+ struct iterator : iterator_base {
+ ElemType& operator*();
+ iterator& operator ++();
+ ElemType *operator->();
+ };
+
+ typedef iterator_base const_iterator;
+ const_iterator begin() const;
+ const_iterator end() const;
+ iterator begin();
+ iterator end();
+ unsigned size() const;
+ ElemType & operator[](unsigned);
+ const ElemType & operator[](unsigned) const;
+ ElemType & at(unsigned);
+ ElemType & at(unsigned, unsigned);
+ const ElemType & at(unsigned) const;
+
+ // Intentionally evil.
+ dependent<ElemType> operator*();
+
+ void foo();
+ void constFoo() const;
+};
+
+template<typename First, typename Second>
+class doublyDependent{
+ public:
+ struct Value {
+ First first;
+ Second second;
+ };
+
+ struct iterator_base {
+ const Value& operator*()const;
+ iterator_base& operator ++();
+ bool operator!=(const iterator_base &other) const;
+ const Value *operator->() const;
+ };
+
+ struct iterator : iterator_base {
+ Value& operator*();
+ Value& operator ++();
+ Value *operator->();
+ };
+
+ typedef iterator_base const_iterator;
+ const_iterator begin() const;
+ const_iterator end() const;
+ iterator begin();
+ iterator end();
+};
+
+template<typename Contained>
+class transparent {
+ public:
+ Contained *at();
+ Contained *operator->();
+ Contained operator*();
+};
+
+template<typename IteratorType>
+struct Nested {
+ typedef IteratorType* iterator;
+ typedef const IteratorType* const_iterator;
+ IteratorType *operator->();
+ IteratorType operator*();
+ iterator begin();
+ iterator end();
+ const_iterator begin() const;
+ const_iterator end() const;
+};
+
+// Like llvm::SmallPtrSet, the iterator has a dereference operator that returns
+// by value instead of by reference.
+template <typename T>
+struct PtrSet {
+ struct iterator {
+ bool operator!=(const iterator &other) const;
+ const T operator*();
+ iterator &operator++();
+ };
+ iterator begin() const;
+ iterator end() const;
+};
+
+template <typename T>
+struct TypedefDerefContainer {
+ struct iterator {
+ typedef T &deref_type;
+ bool operator!=(const iterator &other) const;
+ deref_type operator*();
+ iterator &operator++();
+ };
+ iterator begin() const;
+ iterator end() const;
+};
+
+template <typename T>
+struct RValueDerefContainer {
+ struct iterator {
+ typedef T &&deref_type;
+ bool operator!=(const iterator &other) const;
+ deref_type operator*();
+ iterator &operator++();
+ };
+ iterator begin() const;
+ iterator end() const;
+};
+
+namespace Macros {
+
+struct MacroStruct {
+ int Arr[10];
+};
+static MacroStruct *MacroSt;
+#define CONT MacroSt->
+
+} // namespace Macros
+
+#endif // STRUCTURES_H
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-pass-by-value/header-with-fix.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-pass-by-value/header-with-fix.h
new file mode 100644
index 0000000..62609e2
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-pass-by-value/header-with-fix.h
@@ -0,0 +1,8 @@
+struct S {
+ S(S&&);
+ S(const S&);
+};
+struct Foo {
+ Foo(const S &s);
+ S s;
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-pass-by-value/header.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-pass-by-value/header.h
new file mode 100644
index 0000000..c2103cb
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-pass-by-value/header.h
@@ -0,0 +1,10 @@
+class ThreadId {
+public:
+ ThreadId(const ThreadId &) {}
+ ThreadId(ThreadId &&) {}
+};
+
+struct A {
+ A(const ThreadId &tid) : threadid(tid) {}
+ ThreadId threadid;
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-replace-auto-ptr/memory.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-replace-auto-ptr/memory.h
new file mode 100644
index 0000000..bc476ce
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-replace-auto-ptr/memory.h
@@ -0,0 +1,45 @@
+#ifndef INPUTS_MEMORY_H
+#define INPUTS_MEMORY_H
+
+namespace std {
+
+inline namespace _1 {
+
+template <class Y> struct auto_ptr_ref {
+ Y *y_;
+};
+
+template <class X> class auto_ptr {
+public:
+ typedef X element_type;
+ explicit auto_ptr(X *p = 0) throw() {}
+ auto_ptr(auto_ptr &) throw() {}
+ template <class Y> auto_ptr(auto_ptr<Y> &) throw() {}
+ auto_ptr &operator=(auto_ptr &) throw() { return *this; }
+ template <class Y> auto_ptr &operator=(auto_ptr<Y> &) throw() {
+ return *this;
+ }
+ auto_ptr &operator=(auto_ptr_ref<X> r) throw() { return *this; }
+ ~auto_ptr() throw() {}
+ auto_ptr(auto_ptr_ref<X> r) throw() : x_(r.y_) {}
+ template <class Y> operator auto_ptr_ref<Y>() throw() {
+ auto_ptr_ref<Y> r;
+ r.y_ = x_;
+ return r;
+ }
+ template <class Y> operator auto_ptr<Y>() throw() { return auto_ptr<Y>(x_); }
+
+private:
+ X *x_;
+};
+
+template <> class auto_ptr<void> {
+public:
+ typedef void element_type;
+};
+
+} // namespace _1
+
+} // end namespace std
+
+#endif // INPUTS_MEMORY_H
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-smart-ptr/initializer_list.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-smart-ptr/initializer_list.h
new file mode 100644
index 0000000..28592cf
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-smart-ptr/initializer_list.h
@@ -0,0 +1,32 @@
+namespace std {
+typedef decltype(sizeof(int)) size_t;
+
+template <class _E> class initializer_list {
+ const _E *__begin_;
+ size_t __size_;
+
+ initializer_list(const _E *__b, size_t __s) : __begin_(__b), __size_(__s) {}
+
+public:
+ typedef _E value_type;
+ typedef const _E &reference;
+ typedef const _E &const_reference;
+ typedef size_t size_type;
+
+ typedef const _E *iterator;
+ typedef const _E *const_iterator;
+
+ initializer_list() : __begin_(nullptr), __size_(0) {}
+
+ size_t size() const { return __size_; }
+ const _E *begin() const { return __begin_; }
+ const _E *end() const { return __begin_ + __size_; }
+};
+
+template <class _E>
+class vector {
+ public:
+ vector(initializer_list<_E> init);
+ ~vector();
+};
+} // namespace std
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-smart-ptr/shared_ptr.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-smart-ptr/shared_ptr.h
new file mode 100644
index 0000000..0f4f2a9
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-smart-ptr/shared_ptr.h
@@ -0,0 +1,24 @@
+namespace std {
+
+template <typename type>
+class shared_ptr {
+public:
+ shared_ptr();
+ shared_ptr(type *ptr);
+ shared_ptr(const shared_ptr<type> &t) {}
+ shared_ptr(shared_ptr<type> &&t) {}
+ ~shared_ptr();
+ type &operator*() { return *ptr; }
+ type *operator->() { return ptr; }
+ type *release();
+ void reset();
+ void reset(type *pt);
+ shared_ptr &operator=(shared_ptr &&);
+ template <typename T>
+ shared_ptr &operator=(shared_ptr<T> &&);
+
+private:
+ type *ptr;
+};
+
+} // namespace std
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-smart-ptr/unique_ptr.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-smart-ptr/unique_ptr.h
new file mode 100644
index 0000000..5dc9e02
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-smart-ptr/unique_ptr.h
@@ -0,0 +1,28 @@
+namespace std {
+
+template <typename T>
+class default_delete {};
+
+template <typename type, typename Deleter = std::default_delete<type>>
+class unique_ptr {
+public:
+ unique_ptr() {}
+ unique_ptr(type *ptr) {}
+ unique_ptr(const unique_ptr<type> &t) = delete;
+ unique_ptr(unique_ptr<type> &&t) {}
+ ~unique_ptr() {}
+ type &operator*() { return *ptr; }
+ type *operator->() { return ptr; }
+ type *release() { return ptr; }
+ void reset() {}
+ void reset(type *pt) {}
+ void reset(type pt) {}
+ unique_ptr &operator=(unique_ptr &&) { return *this; }
+ template <typename T>
+ unique_ptr &operator=(unique_ptr<T> &&) { return *this; }
+
+private:
+ type *ptr;
+};
+
+} // namespace std
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-use-auto/containers.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-use-auto/containers.h
new file mode 100644
index 0000000..c99b7a4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/modernize-use-auto/containers.h
@@ -0,0 +1,253 @@
+#ifndef CONTAINERS_H
+#define CONTAINERS_H
+
+namespace std {
+
+template <typename T>
+class iterator {
+public:
+ iterator() {}
+ iterator(const iterator<T> &iter) : ptr(iter.ptr) {}
+
+ typedef T value_type;
+ typedef T *pointer;
+ typedef T &reference;
+
+ reference operator*() const { return *ptr; }
+ pointer operator->() const { return ptr; }
+ iterator &operator++() {
+ ++ptr;
+ return *this;
+ }
+ iterator &operator--() {
+ --ptr;
+ return *this;
+ }
+ iterator operator++(int) {
+ iterator res(*this);
+ ++ptr;
+ return res;
+ }
+ iterator operator--(int) {
+ iterator res(*this);
+ --ptr;
+ return res;
+ }
+ bool operator!=(const iterator<T> &iter) const {
+ return ptr != iter.operator->();
+ }
+
+private:
+ T *ptr;
+};
+
+template <class Iterator>
+class const_iterator {
+public:
+ const_iterator() {}
+ const_iterator(const Iterator &iter) : iter(iter) {}
+ const_iterator(const const_iterator<Iterator> &citer) : iter(citer.iter) {}
+
+ typedef const typename Iterator::value_type value_type;
+ typedef const typename Iterator::pointer pointer;
+ typedef const typename Iterator::reference reference;
+
+ reference operator*() const { return *iter; }
+ pointer operator->() const { return iter.operator->(); }
+
+ const_iterator &operator++() { return ++iter; }
+ const_iterator &operator--() { return --iter; }
+ const_iterator operator++(int) { return iter--; }
+ const_iterator operator--(int) { return iter--; }
+
+ bool operator!=(const Iterator &it) const {
+ return iter->operator->() != it.operator->();
+ }
+ bool operator!=(const const_iterator<Iterator> &it) const {
+ return iter.operator->() != it.operator->();
+ }
+
+private:
+ Iterator iter;
+};
+
+template <class Iterator>
+class forward_iterable {
+public:
+ forward_iterable() {}
+ typedef Iterator iterator;
+ typedef const_iterator<Iterator> const_iterator;
+
+ iterator begin() { return _begin; }
+ iterator end() { return _end; }
+
+ const_iterator begin() const { return _begin; }
+ const_iterator end() const { return _end; }
+
+ const_iterator cbegin() const { return _begin; }
+ const_iterator cend() const { return _end; }
+
+private:
+ iterator _begin, _end;
+};
+
+template <class Iterator>
+class reverse_iterator {
+public:
+ reverse_iterator() {}
+ reverse_iterator(const Iterator &iter) : iter(iter) {}
+ reverse_iterator(const reverse_iterator<Iterator> &rit) : iter(rit.iter) {}
+
+ typedef typename Iterator::value_type value_type;
+ typedef typename Iterator::pointer pointer;
+ typedef typename Iterator::reference reference;
+
+ reference operator*() { return *iter; }
+ pointer operator->() { return iter.operator->(); }
+
+ reverse_iterator &operator++() { return --iter; }
+ reverse_iterator &operator--() { return ++iter; }
+ reverse_iterator operator++(int) { return iter--; }
+ reverse_iterator operator--(int) { return iter++; }
+
+private:
+ Iterator iter;
+};
+
+template <class Iterator>
+class backward_iterable {
+public:
+ backward_iterable() {}
+
+ typedef reverse_iterator<Iterator> reverse_iterator;
+ typedef const_iterator<reverse_iterator> const_reverse_iterator;
+
+ reverse_iterator rbegin() { return _rbegin; }
+ reverse_iterator rend() { return _rend; }
+
+ const_reverse_iterator rbegin() const { return _rbegin; }
+ const_reverse_iterator rend() const { return _rend; }
+
+ const_reverse_iterator crbegin() const { return _rbegin; }
+ const_reverse_iterator crend() const { return _rend; }
+
+private:
+ reverse_iterator _rbegin, _rend;
+};
+
+template <class Iterator>
+class bidirectional_iterable : public forward_iterable<Iterator>,
+ public backward_iterable<Iterator> {};
+
+template <typename A, typename B>
+struct pair {
+ pair(A f, B s) : first(f), second(s) {}
+ A first;
+ B second;
+};
+
+class string {
+public:
+ string() {}
+ string(const char *) {}
+};
+
+template <typename T, int n>
+class array : public backward_iterable<iterator<T>> {
+public:
+ array() {}
+
+ typedef T *iterator;
+ typedef const T *const_iterator;
+
+ iterator begin() { return &v[0]; }
+ iterator end() { return &v[n - 1]; }
+
+ const_iterator begin() const { return &v[0]; }
+ const_iterator end() const { return &v[n - 1]; }
+
+ const_iterator cbegin() const { return &v[0]; }
+ const_iterator cend() const { return &v[n - 1]; }
+
+private:
+ T v[n];
+};
+
+template <typename T>
+class deque : public bidirectional_iterable<iterator<T>> {
+public:
+ deque() {}
+};
+
+template <typename T>
+class list : public bidirectional_iterable<iterator<T>> {
+public:
+ list() {}
+};
+
+template <typename T>
+class forward_list : public forward_iterable<iterator<T>> {
+public:
+ forward_list() {}
+};
+
+template <typename T>
+class vector : public bidirectional_iterable<iterator<T>> {
+public:
+ vector() {}
+};
+
+template <typename T>
+class set : public bidirectional_iterable<iterator<T>> {
+public:
+ set() {}
+};
+
+template <typename T>
+class multiset : public bidirectional_iterable<iterator<T>> {
+public:
+ multiset() {}
+};
+
+template <typename key, typename value>
+class map : public bidirectional_iterable<iterator<pair<key, value>>> {
+public:
+ map() {}
+
+ iterator<pair<key, value>> find(const key &) {}
+ const_iterator<iterator<pair<key, value>>> find(const key &) const {}
+};
+
+template <typename key, typename value>
+class multimap : public bidirectional_iterable<iterator<pair<key, value>>> {
+public:
+ multimap() {}
+};
+
+template <typename T>
+class unordered_set : public forward_iterable<iterator<T>> {
+public:
+ unordered_set() {}
+};
+
+template <typename T>
+class unordered_multiset : public forward_iterable<iterator<T>> {
+public:
+ unordered_multiset() {}
+};
+
+template <typename key, typename value>
+class unordered_map : public forward_iterable<iterator<pair<key, value>>> {
+public:
+ unordered_map() {}
+};
+
+template <typename key, typename value>
+class unordered_multimap : public forward_iterable<iterator<pair<key, value>>> {
+public:
+ unordered_multimap() {}
+};
+
+} // namespace std
+
+#endif // CONTAINERS_H
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/mpi-type-mismatch/mpimock.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/mpi-type-mismatch/mpimock.h
new file mode 100644
index 0000000..cb90028
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/mpi-type-mismatch/mpimock.h
@@ -0,0 +1,64 @@
+// This Message Passing Interface mock header is used, to mock typedefs,
+// constants and functions, required for integration tests being part of
+// clang-tidy MPI checks.
+
+#ifndef MPIMOCK_H
+#define MPIMOCK_H
+
+#define NULL 0
+
+// These typedefs are used to mock MPI types, fixed width integer types and the
+// templated C++ complex number type.
+typedef int MPI_Datatype;
+typedef int MPI_Comm;
+typedef int MPI_Request;
+typedef int MPI_Status;
+typedef int MPI_Op;
+typedef int int8_t;
+typedef int uint8_t;
+typedef int uint16_t;
+typedef int int64_t;
+namespace std { template<class T> struct complex { T real; T imag; }; }
+
+// These defines are used to mock MPI constants.
+#define MPI_DATATYPE_NULL 0
+#define MPI_CHAR 0
+#define MPI_BYTE 0
+#define MPI_SHORT 0
+#define MPI_INT 0
+#define MPI_LONG 0
+#define MPI_LONG_DOUBLE 0
+#define MPI_UNSIGNED 0
+#define MPI_INT8_T 0
+#define MPI_UINT8_T 0
+#define MPI_UINT16_T 0
+#define MPI_C_FLOAT_COMPLEX 0
+#define MPI_C_LONG_DOUBLE_COMPLEX 0
+#define MPI_FLOAT 0
+#define MPI_DOUBLE 0
+#define MPI_CXX_BOOL 0
+#define MPI_CXX_FLOAT_COMPLEX 0
+#define MPI_CXX_DOUBLE_COMPLEX 0
+#define MPI_CXX_LONG_DOUBLE_COMPLEX 0
+#define MPI_IN_PLACE 0
+#define MPI_COMM_WORLD 0
+#define MPI_STATUS_IGNORE 0
+#define MPI_STATUSES_IGNORE 0
+#define MPI_SUM 0
+
+// These declarations are used to mock MPI functions.
+int MPI_Comm_size(MPI_Comm, int *);
+int MPI_Comm_rank(MPI_Comm, int *);
+int MPI_Send(const void *, int, MPI_Datatype, int, int, MPI_Comm);
+int MPI_Recv(void *, int, MPI_Datatype, int, int, MPI_Comm, MPI_Status *);
+int MPI_Isend(const void *, int, MPI_Datatype, int, int, MPI_Comm,
+ MPI_Request *);
+int MPI_Irecv(void *, int, MPI_Datatype, int, int, MPI_Comm, MPI_Request *);
+int MPI_Wait(MPI_Request *, MPI_Status *);
+int MPI_Waitall(int, MPI_Request[], MPI_Status[]);
+int MPI_Reduce(const void *, void *, int, MPI_Datatype, MPI_Op, int, MPI_Comm);
+int MPI_Ireduce(const void *, void *, int, MPI_Datatype, MPI_Op, int, MPI_Comm,
+ MPI_Request *);
+int MPI_Bcast(void *, int count, MPI_Datatype, int, MPI_Comm);
+
+#endif // end of include guard: MPIMOCK_H
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/nolint/trigger_warning.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/nolint/trigger_warning.h
new file mode 100644
index 0000000..e8ebed2
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/nolint/trigger_warning.h
@@ -0,0 +1,5 @@
+void A1(const int &In, int &Out) {
+ if (In > 123) // NOLINT
+ Out = 123;
+}
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/overlapping/o.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/overlapping/o.h
new file mode 100644
index 0000000..bfa7a0a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/overlapping/o.h
@@ -0,0 +1,9 @@
+// run: clang-tidy -checks=-*,llvm-include-order -header-filter=.* %s \
+// run: -- -isystem %S/Inputs/Headers -I %S/Inputs/overlapping | \
+// run: not grep "note: this fix will not be applied because it overlaps with another fix"
+
+#include "b.h"
+#include "a.h"
+
+// The comments above are there to match the offset of the #include with the
+// offset of the #includes in the .cpp file.
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/performance-unnecessary-value-param/header-fixed.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/performance-unnecessary-value-param/header-fixed.h
new file mode 100644
index 0000000..f3e9e72
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/performance-unnecessary-value-param/header-fixed.h
@@ -0,0 +1,15 @@
+// struct ABC is expensive to copy and should be
+// passed as a const referece.
+struct ABC {
+ ABC(const ABC&);
+ int get(int) const;
+};
+
+
+int f1(int n, const ABC& v1, const ABC& v2); // line 9
+
+int f1(int n, ABC v1); // line 11
+
+
+
+int f2( int n, const ABC& v2); // line 15
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/performance-unnecessary-value-param/header.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/performance-unnecessary-value-param/header.h
new file mode 100644
index 0000000..3f55c79
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/performance-unnecessary-value-param/header.h
@@ -0,0 +1,15 @@
+// struct ABC is expensive to copy and should be
+// passed as a const referece.
+struct ABC {
+ ABC(const ABC&);
+ int get(int) const;
+};
+
+
+int f1(int n, ABC v1, ABC v2); // line 9
+
+int f1(int n, ABC v1); // line 11
+
+
+
+int f2( int n, ABC v2); // line 15
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/readability-identifier-naming/system/system-header.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/readability-identifier-naming/system/system-header.h
new file mode 100644
index 0000000..8a394a9
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/readability-identifier-naming/system/system-header.h
@@ -0,0 +1,17 @@
+#ifndef SYSTEM_HEADER_H
+#define SYSTEM_HEADER_H
+
+#define SYSTEM_MACRO(m) int m = 0
+
+namespace SYSTEM_NS {
+class structure {
+ int member;
+};
+
+float global;
+
+void function() {
+}
+}
+
+#endif // SYSTEM_HEADER_H
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/readability-identifier-naming/user-header.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/readability-identifier-naming/user-header.h
new file mode 100644
index 0000000..f03982c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/readability-identifier-naming/user-header.h
@@ -0,0 +1,17 @@
+#ifndef USER_HEADER_H
+#define USER_HEADER_H
+
+#define USER_MACRO(m) int m = 0
+
+namespace USER_NS {
+class object {
+ int member;
+};
+
+float global;
+
+void function() {
+}
+}
+
+#endif // USER_HEADER_H
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/unused-using-decls.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/unused-using-decls.h
new file mode 100644
index 0000000..8245cb1
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/unused-using-decls.h
@@ -0,0 +1,11 @@
+class MyClass {
+public:
+ template <template <typename> class S, typename T>
+ S<T> *func1(T *a) {
+ return new S<T>();
+ }
+ template <typename T, T (*S)()>
+ void func2(T a) {
+ S();
+ }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/vfsoverlay/actual_header.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/vfsoverlay/actual_header.h
new file mode 100644
index 0000000..8e1b9ae
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/vfsoverlay/actual_header.h
@@ -0,0 +1 @@
+struct X {};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/vfsoverlay/vfsoverlay.yaml b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/vfsoverlay/vfsoverlay.yaml
new file mode 100644
index 0000000..80d8fba
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/Inputs/vfsoverlay/vfsoverlay.yaml
@@ -0,0 +1,12 @@
+{
+ 'version': 0,
+ 'roots': [
+ { 'name': 'OUT_DIR', 'type': 'directory',
+ 'contents': [
+ { 'name': 'not_real.h', 'type': 'file',
+ 'external-contents': 'INPUT_DIR/actual_header.h'
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-duration-comparison.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-duration-comparison.cpp
new file mode 100644
index 0000000..9fa422b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-duration-comparison.cpp
@@ -0,0 +1,166 @@
+// RUN: %check_clang_tidy %s abseil-duration-comparison %t -- -- -I%S/Inputs
+
+#include "absl/time/time.h"
+
+void f() {
+ double x;
+ absl::Duration d1, d2;
+ bool b;
+ absl::Time t1, t2;
+
+ // Check against the RHS
+ b = x > absl::ToDoubleSeconds(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Seconds(x) > d1;
+ b = x >= absl::ToDoubleSeconds(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Seconds(x) >= d1;
+ b = x == absl::ToDoubleSeconds(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Seconds(x) == d1;
+ b = x <= absl::ToDoubleSeconds(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Seconds(x) <= d1;
+ b = x < absl::ToDoubleSeconds(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Seconds(x) < d1;
+ b = x == absl::ToDoubleSeconds(t1 - t2);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Seconds(x) == t1 - t2;
+ b = absl::ToDoubleSeconds(d1) > absl::ToDoubleSeconds(d2);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: d1 > d2;
+
+ // Check against the LHS
+ b = absl::ToDoubleSeconds(d1) < x;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: d1 < absl::Seconds(x);
+ b = absl::ToDoubleSeconds(d1) <= x;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: d1 <= absl::Seconds(x);
+ b = absl::ToDoubleSeconds(d1) == x;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: d1 == absl::Seconds(x);
+ b = absl::ToDoubleSeconds(d1) >= x;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: d1 >= absl::Seconds(x);
+ b = absl::ToDoubleSeconds(d1) > x;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: d1 > absl::Seconds(x);
+
+ // Comparison against zero
+ b = absl::ToDoubleSeconds(d1) < 0.0;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: d1 < absl::ZeroDuration();
+ b = absl::ToDoubleSeconds(d1) < 0;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: d1 < absl::ZeroDuration();
+
+ // Scales other than Seconds
+ b = x > absl::ToDoubleMicroseconds(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Microseconds(x) > d1;
+ b = x >= absl::ToDoubleMilliseconds(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Milliseconds(x) >= d1;
+ b = x == absl::ToDoubleNanoseconds(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Nanoseconds(x) == d1;
+ b = x <= absl::ToDoubleMinutes(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Minutes(x) <= d1;
+ b = x < absl::ToDoubleHours(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Hours(x) < d1;
+
+ // Integer comparisons
+ b = x > absl::ToInt64Microseconds(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Microseconds(x) > d1;
+ b = x >= absl::ToInt64Milliseconds(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Milliseconds(x) >= d1;
+ b = x == absl::ToInt64Nanoseconds(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Nanoseconds(x) == d1;
+ b = x == absl::ToInt64Seconds(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Seconds(x) == d1;
+ b = x <= absl::ToInt64Minutes(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Minutes(x) <= d1;
+ b = x < absl::ToInt64Hours(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Hours(x) < d1;
+
+ // Other abseil-duration checks folded into this one
+ b = static_cast<double>(5) > absl::ToDoubleSeconds(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Seconds(5) > d1;
+ b = double(5) > absl::ToDoubleSeconds(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Seconds(5) > d1;
+ b = float(5) > absl::ToDoubleSeconds(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Seconds(5) > d1;
+ b = ((double)5) > absl::ToDoubleSeconds(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Seconds(5) > d1;
+ b = 5.0 > absl::ToDoubleSeconds(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Seconds(5) > d1;
+
+ // A long expression
+ bool some_condition;
+ int very_very_very_very_long_variable_name;
+ absl::Duration SomeDuration;
+ if (some_condition && very_very_very_very_long_variable_name
+ < absl::ToDoubleSeconds(SomeDuration)) {
+ // CHECK-MESSAGES: [[@LINE-2]]:25: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: if (some_condition && absl::Seconds(very_very_very_very_long_variable_name) < SomeDuration) {
+ return;
+ }
+
+ // A complex expression
+ int y;
+ b = (y + 5) * 10 > absl::ToDoubleMilliseconds(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: absl::Milliseconds((y + 5) * 10) > d1;
+
+ // We should still transform the expression inside this macro invocation
+#define VALUE_IF(v, e) v ? (e) : 0
+ int a = VALUE_IF(1, 5 > absl::ToDoubleSeconds(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: VALUE_IF(1, absl::Seconds(5) > d1);
+#undef VALUE_IF
+
+#define VALUE_IF_2(e) (e)
+#define VALUE_IF(v, e) v ? VALUE_IF_2(e) : VALUE_IF_2(0)
+ int a2 = VALUE_IF(1, 5 > absl::ToDoubleSeconds(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:24: warning: perform comparison in the duration domain [abseil-duration-comparison]
+ // CHECK-FIXES: VALUE_IF(1, absl::Seconds(5) > d1);
+#undef VALUE_IF
+#undef VALUE_IF_2
+
+#define VALUE_IF_2(e) (e)
+#define VALUE_IF(v, e, type) (v ? VALUE_IF_2(absl::To##type##Seconds(e)) : 0)
+ int a3 = VALUE_IF(1, d1, Double);
+#undef VALUE_IF
+#undef VALUE_IF_2
+
+#define VALUE_IF_2(e) (e)
+#define VALUE_IF(v, e, type) (v ? (5 > VALUE_IF_2(absl::To##type##Seconds(e))) : 0)
+ int a4 = VALUE_IF(1, d1, Double);
+#undef VALUE_IF
+#undef VALUE_IF_2
+
+ // These should not match
+ b = 6 < 4;
+
+#define TODOUBLE(x) absl::ToDoubleSeconds(x)
+ b = 5.0 > TODOUBLE(d1);
+#undef TODOUBLE
+#define THIRTY 30.0
+ b = THIRTY > absl::ToDoubleSeconds(d1);
+#undef THIRTY
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-duration-division.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-duration-division.cpp
new file mode 100644
index 0000000..51d012f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-duration-division.cpp
@@ -0,0 +1,75 @@
+// RUN: %check_clang_tidy %s abseil-duration-division %t
+
+namespace absl {
+
+class Duration {};
+
+int operator/(Duration lhs, Duration rhs);
+
+double FDivDuration(Duration num, Duration den);
+
+} // namespace absl
+
+void TakesDouble(double);
+
+#define MACRO_EQ(x, y) (x == y)
+#define MACRO_DIVEQ(x,y,z) (x/y == z)
+#define CHECK(x) (x)
+
+void Positives() {
+ absl::Duration d;
+
+ const double num_double = d/d;
+ // CHECK-MESSAGES: [[@LINE-1]]:30: warning: operator/ on absl::Duration objects performs integer division; did you mean to use FDivDuration()? [abseil-duration-division]
+ // CHECK-FIXES: const double num_double = absl::FDivDuration(d, d);
+ const float num_float = d/d;
+ // CHECK-MESSAGES: [[@LINE-1]]:28: warning: operator/ on absl::Duration objects
+ // CHECK-FIXES: const float num_float = absl::FDivDuration(d, d);
+ const auto SomeVal = 1.0 + d/d;
+ // CHECK-MESSAGES: [[@LINE-1]]:31: warning: operator/ on absl::Duration objects
+ // CHECK-FIXES: const auto SomeVal = 1.0 + absl::FDivDuration(d, d);
+ if (MACRO_EQ(d/d, 0.0)) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:17: warning: operator/ on absl::Duration objects
+ // CHECK-FIXES: if (MACRO_EQ(absl::FDivDuration(d, d), 0.0)) {}
+ if (CHECK(MACRO_EQ(d/d, 0.0))) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: operator/ on absl::Duration objects
+ // CHECK-FIXES: if (CHECK(MACRO_EQ(absl::FDivDuration(d, d), 0.0))) {}
+
+ // This one generates a message, but no fix.
+ if (MACRO_DIVEQ(d, d, 0.0)) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: operator/ on absl::Duration objects
+ // CHECK-FIXES: if (MACRO_DIVEQ(d, d, 0.0)) {}
+
+ TakesDouble(d/d);
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: operator/ on absl::Duration objects
+ // CHECK-FIXES: TakesDouble(absl::FDivDuration(d, d));
+}
+
+void TakesInt(int);
+template <class T>
+void TakesGeneric(T);
+
+void Negatives() {
+ absl::Duration d;
+ const int num_int = d/d;
+ const long num_long = d/d;
+ const short num_short = d/d;
+ const char num_char = d/d;
+ const auto num_auto = d/d;
+ const auto SomeVal = 1 + d/d;
+
+ TakesInt(d/d);
+ TakesGeneric(d/d);
+ // Explicit cast should disable the warning.
+ const double num_cast1 = static_cast<double>(d/d);
+ const double num_cast2 = (double)(d/d);
+}
+
+template <class T>
+double DoubleDivision(T t1, T t2) {return t1/t2;}
+
+//This also won't trigger a warning
+void TemplateDivision() {
+ absl::Duration d;
+ DoubleDivision(d, d);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-duration-factory-float.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-duration-factory-float.cpp
new file mode 100644
index 0000000..2649d2b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-duration-factory-float.cpp
@@ -0,0 +1,107 @@
+// RUN: %check_clang_tidy %s abseil-duration-factory-float %t -- -- -I%S/Inputs
+
+#include "absl/time/time.h"
+
+void ConvertFloatTest() {
+ absl::Duration d;
+
+ d = absl::Seconds(60.0);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float]
+ // CHECK-FIXES: absl::Seconds(60);
+ d = absl::Minutes(300.0);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Minutes [abseil-duration-factory-float]
+ // CHECK-FIXES: absl::Minutes(300);
+
+ d = absl::Milliseconds(1e2);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Milliseconds [abseil-duration-factory-float]
+ // CHECK-FIXES: absl::Milliseconds(100);
+ d = absl::Seconds(3.0f);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float]
+ // CHECK-FIXES: absl::Seconds(3);
+ d = absl::Seconds(3.);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float]
+ // CHECK-FIXES: absl::Seconds(3);
+ d = absl::Seconds(0x3.p0);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float]
+ // CHECK-FIXES: absl::Seconds(3);
+ d = absl::Seconds(0x3.p1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float]
+ // CHECK-FIXES: absl::Seconds(6);
+
+
+ // Ignored expressions
+ d = absl::Seconds(.001);
+ d = absl::Seconds(.100);
+ d = ::absl::Seconds(1);
+ d = ::absl::Minutes(1);
+ d = ::absl::Hours(1);
+ d = absl::Seconds(0x3.4p1);
+
+ // Negative literals (we don't yet handle this case)
+ d = absl::Seconds(-3.0);
+
+ // This is bigger than we can safely fit in a positive int32, so we ignore it.
+ d = absl::Seconds(1e12);
+
+ int x;
+ d = absl::Seconds(x);
+ float y;
+ d = absl::Minutes(y);
+
+#define SECONDS(x) absl::Seconds(x)
+ SECONDS(60);
+#undef SECONDS
+#define THIRTY 30.0
+ d = absl::Seconds(THIRTY);
+#undef THIRTY
+}
+
+template <int N>
+void InTemplate() {
+ absl::Duration d;
+
+ d = absl::Seconds(N); // 1
+ // ^ No replacement here.
+
+ d = absl::Minutes(1.0); // 2
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Minutes [abseil-duration-factory-float]
+ // CHECK-FIXES: absl::Minutes(1); // 2
+}
+
+void Instantiate() {
+ InTemplate<60>();
+ InTemplate<1>();
+}
+
+void ConvertCastTest() {
+ absl::Duration d;
+
+ d = absl::Seconds(static_cast<double>(5));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float]
+ // CHECK-FIXES: absl::Seconds(5);
+
+ d = absl::Minutes(static_cast<float>(5));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Minutes [abseil-duration-factory-float]
+ // CHECK-FIXES: absl::Minutes(5);
+
+ d = absl::Seconds((double) 5);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float]
+ // CHECK-FIXES: absl::Seconds(5);
+
+ d = absl::Minutes((float) 5);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Minutes [abseil-duration-factory-float]
+ // CHECK-FIXES: absl::Minutes(5);
+
+ d = absl::Seconds(double(5));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float]
+ // CHECK-FIXES: absl::Seconds(5);
+
+ d = absl::Minutes(float(5));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Minutes [abseil-duration-factory-float]
+ // CHECK-FIXES: absl::Minutes(5);
+
+ // This should not be flagged
+ d = absl::Seconds(static_cast<int>(5.0));
+ d = absl::Seconds((int) 5.0);
+ d = absl::Seconds(int(5.0));
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-duration-factory-scale.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-duration-factory-scale.cpp
new file mode 100644
index 0000000..04c3613
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-duration-factory-scale.cpp
@@ -0,0 +1,118 @@
+// RUN: %check_clang_tidy %s abseil-duration-factory-scale %t -- -- -I%S/Inputs
+
+#include "absl/time/time.h"
+
+namespace std { typedef long long int64_t; }
+using int64_t = std::int64_t;
+
+void ScaleTest() {
+ absl::Duration d;
+
+ // Zeroes
+ d = absl::Hours(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::ZeroDuration();
+ d = absl::Minutes(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::ZeroDuration();
+ d = absl::Seconds(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::ZeroDuration();
+ d = absl::Milliseconds(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::ZeroDuration();
+ d = absl::Microseconds(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::ZeroDuration();
+ d = absl::Nanoseconds(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::ZeroDuration();
+ d = absl::Seconds(0.0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::ZeroDuration();
+ d = absl::Seconds(0x0.000001p-126f);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::ZeroDuration();
+ d = absl::Seconds(int{0});
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::ZeroDuration();
+ d = absl::Seconds(int64_t{0});
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::ZeroDuration();
+ d = absl::Seconds(float{0});
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::ZeroDuration();
+
+ // Fold seconds into minutes
+ d = absl::Seconds(30 * 60);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::Minutes(30);
+ d = absl::Seconds(60 * 30);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::Minutes(30);
+
+ // Try a few more exotic multiplications
+ d = absl::Seconds(60 * 30 * 60);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::Minutes(60 * 30);
+ d = absl::Seconds(1e-3 * 30);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::Milliseconds(30);
+ d = absl::Milliseconds(30 * 1000);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::Seconds(30);
+ d = absl::Milliseconds(30 * 0.001);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::Microseconds(30);
+
+ // Multiple steps
+ d = absl::Seconds(5 * 3600);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::Hours(5);
+ d = absl::Microseconds(5 * 1e6);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::Seconds(5);
+ d = absl::Seconds(5 * 1e-6);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::Microseconds(5);
+ d = absl::Microseconds(5 * 1000000);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::Seconds(5);
+
+ // Division
+ d = absl::Hours(30 / 60.);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::Minutes(30);
+ d = absl::Seconds(30 / 1000.);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::Milliseconds(30);
+ d = absl::Milliseconds(30 / 1e3);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::Microseconds(30);
+ d = absl::Seconds(30 / 1e6);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
+ // CHECK-FIXES: absl::Microseconds(30);
+
+ // None of these should trigger the check
+ d = absl::Seconds(60);
+ d = absl::Seconds(int{60});
+ d = absl::Seconds(float{60});
+ d = absl::Seconds(60 + 30);
+ d = absl::Seconds(60 - 30);
+ d = absl::Seconds(50 * 30);
+ d = absl::Hours(60 * 60);
+ d = absl::Nanoseconds(1e-3 * 30);
+ d = absl::Seconds(1000 / 30);
+ // We don't support division by integers, which could cause rounding
+ d = absl::Seconds(10 / 1000);
+ d = absl::Seconds(30 / 50);
+
+#define EXPRESSION 30 * 60
+ d = absl::Seconds(EXPRESSION);
+#undef EXPRESSION
+
+// This should not trigger
+#define HOURS(x) absl::Minutes(60 * x)
+ d = HOURS(40);
+#undef HOURS
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-duration-subtraction.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-duration-subtraction.cpp
new file mode 100644
index 0000000..154b7d4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-duration-subtraction.cpp
@@ -0,0 +1,64 @@
+// RUN: %check_clang_tidy %s abseil-duration-subtraction %t -- -- -I %S/Inputs
+
+#include "absl/time/time.h"
+
+void f() {
+ double x;
+ absl::Duration d, d1, d2;
+
+ x = absl::ToDoubleSeconds(d) - 1.0;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
+ // CHECK-FIXES: absl::ToDoubleSeconds(d - absl::Seconds(1))
+ x = absl::ToDoubleSeconds(d) - absl::ToDoubleSeconds(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
+ // CHECK-FIXES: absl::ToDoubleSeconds(d - d1);
+ x = absl::ToDoubleSeconds(d) - 6.5 - 8.0;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
+ // CHECK-FIXES: absl::ToDoubleSeconds(d - absl::Seconds(6.5)) - 8.0;
+ x = absl::ToDoubleHours(d) - 1.0;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
+ // CHECK-FIXES: absl::ToDoubleHours(d - absl::Hours(1))
+ x = absl::ToDoubleMinutes(d) - 1;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
+ // CHECK-FIXES: absl::ToDoubleMinutes(d - absl::Minutes(1))
+ x = absl::ToDoubleMilliseconds(d) - 9;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
+ // CHECK-FIXES: absl::ToDoubleMilliseconds(d - absl::Milliseconds(9))
+ x = absl::ToDoubleMicroseconds(d) - 9;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
+ // CHECK-FIXES: absl::ToDoubleMicroseconds(d - absl::Microseconds(9))
+ x = absl::ToDoubleNanoseconds(d) - 42;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
+ // CHECK-FIXES: absl::ToDoubleNanoseconds(d - absl::Nanoseconds(42))
+
+ // We can rewrite the argument of the duration conversion
+#define THIRTY absl::Seconds(30)
+ x = absl::ToDoubleSeconds(THIRTY) - 1.0;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
+ // CHECK-FIXES: absl::ToDoubleSeconds(THIRTY - absl::Seconds(1))
+#undef THIRTY
+
+ // Some other contexts
+ if (absl::ToDoubleSeconds(d) - 1.0 > 10) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
+ // CHECK-FIXES: if (absl::ToDoubleSeconds(d - absl::Seconds(1)) > 10) {}
+
+ // A nested occurance
+ x = absl::ToDoubleSeconds(d) - absl::ToDoubleSeconds(absl::Seconds(5));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
+ // CHECK-FIXES: absl::ToDoubleSeconds(d - absl::Seconds(5))
+ x = absl::ToDoubleSeconds(d) - absl::ToDoubleSeconds(absl::Seconds(absl::ToDoubleSeconds(d1)));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
+ // CHECK-FIXES: absl::ToDoubleSeconds(d - absl::Seconds(absl::ToDoubleSeconds(d1)))
+
+ // These should not match
+ x = 5 - 6;
+ x = 4 - absl::ToDoubleSeconds(d) - 6.5 - 8.0;
+ x = absl::ToDoubleSeconds(d) + 1.0;
+ x = absl::ToDoubleSeconds(d) * 1.0;
+ x = absl::ToDoubleSeconds(d) / 1.0;
+
+#define MINUS_FIVE(z) absl::ToDoubleSeconds(z) - 5
+ x = MINUS_FIVE(d);
+#undef MINUS_FIVE
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-faster-strsplit-delimiter.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-faster-strsplit-delimiter.cpp
new file mode 100644
index 0000000..5895e45
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-faster-strsplit-delimiter.cpp
@@ -0,0 +1,99 @@
+// RUN: %check_clang_tidy %s abseil-faster-strsplit-delimiter %t
+
+namespace absl {
+
+class string_view {
+ public:
+ string_view();
+ string_view(const char *);
+};
+
+namespace strings_internal {
+struct Splitter {};
+struct MaxSplitsImpl {
+ MaxSplitsImpl();
+ ~MaxSplitsImpl();
+};
+} //namespace strings_internal
+
+template <typename Delim>
+strings_internal::Splitter StrSplit(absl::string_view, Delim) {
+ return {};
+}
+template <typename Delim, typename Pred>
+strings_internal::Splitter StrSplit(absl::string_view, Delim, Pred) {
+ return {};
+}
+
+class ByAnyChar {
+ public:
+ explicit ByAnyChar(absl::string_view);
+ ~ByAnyChar();
+};
+
+template <typename Delim>
+strings_internal::MaxSplitsImpl MaxSplits(Delim, int) {
+ return {};
+}
+
+} //namespace absl
+
+void SplitDelimiters() {
+ absl::StrSplit("ABC", "A");
+ // CHECK-MESSAGES: [[@LINE-1]]:25: warning: absl::StrSplit() called with a string literal consisting of a single character; consider using the character overload [abseil-faster-strsplit-delimiter]
+ // CHECK-FIXES: absl::StrSplit("ABC", 'A');
+
+ absl::StrSplit("ABC", absl::ByAnyChar("\n"));
+ // CHECK-MESSAGES: [[@LINE-1]]:41: warning: absl::StrSplit()
+ // CHECK-FIXES: absl::StrSplit("ABC", '\n');
+
+ // Works with predicate
+ absl::StrSplit("ABC", "A", [](absl::string_view) { return true; });
+ // CHECK-MESSAGES: [[@LINE-1]]:25: warning: absl::StrSplit()
+ // CHECK-FIXES: absl::StrSplit("ABC", 'A', [](absl::string_view) { return true; });
+
+ // Doesn't do anything with other strings lenghts.
+ absl::StrSplit("ABC", "AB");
+ absl::StrSplit("ABC", absl::ByAnyChar(""));
+ absl::StrSplit("ABC", absl::ByAnyChar(" \t"));
+
+ // Escapes a single quote in the resulting character literal.
+ absl::StrSplit("ABC", "'");
+ // CHECK-MESSAGES: [[@LINE-1]]:25: warning: absl::StrSplit()
+ // CHECK-FIXES: absl::StrSplit("ABC", '\'');
+
+ absl::StrSplit("ABC", "\"");
+ // CHECK-MESSAGES: [[@LINE-1]]:25: warning: absl::StrSplit()
+ // CHECK-FIXES: absl::StrSplit("ABC", '\"');
+
+ absl::StrSplit("ABC", absl::MaxSplits("\t", 1));
+ // CHECK-MESSAGES: [[@LINE-1]]:41: warning: absl::MaxSplits()
+ // CHECK-FIXES: absl::StrSplit("ABC", absl::MaxSplits('\t', 1));
+
+ auto delim = absl::MaxSplits(absl::ByAnyChar(" "), 1);
+ // CHECK-MESSAGES: [[@LINE-1]]:48: warning: absl::MaxSplits()
+ // CHECK-FIXES: auto delim = absl::MaxSplits(' ', 1);
+}
+
+#define MACRO(str) absl::StrSplit("ABC", str)
+
+void Macro() {
+ MACRO("A");
+}
+
+template <typename T>
+void FunctionTemplate() {
+ // This one should not warn because ByAnyChar is a dependent type.
+ absl::StrSplit("TTT", T("A"));
+
+ // This one will warn, but we are checking that we get a correct warning only
+ // once.
+ absl::StrSplit("TTT", "A");
+ // CHECK-MESSAGES: [[@LINE-1]]:25: warning: absl::StrSplit()
+ // CHECK-FIXES: absl::StrSplit("TTT", 'A');
+}
+
+void FunctionTemplateCaller() {
+ FunctionTemplate<absl::ByAnyChar>();
+ FunctionTemplate<absl::string_view>();
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-no-internal-dependencies.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-no-internal-dependencies.cpp
new file mode 100644
index 0000000..272d006
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-no-internal-dependencies.cpp
@@ -0,0 +1,48 @@
+// RUN: %check_clang_tidy %s abseil-no-internal-dependencies %t, -- -- -I %S/Inputs
+// RUN: clang-tidy -checks='-*, abseil-no-internal-dependencies' -header-filter='.*' %s -- -I %S/Inputs 2>&1 | FileCheck %s
+
+#include "absl/strings/internal-file.h"
+#include "absl/flags/internal-file.h"
+// CHECK-NOT: warning:
+
+#include "absl/external-file.h"
+// CHECK: absl/external-file.h:6:24: warning: do not reference any 'internal' namespaces; those implementation details are reserved to Abseil [abseil-no-internal-dependencies]
+
+void DirectAcess() {
+ absl::strings_internal::InternalFunction();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not reference any 'internal' namespaces; those implementation details are reserved to Abseil
+
+ absl::strings_internal::InternalTemplateFunction<std::string>("a");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not reference any 'internal' namespaces; those implementation details are reserved to Abseil
+}
+
+class FriendUsage {
+ friend struct absl::container_internal::InternalStruct;
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: do not reference any 'internal' namespaces; those implementation details are reserved to Abseil
+};
+
+namespace absl {
+void OpeningNamespace() {
+ strings_internal::InternalFunction();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not reference any 'internal' namespaces; those implementation details are reserved to Abseil
+}
+} // namespace absl
+
+// should not trigger warnings
+void CorrectUsage() {
+ std::string Str = absl::StringsFunction("a");
+ absl::SomeContainer b;
+}
+
+namespace absl {
+SomeContainer b;
+std::string Str = absl::StringsFunction("a");
+} // namespace absl
+
+#define USE_EXTERNAL(x) absl::strings_internal::Internal##x()
+
+void MacroUse() {
+ USE_INTERNAL(Function); // no-warning
+ USE_EXTERNAL(Function);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not reference any 'internal' namespaces; those implementation details are reserved to Abseil
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-no-namespace.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-no-namespace.cpp
new file mode 100644
index 0000000..78821c3
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-no-namespace.cpp
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s abseil-no-namespace %t -- -- -I %S/Inputs
+// RUN: clang-tidy -checks='-*, abseil-no-namespace' -header-filter='.*' %s -- -I %S/Inputs 2>&1 | FileCheck %s
+
+/// Warning will not be triggered on internal Abseil code that is included.
+#include "absl/strings/internal-file.h"
+// CHECK-NOT: warning:
+
+/// Warning will be triggered on code that is not internal that is included.
+#include "absl/external-file.h"
+// CHECK: absl/external-file.h:1:11: warning: namespace 'absl' is reserved
+
+namespace absl {}
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: namespace 'absl' is reserved for implementation of the Abseil library and should not be opened in user code [abseil-no-namespace]
+
+namespace absl {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: namespace 'absl'
+namespace std {
+int i = 5;
+}
+}
+
+// Things that shouldn't trigger the check
+int i = 5;
+namespace std {}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-redundant-strcat-calls.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-redundant-strcat-calls.cpp
new file mode 100644
index 0000000..2d72379
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-redundant-strcat-calls.cpp
@@ -0,0 +1,188 @@
+// RUN: %check_clang_tidy %s abseil-redundant-strcat-calls %t
+
+int strlen(const char *);
+
+// Here we mimic the hierarchy of ::string.
+// We need to do so because we are matching on the fully qualified name of the
+// methods.
+struct __sso_string_base {};
+namespace __gnu_cxx {
+template <typename A, typename B, typename C, typename D = __sso_string_base>
+class __versa_string {
+ public:
+ const char *c_str() const;
+ const char *data() const;
+ int size() const;
+ int capacity() const;
+ int length() const;
+ bool empty() const;
+ char &operator[](int);
+ void clear();
+ void resize(int);
+ int compare(const __versa_string &) const;
+};
+} // namespace __gnu_cxx
+
+namespace std {
+template <typename T>
+class char_traits {};
+template <typename T>
+class allocator {};
+} // namespace std
+
+template <typename A, typename B = std::char_traits<A>,
+ typename C = std::allocator<A>>
+class basic_string : public __gnu_cxx::__versa_string<A, B, C> {
+ public:
+ basic_string();
+ basic_string(const basic_string &);
+ basic_string(const char *, C = C());
+ basic_string(const char *, int, C = C());
+ basic_string(const basic_string &, int, int, C = C());
+ ~basic_string();
+
+ basic_string &operator+=(const basic_string &);
+};
+
+template <typename A, typename B, typename C>
+basic_string<A, B, C> operator+(const basic_string<A, B, C> &,
+ const basic_string<A, B, C> &);
+template <typename A, typename B, typename C>
+basic_string<A, B, C> operator+(const basic_string<A, B, C> &, const char *);
+
+typedef basic_string<char> string;
+
+bool operator==(const string &, const string &);
+bool operator==(const string &, const char *);
+bool operator==(const char *, const string &);
+
+bool operator!=(const string &, const string &);
+bool operator<(const string &, const string &);
+bool operator>(const string &, const string &);
+bool operator<=(const string &, const string &);
+bool operator>=(const string &, const string &);
+
+namespace std {
+template <typename _CharT, typename _Traits = char_traits<_CharT>,
+ typename _Alloc = allocator<_CharT>>
+class basic_string;
+
+template <typename _CharT, typename _Traits, typename _Alloc>
+class basic_string {
+ public:
+ basic_string();
+ basic_string(const basic_string &);
+ basic_string(const char *, const _Alloc & = _Alloc());
+ basic_string(const char *, int, const _Alloc & = _Alloc());
+ basic_string(const basic_string &, int, int, const _Alloc & = _Alloc());
+ ~basic_string();
+
+ basic_string &operator+=(const basic_string &);
+
+ unsigned size() const;
+ unsigned length() const;
+ bool empty() const;
+};
+
+typedef basic_string<char> string;
+} // namespace std
+
+namespace absl {
+
+class string_view {
+ public:
+ typedef std::char_traits<char> traits_type;
+
+ string_view();
+ string_view(const char *);
+ string_view(const string &);
+ string_view(const char *, int);
+ string_view(string_view, int);
+
+ template <typename A>
+ explicit operator ::basic_string<char, traits_type, A>() const;
+
+ const char *data() const;
+ int size() const;
+ int length() const;
+};
+
+bool operator==(string_view A, string_view B);
+
+struct AlphaNum {
+ AlphaNum(int i);
+ AlphaNum(double f);
+ AlphaNum(const char *c_str);
+ AlphaNum(const string &str);
+ AlphaNum(const string_view &pc);
+
+ private:
+ AlphaNum(const AlphaNum &);
+ AlphaNum &operator=(const AlphaNum &);
+};
+
+string StrCat(const AlphaNum &A);
+string StrCat(const AlphaNum &A, const AlphaNum &B);
+string StrCat(const AlphaNum &A, const AlphaNum &B, const AlphaNum &C);
+string StrCat(const AlphaNum &A, const AlphaNum &B, const AlphaNum &C,
+ const AlphaNum &D);
+
+// Support 5 or more arguments
+template <typename... AV>
+string StrCat(const AlphaNum &A, const AlphaNum &B, const AlphaNum &C,
+ const AlphaNum &D, const AlphaNum &E, const AV &... args);
+
+void StrAppend(string *Dest, const AlphaNum &A);
+void StrAppend(string *Dest, const AlphaNum &A, const AlphaNum &B);
+void StrAppend(string *Dest, const AlphaNum &A, const AlphaNum &B,
+ const AlphaNum &C);
+void StrAppend(string *Dest, const AlphaNum &A, const AlphaNum &B,
+ const AlphaNum &C, const AlphaNum &D);
+
+// Support 5 or more arguments
+template <typename... AV>
+void StrAppend(string *Dest, const AlphaNum &A, const AlphaNum &B,
+ const AlphaNum &C, const AlphaNum &D, const AlphaNum &E,
+ const AV &... args);
+
+} // namespace absl
+
+using absl::AlphaNum;
+using absl::StrAppend;
+using absl::StrCat;
+
+void Positives() {
+ string S = StrCat(1, StrCat("A", StrCat(1.1)));
+ // CHECK-MESSAGES: [[@LINE-1]]:14: warning: multiple calls to 'absl::StrCat' can be flattened into a single call
+
+ S = StrCat(StrCat(StrCat(StrCat(StrCat(1)))));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: multiple calls to 'absl::StrCat' can be flattened into a single call
+
+ // TODO: should trigger. The issue here is that in the current
+ // implementation we ignore any StrCat with StrCat ancestors. Therefore
+ // inserting anything in between calls will disable triggering the deepest
+ // ones.
+ // s = StrCat(Identity(StrCat(StrCat(1, 2), StrCat(3, 4))));
+
+ StrAppend(&S, 001, StrCat(1, 2, "3"), StrCat("FOO"));
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple calls to 'absl::StrCat' can be flattened into a single call
+
+ StrAppend(&S, 001, StrCat(StrCat(1, 2), "3"), StrCat("FOO"));
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple calls to 'absl::StrCat' can be flattened into a single call
+
+ // Too many args. Ignore for now.
+ S = StrCat(1, 2, StrCat(3, 4, 5, 6, 7), 8, 9, 10,
+ StrCat(11, 12, 13, 14, 15, 16, 17, 18), 19, 20, 21, 22, 23, 24, 25,
+ 26, 27);
+ // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: multiple calls to 'absl::StrCat' can be flattened into a single call
+ StrAppend(&S, StrCat(1, 2, 3, 4, 5), StrCat(6, 7, 8, 9, 10));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: multiple calls to 'absl::StrCat' can be flattened into a single call
+}
+
+void Negatives() {
+ // One arg. It is used for conversion. Ignore.
+ string S = StrCat(1);
+
+#define A_MACRO(x, y, z) StrCat(x, y, z)
+ S = A_MACRO(1, 2, StrCat("A", "B"));
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-str-cat-append.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-str-cat-append.cpp
new file mode 100644
index 0000000..5ecb284
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-str-cat-append.cpp
@@ -0,0 +1,129 @@
+// RUN: %check_clang_tidy %s abseil-str-cat-append %t -- -- -I%S -std=c++11
+
+typedef unsigned __INT16_TYPE__ char16;
+typedef unsigned __INT32_TYPE__ char32;
+typedef __SIZE_TYPE__ size;
+
+namespace std {
+template <typename T>
+class allocator {};
+template <typename T>
+class char_traits {};
+template <typename C, typename T, typename A>
+struct basic_string {
+ typedef basic_string<C, T, A> _Type;
+ basic_string();
+ basic_string(const C* p, const A& a = A());
+
+ const C* c_str() const;
+ const C* data() const;
+
+ _Type& append(const C* s);
+ _Type& append(const C* s, size n);
+ _Type& assign(const C* s);
+ _Type& assign(const C* s, size n);
+
+ int compare(const _Type&) const;
+ int compare(const C* s) const;
+ int compare(size pos, size len, const _Type&) const;
+ int compare(size pos, size len, const C* s) const;
+
+ size find(const _Type& str, size pos = 0) const;
+ size find(const C* s, size pos = 0) const;
+ size find(const C* s, size pos, size n) const;
+
+ _Type& insert(size pos, const _Type& str);
+ _Type& insert(size pos, const C* s);
+ _Type& insert(size pos, const C* s, size n);
+
+ _Type& operator+=(const _Type& str);
+ _Type& operator+=(const C* s);
+ _Type& operator=(const _Type& str);
+ _Type& operator=(const C* s);
+};
+
+typedef basic_string<char, std::char_traits<char>, std::allocator<char>> string;
+typedef basic_string<wchar_t, std::char_traits<wchar_t>,
+ std::allocator<wchar_t>>
+ wstring;
+typedef basic_string<char16, std::char_traits<char16>, std::allocator<char16>>
+ u16string;
+typedef basic_string<char32, std::char_traits<char32>, std::allocator<char32>>
+ u32string;
+} // namespace std
+
+std::string operator+(const std::string&, const std::string&);
+std::string operator+(const std::string&, const char*);
+std::string operator+(const char*, const std::string&);
+
+bool operator==(const std::string&, const std::string&);
+bool operator==(const std::string&, const char*);
+bool operator==(const char*, const std::string&);
+
+namespace llvm {
+struct StringRef {
+ StringRef(const char* p);
+ StringRef(const std::string&);
+};
+} // namespace llvm
+
+namespace absl {
+
+struct AlphaNum {
+ AlphaNum(int i);
+ AlphaNum(double f);
+ AlphaNum(const char* c_str);
+ AlphaNum(const std::string& str);
+
+ private:
+ AlphaNum(const AlphaNum&);
+ AlphaNum& operator=(const AlphaNum&);
+};
+
+std::string StrCat(const AlphaNum& A);
+std::string StrCat(const AlphaNum& A, const AlphaNum& B);
+
+template <typename A>
+void Foo(A& a) {
+ a = StrCat(a);
+}
+
+void Bar() {
+ std::string A, B;
+ Foo<std::string>(A);
+
+ std::string C = StrCat(A);
+ A = StrCat(A);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: call to 'absl::StrCat' has no effect
+ A = StrCat(A, B);
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: call 'absl::StrAppend' instead of 'absl::StrCat' when appending to a string to avoid a performance penalty
+// CHECK-FIXES: {{^}} absl::StrAppend(&A, B);
+ B = StrCat(A, B);
+
+#define M(X) X = StrCat(X, A)
+ M(B);
+// CHECK-MESSAGES: [[@LINE-1]]:5: warning: call 'absl::StrAppend' instead of 'absl::StrCat' when appending to a string to avoid a performance penalty
+// CHECK-FIXES: #define M(X) X = StrCat(X, A)
+}
+
+void Regression_SelfAppend() {
+ std::string A;
+ A = StrCat(A, A);
+}
+
+} // namespace absl
+
+void OutsideAbsl() {
+ std::string A, B;
+ A = absl::StrCat(A, B);
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: call 'absl::StrAppend' instead of 'absl::StrCat' when appending to a string to avoid a performance penalty
+// CHECK-FIXES: {{^}} absl::StrAppend(&A, B);
+}
+
+void OutsideUsingAbsl() {
+ std::string A, B;
+ using absl::StrCat;
+ A = StrCat(A, B);
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: call 'absl::StrAppend' instead of 'absl::StrCat' when appending to a string to avoid a performance penalty
+// CHECK-FIXES: {{^}} absl::StrAppend(&A, B);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-string-find-startswith.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-string-find-startswith.cpp
new file mode 100644
index 0000000..7d5fd73
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-string-find-startswith.cpp
@@ -0,0 +1,70 @@
+// RUN: %check_clang_tidy %s abseil-string-find-startswith %t -- \
+// RUN: -config="{CheckOptions: [{key: 'abseil-string-find-startswith.StringLikeClasses', value: '::std::basic_string;::basic_string'}]}" \
+// RUN: -- -std=c++11
+
+namespace std {
+template <typename T> class allocator {};
+template <typename T> class char_traits {};
+template <typename C, typename T = std::char_traits<C>,
+ typename A = std::allocator<C>>
+struct basic_string {
+ basic_string();
+ basic_string(const basic_string &);
+ basic_string(const C *, const A &a = A());
+ ~basic_string();
+ int find(basic_string<C> s, int pos = 0);
+ int find(const char *s, int pos = 0);
+};
+typedef basic_string<char> string;
+typedef basic_string<wchar_t> wstring;
+
+struct cxx_string {
+ int find(const char *s, int pos = 0);
+};
+} // namespace std
+
+struct basic_string : public std::cxx_string {
+ basic_string();
+};
+typedef basic_string global_string;
+
+std::string foo(std::string);
+std::string bar();
+
+#define A_MACRO(x, y) ((x) == (y))
+
+void tests(std::string s, global_string s2) {
+ s.find("a") == 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith instead of find() == 0 [abseil-string-find-startswith]
+ // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s, "a");{{$}}
+
+ s.find(s) == 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith
+ // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s, s);{{$}}
+
+ s.find("aaa") != 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StartsWith
+ // CHECK-FIXES: {{^[[:space:]]*}}!absl::StartsWith(s, "aaa");{{$}}
+
+ s.find(foo(foo(bar()))) != 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StartsWith
+ // CHECK-FIXES: {{^[[:space:]]*}}!absl::StartsWith(s, foo(foo(bar())));{{$}}
+
+ if (s.find("....") == 0) { /* do something */ }
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use absl::StartsWith
+ // CHECK-FIXES: {{^[[:space:]]*}}if (absl::StartsWith(s, "....")) { /* do something */ }{{$}}
+
+ 0 != s.find("a");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StartsWith
+ // CHECK-FIXES: {{^[[:space:]]*}}!absl::StartsWith(s, "a");{{$}}
+
+ s2.find("a") == 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith
+ // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s2, "a");{{$}}
+
+ // expressions that don't trigger the check are here.
+ A_MACRO(s.find("a"), 0);
+ s.find("a", 1) == 0;
+ s.find("a", 1) == 1;
+ s.find("a") == 1;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-upgrade-duration-conversions.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-upgrade-duration-conversions.cpp
new file mode 100644
index 0000000..7d8ad43
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/abseil-upgrade-duration-conversions.cpp
@@ -0,0 +1,432 @@
+// RUN: %check_clang_tidy %s abseil-upgrade-duration-conversions %t -- -- -I%S/Inputs
+
+using int64_t = long long;
+
+#include "absl/time/time.h"
+
+template <typename T> struct ConvertibleTo {
+ operator T() const;
+};
+
+template <typename T>
+ConvertibleTo<T> operator+(ConvertibleTo<T>, ConvertibleTo<T>);
+
+template <typename T>
+ConvertibleTo<T> operator*(ConvertibleTo<T>, ConvertibleTo<T>);
+
+void arithmeticOperatorBasicPositive() {
+ absl::Duration d;
+ d *= ConvertibleTo<int64_t>();
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d *= static_cast<int64_t>(ConvertibleTo<int64_t>());
+ d /= ConvertibleTo<int64_t>();
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d /= static_cast<int64_t>(ConvertibleTo<int64_t>());
+ d = ConvertibleTo<int64_t>() * d;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d = static_cast<int64_t>(ConvertibleTo<int64_t>()) * d;
+ d = d * ConvertibleTo<int64_t>();
+ // CHECK-MESSAGES: [[@LINE-1]]:11: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d = d * static_cast<int64_t>(ConvertibleTo<int64_t>());
+ d = d / ConvertibleTo<int64_t>();
+ // CHECK-MESSAGES: [[@LINE-1]]:11: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d = d / static_cast<int64_t>(ConvertibleTo<int64_t>());
+ d.operator*=(ConvertibleTo<int64_t>());
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d.operator*=(static_cast<int64_t>(ConvertibleTo<int64_t>()));
+ d.operator/=(ConvertibleTo<int64_t>());
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d.operator/=(static_cast<int64_t>(ConvertibleTo<int64_t>()));
+ d = operator*(ConvertibleTo<int64_t>(), d);
+ // CHECK-MESSAGES: [[@LINE-1]]:17: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d = operator*(static_cast<int64_t>(ConvertibleTo<int64_t>()), d);
+ d = operator*(d, ConvertibleTo<int64_t>());
+ // CHECK-MESSAGES: [[@LINE-1]]:20: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d = operator*(d, static_cast<int64_t>(ConvertibleTo<int64_t>()));
+ d = operator/(d, ConvertibleTo<int64_t>());
+ // CHECK-MESSAGES: [[@LINE-1]]:20: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d = operator/(d, static_cast<int64_t>(ConvertibleTo<int64_t>()));
+ ConvertibleTo<int64_t> c;
+ d *= (c + c) * c + c;
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d *= static_cast<int64_t>((c + c) * c + c)
+ d /= (c + c) * c + c;
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d /= static_cast<int64_t>((c + c) * c + c)
+ d = d * c * c;
+ // CHECK-MESSAGES: [[@LINE-1]]:11: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-MESSAGES: [[@LINE-2]]:15: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d = d * static_cast<int64_t>(c) * static_cast<int64_t>(c)
+ d = c * d * c;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-MESSAGES: [[@LINE-2]]:15: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d = static_cast<int64_t>(c) * d * static_cast<int64_t>(c)
+ d = d / c * c;
+ // CHECK-MESSAGES: [[@LINE-1]]:11: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-MESSAGES: [[@LINE-2]]:15: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d = d / static_cast<int64_t>(c) * static_cast<int64_t>(c)
+}
+
+void arithmeticOperatorBasicNegative() {
+ absl::Duration d;
+ d *= char{1};
+ d *= 1;
+ d *= int64_t{1};
+ d *= 1.0f;
+ d *= 1.0;
+ d *= 1.0l;
+ d /= char{1};
+ d /= 1;
+ d /= int64_t{1};
+ d /= 1.0f;
+ d /= 1.0;
+ d /= 1.0l;
+ d = d * char{1};
+ d = d * 1;
+ d = d * int64_t{1};
+ d = d * 1.0f;
+ d = d * 1.0;
+ d = d * 1.0l;
+ d = char{1} * d;
+ d = 1 * d;
+ d = int64_t{1} * d;
+ d = 1.0f * d;
+ d = 1.0 * d;
+ d = 1.0l * d;
+ d = d / char{1};
+ d = d / 1;
+ d = d / int64_t{1};
+ d = d / 1.0f;
+ d = d / 1.0;
+ d = d / 1.0l;
+
+ d *= static_cast<int>(ConvertibleTo<int>());
+ d *= (int)ConvertibleTo<int>();
+ d *= int(ConvertibleTo<int>());
+ d /= static_cast<int>(ConvertibleTo<int>());
+ d /= (int)ConvertibleTo<int>();
+ d /= int(ConvertibleTo<int>());
+ d = static_cast<int>(ConvertibleTo<int>()) * d;
+ d = (int)ConvertibleTo<int>() * d;
+ d = int(ConvertibleTo<int>()) * d;
+ d = d * static_cast<int>(ConvertibleTo<int>());
+ d = d * (int)ConvertibleTo<int>();
+ d = d * int(ConvertibleTo<int>());
+ d = d / static_cast<int>(ConvertibleTo<int>());
+ d = d / (int)ConvertibleTo<int>();
+ d = d / int(ConvertibleTo<int>());
+
+ d *= 1 + ConvertibleTo<int>();
+ d /= 1 + ConvertibleTo<int>();
+ d = (1 + ConvertibleTo<int>()) * d;
+ d = d * (1 + ConvertibleTo<int>());
+ d = d / (1 + ConvertibleTo<int>());
+}
+
+template <typename T> void templateForOpsSpecialization(T) {}
+template <>
+void templateForOpsSpecialization<absl::Duration>(absl::Duration d) {
+ d *= ConvertibleTo<int64_t>();
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d *= static_cast<int64_t>(ConvertibleTo<int64_t>());
+}
+
+template <int N> void arithmeticNonTypeTemplateParamSpecialization() {
+ absl::Duration d;
+ d *= N;
+}
+
+template <> void arithmeticNonTypeTemplateParamSpecialization<5>() {
+ absl::Duration d;
+ d *= ConvertibleTo<int>();
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d *= static_cast<int64_t>(ConvertibleTo<int>());
+}
+
+template <typename T> void templateOpsFix() {
+ absl::Duration d;
+ d *= ConvertibleTo<int64_t>();
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d *= static_cast<int64_t>(ConvertibleTo<int64_t>());
+}
+
+template <typename T, typename U> void templateOpsWarnOnly(T t, U u) {
+ t *= u;
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ absl::Duration d;
+ d *= u;
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+}
+
+template <typename T> struct TemplateTypeOpsWarnOnly {
+ void memberA(T t) {
+ d *= t;
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ }
+ template <typename U, typename V> void memberB(U u, V v) {
+ u *= v;
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ d *= v;
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ }
+
+ absl::Duration d;
+};
+
+template <typename T, typename U>
+void templateOpsInstantiationBeforeDefinition(T t, U u);
+
+void arithmeticOperatorsInTemplates() {
+ templateForOpsSpecialization(5);
+ templateForOpsSpecialization(absl::Duration());
+ arithmeticNonTypeTemplateParamSpecialization<1>();
+ arithmeticNonTypeTemplateParamSpecialization<5>();
+ templateOpsFix<int>();
+ templateOpsWarnOnly(absl::Duration(), ConvertibleTo<int>());
+ templateOpsInstantiationBeforeDefinition(absl::Duration(),
+ ConvertibleTo<int>());
+ TemplateTypeOpsWarnOnly<ConvertibleTo<int>> t;
+ t.memberA(ConvertibleTo<int>());
+ t.memberB(absl::Duration(), ConvertibleTo<int>());
+}
+
+template <typename T, typename U>
+void templateOpsInstantiationBeforeDefinition(T t, U u) {
+ t *= u;
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ absl::Duration d;
+ d *= u;
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+}
+
+#define FUNCTION_MACRO(x) x
+#define CONVERTIBLE_TMP ConvertibleTo<int>()
+#define ONLY_WARN_INSIDE_MACRO_ARITHMETIC_OP d *= ConvertibleTo<int>()
+
+#define T_OBJECT T()
+#define T_CALL_EXPR d *= T()
+
+template <typename T> void arithmeticTemplateAndMacro() {
+ absl::Duration d;
+ d *= T_OBJECT;
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ d *= CONVERTIBLE_TMP;
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d *= static_cast<int64_t>(CONVERTIBLE_TMP);
+ T_CALL_EXPR;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+}
+
+#define TEMPLATE_MACRO(type) \
+ template <typename T> void TemplateInMacro(T t) { \
+ type d; \
+ d *= t; \
+ }
+
+TEMPLATE_MACRO(absl::Duration)
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+
+void arithmeticOperatorsInMacros() {
+ absl::Duration d;
+ d = FUNCTION_MACRO(d * ConvertibleTo<int>());
+ // CHECK-MESSAGES: [[@LINE-1]]:26: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d = FUNCTION_MACRO(d * static_cast<int64_t>(ConvertibleTo<int>()));
+ d *= FUNCTION_MACRO(ConvertibleTo<int>());
+ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d *= static_cast<int64_t>(FUNCTION_MACRO(ConvertibleTo<int>()));
+ d *= CONVERTIBLE_TMP;
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: d *= static_cast<int64_t>(CONVERTIBLE_TMP);
+ ONLY_WARN_INSIDE_MACRO_ARITHMETIC_OP;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ arithmeticTemplateAndMacro<ConvertibleTo<int>>();
+ TemplateInMacro(ConvertibleTo<int>());
+}
+
+void factoryFunctionPositive() {
+ // User defined conversion:
+ (void)absl::Nanoseconds(ConvertibleTo<int64_t>());
+ // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(ConvertibleTo<int64_t>()));
+ (void)absl::Microseconds(ConvertibleTo<int64_t>());
+ // CHECK-MESSAGES: [[@LINE-1]]:28: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Microseconds(static_cast<int64_t>(ConvertibleTo<int64_t>()));
+ (void)absl::Milliseconds(ConvertibleTo<int64_t>());
+ // CHECK-MESSAGES: [[@LINE-1]]:28: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Milliseconds(static_cast<int64_t>(ConvertibleTo<int64_t>()));
+ (void)absl::Seconds(ConvertibleTo<int64_t>());
+ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Seconds(static_cast<int64_t>(ConvertibleTo<int64_t>()));
+ (void)absl::Minutes(ConvertibleTo<int64_t>());
+ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Minutes(static_cast<int64_t>(ConvertibleTo<int64_t>()));
+ (void)absl::Hours(ConvertibleTo<int64_t>());
+ // CHECK-MESSAGES: [[@LINE-1]]:21: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Hours(static_cast<int64_t>(ConvertibleTo<int64_t>()));
+
+ // User defined conversion to integral type, followed by built-in conversion:
+ (void)absl::Nanoseconds(ConvertibleTo<char>());
+ // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(ConvertibleTo<char>()));
+ (void)absl::Microseconds(ConvertibleTo<char>());
+ // CHECK-MESSAGES: [[@LINE-1]]:28: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Microseconds(static_cast<int64_t>(ConvertibleTo<char>()));
+ (void)absl::Milliseconds(ConvertibleTo<char>());
+ // CHECK-MESSAGES: [[@LINE-1]]:28: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Milliseconds(static_cast<int64_t>(ConvertibleTo<char>()));
+ (void)absl::Seconds(ConvertibleTo<char>());
+ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Seconds(static_cast<int64_t>(ConvertibleTo<char>()));
+ (void)absl::Minutes(ConvertibleTo<char>());
+ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Minutes(static_cast<int64_t>(ConvertibleTo<char>()));
+ (void)absl::Hours(ConvertibleTo<char>());
+ // CHECK-MESSAGES: [[@LINE-1]]:21: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Hours(static_cast<int64_t>(ConvertibleTo<char>()));
+
+ // User defined conversion to floating point type, followed by built-in conversion:
+ (void)absl::Nanoseconds(ConvertibleTo<float>());
+ // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(ConvertibleTo<float>()));
+ (void)absl::Microseconds(ConvertibleTo<float>());
+ // CHECK-MESSAGES: [[@LINE-1]]:28: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Microseconds(static_cast<int64_t>(ConvertibleTo<float>()));
+ (void)absl::Milliseconds(ConvertibleTo<float>());
+ // CHECK-MESSAGES: [[@LINE-1]]:28: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Milliseconds(static_cast<int64_t>(ConvertibleTo<float>()));
+ (void)absl::Seconds(ConvertibleTo<float>());
+ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Seconds(static_cast<int64_t>(ConvertibleTo<float>()));
+ (void)absl::Minutes(ConvertibleTo<float>());
+ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Minutes(static_cast<int64_t>(ConvertibleTo<float>()));
+ (void)absl::Hours(ConvertibleTo<float>());
+ // CHECK-MESSAGES: [[@LINE-1]]:21: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Hours(static_cast<int64_t>(ConvertibleTo<float>()));
+}
+
+void factoryFunctionNegative() {
+ (void)absl::Nanoseconds(char{1});
+ (void)absl::Nanoseconds(1);
+ (void)absl::Nanoseconds(int64_t{1});
+ (void)absl::Nanoseconds(1.0f);
+ (void)absl::Microseconds(char{1});
+ (void)absl::Microseconds(1);
+ (void)absl::Microseconds(int64_t{1});
+ (void)absl::Microseconds(1.0f);
+ (void)absl::Milliseconds(char{1});
+ (void)absl::Milliseconds(1);
+ (void)absl::Milliseconds(int64_t{1});
+ (void)absl::Milliseconds(1.0f);
+ (void)absl::Seconds(char{1});
+ (void)absl::Seconds(1);
+ (void)absl::Seconds(int64_t{1});
+ (void)absl::Seconds(1.0f);
+ (void)absl::Minutes(char{1});
+ (void)absl::Minutes(1);
+ (void)absl::Minutes(int64_t{1});
+ (void)absl::Minutes(1.0f);
+ (void)absl::Hours(char{1});
+ (void)absl::Hours(1);
+ (void)absl::Hours(int64_t{1});
+ (void)absl::Hours(1.0f);
+
+ (void)absl::Nanoseconds(static_cast<int>(ConvertibleTo<int>()));
+ (void)absl::Microseconds(static_cast<int>(ConvertibleTo<int>()));
+ (void)absl::Milliseconds(static_cast<int>(ConvertibleTo<int>()));
+ (void)absl::Seconds(static_cast<int>(ConvertibleTo<int>()));
+ (void)absl::Minutes(static_cast<int>(ConvertibleTo<int>()));
+ (void)absl::Hours(static_cast<int>(ConvertibleTo<int>()));
+}
+
+template <typename T> void templateForFactorySpecialization(T) {}
+template <> void templateForFactorySpecialization<ConvertibleTo<int>>(ConvertibleTo<int> c) {
+ (void)absl::Nanoseconds(c);
+ // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(c));
+}
+
+template <int N> void factoryNonTypeTemplateParamSpecialization() {
+ (void)absl::Nanoseconds(N);
+}
+
+template <> void factoryNonTypeTemplateParamSpecialization<5>() {
+ (void)absl::Nanoseconds(ConvertibleTo<int>());
+ // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(ConvertibleTo<int>()));
+}
+
+template <typename T> void templateFactoryFix() {
+ (void)absl::Nanoseconds(ConvertibleTo<int>());
+ // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(ConvertibleTo<int>()));
+}
+
+template <typename T> void templateFactoryWarnOnly(T t) {
+ (void)absl::Nanoseconds(t);
+ // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+}
+
+template <typename T> void templateFactoryInstantiationBeforeDefinition(T t);
+
+template <typename T> struct TemplateTypeFactoryWarnOnly {
+ void memberA(T t) {
+ (void)absl::Nanoseconds(t);
+ // CHECK-MESSAGES: [[@LINE-1]]:29: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ }
+ template <typename U> void memberB(U u) {
+ (void)absl::Nanoseconds(u);
+ // CHECK-MESSAGES: [[@LINE-1]]:29: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ }
+};
+
+void factoryInTemplates() {
+ templateForFactorySpecialization(5);
+ templateForFactorySpecialization(ConvertibleTo<int>());
+ factoryNonTypeTemplateParamSpecialization<1>();
+ factoryNonTypeTemplateParamSpecialization<5>();
+ templateFactoryFix<int>();
+ templateFactoryWarnOnly(ConvertibleTo<int>());
+ templateFactoryInstantiationBeforeDefinition(ConvertibleTo<int>());
+ TemplateTypeFactoryWarnOnly<ConvertibleTo<int>> t;
+ t.memberA(ConvertibleTo<int>());
+ t.memberB(ConvertibleTo<int>());
+}
+
+template <typename T> void templateFactoryInstantiationBeforeDefinition(T t) {
+ (void)absl::Nanoseconds(t);
+ // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+}
+
+#define ONLY_WARN_INSIDE_MACRO_FACTORY \
+ (void)absl::Nanoseconds(ConvertibleTo<int>())
+#define T_CALL_FACTORTY_INSIDE_MACRO (void)absl::Nanoseconds(T())
+
+template <typename T> void factoryTemplateAndMacro() {
+ (void)absl::Nanoseconds(T_OBJECT);
+ // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ (void)absl::Nanoseconds(CONVERTIBLE_TMP);
+ // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(CONVERTIBLE_TMP))
+ T_CALL_FACTORTY_INSIDE_MACRO;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+}
+
+#define TEMPLATE_FACTORY_MACRO(factory) \
+ template <typename T> void TemplateFactoryInMacro(T t) { (void)factory(t); }
+
+TEMPLATE_FACTORY_MACRO(absl::Nanoseconds)
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+
+void factoryInMacros() {
+ (void)absl::Nanoseconds(FUNCTION_MACRO(ConvertibleTo<int>()));
+ // CHECK-MESSAGES: [[@LINE-1]]:42: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(FUNCTION_MACRO(ConvertibleTo<int>())));
+ (void)absl::Nanoseconds(CONVERTIBLE_TMP);
+ // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(CONVERTIBLE_TMP))
+ ONLY_WARN_INSIDE_MACRO_FACTORY;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
+ factoryTemplateAndMacro<ConvertibleTo<int>>();
+ TemplateFactoryInMacro(ConvertibleTo<int>());
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-accept.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-accept.cpp
new file mode 100644
index 0000000..9990594
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-accept.cpp
@@ -0,0 +1,28 @@
+// RUN: %check_clang_tidy %s android-cloexec-accept %t
+
+struct sockaddr {};
+typedef int socklen_t;
+#define NULL 0
+
+extern "C" int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
+
+void f() {
+ accept(0, NULL, NULL);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer accept4() to accept() because accept4() allows SOCK_CLOEXEC [android-cloexec-accept]
+ // CHECK-FIXES: accept4(0, NULL, NULL, SOCK_CLOEXEC);
+}
+
+namespace i {
+int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
+void g() {
+ accept(0, NULL, NULL);
+}
+} // namespace i
+
+class C {
+public:
+ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
+ void h() {
+ accept(0, NULL, NULL);
+ }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-accept4.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-accept4.cpp
new file mode 100644
index 0000000..448d4a9
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-accept4.cpp
@@ -0,0 +1,66 @@
+// RUN: %check_clang_tidy %s android-cloexec-accept4 %t
+
+typedef int socklen_t;
+struct sockaddr {};
+
+#define SOCK_NONBLOCK 1
+#define __O_CLOEXEC 3
+#define SOCK_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+ ({ \
+ int _rc; \
+ do { \
+ _rc = (exp); \
+ } while (_rc == -1); \
+ })
+#define NULL 0
+
+extern "C" int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
+
+void a() {
+ accept4(0, NULL, NULL, SOCK_NONBLOCK);
+ // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: 'accept4' should use SOCK_CLOEXEC where possible [android-cloexec-accept4]
+ // CHECK-FIXES: accept4(0, NULL, NULL, SOCK_NONBLOCK | SOCK_CLOEXEC);
+ TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, SOCK_NONBLOCK));
+ // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: 'accept4'
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, SOCK_NONBLOCK | SOCK_CLOEXEC));
+}
+
+void f() {
+ accept4(0, NULL, NULL, 3);
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'accept4'
+ // CHECK-FIXES: accept4(0, NULL, NULL, 3 | SOCK_CLOEXEC);
+ TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, 3));
+ // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: 'accept4'
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, 3 | SOCK_CLOEXEC));
+
+ int flag = SOCK_NONBLOCK;
+ accept4(0, NULL, NULL, flag);
+ TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, flag));
+}
+
+namespace i {
+int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
+
+void d() {
+ accept4(0, NULL, NULL, SOCK_NONBLOCK);
+ TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, SOCK_NONBLOCK));
+}
+
+} // namespace i
+
+void e() {
+ accept4(0, NULL, NULL, SOCK_CLOEXEC);
+ TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, SOCK_CLOEXEC));
+ accept4(0, NULL, NULL, SOCK_NONBLOCK | SOCK_CLOEXEC);
+ TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, SOCK_NONBLOCK | SOCK_CLOEXEC));
+}
+
+class G {
+public:
+ int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
+ void d() {
+ accept4(0, NULL, NULL, SOCK_NONBLOCK);
+ TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, SOCK_NONBLOCK));
+ }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-creat.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-creat.cpp
new file mode 100644
index 0000000..df57b10
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-creat.cpp
@@ -0,0 +1,35 @@
+// RUN: %check_clang_tidy %s android-cloexec-creat %t
+
+typedef int mode_t;
+
+extern "C" int creat(const char *path, mode_t, ...);
+extern "C" int create(const char *path, mode_t, ...);
+
+void f() {
+ creat("filename", 0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer open() to creat() because open() allows O_CLOEXEC [android-cloexec-creat]
+ // CHECK-FIXES: open ("filename", O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0);
+ create("filename", 0);
+ // CHECK-MESSAGES-NOT: warning:
+ mode_t mode = 0755;
+ creat("filename", mode);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning:
+ // CHECK-FIXES: open ("filename", O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, mode);
+}
+
+namespace i {
+int creat(const char *path, mode_t, ...);
+void g() {
+ creat("filename", 0);
+ // CHECK-MESSAGES-NOT: warning:
+}
+} // namespace i
+
+class C {
+public:
+ int creat(const char *path, mode_t, ...);
+ void h() {
+ creat("filename", 0);
+ // CHECK-MESSAGES-NOT: warning:
+ }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-dup.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-dup.cpp
new file mode 100644
index 0000000..f7011b8
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-dup.cpp
@@ -0,0 +1,31 @@
+// RUN: %check_clang_tidy %s android-cloexec-dup %t
+
+extern "C" int dup(int oldfd);
+void f() {
+ dup(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer fcntl() to dup() because fcntl() allows F_DUPFD_CLOEXEC [android-cloexec-dup]
+ // CHECK-FIXES: fcntl(1, F_DUPFD_CLOEXEC);
+ int oldfd = 0;
+ dup(oldfd);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer
+ // CHECK-FIXES: fcntl(oldfd, F_DUPFD_CLOEXEC);
+}
+
+namespace i {
+int dup(int oldfd);
+void g() {
+ dup(0);
+ int oldfd = 1;
+ dup(oldfd);
+}
+} // namespace i
+
+class C {
+public:
+ int dup(int oldfd);
+ void h() {
+ dup(0);
+ int oldfd = 1;
+ dup(oldfd);
+ }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-epoll-create.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-epoll-create.cpp
new file mode 100644
index 0000000..d58e493
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-epoll-create.cpp
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s android-cloexec-epoll-create %t
+
+extern "C" int epoll_create(int size);
+
+void f() {
+ epoll_create(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer epoll_create() to epoll_create1() because epoll_create1() allows EPOLL_CLOEXEC [android-cloexec-epoll-create]
+ // CHECK-FIXES: epoll_create1(EPOLL_CLOEXEC);
+}
+
+namespace i {
+int epoll_create(int size);
+void g() {
+ epoll_create(0);
+}
+} // namespace i
+
+class C {
+public:
+ int epoll_create(int size);
+ void h() {
+ epoll_create(0);
+ }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-epoll-create1.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-epoll-create1.cpp
new file mode 100644
index 0000000..696a20c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-epoll-create1.cpp
@@ -0,0 +1,59 @@
+// RUN: %check_clang_tidy %s android-cloexec-epoll-create1 %t
+
+#define __O_CLOEXEC 3
+#define EPOLL_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+ ({ \
+ int _rc; \
+ do { \
+ _rc = (exp); \
+ } while (_rc == -1); \
+ })
+
+extern "C" int epoll_create1(int flags);
+
+void a() {
+ epoll_create1(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'epoll_create1' should use EPOLL_CLOEXEC where possible [android-cloexec-epoll-create1]
+ // CHECK-FIXES: epoll_create1(EPOLL_CLOEXEC);
+ TEMP_FAILURE_RETRY(epoll_create1(0));
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'epoll_create1'
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
+}
+
+void f() {
+ epoll_create1(3);
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'epoll_create1'
+ // CHECK-FIXES: epoll_create1(EPOLL_CLOEXEC);
+ TEMP_FAILURE_RETRY(epoll_create1(3));
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'epoll_create1'
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
+
+ int flag = 0;
+ epoll_create1(EPOLL_CLOEXEC);
+ TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
+}
+
+namespace i {
+int epoll_create1(int flags);
+
+void d() {
+ epoll_create1(0);
+ TEMP_FAILURE_RETRY(epoll_create1(0));
+}
+
+} // namespace i
+
+void e() {
+ epoll_create1(EPOLL_CLOEXEC);
+ TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
+}
+
+class G {
+public:
+ int epoll_create1(int flags);
+ void d() {
+ epoll_create1(EPOLL_CLOEXEC);
+ TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
+ }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-fopen.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-fopen.cpp
new file mode 100644
index 0000000..6b6c655
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-fopen.cpp
@@ -0,0 +1,57 @@
+// RUN: %check_clang_tidy %s android-cloexec-fopen %t
+
+#define FILE_OPEN_RO "r"
+
+typedef int FILE;
+
+extern "C" FILE *fopen(const char *filename, const char *mode, ...);
+extern "C" FILE *open(const char *filename, const char *mode, ...);
+
+void f() {
+ fopen("filename", "r");
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use 'fopen' mode 'e' to set O_CLOEXEC [android-cloexec-fopen]
+ // CHECK-FIXES: fopen("filename", "re");
+
+ fopen("filename", FILE_OPEN_RO);
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use 'fopen' mode 'e'
+ // CHECK-FIXES: fopen("filename", FILE_OPEN_RO "e");
+
+ fopen("filename", "er");
+ // CHECK-MESSAGES-NOT: warning:
+ fopen("filename", "re");
+ // CHECK-MESSAGES-NOT: warning:
+ fopen("filename", "e");
+ // CHECK-MESSAGES-NOT: warning:
+ open("filename", "e");
+ // CHECK-MESSAGES-NOT: warning:
+
+ char *str = "r";
+ fopen("filename", str);
+ // CHECK-MESSAGES-NOT: warning:
+ str = "re";
+ fopen("filename", str);
+ // CHECK-MESSAGES-NOT: warning:
+ char arr[2] = "r";
+ fopen("filename", arr);
+ // CHECK-MESSAGES-NOT: warning:
+ char arr2[3] = "re";
+ fopen("filename", arr2);
+ // CHECK-MESSAGES-NOT: warning:
+}
+
+namespace i {
+int *fopen(const char *filename, const char *mode, ...);
+void g() {
+ fopen("filename", "e");
+ // CHECK-MESSAGES-NOT: warning:
+}
+} // namespace i
+
+class C {
+public:
+ int *fopen(const char *filename, const char *mode, ...);
+ void h() {
+ fopen("filename", "e");
+ // CHECK-MESSAGES-NOT: warning:
+ }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-inotify-init.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-inotify-init.cpp
new file mode 100644
index 0000000..01eb51e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-inotify-init.cpp
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s android-cloexec-inotify-init %t
+
+extern "C" int inotify_init();
+
+void f() {
+ inotify_init();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer inotify_init() to inotify_init1() because inotify_init1() allows IN_CLOEXEC [android-cloexec-inotify-init]
+ // CHECK-FIXES: inotify_init1(IN_CLOEXEC);
+}
+
+namespace i {
+int inotify_init();
+void g() {
+ inotify_init();
+}
+} // namespace i
+
+class C {
+public:
+ int inotify_init();
+ void h() {
+ inotify_init();
+ }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-inotify-init1.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-inotify-init1.cpp
new file mode 100644
index 0000000..2b74fad
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-inotify-init1.cpp
@@ -0,0 +1,64 @@
+// RUN: %check_clang_tidy %s android-cloexec-inotify-init1 %t
+
+#define IN_NONBLOCK 1
+#define __O_CLOEXEC 3
+#define IN_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+ ({ \
+ int _rc; \
+ do { \
+ _rc = (exp); \
+ } while (_rc == -1); \
+ })
+
+extern "C" int inotify_init1(int flags);
+
+void a() {
+ inotify_init1(IN_NONBLOCK);
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: 'inotify_init1' should use IN_CLOEXEC where possible [android-cloexec-inotify-init1]
+ // CHECK-FIXES: inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+ TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK));
+ // CHECK-MESSAGES: :[[@LINE-1]]:47: warning: 'inotify_init1'
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK | IN_CLOEXEC));
+}
+
+void f() {
+ inotify_init1(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'inotify_init1'
+ // CHECK-FIXES: inotify_init1(IN_CLOEXEC);
+ TEMP_FAILURE_RETRY(inotify_init1(0));
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'inotify_init1'
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(inotify_init1(IN_CLOEXEC));
+
+ int flag = 1;
+ inotify_init1(flag);
+ TEMP_FAILURE_RETRY(inotify_init1(flag));
+}
+
+namespace i {
+int inotify_init1(int flags);
+
+void d() {
+ inotify_init1(IN_NONBLOCK);
+ TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK));
+}
+
+} // namespace i
+
+void e() {
+ inotify_init1(IN_CLOEXEC);
+ TEMP_FAILURE_RETRY(inotify_init1(IN_CLOEXEC));
+ inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+ TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK | IN_CLOEXEC));
+}
+
+class G {
+public:
+ int inotify_init1(int flags);
+ void d() {
+ inotify_init1(IN_CLOEXEC);
+ TEMP_FAILURE_RETRY(inotify_init1(IN_CLOEXEC));
+ inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+ TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK | IN_CLOEXEC));
+ }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-memfd-create.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-memfd-create.cpp
new file mode 100644
index 0000000..a8dafd5
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-memfd-create.cpp
@@ -0,0 +1,63 @@
+// RUN: %check_clang_tidy %s android-cloexec-memfd-create %t
+
+#define MFD_ALLOW_SEALING 1
+#define __O_CLOEXEC 3
+#define MFD_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+ ({ \
+ int _rc; \
+ do { \
+ _rc = (exp); \
+ } while (_rc == -1); \
+ })
+#define NULL 0
+
+extern "C" int memfd_create(const char *name, unsigned int flags);
+
+void a() {
+ memfd_create(NULL, MFD_ALLOW_SEALING);
+ // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: 'memfd_create' should use MFD_CLOEXEC where possible [android-cloexec-memfd-create]
+ // CHECK-FIXES: memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC)
+ TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+ // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: 'memfd_create'
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC))
+}
+
+void f() {
+ memfd_create(NULL, 3);
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'memfd_create'
+ // CHECK-FIXES: memfd_create(NULL, 3 | MFD_CLOEXEC)
+ TEMP_FAILURE_RETRY(memfd_create(NULL, 3));
+ // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: 'memfd_create'
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, 3 | MFD_CLOEXEC))
+
+ int flag = 3;
+ memfd_create(NULL, flag);
+ TEMP_FAILURE_RETRY(memfd_create(NULL, flag));
+}
+
+namespace i {
+int memfd_create(const char *name, unsigned int flags);
+
+void d() {
+ memfd_create(NULL, MFD_ALLOW_SEALING);
+ TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+}
+
+} // namespace i
+
+void e() {
+ memfd_create(NULL, MFD_CLOEXEC);
+ TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_CLOEXEC));
+ memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC);
+ TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC));
+}
+
+class G {
+public:
+ int memfd_create(const char *name, unsigned int flags);
+ void d() {
+ memfd_create(NULL, MFD_ALLOW_SEALING);
+ TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+ }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-open.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-open.cpp
new file mode 100644
index 0000000..4ef1f40
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-open.cpp
@@ -0,0 +1,180 @@
+// RUN: %check_clang_tidy %s android-cloexec-open %t
+
+#define O_RDWR 1
+#define O_EXCL 2
+#define __O_CLOEXEC 3
+#define O_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+ ({ \
+ int _rc; \
+ do { \
+ _rc = (exp); \
+ } while (_rc == -1); \
+ })
+
+extern "C" int open(const char *fn, int flags, ...);
+extern "C" int open64(const char *fn, int flags, ...);
+extern "C" int openat(int dirfd, const char *pathname, int flags, ...);
+
+void a() {
+ open("filename", O_RDWR);
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'open' should use O_CLOEXEC where possible [android-cloexec-open]
+ // CHECK-FIXES: O_RDWR | O_CLOEXEC
+ TEMP_FAILURE_RETRY(open("filename", O_RDWR));
+ // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: 'open' should use O_CLOEXEC where
+ // CHECK-FIXES: O_RDWR | O_CLOEXEC
+ open("filename", O_RDWR | O_EXCL);
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: 'open' should use O_CLOEXEC where
+ // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+ TEMP_FAILURE_RETRY(open("filename", O_RDWR | O_EXCL));
+ // CHECK-MESSAGES: :[[@LINE-1]]:54: warning: 'open' should use O_CLOEXEC where
+ // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void b() {
+ open64("filename", O_RDWR);
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: 'open64' should use O_CLOEXEC where possible [android-cloexec-open]
+ // CHECK-FIXES: O_RDWR | O_CLOEXEC
+ TEMP_FAILURE_RETRY(open64("filename", O_RDWR));
+ // CHECK-MESSAGES: :[[@LINE-1]]:47: warning: 'open64' should use O_CLOEXEC where
+ // CHECK-FIXES: O_RDWR | O_CLOEXEC
+ open64("filename", O_RDWR | O_EXCL);
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'open64' should use O_CLOEXEC where
+ // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+ TEMP_FAILURE_RETRY(open64("filename", O_RDWR | O_EXCL));
+ // CHECK-MESSAGES: :[[@LINE-1]]:56: warning: 'open64' should use O_CLOEXEC where
+ // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void c() {
+ openat(0, "filename", O_RDWR);
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'openat' should use O_CLOEXEC where possible [android-cloexec-open]
+ // CHECK-FIXES: O_RDWR | O_CLOEXEC
+ TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR));
+ // CHECK-MESSAGES: :[[@LINE-1]]:50: warning: 'openat' should use O_CLOEXEC where
+ // CHECK-FIXES: O_RDWR | O_CLOEXEC
+ openat(0, "filename", O_RDWR | O_EXCL);
+ // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: 'openat' should use O_CLOEXEC where
+ // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+ TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR | O_EXCL));
+ // CHECK-MESSAGES: :[[@LINE-1]]:59: warning: 'openat' should use O_CLOEXEC where
+ // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void f() {
+ open("filename", 3);
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'open' should use O_CLOEXEC where possible [android-cloexec-open]
+ // CHECK-FIXES: 3 | O_CLOEXEC
+ TEMP_FAILURE_RETRY(open("filename", 3));
+ // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: 'open' should use O_CLOEXEC where
+ // CHECK-FIXES: 3 | O_CLOEXEC
+ open64("filename", 3);
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'open64' should use O_CLOEXEC where possible [android-cloexec-open]
+ // CHECK-FIXES: 3 | O_CLOEXEC
+ TEMP_FAILURE_RETRY(open64("filename", 3));
+ // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: 'open64' should use O_CLOEXEC where
+ // CHECK-FIXES: 3 | O_CLOEXEC
+ openat(0, "filename", 3);
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'openat' should use O_CLOEXEC where possible [android-cloexec-open]
+ // CHECK-FIXES: 3 | O_CLOEXEC
+ TEMP_FAILURE_RETRY(openat(0, "filename", 3));
+ // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: 'openat' should use O_CLOEXEC where
+ // CHECK-FIXES: 3 | O_CLOEXEC
+
+ int flag = 3;
+ open("filename", flag);
+ // CHECK-MESSAGES-NOT: warning:
+ TEMP_FAILURE_RETRY(open("filename", flag));
+ // CHECK-MESSAGES-NOT: warning:
+ open64("filename", flag);
+ // CHECK-MESSAGES-NOT: warning:
+ TEMP_FAILURE_RETRY(open64("filename", flag));
+ // CHECK-MESSAGES-NOT: warning:
+ openat(0, "filename", flag);
+ // CHECK-MESSAGES-NOT: warning:
+ TEMP_FAILURE_RETRY(openat(0, "filename", flag));
+ // CHECK-MESSAGES-NOT: warning:
+}
+
+namespace i {
+int open(const char *pathname, int flags, ...);
+int open64(const char *pathname, int flags, ...);
+int openat(int dirfd, const char *pathname, int flags, ...);
+
+void d() {
+ open("filename", O_RDWR);
+ // CHECK-MESSAGES-NOT: warning:
+ TEMP_FAILURE_RETRY(open("filename", O_RDWR));
+ // CHECK-MESSAGES-NOT: warning:
+ open64("filename", O_RDWR);
+ // CHECK-MESSAGES-NOT: warning:
+ TEMP_FAILURE_RETRY(open64("filename", O_RDWR));
+ // CHECK-MESSAGES-NOT: warning:
+ openat(0, "filename", O_RDWR);
+ // CHECK-MESSAGES-NOT: warning:
+ TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR));
+ // CHECK-MESSAGES-NOT: warning:
+}
+
+} // namespace i
+
+void e() {
+ open("filename", O_CLOEXEC);
+ // CHECK-MESSAGES-NOT: warning:
+ TEMP_FAILURE_RETRY(open("filename", O_CLOEXEC));
+ // CHECK-MESSAGES-NOT: warning:
+ open("filename", O_RDWR | O_CLOEXEC);
+ // CHECK-MESSAGES-NOT: warning:
+ TEMP_FAILURE_RETRY(open("filename", O_RDWR | O_CLOEXEC));
+ // CHECK-MESSAGES-NOT: warning:
+ open("filename", O_RDWR | O_CLOEXEC | O_EXCL);
+ // CHECK-MESSAGES-NOT: warning:
+ TEMP_FAILURE_RETRY(open("filename", O_RDWR | O_CLOEXEC | O_EXCL));
+ // CHECK-MESSAGES-NOT: warning:
+ open64("filename", O_CLOEXEC);
+ // CHECK-MESSAGES-NOT: warning:
+ TEMP_FAILURE_RETRY(open64("filename", O_CLOEXEC));
+ // CHECK-MESSAGES-NOT: warning:
+ open64("filename", O_RDWR | O_CLOEXEC);
+ // CHECK-MESSAGES-NOT: warning:
+ TEMP_FAILURE_RETRY(open64("filename", O_RDWR | O_CLOEXEC));
+ // CHECK-MESSAGES-NOT: warning:
+ open64("filename", O_RDWR | O_CLOEXEC | O_EXCL);
+ // CHECK-MESSAGES-NOT: warning:
+ TEMP_FAILURE_RETRY(open64("filename", O_RDWR | O_CLOEXEC | O_EXCL));
+ // CHECK-MESSAGES-NOT: warning:
+ openat(0, "filename", O_CLOEXEC);
+ // CHECK-MESSAGES-NOT: warning:
+ TEMP_FAILURE_RETRY(openat(0, "filename", O_CLOEXEC));
+ // CHECK-MESSAGES-NOT: warning:
+ openat(0, "filename", O_RDWR | O_CLOEXEC);
+ // CHECK-MESSAGES-NOT: warning:
+ TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR | O_CLOEXEC));
+ // CHECK-MESSAGES-NOT: warning:
+ openat(0, "filename", O_RDWR | O_CLOEXEC | O_EXCL);
+ // CHECK-MESSAGES-NOT: warning:
+ TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR | O_CLOEXEC | O_EXCL));
+ // CHECK-MESSAGES-NOT: warning:
+}
+
+class G {
+public:
+ int open(const char *pathname, int flags, ...);
+ int open64(const char *pathname, int flags, ...);
+ int openat(int dirfd, const char *pathname, int flags, ...);
+
+ void h() {
+ open("filename", O_RDWR);
+ // CHECK-MESSAGES-NOT: warning:
+ TEMP_FAILURE_RETRY(open("filename", O_RDWR));
+ // CHECK-MESSAGES-NOT: warning:
+ open64("filename", O_RDWR);
+ // CHECK-MESSAGES-NOT: warning:
+ TEMP_FAILURE_RETRY(open64("filename", O_RDWR));
+ // CHECK-MESSAGES-NOT: warning:
+ openat(0, "filename", O_RDWR);
+ // CHECK-MESSAGES-NOT: warning:
+ TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR));
+ // CHECK-MESSAGES-NOT: warning:
+ }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-socket.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-socket.cpp
new file mode 100644
index 0000000..25f332d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-cloexec-socket.cpp
@@ -0,0 +1,75 @@
+// RUN: %check_clang_tidy %s android-cloexec-socket %t
+
+#define SOCK_STREAM 1
+#define SOCK_DGRAM 2
+#define __O_CLOEXEC 3
+#define SOCK_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+ ({ \
+ int _rc; \
+ do { \
+ _rc = (exp); \
+ } while (_rc == -1); \
+ })
+
+extern "C" int socket(int domain, int type, int protocol);
+
+void a() {
+ socket(0, SOCK_STREAM, 0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'socket' should use SOCK_CLOEXEC where possible [android-cloexec-socket]
+ // CHECK-FIXES: socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0)
+ TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM, 0));
+ // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: 'socket'
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0))
+ socket(0, SOCK_STREAM | SOCK_DGRAM, 0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'socket'
+ // CHECK-FIXES: socket(0, SOCK_STREAM | SOCK_DGRAM | SOCK_CLOEXEC, 0)
+ TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM, 0));
+ // CHECK-MESSAGES: :[[@LINE-1]]:56: warning: 'socket'
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM | SOCK_CLOEXEC, 0))
+}
+
+void f() {
+ socket(0, 3, 0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 'socket'
+ // CHECK-FIXES: socket(0, 3 | SOCK_CLOEXEC, 0)
+ TEMP_FAILURE_RETRY(socket(0, 3, 0));
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: 'socket'
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, 3 | SOCK_CLOEXEC, 0))
+
+ int flag = 3;
+ socket(0, flag, 0);
+ TEMP_FAILURE_RETRY(socket(0, flag, 0));
+}
+
+namespace i {
+int socket(int domain, int type, int protocol);
+
+void d() {
+ socket(0, SOCK_STREAM, 0);
+ TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM, 0));
+ socket(0, SOCK_STREAM | SOCK_DGRAM, 0);
+ TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM, 0));
+}
+
+} // namespace i
+
+void e() {
+ socket(0, SOCK_CLOEXEC, 0);
+ TEMP_FAILURE_RETRY(socket(0, SOCK_CLOEXEC, 0));
+ socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0));
+ socket(0, SOCK_STREAM | SOCK_CLOEXEC | SOCK_DGRAM, 0);
+ TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_CLOEXEC | SOCK_DGRAM, 0));
+}
+
+class G {
+public:
+ int socket(int domain, int type, int protocol);
+ void d() {
+ socket(0, SOCK_STREAM, 0);
+ TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM, 0));
+ socket(0, SOCK_STREAM | SOCK_DGRAM, 0);
+ TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM, 0));
+ }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/android-comparison-in-temp-failure-retry.c b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-comparison-in-temp-failure-retry.c
new file mode 100644
index 0000000..3be3eec
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/android-comparison-in-temp-failure-retry.c
@@ -0,0 +1,148 @@
+// RUN: %check_clang_tidy %s android-comparison-in-temp-failure-retry %t
+
+#define TEMP_FAILURE_RETRY(x) \
+ ({ \
+ typeof(x) __z; \
+ do \
+ __z = (x); \
+ while (__z == -1); \
+ __z; \
+ })
+
+int foo();
+int bar(int a);
+
+void test() {
+ int i;
+ TEMP_FAILURE_RETRY((i = foo()));
+ TEMP_FAILURE_RETRY(foo());
+ TEMP_FAILURE_RETRY((foo()));
+
+ TEMP_FAILURE_RETRY(foo() == 1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: top-level comparison in TEMP_FAILURE_RETRY [android-comparison-in-temp-failure-retry]
+ TEMP_FAILURE_RETRY((foo() == 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: top-level comparison in TEMP_FAILURE_RETRY
+ TEMP_FAILURE_RETRY((int)(foo() == 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: top-level comparison in TEMP_FAILURE_RETRY
+
+ TEMP_FAILURE_RETRY(bar(foo() == 1));
+ TEMP_FAILURE_RETRY((bar(foo() == 1)));
+ TEMP_FAILURE_RETRY((bar(foo() == 1)) == 1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: top-level comparison in TEMP_FAILURE_RETRY
+ TEMP_FAILURE_RETRY(((bar(foo() == 1)) == 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: top-level comparison in TEMP_FAILURE_RETRY
+ TEMP_FAILURE_RETRY((int)((bar(foo() == 1)) == 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: top-level comparison in TEMP_FAILURE_RETRY
+
+#define INDIRECT TEMP_FAILURE_RETRY
+ INDIRECT(foo());
+ INDIRECT((foo() == 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: top-level comparison in TEMP_FAILURE_RETRY
+ INDIRECT(bar(foo() == 1));
+ INDIRECT((int)((bar(foo() == 1)) == 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: top-level comparison in TEMP_FAILURE_RETRY
+
+#define TFR(x) TEMP_FAILURE_RETRY(x)
+ TFR(foo());
+ TFR((foo() == 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: top-level comparison in TEMP_FAILURE_RETRY
+ TFR(bar(foo() == 1));
+ TFR((int)((bar(foo() == 1)) == 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: top-level comparison in TEMP_FAILURE_RETRY
+
+#define ADD_TFR(x) (1 + TEMP_FAILURE_RETRY(x) + 1)
+ ADD_TFR(foo());
+ ADD_TFR(foo() == 1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: top-level comparison in TEMP_FAILURE_RETRY
+
+ ADD_TFR(bar(foo() == 1));
+ ADD_TFR((int)((bar(foo() == 1)) == 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: top-level comparison in TEMP_FAILURE_RETRY
+
+#define ADDP_TFR(x) (1 + TEMP_FAILURE_RETRY((x)) + 1)
+ ADDP_TFR(foo());
+ ADDP_TFR((foo() == 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: top-level comparison in TEMP_FAILURE_RETRY
+
+ ADDP_TFR(bar(foo() == 1));
+ ADDP_TFR((int)((bar(foo() == 1)) == 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: top-level comparison in TEMP_FAILURE_RETRY
+
+#define MACRO TEMP_FAILURE_RETRY(foo() == 1)
+ MACRO;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: top-level comparison in TEMP_FAILURE_RETRY
+
+ // Be sure that being a macro arg doesn't mess with this.
+#define ID(x) (x)
+ ID(ADDP_TFR(bar(foo() == 1)));
+ ID(ADDP_TFR(bar(foo() == 1) == 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: top-level comparison in TEMP_FAILURE_RETRY
+ ID(MACRO);
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: top-level comparison in TEMP_FAILURE_RETRY
+
+#define CMP(x) x == 1
+ TEMP_FAILURE_RETRY(CMP(foo()));
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: top-level comparison in TEMP_FAILURE_RETRY
+}
+
+// Be sure that it works inside of things like loops, if statements, etc.
+void control_flow() {
+ do {
+ if (TEMP_FAILURE_RETRY(foo())) {
+ }
+
+ if (TEMP_FAILURE_RETRY(foo() == 1)) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: top-level comparison in TEMP_FAILURE_RETRY
+ }
+
+ if (TEMP_FAILURE_RETRY(bar(foo() == 1))) {
+ }
+
+ if (TEMP_FAILURE_RETRY(bar(foo() == 1) == 1)) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: top-level comparison in TEMP_FAILURE_RETRY
+ }
+ } while (TEMP_FAILURE_RETRY(foo() == 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: top-level comparison in TEMP_FAILURE_RETRY
+}
+
+void with_nondependent_variable_type() {
+#undef TEMP_FAILURE_RETRY
+#define TEMP_FAILURE_RETRY(x) \
+ ({ \
+ long int __z; \
+ do \
+ __z = (x); \
+ while (__z == -1); \
+ __z; \
+ })
+
+ TEMP_FAILURE_RETRY((foo()));
+ TEMP_FAILURE_RETRY((int)(foo() == 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: top-level comparison in TEMP_FAILURE_RETRY
+ TEMP_FAILURE_RETRY((bar(foo() == 1)));
+ TEMP_FAILURE_RETRY((int)((bar(foo() == 1)) == 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: top-level comparison in TEMP_FAILURE_RETRY
+}
+
+// I can't find a case where TEMP_FAILURE_RETRY is implemented like this, but if
+// we can cheaply support it, I don't see why not.
+void obscured_temp_failure_retry() {
+#undef TEMP_FAILURE_RETRY
+#define IMPL(x) \
+ ({ \
+ typeof(x) __z; \
+ do \
+ __z = (x); \
+ while (__z == -1); \
+ __z; \
+ })
+
+#define IMPL2(x) IMPL(x)
+#define TEMP_FAILURE_RETRY(x) IMPL2(x)
+ TEMP_FAILURE_RETRY((foo()));
+ TEMP_FAILURE_RETRY((int)(foo() == 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: top-level comparison in TEMP_FAILURE_RETRY
+ TEMP_FAILURE_RETRY((bar(foo() == 1)));
+ TEMP_FAILURE_RETRY((int)((bar(foo() == 1)) == 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: top-level comparison in TEMP_FAILURE_RETRY
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/basic.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/basic.cpp
new file mode 100644
index 0000000..e573502
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/basic.cpp
@@ -0,0 +1,5 @@
+// RUN: clang-tidy %s -checks='-*,llvm-namespace-comment' -- | FileCheck %s
+
+namespace i {
+}
+// CHECK: warning: namespace 'i' not terminated with a closing comment [llvm-namespace-comment]
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/boost-use-to-string.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/boost-use-to-string.cpp
new file mode 100644
index 0000000..44ba172
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/boost-use-to-string.cpp
@@ -0,0 +1,169 @@
+// RUN: %check_clang_tidy %s boost-use-to-string %t
+
+namespace std {
+
+template <typename T>
+class basic_string {};
+
+using string = basic_string<char>;
+using wstring = basic_string<wchar_t>;
+}
+
+namespace boost {
+template <typename T, typename V>
+T lexical_cast(const V &) {
+ return T();
+};
+}
+
+struct my_weird_type {};
+
+std::string fun(const std::string &) {}
+
+void test_to_string1() {
+
+ auto xa = boost::lexical_cast<std::string>(5);
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::to_string instead of boost::lexical_cast<std::string> [boost-use-to-string]
+ // CHECK-FIXES: auto xa = std::to_string(5);
+
+ auto z = boost::lexical_cast<std::string>(42LL);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use std::to_string
+ // CHECK-FIXES: auto z = std::to_string(42LL);
+
+ // this should not trigger
+ fun(boost::lexical_cast<std::string>(42.0));
+ auto non = boost::lexical_cast<my_weird_type>(42);
+ boost::lexical_cast<int>("12");
+}
+
+void test_to_string2() {
+ int a;
+ long b;
+ long long c;
+ unsigned d;
+ unsigned long e;
+ unsigned long long f;
+ float g;
+ double h;
+ long double i;
+ bool j;
+
+ fun(boost::lexical_cast<std::string>(a));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_string
+ // CHECK-FIXES: fun(std::to_string(a));
+ fun(boost::lexical_cast<std::string>(b));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_string
+ // CHECK-FIXES: fun(std::to_string(b));
+ fun(boost::lexical_cast<std::string>(c));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_string
+ // CHECK-FIXES: fun(std::to_string(c));
+ fun(boost::lexical_cast<std::string>(d));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_string
+ // CHECK-FIXES: fun(std::to_string(d));
+ fun(boost::lexical_cast<std::string>(e));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_string
+ // CHECK-FIXES: fun(std::to_string(e));
+ fun(boost::lexical_cast<std::string>(f));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_string
+ // CHECK-FIXES: fun(std::to_string(f));
+
+ // No change for floating numbers.
+ fun(boost::lexical_cast<std::string>(g));
+ fun(boost::lexical_cast<std::string>(h));
+ fun(boost::lexical_cast<std::string>(i));
+ // And bool.
+ fun(boost::lexical_cast<std::string>(j));
+}
+
+std::string fun(const std::wstring &) {}
+
+void test_to_wstring() {
+ int a;
+ long b;
+ long long c;
+ unsigned d;
+ unsigned long e;
+ unsigned long long f;
+ float g;
+ double h;
+ long double i;
+ bool j;
+
+ fun(boost::lexical_cast<std::wstring>(a));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_wstring instead of boost::lexical_cast<std::wstring> [boost-use-to-string]
+ // CHECK-FIXES: fun(std::to_wstring(a));
+ fun(boost::lexical_cast<std::wstring>(b));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_wstring
+ // CHECK-FIXES: fun(std::to_wstring(b));
+ fun(boost::lexical_cast<std::wstring>(c));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_wstring
+ // CHECK-FIXES: fun(std::to_wstring(c));
+ fun(boost::lexical_cast<std::wstring>(d));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_wstring
+ // CHECK-FIXES: fun(std::to_wstring(d));
+ fun(boost::lexical_cast<std::wstring>(e));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_wstring
+ // CHECK-FIXES: fun(std::to_wstring(e));
+ fun(boost::lexical_cast<std::wstring>(f));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_wstring
+ // CHECK-FIXES: fun(std::to_wstring(f));
+
+ // No change for floating numbers
+ fun(boost::lexical_cast<std::wstring>(g));
+ fun(boost::lexical_cast<std::wstring>(h));
+ fun(boost::lexical_cast<std::wstring>(i));
+ // and bool.
+ fun(boost::lexical_cast<std::wstring>(j));
+}
+
+const auto glob = boost::lexical_cast<std::string>(42);
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use std::to_string
+// CHECK-FIXES: const auto glob = std::to_string(42);
+
+template <typename T>
+void string_as_T(T t = T()) {
+ boost::lexical_cast<std::string>(42);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use std::to_string
+ // CHECK-FIXES: std::to_string(42);
+
+ boost::lexical_cast<T>(42);
+ string_as_T(boost::lexical_cast<T>(42));
+ auto p = boost::lexical_cast<T>(42);
+ auto p2 = (T)boost::lexical_cast<T>(42);
+ auto p3 = static_cast<T>(boost::lexical_cast<T>(42));
+}
+
+#define my_to_string boost::lexical_cast<std::string>
+
+void no_fixup_inside_macro() {
+ my_to_string(12);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use std::to_string
+}
+
+void no_warnings() {
+ fun(boost::lexical_cast<std::string>("abc"));
+ fun(boost::lexical_cast<std::wstring>("abc"));
+ fun(boost::lexical_cast<std::string>(my_weird_type{}));
+ string_as_T<int>();
+ string_as_T<std::string>();
+}
+
+struct Fields {
+ int integer;
+ float floating;
+ Fields* wierd;
+ const int &getConstInteger() const {return integer;}
+};
+
+void testFields() {
+ Fields fields;
+ auto s1 = boost::lexical_cast<std::string>(fields.integer);
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::to_string
+ // CHECK-FIXES: auto s1 = std::to_string(fields.integer);
+
+ auto s2 = boost::lexical_cast<std::string>(fields.floating);
+ auto s3 = boost::lexical_cast<std::string>(fields.wierd);
+ auto s4 = boost::lexical_cast<std::string>(fields.getConstInteger());
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::to_string
+ // CHECK-FIXES: auto s4 = std::to_string(fields.getConstInteger());
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-argument-comment-gmock.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-argument-comment-gmock.cpp
new file mode 100644
index 0000000..95b1a07
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-argument-comment-gmock.cpp
@@ -0,0 +1,130 @@
+// RUN: %check_clang_tidy %s bugprone-argument-comment %t
+
+namespace testing {
+namespace internal {
+
+template <typename F>
+struct Function;
+
+template <typename R>
+struct Function<R()> {
+ typedef R Result;
+};
+
+template <typename R, typename A1>
+struct Function<R(A1)>
+ : Function<R()> {
+ typedef A1 Argument1;
+};
+
+template <typename R, typename A1, typename A2>
+struct Function<R(A1, A2)>
+ : Function<R(A1)> {
+ typedef A2 Argument2;
+};
+
+} // namespace internal
+
+template <typename F>
+class MockSpec {
+ public:
+ void f();
+};
+
+template <typename T>
+class Matcher {
+ public:
+ explicit Matcher();
+ Matcher(T value);
+};
+
+} // namespace testing
+
+#define GMOCK_RESULT_(tn, ...) \
+ tn ::testing::internal::Function<__VA_ARGS__>::Result
+#define GMOCK_ARG_(tn, N, ...) \
+ tn ::testing::internal::Function<__VA_ARGS__>::Argument##N
+#define GMOCK_MATCHER_(tn, N, ...) \
+ const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>&
+#define GMOCK_METHOD2_(tn, constness, ct, Method, ...) \
+ GMOCK_RESULT_(tn, __VA_ARGS__) \
+ ct Method( \
+ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
+ GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2) constness; \
+ ::testing::MockSpec<__VA_ARGS__> \
+ gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
+ GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2) constness
+#define MOCK_METHOD2(m, ...) GMOCK_METHOD2_(, , , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD2(m, ...) GMOCK_METHOD2_(, const, , m, __VA_ARGS__)
+#define GMOCK_EXPECT_CALL_IMPL_(obj, call) \
+ ((obj).gmock_##call).f()
+#define EXPECT_CALL(obj, call) GMOCK_EXPECT_CALL_IMPL_(obj, call)
+
+class Base {
+ public:
+ virtual void Method(int param_one_base, int param_two_base);
+};
+class Derived : public Base {
+ public:
+ virtual void Method(int param_one, int param_two);
+ virtual void Method2(int p_one, int p_two) const;
+};
+class MockDerived : public Derived {
+ public:
+ MOCK_METHOD2(Method, void(int a, int b));
+ MOCK_CONST_METHOD2(Method2, void(int c, int d));
+};
+
+class MockStandalone {
+ public:
+ MOCK_METHOD2(Method, void(int aaa, int bbb));
+};
+
+void test_gmock_expectations() {
+ MockDerived m;
+ EXPECT_CALL(m, Method(/*param_one=*/1, /*param_tw=*/2));
+// CHECK-NOTES: [[@LINE-1]]:42: warning: argument name 'param_tw' in comment does not match parameter name 'param_two'
+// CHECK-NOTES: [[@LINE-18]]:42: note: 'param_two' declared here
+// CHECK-NOTES: [[@LINE-14]]:3: note: actual callee ('gmock_Method') is declared here
+// CHECK-NOTES: [[@LINE-32]]:30: note: expanded from macro 'MOCK_METHOD2'
+// CHECK-NOTES: [[@LINE-35]]:7: note: expanded from macro 'GMOCK_METHOD2_'
+// CHECK-NOTES: note: expanded from here
+// CHECK-FIXES: EXPECT_CALL(m, Method(/*param_one=*/1, /*param_two=*/2));
+ EXPECT_CALL(m, Method2(/*p_on=*/3, /*p_two=*/4));
+// CHECK-NOTES: [[@LINE-1]]:26: warning: argument name 'p_on' in comment does not match parameter name 'p_one'
+// CHECK-NOTES: [[@LINE-25]]:28: note: 'p_one' declared here
+// CHECK-NOTES: [[@LINE-21]]:3: note: actual callee ('gmock_Method2') is declared here
+// CHECK-NOTES: [[@LINE-39]]:36: note: expanded from macro 'MOCK_CONST_METHOD2'
+// CHECK-NOTES: [[@LINE-43]]:7: note: expanded from macro 'GMOCK_METHOD2_'
+// CHECK-NOTES: note: expanded from here
+// CHECK-FIXES: EXPECT_CALL(m, Method2(/*p_one=*/3, /*p_two=*/4));
+
+ #define PARAM1 11
+ #define PARAM2 22
+ EXPECT_CALL(m, Method2(/*p_on1=*/PARAM1, /*p_tw2=*/PARAM2));
+// CHECK-NOTES: [[@LINE-1]]:26: warning: argument name 'p_on1' in comment does not match parameter name 'p_one'
+// CHECK-NOTES: [[@LINE-36]]:28: note: 'p_one' declared here
+// CHECK-NOTES: [[@LINE-32]]:3: note: actual callee ('gmock_Method2') is declared here
+// CHECK-NOTES: [[@LINE-50]]:36: note: expanded from macro 'MOCK_CONST_METHOD2'
+// CHECK-NOTES: [[@LINE-54]]:7: note: expanded from macro 'GMOCK_METHOD2_'
+// CHECK-NOTES: note: expanded from here
+// CHECK-NOTES: [[@LINE-7]]:44: warning: argument name 'p_tw2' in comment does not match parameter name 'p_two'
+// CHECK-NOTES: [[@LINE-42]]:39: note: 'p_two' declared here
+// CHECK-NOTES: [[@LINE-38]]:3: note: actual callee ('gmock_Method2') is declared here
+// CHECK-NOTES: [[@LINE-56]]:36: note: expanded from macro 'MOCK_CONST_METHOD2'
+// CHECK-NOTES: [[@LINE-60]]:7: note: expanded from macro 'GMOCK_METHOD2_'
+// CHECK-NOTES: note: expanded from here
+// CHECK-FIXES: EXPECT_CALL(m, Method2(/*p_one=*/PARAM1, /*p_two=*/PARAM2));
+
+ MockStandalone m2;
+ EXPECT_CALL(m2, Method(/*aaa=*/5, /*bbc=*/6));
+}
+
+void test_gmock_direct_calls() {
+ MockDerived m;
+ m.Method(/*param_one=*/1, /*param_tw=*/2);
+// CHECK-NOTES: [[@LINE-1]]:29: warning: argument name 'param_tw' in comment does not match parameter name 'param_two'
+// CHECK-NOTES: [[@LINE-58]]:42: note: 'param_two' declared here
+// CHECK-NOTES: [[@LINE-54]]:16: note: actual callee ('Method') is declared here
+// CHECK-FIXES: m.Method(/*param_one=*/1, /*param_two=*/2);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-argument-comment-strict.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-argument-comment-strict.cpp
new file mode 100644
index 0000000..46e346f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-argument-comment-strict.cpp
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s bugprone-argument-comment %t -- \
+// RUN: -config="{CheckOptions: [{key: StrictMode, value: 1}]}" --
+
+void f(int _with_underscores_);
+void g(int x_);
+void ignores_underscores() {
+ f(/*With_Underscores=*/0);
+// CHECK-NOTES: [[@LINE-1]]:5: warning: argument name 'With_Underscores' in comment does not match parameter name '_with_underscores_'
+// CHECK-NOTES: [[@LINE-5]]:12: note: '_with_underscores_' declared here
+// CHECK-FIXES: f(/*_with_underscores_=*/0);
+
+ f(/*with_underscores=*/1);
+// CHECK-NOTES: [[@LINE-1]]:5: warning: argument name 'with_underscores' in comment does not match parameter name '_with_underscores_'
+// CHECK-NOTES: [[@LINE-10]]:12: note: '_with_underscores_' declared here
+// CHECK-FIXES: f(/*_with_underscores_=*/1);
+ f(/*_With_Underscores_=*/2);
+// CHECK-NOTES: [[@LINE-1]]:5: warning: argument name '_With_Underscores_' in comment does not match parameter name '_with_underscores_'
+// CHECK-NOTES: [[@LINE-14]]:12: note: '_with_underscores_' declared here
+// CHECK-FIXES: f(/*_with_underscores_=*/2);
+ g(/*X=*/3);
+// CHECK-NOTES: [[@LINE-1]]:5: warning: argument name 'X' in comment does not match parameter name 'x_'
+// CHECK-NOTES: [[@LINE-17]]:12: note: 'x_' declared here
+// CHECK-FIXES: g(/*x_=*/3);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-argument-comment.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-argument-comment.cpp
new file mode 100644
index 0000000..08f8717
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-argument-comment.cpp
@@ -0,0 +1,95 @@
+// RUN: %check_clang_tidy %s bugprone-argument-comment %t
+
+// FIXME: clang-tidy should provide a -verify mode to make writing these checks
+// easier and more accurate.
+
+void ffff(int xxxx, int yyyy);
+
+void f(int x, int y);
+void g() {
+ // CHECK-NOTES: [[@LINE+4]]:5: warning: argument name 'y' in comment does not match parameter name 'x'
+ // CHECK-NOTES: [[@LINE-3]]:12: note: 'x' declared here
+ // CHECK-NOTES: [[@LINE+2]]:14: warning: argument name 'z' in comment does not match parameter name 'y'
+ // CHECK-NOTES: [[@LINE-5]]:19: note: 'y' declared here
+ f(/*y=*/0, /*z=*/0);
+ // CHECK-FIXES: {{^}} f(/*y=*/0, /*z=*/0);
+
+ f(/*x=*/1, /*y=*/1);
+
+ ffff(0 /*aaaa=*/, /*bbbb*/ 0); // Unsupported formats.
+}
+
+struct C {
+ C(int x, int y);
+};
+C c(/*x=*/0, /*y=*/0);
+
+struct Closure {};
+
+template <typename T1, typename T2>
+Closure *NewCallback(void (*f)(T1, T2), T1 arg1, T2 arg2) { return nullptr; }
+
+template <typename T1, typename T2>
+Closure *NewPermanentCallback(void (*f)(T1, T2), T1 arg1, T2 arg2) { return nullptr; }
+
+void h() {
+ (void)NewCallback(&ffff, /*xxxx=*/11, /*yyyy=*/22);
+ (void)NewPermanentCallback(&ffff, /*xxxx=*/11, /*yyyy=*/22);
+}
+
+template<typename... Args>
+void variadic(Args&&... args);
+
+template<typename... Args>
+void variadic2(int zzz, Args&&... args);
+
+void templates() {
+ variadic(/*xxx=*/0, /*yyy=*/1);
+ variadic2(/*zzU=*/0, /*xxx=*/1, /*yyy=*/2);
+ // CHECK-NOTES: [[@LINE-1]]:13: warning: argument name 'zzU' in comment does not match parameter name 'zzz'
+ // CHECK-NOTES: :[[@LINE-6]]:20: note: 'zzz' declared here
+ // CHECK-FIXES: variadic2(/*zzz=*/0, /*xxx=*/1, /*yyy=*/2);
+}
+
+#define FALSE 0
+void qqq(bool aaa);
+void f2() { qqq(/*bbb=*/FALSE); }
+// CHECK-NOTES: [[@LINE-1]]:17: warning: argument name 'bbb' in comment does not match parameter name 'aaa'
+// CHECK-NOTES: [[@LINE-3]]:15: note: 'aaa' declared here
+// CHECK-FIXES: void f2() { qqq(/*bbb=*/FALSE); }
+
+void f3(bool _with_underscores_);
+void ignores_underscores() {
+ f3(/*With_Underscores=*/false);
+}
+
+namespace ThisEditDistanceAboveThreshold {
+void f4(int xxx);
+void g() { f4(/*xyz=*/0); }
+// CHECK-NOTES: [[@LINE-1]]:15: warning: argument name 'xyz' in comment does not match parameter name 'xxx'
+// CHECK-NOTES: [[@LINE-3]]:13: note: 'xxx' declared here
+// CHECK-FIXES: void g() { f4(/*xyz=*/0); }
+}
+
+namespace OtherEditDistanceAboveThreshold {
+void f5(int xxx, int yyy);
+void g() { f5(/*Zxx=*/0, 0); }
+// CHECK-NOTES: [[@LINE-1]]:15: warning: argument name 'Zxx' in comment does not match parameter name 'xxx'
+// CHECK-NOTES: [[@LINE-3]]:13: note: 'xxx' declared here
+// CHECK-FIXES: void g() { f5(/*xxx=*/0, 0); }
+struct C2 {
+ C2(int xxx, int yyy);
+};
+C2 c2(/*Zxx=*/0, 0);
+// CHECK-NOTES: [[@LINE-1]]:7: warning: argument name 'Zxx' in comment does not match parameter name 'xxx'
+// CHECK-NOTES: [[@LINE-4]]:10: note: 'xxx' declared here
+// CHECK-FIXES: C2 c2(/*xxx=*/0, 0);
+}
+
+namespace OtherEditDistanceBelowThreshold {
+void f6(int xxx, int yyy);
+void g() { f6(/*xxy=*/0, 0); }
+// CHECK-NOTES: [[@LINE-1]]:15: warning: argument name 'xxy' in comment does not match parameter name 'xxx'
+// CHECK-NOTES: [[@LINE-3]]:13: note: 'xxx' declared here
+// CHECK-FIXES: void g() { f6(/*xxy=*/0, 0); }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-assert-side-effect.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-assert-side-effect.cpp
new file mode 100644
index 0000000..0933402
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-assert-side-effect.cpp
@@ -0,0 +1,114 @@
+// RUN: %check_clang_tidy %s bugprone-assert-side-effect %t -- -config="{CheckOptions: [{key: bugprone-assert-side-effect.CheckFunctionCalls, value: 1}, {key: bugprone-assert-side-effect.AssertMacros, value: 'assert,assert2,my_assert,convoluted_assert,msvc_assert'}]}" -- -fexceptions
+
+//===--- assert definition block ------------------------------------------===//
+int abort() { return 0; }
+
+#ifdef NDEBUG
+#define assert(x) 1
+#else
+#define assert(x) \
+ if (!(x)) \
+ (void)abort()
+#endif
+
+void print(...);
+#define assert2(e) (__builtin_expect(!(e), 0) ? \
+ print (#e, __FILE__, __LINE__) : (void)0)
+
+#ifdef NDEBUG
+#define my_assert(x) 1
+#else
+#define my_assert(x) \
+ ((void)((x) ? 1 : abort()))
+#endif
+
+#ifdef NDEBUG
+#define not_my_assert(x) 1
+#else
+#define not_my_assert(x) \
+ if (!(x)) \
+ (void)abort()
+#endif
+
+#define real_assert(x) ((void)((x) ? 1 : abort()))
+#define wrap1(x) real_assert(x)
+#define wrap2(x) wrap1(x)
+#define convoluted_assert(x) wrap2(x)
+
+#define msvc_assert(expression) (void)( \
+ (!!(expression)) || \
+ (abort(), 0) \
+ )
+
+
+//===----------------------------------------------------------------------===//
+
+class MyClass {
+public:
+ bool badFunc(int a, int b) { return a * b > 0; }
+ bool goodFunc(int a, int b) const { return a * b > 0; }
+
+ MyClass &operator=(const MyClass &rhs) { return *this; }
+
+ int operator-() { return 1; }
+
+ operator bool() const { return true; }
+
+ void operator delete(void *p) {}
+};
+
+bool freeFunction() {
+ return true;
+}
+
+int main() {
+
+ int X = 0;
+ bool B = false;
+ assert(X == 1);
+
+ assert(X = 1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() with side effect [bugprone-assert-side-effect]
+ my_assert(X = 1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found my_assert() with side effect
+ convoluted_assert(X = 1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found convoluted_assert() with side effect
+ not_my_assert(X = 1);
+
+ assert(++X);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() with side effect
+ assert(!B);
+
+ assert(B || true);
+
+ assert(freeFunction());
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() with side effect
+
+ MyClass mc;
+ assert(mc.badFunc(0, 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() with side effect
+ assert(mc.goodFunc(0, 1));
+
+ MyClass mc2;
+ assert(mc2 = mc);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() with side effect
+
+ assert(-mc > 0);
+
+ MyClass *mcp;
+ assert(mcp = new MyClass);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() with side effect
+
+ assert((delete mcp, false));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() with side effect
+
+ assert((throw 1, false));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() with side effect
+
+ assert2(1 == 2 - 1);
+
+ msvc_assert(mc2 = mc);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found msvc_assert() with side effect
+
+ return 0;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-bool-pointer-implicit-conversion.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-bool-pointer-implicit-conversion.cpp
new file mode 100644
index 0000000..37c6939
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-bool-pointer-implicit-conversion.cpp
@@ -0,0 +1,82 @@
+// RUN: %check_clang_tidy %s bugprone-bool-pointer-implicit-conversion %t
+
+bool *SomeFunction();
+void SomeOtherFunction(bool*);
+bool F();
+void G(bool);
+
+
+template <typename T>
+void t(T b) {
+ if (b) {
+ }
+}
+
+void foo() {
+ bool *b = SomeFunction();
+ if (b) {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: dubious check of 'bool *' against 'nullptr'
+// CHECK-FIXES: if (*b) {
+ }
+
+ if (F() && b) {
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: dubious check of 'bool *' against 'nullptr'
+// CHECK-FIXES: if (F() && *b) {
+ }
+
+ // TODO: warn here.
+ if (b) {
+ G(b);
+ }
+
+#define TESTMACRO if (b || F())
+
+ TESTMACRO {
+ }
+
+ t(b);
+
+ if (!b) {
+ // no-warning
+ }
+
+ if (SomeFunction()) {
+ // no-warning
+ }
+
+ bool *c = SomeFunction();
+ if (c) {
+ (void)c;
+ (void)*c; // no-warning
+ }
+
+ if (c) {
+ *c = true; // no-warning
+ }
+
+ if (c) {
+ c[0] = false; // no-warning
+ }
+
+ if (c) {
+ SomeOtherFunction(c); // no-warning
+ }
+
+ if (c) {
+ delete[] c; // no-warning
+ }
+
+ if (c) {
+ *(c) = false; // no-warning
+ }
+
+ struct {
+ bool *b;
+ } d = { SomeFunction() };
+
+ if (d.b)
+ (void)*d.b; // no-warning
+
+#define CHECK(b) if (b) {}
+ CHECK(c)
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-copy-constructor-init.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-copy-constructor-init.cpp
new file mode 100644
index 0000000..981d0b5
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-copy-constructor-init.cpp
@@ -0,0 +1,188 @@
+// RUN: %check_clang_tidy %s bugprone-copy-constructor-init %t
+
+class NonCopyable {
+public:
+ NonCopyable() = default;
+ NonCopyable(const NonCopyable &) = delete;
+
+private:
+ int a;
+};
+
+class NonCopyable2 {
+public:
+ NonCopyable2() = default;
+
+private:
+ NonCopyable2(const NonCopyable2 &);
+ int a;
+};
+
+class Copyable {
+public:
+ Copyable() = default;
+ Copyable(const Copyable &) = default;
+
+private:
+ int a;
+};
+
+class Copyable2 {
+public:
+ Copyable2() = default;
+ Copyable2(const Copyable2 &) = default;
+
+private:
+ int a;
+};
+
+class Copyable3 : public Copyable {
+public:
+ Copyable3() = default;
+ Copyable3(const Copyable3 &) = default;
+};
+
+template <class C>
+class Copyable4 {
+public:
+ Copyable4() = default;
+ Copyable4(const Copyable4 &) = default;
+
+private:
+ int a;
+};
+
+template <class T, class S>
+class Copyable5 {
+public:
+ Copyable5() = default;
+ Copyable5(const Copyable5 &) = default;
+
+private:
+ int a;
+};
+
+class EmptyCopyable {
+public:
+ EmptyCopyable() = default;
+ EmptyCopyable(const EmptyCopyable &) = default;
+};
+
+template <typename T>
+using CopyableAlias = Copyable5<T, int>;
+
+typedef Copyable5<int, int> CopyableAlias2;
+
+class X : public Copyable, public EmptyCopyable {
+ X(const X &other) : Copyable(other) {}
+};
+
+class X2 : public Copyable2 {
+ X2(const X2 &other) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor other than the copy constructor [bugprone-copy-constructor-init]
+ // CHECK-FIXES: X2(const X2 &other) : Copyable2(other) {}
+};
+
+class X2_A : public Copyable2 {
+ X2_A(const X2_A &) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
+ // CHECK-FIXES: X2_A(const X2_A &) {}
+};
+
+class X3 : public Copyable, public Copyable2 {
+ X3(const X3 &other) : Copyable(other) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
+ // CHECK-FIXES: X3(const X3 &other) : Copyable(other) {}
+};
+
+class X4 : public Copyable {
+ X4(const X4 &other) : Copyable() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
+ // CHECK-FIXES: X4(const X4 &other) : Copyable(other) {}
+};
+
+class X5 : public Copyable3 {
+ X5(const X5 &other) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
+ // CHECK-FIXES: X5(const X5 &other) : Copyable3(other) {}
+};
+
+class X6 : public Copyable2, public Copyable3 {
+ X6(const X6 &other) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
+ // CHECK-FIXES: X6(const X6 &other) : Copyable2(other), Copyable3(other) {}
+};
+
+class X7 : public Copyable, public Copyable2 {
+ X7(const X7 &other) : Copyable() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
+ // CHECK-FIXES: X7(const X7 &other) : Copyable(other) {}
+};
+
+class X8 : public Copyable4<int> {
+ X8(const X8 &other) : Copyable4(other) {}
+};
+
+class X9 : public Copyable4<int> {
+ X9(const X9 &other) : Copyable4() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
+ // CHECK-FIXES: X9(const X9 &other) : Copyable4(other) {}
+};
+
+class X10 : public Copyable4<int> {
+ X10(const X10 &other) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
+ // CHECK-FIXES: X10(const X10 &other) : Copyable4(other) {}
+};
+
+class X11 : public Copyable5<int, float> {
+ X11(const X11 &other) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
+ // CHECK-FIXES: X11(const X11 &other) : Copyable5(other) {}
+};
+
+class X12 : public CopyableAlias<float> {
+ X12(const X12 &other) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
+ // CHECK-FIXES: X12(const X12 &other) {}
+};
+
+template <typename T>
+class X13 : T {
+ X13(const X13 &other) {}
+};
+
+template class X13<EmptyCopyable>;
+template class X13<Copyable>;
+
+#define FROMMACRO \
+ class X14 : public Copyable2 { \
+ X14(const X14 &other) {} \
+ };
+
+FROMMACRO
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: calling a base constructor
+
+class X15 : public CopyableAlias2 {
+ X15(const X15 &other) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
+ // CHECK-FIXES: X15(const X15 &other) {}
+};
+
+class X16 : public NonCopyable {
+ X16(const X16 &other) {}
+};
+
+class X17 : public NonCopyable2 {
+ X17(const X17 &other) {}
+};
+
+class X18 : private Copyable {
+ X18(const X18 &other) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
+ // CHECK-FIXES: X18(const X18 &other) : Copyable(other) {}
+};
+
+class X19 : private Copyable {
+ X19(const X19 &other) : Copyable(other) {}
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-dangling-handle.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-dangling-handle.cpp
new file mode 100644
index 0000000..d11a2f2
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-dangling-handle.cpp
@@ -0,0 +1,195 @@
+// RUN: %check_clang_tidy %s bugprone-dangling-handle %t -- \
+// RUN: -config="{CheckOptions: \
+// RUN: [{key: bugprone-dangling-handle.HandleClasses, \
+// RUN: value: 'std::basic_string_view; ::llvm::StringRef;'}]}" \
+// RUN: -- -std=c++11
+
+namespace std {
+
+template <typename T>
+class vector {
+ public:
+ using const_iterator = const T*;
+ using iterator = T*;
+ using size_type = int;
+
+ void assign(size_type count, const T& value);
+ iterator insert(const_iterator pos, const T& value);
+ iterator insert(const_iterator pos, T&& value);
+ iterator insert(const_iterator pos, size_type count, const T& value);
+ void push_back(const T&);
+ void push_back(T&&);
+ void resize(size_type count, const T& value);
+};
+
+template <typename, typename>
+class pair {};
+
+template <typename T>
+class set {
+ public:
+ using const_iterator = const T*;
+ using iterator = T*;
+
+ std::pair<iterator, bool> insert(const T& value);
+ std::pair<iterator, bool> insert(T&& value);
+ iterator insert(const_iterator hint, const T& value);
+ iterator insert(const_iterator hint, T&& value);
+};
+
+template <typename Key, typename Value>
+class map {
+ public:
+ using value_type = pair<Key, Value>;
+ value_type& operator[](const Key& key);
+ value_type& operator[](Key&& key);
+};
+
+class basic_string_view;
+
+class basic_string {
+ public:
+ basic_string();
+ basic_string(const char*);
+
+ operator basic_string_view() const noexcept;
+
+ ~basic_string();
+};
+
+typedef basic_string string;
+
+class basic_string_view {
+ public:
+ basic_string_view(const char*);
+};
+
+typedef basic_string_view string_view;
+
+} // namespace std
+
+namespace llvm {
+
+class StringRef {
+ public:
+ StringRef();
+ StringRef(const char*);
+ StringRef(const std::string&);
+};
+
+} // namespace llvm
+
+std::string ReturnsAString();
+
+void Positives() {
+ std::string_view view1 = std::string();
+ // CHECK-MESSAGES: [[@LINE-1]]:20: warning: std::basic_string_view outlives its value [bugprone-dangling-handle]
+
+ std::string_view view_2 = ReturnsAString();
+ // CHECK-MESSAGES: [[@LINE-1]]:20: warning: std::basic_string_view outlives
+
+ view1 = std::string();
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: std::basic_string_view outlives
+
+ const std::string& str_ref = "";
+ std::string_view view3 = true ? "A" : str_ref;
+ // CHECK-MESSAGES: [[@LINE-1]]:20: warning: std::basic_string_view outlives
+ view3 = true ? "A" : str_ref;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: std::basic_string_view outlives
+
+ std::string_view view4(ReturnsAString());
+ // CHECK-MESSAGES: [[@LINE-1]]:20: warning: std::basic_string_view outlives
+}
+
+void OtherTypes() {
+ llvm::StringRef ref = std::string();
+ // CHECK-MESSAGES: [[@LINE-1]]:19: warning: llvm::StringRef outlives its value
+}
+
+const char static_array[] = "A";
+std::string_view ReturnStatements(int i, std::string value_arg,
+ const std::string &ref_arg) {
+ const char array[] = "A";
+ const char* ptr = "A";
+ std::string s;
+ static std::string ss;
+ switch (i) {
+ // Bad cases
+ case 0:
+ return array; // refers to local
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: std::basic_string_view outliv
+ case 1:
+ return s; // refers to local
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: std::basic_string_view outliv
+ case 2:
+ return std::string(); // refers to temporary
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: std::basic_string_view outliv
+ case 3:
+ return value_arg; // refers to by-value arg
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: std::basic_string_view outliv
+
+ // Ok cases
+ case 100:
+ return ss; // refers to static
+ case 101:
+ return static_array; // refers to static
+ case 102:
+ return ptr; // pointer is ok
+ case 103:
+ return ref_arg; // refers to by-ref arg
+ }
+
+ struct S {
+ std::string_view view() { return value; }
+ std::string value;
+ };
+
+ (void)[&]()->std::string_view {
+ // This should not warn. The string is bound by reference.
+ return s;
+ };
+ (void)[=]() -> std::string_view {
+ // This should not warn. The reference is valid as long as the lambda.
+ return s;
+ };
+ (void)[=]() -> std::string_view {
+ // FIXME: This one should warn. We are returning a reference to a local
+ // lambda variable.
+ std::string local;
+ return local;
+ };
+ return "";
+}
+
+void Containers() {
+ std::vector<std::string_view> v;
+ v.assign(3, std::string());
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: std::basic_string_view outlives
+ v.insert(nullptr, std::string());
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: std::basic_string_view outlives
+ v.insert(nullptr, 3, std::string());
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: std::basic_string_view outlives
+ v.push_back(std::string());
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: std::basic_string_view outlives
+ v.resize(3, std::string());
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: std::basic_string_view outlives
+
+ std::set<std::string_view> s;
+ s.insert(std::string());
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: std::basic_string_view outlives
+ s.insert(nullptr, std::string());
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: std::basic_string_view outlives
+
+ std::map<std::string_view, int> m;
+ m[std::string()];
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: std::basic_string_view outlives
+}
+
+void TakesAStringView(std::string_view);
+
+void Negatives(std::string_view default_arg = ReturnsAString()) {
+ std::string str;
+ std::string_view view = str;
+
+ TakesAStringView(std::string());
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-exception-escape.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-exception-escape.cpp
new file mode 100644
index 0000000..eba14bf
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-exception-escape.cpp
@@ -0,0 +1,290 @@
+// RUN: %check_clang_tidy %s bugprone-exception-escape %t -- -extra-arg=-std=c++11 -extra-arg=-fexceptions -config="{CheckOptions: [{key: bugprone-exception-escape.IgnoredExceptions, value: 'ignored1,ignored2'}, {key: bugprone-exception-escape.FunctionsThatShouldNotThrow, value: 'enabled1,enabled2,enabled3'}]}" --
+
+struct throwing_destructor {
+ ~throwing_destructor() {
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: an exception may be thrown in function '~throwing_destructor' which should not throw exceptions
+ throw 1;
+ }
+};
+
+struct throwing_move_constructor {
+ throwing_move_constructor(throwing_move_constructor&&) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: an exception may be thrown in function 'throwing_move_constructor' which should not throw exceptions
+ throw 1;
+ }
+};
+
+struct throwing_move_assignment {
+ throwing_move_assignment& operator=(throwing_move_assignment&&) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: an exception may be thrown in function 'operator=' which should not throw exceptions
+ throw 1;
+ }
+};
+
+void throwing_noexcept() noexcept {
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throwing_noexcept' which should not throw exceptions
+ throw 1;
+}
+
+void throwing_throw_nothing() throw() {
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throwing_throw_nothing' which should not throw exceptions
+ throw 1;
+}
+
+void throw_and_catch() noexcept {
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_and_catch' which should not throw exceptions
+ try {
+ throw 1;
+ } catch(int &) {
+ }
+}
+
+void throw_and_catch_some(int n) noexcept {
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_and_catch_some' which should not throw exceptions
+ try {
+ if (n) throw 1;
+ throw 1.1;
+ } catch(int &) {
+ }
+}
+
+void throw_and_catch_each(int n) noexcept {
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_and_catch_each' which should not throw exceptions
+ try {
+ if (n) throw 1;
+ throw 1.1;
+ } catch(int &) {
+ } catch(double &) {
+ }
+}
+
+void throw_and_catch_all(int n) noexcept {
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_and_catch_all' which should not throw exceptions
+ try {
+ if (n) throw 1;
+ throw 1.1;
+ } catch(...) {
+ }
+}
+
+void throw_and_rethrow() noexcept {
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_and_rethrow' which should not throw exceptions
+ try {
+ throw 1;
+ } catch(int &) {
+ throw;
+ }
+}
+
+void throw_catch_throw() noexcept {
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_catch_throw' which should not throw exceptions
+ try {
+ throw 1;
+ } catch(int &) {
+ throw 2;
+ }
+}
+
+void throw_catch_rethrow_the_rest(int n) noexcept {
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_catch_rethrow_the_rest' which should not throw exceptions
+ try {
+ if (n) throw 1;
+ throw 1.1;
+ } catch(int &) {
+ } catch(...) {
+ throw;
+ }
+}
+
+class base {};
+class derived: public base {};
+
+void throw_derived_catch_base() noexcept {
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_derived_catch_base' which should not throw exceptions
+ try {
+ throw derived();
+ } catch(base &) {
+ }
+}
+
+void try_nested_try(int n) noexcept {
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'try_nested_try' which should not throw exceptions
+ try {
+ try {
+ if (n) throw 1;
+ throw 1.1;
+ } catch(int &) {
+ }
+ } catch(double &) {
+ }
+}
+
+void bad_try_nested_try(int n) noexcept {
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'bad_try_nested_try' which should not throw exceptions
+ try {
+ if (n) throw 1;
+ try {
+ throw 1.1;
+ } catch(int &) {
+ }
+ } catch(double &) {
+ }
+}
+
+void try_nested_catch() noexcept {
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'try_nested_catch' which should not throw exceptions
+ try {
+ try {
+ throw 1;
+ } catch(int &) {
+ throw 1.1;
+ }
+ } catch(double &) {
+ }
+}
+
+void catch_nested_try() noexcept {
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'catch_nested_try' which should not throw exceptions
+ try {
+ throw 1;
+ } catch(int &) {
+ try {
+ throw 1;
+ } catch(int &) {
+ }
+ }
+}
+
+void bad_catch_nested_try() noexcept {
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'bad_catch_nested_try' which should not throw exceptions
+ try {
+ throw 1;
+ } catch(int &) {
+ try {
+ throw 1.1;
+ } catch(int &) {
+ }
+ } catch(double &) {
+ }
+}
+
+void implicit_int_thrower() {
+ throw 1;
+}
+
+void explicit_int_thrower() throw(int);
+
+void indirect_implicit() noexcept {
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'indirect_implicit' which should not throw exceptions
+ implicit_int_thrower();
+}
+
+void indirect_explicit() noexcept {
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'indirect_explicit' which should not throw exceptions
+ explicit_int_thrower();
+}
+
+void indirect_catch() noexcept {
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'indirect_catch' which should not throw exceptions
+ try {
+ implicit_int_thrower();
+ } catch(int&) {
+ }
+}
+
+template<typename T>
+void dependent_throw() noexcept(sizeof(T)<4) {
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'dependent_throw' which should not throw exceptions
+ if (sizeof(T) > 4)
+ throw 1;
+}
+
+void swap(int&, int&) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'swap' which should not throw exceptions
+ throw 1;
+}
+
+namespace std {
+class bad_alloc {};
+}
+
+void alloc() {
+ throw std::bad_alloc();
+}
+
+void allocator() noexcept {
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'allocator' which should not throw exceptions
+ alloc();
+}
+
+void enabled1() {
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'enabled1' which should not throw exceptions
+ throw 1;
+}
+
+void enabled2() {
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'enabled2' which should not throw exceptions
+ enabled1();
+}
+
+void enabled3() {
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'enabled3' which should not throw exceptions
+ try {
+ enabled1();
+ } catch(...) {
+ }
+}
+
+class ignored1 {};
+class ignored2 {};
+
+void this_does_not_count() noexcept {
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'this_does_not_count' which should not throw exceptions
+ throw ignored1();
+}
+
+void this_does_not_count_either(int n) noexcept {
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'this_does_not_count_either' which should not throw exceptions
+ try {
+ throw 1;
+ if (n) throw ignored2();
+ } catch(int &) {
+ }
+}
+
+void this_counts(int n) noexcept {
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'this_counts' which should not throw exceptions
+ if (n) throw 1;
+ throw ignored1();
+}
+
+void thrower(int n) {
+ throw n;
+}
+
+int directly_recursive(int n) noexcept {
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'directly_recursive' which should not throw exceptions
+ if (n == 0)
+ thrower(n);
+ return directly_recursive(n);
+}
+
+int indirectly_recursive(int n) noexcept;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'indirectly_recursive' which should not throw exceptions
+
+int recursion_helper(int n) {
+ indirectly_recursive(n);
+}
+
+int indirectly_recursive(int n) noexcept {
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'indirectly_recursive' which should not throw exceptions
+ if (n == 0)
+ thrower(n);
+ return recursion_helper(n);
+}
+
+int main() {
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'main' which should not throw exceptions
+ throw 1;
+ return 0;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-fold-init-type.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-fold-init-type.cpp
new file mode 100644
index 0000000..e7fdf39
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-fold-init-type.cpp
@@ -0,0 +1,158 @@
+// RUN: %check_clang_tidy %s bugprone-fold-init-type %t
+
+namespace std {
+template <class InputIt, class T>
+T accumulate(InputIt first, InputIt last, T init);
+
+template <class InputIt, class T>
+T reduce(InputIt first, InputIt last, T init);
+template <class ExecutionPolicy, class InputIt, class T>
+T reduce(ExecutionPolicy &&policy,
+ InputIt first, InputIt last, T init);
+
+struct parallel_execution_policy {};
+constexpr parallel_execution_policy par{};
+
+template <class InputIt1, class InputIt2, class T>
+T inner_product(InputIt1 first1, InputIt1 last1,
+ InputIt2 first2, T value);
+
+template <class ExecutionPolicy, class InputIt1, class InputIt2, class T>
+T inner_product(ExecutionPolicy &&policy, InputIt1 first1, InputIt1 last1,
+ InputIt2 first2, T value);
+
+} // namespace std
+
+struct FloatIterator {
+ typedef float value_type;
+};
+template <typename ValueType>
+struct TypedefTemplateIterator { typedef ValueType value_type; };
+template <typename ValueType>
+struct UsingTemplateIterator { using value_type = ValueType; };
+template <typename ValueType>
+struct DependentTypedefTemplateIterator { typedef typename ValueType::value_type value_type; };
+template <typename ValueType>
+struct DependentUsingTemplateIterator : public TypedefTemplateIterator<ValueType> { using typename TypedefTemplateIterator<ValueType>::value_type; };
+using TypedeffedIterator = FloatIterator;
+
+// Positives.
+
+int accumulatePositive1() {
+ float a[1] = {0.5f};
+ return std::accumulate(a, a + 1, 0);
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: folding type 'float' into type 'int'
+}
+
+int accumulatePositive2() {
+ FloatIterator it;
+ return std::accumulate(it, it, 0);
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: folding type 'float' into type 'int'
+}
+
+int accumulatePositive3() {
+ double a[1] = {0.0};
+ return std::accumulate(a, a + 1, 0.0f);
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: folding type 'double' into type 'float'
+}
+
+int accumulatePositive4() {
+ TypedefTemplateIterator<unsigned> it;
+ return std::accumulate(it, it, 0);
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: folding type 'unsigned int' into type 'int'
+}
+
+int accumulatePositive5() {
+ UsingTemplateIterator<unsigned> it;
+ return std::accumulate(it, it, 0);
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: folding type 'unsigned int' into type 'int'
+}
+
+int accumulatePositive6() {
+ DependentTypedefTemplateIterator<UsingTemplateIterator<unsigned>> it;
+ return std::accumulate(it, it, 0);
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: folding type 'unsigned int' into type 'int'
+}
+
+int accumulatePositive7() {
+ TypedeffedIterator it;
+ return std::accumulate(it, it, 0);
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: folding type 'float' into type 'int'
+}
+
+int accumulatePositive8() {
+ DependentUsingTemplateIterator<unsigned> it;
+ return std::accumulate(it, it, 0);
+ // FIXME: this one should trigger too.
+}
+
+int reducePositive1() {
+ float a[1] = {0.5f};
+ return std::reduce(a, a + 1, 0);
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: folding type 'float' into type 'int'
+}
+
+int reducePositive2() {
+ float a[1] = {0.5f};
+ return std::reduce(std::par, a, a + 1, 0);
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: folding type 'float' into type 'int'
+}
+
+int innerProductPositive1() {
+ float a[1] = {0.5f};
+ int b[1] = {1};
+ return std::inner_product(std::par, a, a + 1, b, 0);
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: folding type 'float' into type 'int'
+}
+
+int innerProductPositive2() {
+ float a[1] = {0.5f};
+ int b[1] = {1};
+ return std::inner_product(std::par, a, a + 1, b, 0);
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: folding type 'float' into type 'int'
+}
+
+// Negatives.
+
+int negative1() {
+ float a[1] = {0.5f};
+ // This is OK because types match.
+ return std::accumulate(a, a + 1, 0.0);
+}
+
+int negative2() {
+ float a[1] = {0.5f};
+ // This is OK because double is bigger than float.
+ return std::accumulate(a, a + 1, 0.0);
+}
+
+int negative3() {
+ float a[1] = {0.5f};
+ // This is OK because the user explicitly specified T.
+ return std::accumulate<float *, float>(a, a + 1, 0);
+}
+
+int negative4() {
+ TypedefTemplateIterator<unsigned> it;
+ // For now this is OK.
+ return std::accumulate(it, it, 0.0);
+}
+
+int negative5() {
+ float a[1] = {0.5f};
+ float b[1] = {1.0f};
+ return std::inner_product(std::par, a, a + 1, b, 0.0f);
+}
+
+namespace blah {
+namespace std {
+template <class InputIt, class T>
+T accumulate(InputIt, InputIt, T); // We should not care about this one.
+}
+
+int negative5() {
+ float a[1] = {0.5f};
+ // Note that this is using blah::std::accumulate.
+ return std::accumulate(a, a + 1, 0);
+}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-forward-declaration-namespace.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-forward-declaration-namespace.cpp
new file mode 100644
index 0000000..e0b2258
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-forward-declaration-namespace.cpp
@@ -0,0 +1,163 @@
+// RUN: %check_clang_tidy %s bugprone-forward-declaration-namespace %t
+
+namespace {
+// This is a declaration in a wrong namespace.
+class T_A;
+// CHECK-NOTES: :[[@LINE-1]]:7: warning: declaration 'T_A' is never referenced, but a declaration with the same name found in another namespace 'na' [bugprone-forward-declaration-namespace]
+// CHECK-NOTES: note: a declaration of 'T_A' is found here
+// CHECK-NOTES: :[[@LINE-3]]:7: warning: no definition found for 'T_A', but a definition with the same name 'T_A' found in another namespace '(global)' [bugprone-forward-declaration-namespace]
+// CHECK-NOTES: note: a definition of 'T_A' is found here
+}
+
+namespace na {
+// This is a declaration in a wrong namespace.
+class T_A;
+// CHECK-NOTES: :[[@LINE-1]]:7: warning: declaration 'T_A' is never referenced, but a declaration with the same name found in another namespace '(anonymous)'
+// CHECK-NOTES: note: a declaration of 'T_A' is found here
+// CHECK-NOTES: :[[@LINE-3]]:7: warning: no definition found for 'T_A', but a definition with the same name 'T_A' found in another namespace '(global)'
+// CHECK-NOTES: note: a definition of 'T_A' is found here
+}
+
+class T_A;
+
+class T_A {
+ int x;
+};
+
+class NESTED;
+// CHECK-NOTES: :[[@LINE-1]]:7: warning: no definition found for 'NESTED', but a definition with the same name 'NESTED' found in another namespace '(anonymous namespace)::nq::(anonymous)'
+// CHECK-NOTES: note: a definition of 'NESTED' is found here
+
+namespace {
+namespace nq {
+namespace {
+class NESTED {};
+}
+}
+}
+
+namespace na {
+class T_B;
+// CHECK-NOTES: :[[@LINE-1]]:7: warning: declaration 'T_B' is never referenced, but a declaration with the same name found in another namespace 'nb'
+// CHECK-NOTES: note: a declaration of 'T_B' is found here
+// CHECK-NOTES: :[[@LINE-3]]:7: warning: no definition found for 'T_B', but a definition with the same name 'T_B' found in another namespace 'nb'
+// CHECK-NOTES: note: a definition of 'T_B' is found here
+}
+
+namespace nb {
+class T_B;
+}
+
+namespace nb {
+class T_B {
+ int x;
+};
+}
+
+namespace na {
+class T_B;
+// CHECK-NOTES: :[[@LINE-1]]:7: warning: declaration 'T_B' is never referenced, but a declaration with the same name found in another namespace 'nb'
+// CHECK-NOTES: note: a declaration of 'T_B' is found here
+// CHECK-NOTES: :[[@LINE-3]]:7: warning: no definition found for 'T_B', but a definition with the same name 'T_B' found in another namespace 'nb'
+// CHECK-NOTES: note: a definition of 'T_B' is found here
+}
+
+// A simple forward declaration. Although it is never used, but no declaration
+// with the same name is found in other namespace.
+class OUTSIDER;
+
+namespace na {
+// This class is referenced declaration, we don't generate warning.
+class OUTSIDER_1;
+}
+
+void f(na::OUTSIDER_1);
+
+namespace nc {
+// This class is referenced as friend in OOP.
+class OUTSIDER_1;
+
+class OOP {
+ friend struct OUTSIDER_1;
+};
+}
+
+namespace nd {
+class OUTSIDER_1;
+void f(OUTSIDER_1 *);
+}
+
+namespace nb {
+class OUTSIDER_1;
+// CHECK-NOTES: :[[@LINE-1]]:7: warning: declaration 'OUTSIDER_1' is never referenced, but a declaration with the same name found in another namespace 'na'
+// CHECK-NOTES: note: a declaration of 'OUTSIDER_1' is found here
+}
+
+
+namespace na {
+template<typename T>
+class T_C;
+}
+
+namespace nb {
+// FIXME: this is an error, but we don't consider template class declaration
+// now.
+template<typename T>
+class T_C;
+}
+
+namespace na {
+template<typename T>
+class T_C {
+ int x;
+};
+}
+
+namespace na {
+
+template <typename T>
+class T_TEMP {
+ template <typename _Tp1>
+ struct rebind { typedef T_TEMP<_Tp1> other; };
+};
+
+// We ignore class template specialization.
+template class T_TEMP<char>;
+}
+
+namespace nb {
+
+template <typename T>
+class T_TEMP_1 {
+ template <typename _Tp1>
+ struct rebind { typedef T_TEMP_1<_Tp1> other; };
+};
+
+// We ignore class template specialization.
+extern template class T_TEMP_1<char>;
+}
+
+namespace nd {
+class D;
+// CHECK-NOTES: :[[@LINE-1]]:7: warning: declaration 'D' is never referenced, but a declaration with the same name found in another namespace 'nd::ne'
+// CHECK-NOTES: note: a declaration of 'D' is found here
+}
+
+namespace nd {
+namespace ne {
+class D;
+}
+}
+
+int f(nd::ne::D &d);
+
+
+// This should be ignored by the check.
+template <typename... Args>
+class Observer {
+ class Impl;
+};
+
+template <typename... Args>
+class Observer<Args...>::Impl {
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-forwarding-reference-overload.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-forwarding-reference-overload.cpp
new file mode 100644
index 0000000..cb842e3
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-forwarding-reference-overload.cpp
@@ -0,0 +1,152 @@
+// RUN: %check_clang_tidy %s bugprone-forwarding-reference-overload %t -- -- -std=c++14
+
+namespace std {
+template <bool B, class T = void> struct enable_if { typedef T type; };
+
+template <class T> struct enable_if<true, T> { typedef T type; };
+
+template <bool B, class T = void>
+using enable_if_t = typename enable_if<B, T>::type;
+
+template <class T> struct enable_if_nice { typedef T type; };
+} // namespace std
+
+namespace foo {
+template <class T> struct enable_if { typedef T type; };
+} // namespace foo
+
+template <typename T> constexpr bool just_true = true;
+
+class Test1 {
+public:
+ template <typename T> Test1(T &&n);
+ // CHECK-NOTES: [[@LINE-1]]:25: warning: constructor accepting a forwarding reference can hide the copy and move constructors [bugprone-forwarding-reference-overload]
+ // CHECK-NOTES: 48:3: note: copy constructor declared here
+ // CHECK-NOTES: 49:3: note: copy constructor declared here
+ // CHECK-NOTES: 50:3: note: move constructor declared here
+
+ template <typename T> Test1(T &&n, int i = 5, ...);
+ // CHECK-NOTES: :[[@LINE-1]]:25: warning: constructor accepting a forwarding reference can hide the copy and move constructors
+ // CHECK-NOTES: 48:3: note: copy constructor declared here
+ // CHECK-NOTES: 49:3: note: copy constructor declared here
+ // CHECK-NOTES: 50:3: note: move constructor declared here
+
+ template <typename T, typename U = typename std::enable_if_nice<T>::type>
+ Test1(T &&n);
+ // CHECK-NOTES: :[[@LINE-1]]:3: warning: constructor accepting a forwarding reference can hide the copy and move constructors
+ // CHECK-NOTES: 48:3: note: copy constructor declared here
+ // CHECK-NOTES: 49:3: note: copy constructor declared here
+ // CHECK-NOTES: 50:3: note: move constructor declared here
+
+ template <typename T>
+ Test1(T &&n, typename foo::enable_if<long>::type i = 5, ...);
+ // CHECK-NOTES: :[[@LINE-1]]:3: warning: constructor accepting a forwarding reference can hide the copy and move constructors
+ // CHECK-NOTES: 48:3: note: copy constructor declared here
+ // CHECK-NOTES: 49:3: note: copy constructor declared here
+ // CHECK-NOTES: 50:3: note: move constructor declared here
+
+ Test1(const Test1 &other) {}
+ Test1(Test1 &other) {}
+ Test1(Test1 &&other) {}
+};
+
+template <typename U> class Test2 {
+public:
+ // Two parameters without default value, can't act as copy / move constructor.
+ template <typename T, class V> Test2(T &&n, V &&m, int i = 5, ...);
+
+ // Guarded with enable_if.
+ template <typename T>
+ Test2(T &&n, int i = 5,
+ std::enable_if_t<sizeof(int) < sizeof(long), int> a = 5, ...);
+
+ // Guarded with enable_if.
+ template <typename T, typename X = typename std::enable_if<
+ sizeof(int) < sizeof(long), double>::type &>
+ Test2(T &&n);
+
+ // Guarded with enable_if.
+ template <typename T>
+ Test2(T &&n, typename std::enable_if<just_true<T>>::type **a = nullptr);
+
+ // Guarded with enable_if.
+ template <typename T, typename X = std::enable_if_t<just_true<T>> *&&>
+ Test2(T &&n, double d = 0.0);
+
+ // Not a forwarding reference parameter.
+ template <typename T> Test2(const T &&n);
+
+ // Not a forwarding reference parameter.
+ Test2(int &&x);
+
+ // Two parameters without default value, can't act as copy / move constructor.
+ template <typename T> Test2(T &&n, int x);
+
+ // Not a forwarding reference parameter.
+ template <typename T> Test2(U &&n);
+};
+
+// The copy and move constructors are both disabled.
+class Test3 {
+public:
+ template <typename T> Test3(T &&n);
+
+ template <typename T> Test3(T &&n, int I = 5, ...);
+
+ Test3(const Test3 &rhs) = delete;
+
+private:
+ Test3(Test3 &&rhs);
+};
+
+// Both the copy and the (compiler generated) move constructors can be hidden.
+class Test4 {
+public:
+ template <typename T> Test4(T &&n);
+ // CHECK-NOTES: :[[@LINE-1]]:25: warning: constructor accepting a forwarding reference can hide the copy and move constructors
+
+ Test4(const Test4 &rhs);
+ // CHECK-NOTES: :[[@LINE-1]]:3: note: copy constructor declared here
+};
+
+// Nothing can be hidden, the copy constructor is implicitly deleted.
+class Test5 {
+public:
+ template <typename T> Test5(T &&n);
+
+ Test5(Test5 &&rhs) = delete;
+};
+
+// Only the move constructor can be hidden.
+class Test6 {
+public:
+ template <typename T> Test6(T &&n);
+ // CHECK-NOTES: :[[@LINE-1]]:25: warning: constructor accepting a forwarding reference can hide the move constructor
+
+ Test6(Test6 &&rhs);
+ // CHECK-NOTES: :[[@LINE-1]]:3: note: move constructor declared here
+private:
+ Test6(const Test6 &rhs);
+};
+
+// Do not dereference a null BaseType.
+template <class _Callable> class result_of;
+template <class _Fp, class ..._Args> class result_of<_Fp(_Args...)> { };
+template <class _Tp> using result_of_t = typename result_of<_Tp>::type;
+
+template <class... _Types> struct __overload;
+template <class _Tp, class... _Types>
+struct __overload<_Tp, _Types...> : __overload<_Types...> {
+ using __overload<_Types...>::operator();
+};
+
+template <class _Tp, class... _Types>
+using __best_match_t = typename result_of_t<__overload<_Types...>(_Tp&&)>::type;
+
+template <class... _Types>
+class variant {
+public:
+ template <class _Arg, class _Tp = __best_match_t<_Arg, _Types...> >
+ constexpr variant(_Arg&& __arg) {}
+ // CHECK-NOTES: :[[@LINE-1]]:13: warning: constructor accepting a forwarding reference can hide the copy and move constructors
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-inaccurate-erase.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-inaccurate-erase.cpp
new file mode 100644
index 0000000..d29fa9c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-inaccurate-erase.cpp
@@ -0,0 +1,100 @@
+// RUN: %check_clang_tidy %s bugprone-inaccurate-erase %t
+
+namespace std {
+template <typename T> struct vec_iterator {
+ T ptr;
+ vec_iterator operator++(int);
+
+ template <typename X>
+ vec_iterator(const vec_iterator<X> &); // Omit enable_if<...>.
+};
+
+template <typename T> struct vector {
+ typedef vec_iterator<T*> iterator;
+
+ iterator begin();
+ iterator end();
+
+ void erase(iterator);
+ void erase(iterator, iterator);
+};
+
+template <typename T> struct vector_with_const_iterator {
+ typedef vec_iterator<T*> iterator;
+ typedef vec_iterator<const T*> const_iterator;
+
+ iterator begin();
+ iterator end();
+
+ void erase(const_iterator);
+ void erase(const_iterator, const_iterator);
+};
+
+template <typename FwIt, typename T>
+FwIt remove(FwIt begin, FwIt end, const T &val);
+
+template <typename FwIt, typename Func>
+FwIt remove_if(FwIt begin, FwIt end, Func f);
+
+template <typename FwIt> FwIt unique(FwIt begin, FwIt end);
+
+template <typename T> struct unique_ptr {};
+} // namespace std
+
+struct custom_iter {};
+struct custom_container {
+ void erase(...);
+ custom_iter begin();
+ custom_iter end();
+};
+
+template <typename T> void g() {
+ T t;
+ t.erase(std::remove(t.begin(), t.end(), 10));
+ // CHECK-FIXES: {{^ }}t.erase(std::remove(t.begin(), t.end(), 10));{{$}}
+
+ std::vector<int> v;
+ v.erase(remove(v.begin(), v.end(), 10));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this call will remove at most one
+ // CHECK-FIXES: {{^ }}v.erase(remove(v.begin(), v.end(), 10), v.end());{{$}}
+}
+
+#define ERASE(x, y) x.erase(remove(x.begin(), x.end(), y))
+// CHECK-FIXES: #define ERASE(x, y) x.erase(remove(x.begin(), x.end(), y))
+
+int main() {
+ std::vector<int> v;
+
+ v.erase(remove(v.begin(), v.end(), 10));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this call will remove at most one item even when multiple items should be removed [bugprone-inaccurate-erase]
+ // CHECK-FIXES: {{^ }}v.erase(remove(v.begin(), v.end(), 10), v.end());{{$}}
+ v.erase(remove(v.begin(), v.end(), 20), v.end());
+
+ auto *p = &v;
+ p->erase(remove(p->begin(), p->end(), 11));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this call will remove at most one
+ // CHECK-FIXES: {{^ }}p->erase(remove(p->begin(), p->end(), 11), p->end());{{$}}
+
+ std::vector_with_const_iterator<int> v2;
+ v2.erase(remove(v2.begin(), v2.end(), 12));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this call will remove at most one
+ // CHECK-FIXES: {{^ }}v2.erase(remove(v2.begin(), v2.end(), 12), v2.end());{{$}}
+
+ // Fix is not trivial.
+ auto it = v.end();
+ v.erase(remove(v.begin(), it, 10));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this call will remove at most one
+ // CHECK-FIXES: {{^ }}v.erase(remove(v.begin(), it, 10));{{$}}
+
+ g<std::vector<int>>();
+ g<custom_container>();
+
+ ERASE(v, 15);
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: this call will remove at most one
+ // CHECK-FIXES: {{^ }}ERASE(v, 15);{{$}}
+
+ std::vector<std::unique_ptr<int>> vupi;
+ auto iter = vupi.begin();
+ vupi.erase(iter++);
+ // CHECK-FIXES: {{^ }}vupi.erase(iter++);{{$}}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-incorrect-roundings.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-incorrect-roundings.cpp
new file mode 100644
index 0000000..7ada061
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-incorrect-roundings.cpp
@@ -0,0 +1,86 @@
+// RUN: %check_clang_tidy %s bugprone-incorrect-roundings %t
+
+void b(int x) {}
+
+void f1() {
+ float f;
+ double d;
+ long double ld;
+ int x;
+
+ x = (d + 0.5);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5) to integer leads to incorrect rounding; consider using lround (#include <cmath>) instead [bugprone-incorrect-roundings]
+ x = (d + 0.5f);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5)
+ x = (f + 0.5);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5)
+ x = (f + 0.5f);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5)
+ x = (0.5 + d);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5)
+ x = (0.5f + d);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5)
+ x = (0.5 + ld);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5)
+ x = (0.5f + ld);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5)
+ x = (0.5 + f);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5)
+ x = (0.5f + f);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5)
+ x = (int)(d + 0.5);
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5)
+ x = (int)(d + 0.5f);
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5)
+ x = (int)(ld + 0.5);
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5)
+ x = (int)(ld + 0.5f);
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5)
+ x = (int)(f + 0.5);
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5)
+ x = (int)(f + 0.5f);
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5)
+ x = (int)(0.5 + d);
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5)
+ x = (int)(0.5f + d);
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5)
+ x = (int)(0.5 + ld);
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5)
+ x = (int)(0.5f + ld);
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5)
+ x = (int)(0.5 + f);
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5)
+ x = (int)(0.5f + f);
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5)
+ x = static_cast<int>(d + 0.5);
+ // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5)
+ x = static_cast<int>(d + 0.5f);
+ // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5)
+ x = static_cast<int>(ld + 0.5);
+ // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5)
+ x = static_cast<int>(ld + 0.5f);
+ // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5)
+ x = static_cast<int>(f + 0.5);
+ // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5)
+ x = static_cast<int>(f + 0.5f);
+ // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5)
+ x = static_cast<int>(0.5 + d);
+ // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5)
+ x = static_cast<int>(0.5f + d);
+ // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5)
+ x = static_cast<int>(0.5 + ld);
+ // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5)
+ x = static_cast<int>(0.5f + ld);
+ // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5)
+ x = static_cast<int>(0.5 + f);
+ // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5)
+ x = static_cast<int>(0.5f + f);
+ // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5)
+
+ // Don't warn if constant is not 0.5.
+ x = (int)(d + 0.6);
+ x = (int)(0.6 + d);
+
+ // Don't warn if binary operator is not directly beneath cast.
+ x = (int)(1 + (0.5 + f));
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-integer-division.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-integer-division.cpp
new file mode 100644
index 0000000..243ad46
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-integer-division.cpp
@@ -0,0 +1,130 @@
+// RUN: %check_clang_tidy %s bugprone-integer-division %t
+
+// Functions expecting a floating-point parameter.
+void floatArg(float x) {}
+void doubleArg(double x) {}
+void longDoubleArg(long double x) {}
+
+// Functions expected to return a floating-point value.
+float singleDiv() {
+ int x = -5;
+ int y = 2;
+ return x/y;
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: result of integer division used in
+}
+
+double wrongOrder(int x, int y) {
+ return x/y/0.1;
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: result of integer division used in
+}
+
+long double rightOrder(int x, int y) {
+ return 0.1/x/y; // OK
+}
+
+// Typical mathematical functions.
+float sin(float);
+double acos(double);
+long double tanh(long double);
+
+namespace std {
+ using ::sin;
+}
+
+template <typename T>
+void intDivSin(T x) {
+ sin(x);
+}
+
+int intFunc(int);
+
+struct X {
+ int n;
+ void m() {
+ sin(n / 3);
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: result of integer division used in
+ }
+};
+
+void integerDivision() {
+ char a = 2;
+ short b = -5;
+ int c = 9784;
+ enum third { x, y, z=2 };
+ third d = z;
+ char e[] = {'a', 'b', 'c'};
+ char f = *(e + 1 / a);
+ bool g = 1;
+
+ sin(1 + c / (2 + 2));
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: result of integer division used in
+ sin(c / (1 + .5));
+ sin((c + .5) / 3);
+
+ sin(intFunc(3) / 5);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: result of integer division used in
+ acos(2 / intFunc(7));
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: result of integer division used in
+
+ floatArg(1 + 2 / 3);
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: result of integer division used in
+ sin(1 + 2 / 3);
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: result of integer division used in
+ intFunc(sin(1 + 2 / 3));
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: result of integer division used in
+
+ floatArg(1 + intFunc(1 + 2 / 3));
+ floatArg(1 + 3 * intFunc(a / b));
+
+ 1 << (2 / 3);
+ 1 << intFunc(2 / 3);
+
+#define M_SIN sin(a / b);
+ M_SIN
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: result of integer division used in
+
+ intDivSin<float>(a / b);
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: result of integer division used in
+ intDivSin<double>(c / d);
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: result of integer division used in
+ intDivSin<long double>(f / g);
+// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: result of integer division used in
+
+ floatArg(1 / 3);
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: result of integer division used in
+ doubleArg(a / b);
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: result of integer division used in
+ longDoubleArg(3 / d);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: result of integer division used in
+ floatArg(a / b / 0.1);
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: result of integer division used in
+ doubleArg(1 / 3 / 0.1);
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: result of integer division used in
+ longDoubleArg(2 / 3 / 5);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: result of integer division used in
+
+ std::sin(2 / 3);
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: result of integer division used in
+ ::acos(7 / d);
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: result of integer division used in
+ tanh(f / g);
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: result of integer division used in
+
+ floatArg(0.1 / a / b);
+ doubleArg(0.1 / 3 / 1);
+
+ singleDiv();
+ wrongOrder(a,b);
+ rightOrder(a,b);
+
+ sin(a / b);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: result of integer division used in
+ acos(f / d);
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: result of integer division used in
+ tanh(c / g);
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: result of integer division used in
+
+ sin(3.0 / a);
+ acos(b / 3.14);
+ tanh(3.14 / f / g);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-lambda-function-name.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-lambda-function-name.cpp
new file mode 100644
index 0000000..145928b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-lambda-function-name.cpp
@@ -0,0 +1,41 @@
+// RUN: %check_clang_tidy %s bugprone-lambda-function-name %t
+
+void Foo(const char* a, const char* b, int c) {}
+
+#define FUNC_MACRO Foo(__func__, "", 0)
+#define FUNCTION_MACRO Foo(__FUNCTION__, "", 0)
+#define EMBED_IN_ANOTHER_MACRO1 FUNC_MACRO
+
+void Positives() {
+ [] { __func__; }();
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: inside a lambda, '__func__' expands to the name of the function call operator; consider capturing the name of the enclosing function explicitly [bugprone-lambda-function-name]
+ [] { __FUNCTION__; }();
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: inside a lambda, '__FUNCTION__' expands to the name of the function call operator; consider capturing the name of the enclosing function explicitly [bugprone-lambda-function-name]
+ [] { FUNC_MACRO; }();
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: inside a lambda, '__func__' expands to the name of the function call operator; consider capturing the name of the enclosing function explicitly [bugprone-lambda-function-name]
+ [] { FUNCTION_MACRO; }();
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: inside a lambda, '__FUNCTION__' expands to the name of the function call operator; consider capturing the name of the enclosing function explicitly [bugprone-lambda-function-name]
+ [] { EMBED_IN_ANOTHER_MACRO1; }();
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: inside a lambda, '__func__' expands to the name of the function call operator; consider capturing the name of the enclosing function explicitly [bugprone-lambda-function-name]
+}
+
+#define FUNC_MACRO_WITH_FILE_AND_LINE Foo(__func__, __FILE__, __LINE__)
+#define FUNCTION_MACRO_WITH_FILE_AND_LINE Foo(__FUNCTION__, __FILE__, __LINE__)
+#define EMBED_IN_ANOTHER_MACRO2 FUNC_MACRO_WITH_FILE_AND_LINE
+
+void Negatives() {
+ __func__;
+ __FUNCTION__;
+
+ // __PRETTY_FUNCTION__ should not trigger a warning because its value is
+ // actually potentially useful.
+ __PRETTY_FUNCTION__;
+ [] { __PRETTY_FUNCTION__; }();
+
+ // Don't warn if __func__/__FUNCTION is used inside a macro that also uses
+ // __FILE__ and __LINE__, on the assumption that __FILE__ and __LINE__ will
+ // be useful even if __func__/__FUNCTION__ is not.
+ [] { FUNC_MACRO_WITH_FILE_AND_LINE; }();
+ [] { FUNCTION_MACRO_WITH_FILE_AND_LINE; }();
+ [] { EMBED_IN_ANOTHER_MACRO2; }();
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-macro-parentheses-cmdline.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-macro-parentheses-cmdline.cpp
new file mode 100644
index 0000000..9ff757d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-macro-parentheses-cmdline.cpp
@@ -0,0 +1,10 @@
+// RUN: %check_clang_tidy %s bugprone-macro-parentheses %t -- -- -DVAL=0+0
+
+// The previous command-line is producing warnings and fixes with the source
+// locations from a virtual buffer. VAL is replaced by '0+0'.
+// Fixes could not be applied and should not be reported.
+int foo() { return VAL; }
+
+#define V 0+0
+int bar() { return V; }
+// CHECK-FIXES: #define V (0+0)
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-macro-parentheses.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-macro-parentheses.cpp
new file mode 100644
index 0000000..2cc45e8
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-macro-parentheses.cpp
@@ -0,0 +1,49 @@
+// RUN: %check_clang_tidy %s bugprone-macro-parentheses %t
+
+#define BAD1 -1
+// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: macro replacement list should be enclosed in parentheses [bugprone-macro-parentheses]
+#define BAD2 1+2
+// CHECK-MESSAGES: :[[@LINE-1]]:28: warning: macro replacement list should be enclosed in parentheses [bugprone-macro-parentheses]
+#define BAD3(A) (A+1)
+// CHECK-MESSAGES: :[[@LINE-1]]:28: warning: macro argument should be enclosed in parentheses [bugprone-macro-parentheses]
+#define BAD4(x) ((unsigned char)(x & 0xff))
+// CHECK-MESSAGES: :[[@LINE-1]]:44: warning: macro argument should be enclosed in parentheses [bugprone-macro-parentheses]
+#define BAD5(X) A*B=(C*)X+2
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: macro argument should be enclosed in parentheses [bugprone-macro-parentheses]
+
+#define GOOD1 1
+#define GOOD2 (1+2)
+#define GOOD3(A) #A
+#define GOOD4(A,B) A ## B
+#define GOOD5(T) ((T*)0)
+#define GOOD6(B) "A" B "C"
+#define GOOD7(b) A b
+#define GOOD8(a) a B
+#define GOOD9(type) (type(123))
+#define GOOD10(car, ...) car
+#define GOOD11 a[b+c]
+#define GOOD12(x) a[x]
+#define GOOD13(x) a.x
+#define GOOD14(x) a->x
+#define GOOD15(x) ({ int a = x; a+4; })
+#define GOOD16(x) a_ ## x, b_ ## x = c_ ## x - 1,
+#define GOOD17 case 123: x=4+5; break;
+#define GOOD18(x) ;x;
+#define GOOD19 ;-2;
+#define GOOD20 void*
+#define GOOD21(a) case Fred::a:
+#define GOOD22(a) if (verbose) return a;
+#define GOOD23(type) (type::Field)
+#define GOOD24(t) std::set<t> s
+#define GOOD25(t) std::set<t,t,t> s
+#define GOOD26(x) (a->*x)
+#define GOOD27(x) (a.*x)
+#define GOOD28(x) namespace x {int b;}
+#define GOOD29(...) std::cout << __VA_ARGS__;
+#define GOOD30(args...) std::cout << args;
+#define GOOD31(X) A*X=2
+#define GOOD32(X) std::vector<X>
+
+// These are allowed for now..
+#define MAYBE1 *12.34
+#define MAYBE2 <<3
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-macro-repeated-side-effects.c b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-macro-repeated-side-effects.c
new file mode 100644
index 0000000..995d872
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-macro-repeated-side-effects.c
@@ -0,0 +1,125 @@
+// RUN: %check_clang_tidy %s bugprone-macro-repeated-side-effects %t
+
+#define badA(x,y) ((x)+((x)+(y))+(y))
+void bad(int ret, int a, int b) {
+ ret = badA(a++, b);
+ // CHECK-NOTES: :[[@LINE-1]]:14: warning: side effects in the 1st macro argument 'x' are repeated in macro expansion [bugprone-macro-repeated-side-effects]
+ // CHECK-NOTES: :[[@LINE-4]]:9: note: macro 'badA' defined here
+ ret = badA(++a, b);
+ // CHECK-NOTES: :[[@LINE-1]]:14: warning: side effects in the 1st macro argument 'x'
+ // CHECK-NOTES: :[[@LINE-7]]:9: note: macro 'badA' defined here
+ ret = badA(a--, b);
+ // CHECK-NOTES: :[[@LINE-1]]:14: warning: side effects in the 1st macro argument 'x'
+ // CHECK-NOTES: :[[@LINE-10]]:9: note: macro 'badA' defined here
+ ret = badA(--a, b);
+ // CHECK-NOTES: :[[@LINE-1]]:14: warning: side effects in the 1st macro argument 'x'
+ // CHECK-NOTES: :[[@LINE-13]]:9: note: macro 'badA' defined here
+ ret = badA(a, b++);
+ // CHECK-NOTES: :[[@LINE-1]]:17: warning: side effects in the 2nd macro argument 'y'
+ // CHECK-NOTES: :[[@LINE-16]]:9: note: macro 'badA' defined here
+ ret = badA(a, ++b);
+ // CHECK-NOTES: :[[@LINE-1]]:17: warning: side effects in the 2nd macro argument 'y'
+ // CHECK-NOTES: :[[@LINE-19]]:9: note: macro 'badA' defined here
+ ret = badA(a, b--);
+ // CHECK-NOTES: :[[@LINE-1]]:17: warning: side effects in the 2nd macro argument 'y'
+ // CHECK-NOTES: :[[@LINE-22]]:9: note: macro 'badA' defined here
+ ret = badA(a, --b);
+ // CHECK-NOTES: :[[@LINE-1]]:17: warning: side effects in the 2nd macro argument 'y'
+ // CHECK-NOTES: :[[@LINE-25]]:9: note: macro 'badA' defined here
+}
+
+
+#define MIN(A,B) ((A) < (B) ? (A) : (B)) // single ?:
+#define LIMIT(X,A,B) ((X) < (A) ? (A) : ((X) > (B) ? (B) : (X))) // two ?:
+void question(int x) {
+ MIN(x++, 12);
+ // CHECK-NOTES: :[[@LINE-1]]:7: warning: side effects in the 1st macro argument 'A'
+ // CHECK-NOTES: :[[@LINE-5]]:9: note: macro 'MIN' defined here
+ MIN(34, x++);
+ // CHECK-NOTES: :[[@LINE-1]]:11: warning: side effects in the 2nd macro argument 'B'
+ // CHECK-NOTES: :[[@LINE-8]]:9: note: macro 'MIN' defined here
+ LIMIT(x++, 0, 100);
+ // CHECK-NOTES: :[[@LINE-1]]:9: warning: side effects in the 1st macro argument 'X'
+ // CHECK-NOTES: :[[@LINE-10]]:9: note: macro 'LIMIT' defined here
+ LIMIT(20, x++, 100);
+ // CHECK-NOTES: :[[@LINE-1]]:13: warning: side effects in the 2nd macro argument 'A'
+ // CHECK-NOTES: :[[@LINE-13]]:9: note: macro 'LIMIT' defined here
+ LIMIT(20, 0, x++);
+ // CHECK-NOTES: :[[@LINE-1]]:16: warning: side effects in the 3rd macro argument 'B'
+ // CHECK-NOTES: :[[@LINE-16]]:9: note: macro 'LIMIT' defined here
+}
+
+// False positive: Repeated side effects is intentional.
+// It is hard to know when it's done by intention so right now we warn.
+#define UNROLL(A) {A A}
+void fp1(int i) {
+ UNROLL({ i++; });
+ // CHECK-NOTES: :[[@LINE-1]]:10: warning: side effects in the 1st macro argument 'A'
+ // CHECK-NOTES: :[[@LINE-4]]:9: note: macro 'UNROLL' defined here
+}
+
+// Do not produce a false positive on a strchr() macro. Explanation; Currently the '?'
+// triggers the test to bail out, because it cannot evaluate __builtin_constant_p(c).
+# define strchrs(s, c) \
+ (__extension__ (__builtin_constant_p (c) && !__builtin_constant_p (s) \
+ && (c) == '\0' \
+ ? (char *) __rawmemchr (s, c) \
+ : __builtin_strchr (s, c)))
+char* __rawmemchr(char* a, char b) {
+ return a;
+}
+void pass(char* pstr, char ch) {
+ strchrs(pstr, ch++); // No error.
+}
+
+// Check large arguments (t=20, u=21).
+#define largeA(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, x, y, z) \
+ ((a) + (a) + (b) + (b) + (c) + (c) + (d) + (d) + (e) + (e) + (f) + (f) + (g) + (g) + \
+ (h) + (h) + (i) + (i) + (j) + (j) + (k) + (k) + (l) + (l) + (m) + (m) + (n) + (n) + \
+ (o) + (o) + (p) + (p) + (q) + (q) + (r) + (r) + (s) + (s) + (t) + (t) + (u) + (u) + \
+ (v) + (v) + (x) + (x) + (y) + (y) + (z) + (z))
+void large(int a) {
+ largeA(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a++, 0, 0, 0, 0, 0, 0);
+ // CHECK-NOTES: :[[@LINE-1]]:64: warning: side effects in the 19th macro argument 's'
+ // CHECK-NOTES: :[[@LINE-8]]:9: note: macro 'largeA' defined here
+ largeA(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a++, 0, 0, 0, 0, 0);
+ // CHECK-NOTES: :[[@LINE-1]]:67: warning: side effects in the 20th macro argument 't'
+ // CHECK-NOTES: :[[@LINE-11]]:9: note: macro 'largeA' defined here
+ largeA(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a++, 0, 0, 0, 0);
+ // CHECK-NOTES: :[[@LINE-1]]:70: warning: side effects in the 21st macro argument 'u'
+ // CHECK-NOTES: :[[@LINE-14]]:9: note: macro 'largeA' defined here
+}
+
+// Passing macro argument as argument to __builtin_constant_p and macros.
+#define builtinbad(x) (__builtin_constant_p(x) + (x) + (x))
+#define builtingood1(x) (__builtin_constant_p(x) + (x))
+#define builtingood2(x) ((__builtin_constant_p(x) && (x)) || (x))
+#define macrobad(x) (builtingood1(x) + (x) + (x))
+#define macrogood(x) (builtingood1(x) + (x))
+void builtins(int ret, int a) {
+ ret += builtinbad(a++);
+ // CHECK-NOTES: :[[@LINE-1]]:21: warning: side effects in the 1st macro argument 'x'
+ // CHECK-NOTES: :[[@LINE-8]]:9: note: macro 'builtinbad' defined here
+
+ ret += builtingood1(a++);
+ ret += builtingood2(a++);
+
+ ret += macrobad(a++);
+ // CHECK-NOTES: :[[@LINE-1]]:19: warning: side effects in the 1st macro argument 'x'
+ // CHECK-NOTES: :[[@LINE-12]]:9: note: macro 'macrobad' defined here
+
+ ret += macrogood(a++);
+}
+
+// Bail out for conditionals.
+#define condB(x,y) if(x) {x=y;} else {x=y + 1;}
+void conditionals(int a, int b)
+{
+ condB(a, b++);
+}
+
+void log(const char *s, int v);
+#define LOG(val) log(#val, (val))
+void test_log(int a) {
+ LOG(a++);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-misplaced-operator-in-strlen-in-alloc.c b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-misplaced-operator-in-strlen-in-alloc.c
new file mode 100644
index 0000000..c5deb25
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-misplaced-operator-in-strlen-in-alloc.c
@@ -0,0 +1,85 @@
+// RUN: %check_clang_tidy %s bugprone-misplaced-operator-in-strlen-in-alloc %t
+
+typedef __typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+void *alloca(size_t);
+void *calloc(size_t, size_t);
+void *realloc(void *, size_t);
+
+size_t strlen(const char *);
+size_t strnlen(const char *, size_t);
+size_t strnlen_s(const char *, size_t);
+
+typedef unsigned wchar_t;
+
+size_t wcslen(const wchar_t *);
+size_t wcsnlen(const wchar_t *, size_t);
+size_t wcsnlen_s(const wchar_t *, size_t);
+
+void bad_malloc(char *name) {
+ char *new_name = (char *)malloc(strlen(name + 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: addition operator is applied to the argument of strlen
+ // CHECK-FIXES: {{^ char \*new_name = \(char \*\)malloc\(}}strlen(name) + 1{{\);$}}
+ new_name = (char *)malloc(strnlen(name + 1, 10));
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: addition operator is applied to the argument of strnlen
+ // CHECK-FIXES: {{^ new_name = \(char \*\)malloc\(}}strnlen(name, 10) + 1{{\);$}}
+ new_name = (char *)malloc(strnlen_s(name + 1, 10));
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: addition operator is applied to the argument of strnlen_s
+ // CHECK-FIXES: {{^ new_name = \(char \*\)malloc\(}}strnlen_s(name, 10) + 1{{\);$}}
+}
+
+void bad_malloc_wide(wchar_t *name) {
+ wchar_t *new_name = (wchar_t *)malloc(wcslen(name + 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: addition operator is applied to the argument of wcslen
+ // CHECK-FIXES: {{^ wchar_t \*new_name = \(wchar_t \*\)malloc\(}}wcslen(name) + 1{{\);$}}
+ new_name = (wchar_t *)malloc(wcsnlen(name + 1, 10));
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: addition operator is applied to the argument of wcsnlen
+ // CHECK-FIXES: {{^ new_name = \(wchar_t \*\)malloc\(}}wcsnlen(name, 10) + 1{{\);$}}
+ new_name = (wchar_t *)malloc(wcsnlen_s(name + 1, 10));
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: addition operator is applied to the argument of wcsnlen_s
+ // CHECK-FIXES: {{^ new_name = \(wchar_t \*\)malloc\(}}wcsnlen_s(name, 10) + 1{{\);$}}
+}
+
+void bad_alloca(char *name) {
+ char *new_name = (char *)alloca(strlen(name + 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: addition operator is applied to the argument of strlen
+ // CHECK-FIXES: {{^ char \*new_name = \(char \*\)alloca\(}}strlen(name) + 1{{\);$}}
+}
+
+void bad_calloc(char *name) {
+ char *new_names = (char *)calloc(2, strlen(name + 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: addition operator is applied to the argument of strlen
+ // CHECK-FIXES: {{^ char \*new_names = \(char \*\)calloc\(2, }}strlen(name) + 1{{\);$}}
+}
+
+void bad_realloc(char *old_name, char *name) {
+ char *new_name = (char *)realloc(old_name, strlen(name + 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: addition operator is applied to the argument of strlen
+ // CHECK-FIXES: {{^ char \*new_name = \(char \*\)realloc\(old_name, }}strlen(name) + 1{{\);$}}
+}
+
+void intentional1(char *name) {
+ char *new_name = (char *)malloc(strlen(name + 1) + 1);
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:28: warning: addition operator is applied to the argument of strlen
+ // We have + 1 outside as well so we assume this is intentional
+}
+
+void intentional2(char *name) {
+ char *new_name = (char *)malloc(strlen(name + 2));
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:28: warning: addition operator is applied to the argument of strlen
+ // Only give warning for + 1, not + 2
+}
+
+void intentional3(char *name) {
+ char *new_name = (char *)malloc(strlen((name + 1)));
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:28: warning: addition operator is applied to the argument of strlen
+ // If expression is in extra parentheses, consider it as intentional
+}
+
+void (*(*const alloc_ptr)(size_t)) = malloc;
+
+void bad_indirect_alloc(char *name) {
+ char *new_name = (char *)alloc_ptr(strlen(name + 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: addition operator is applied to the argument of strlen
+ // CHECK-FIXES: {{^ char \*new_name = \(char \*\)alloc_ptr\(}}strlen(name) + 1{{\);$}}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-misplaced-operator-in-strlen-in-alloc.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-misplaced-operator-in-strlen-in-alloc.cpp
new file mode 100644
index 0000000..58d63fa
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-misplaced-operator-in-strlen-in-alloc.cpp
@@ -0,0 +1,58 @@
+// RUN: %check_clang_tidy %s bugprone-misplaced-operator-in-strlen-in-alloc %t
+
+namespace std {
+typedef __typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+
+size_t strlen(const char *);
+} // namespace std
+
+namespace non_std {
+typedef __typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+
+size_t strlen(const char *);
+} // namespace non_std
+
+void bad_std_malloc_std_strlen(char *name) {
+ char *new_name = (char *)std::malloc(std::strlen(name + 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: addition operator is applied to the argument of strlen
+ // CHECK-FIXES: {{^ char \*new_name = \(char \*\)std::malloc\(}}std::strlen(name) + 1{{\);$}}
+}
+
+void ignore_non_std_malloc_std_strlen(char *name) {
+ char *new_name = (char *)non_std::malloc(std::strlen(name + 1));
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:28: warning: addition operator is applied to the argument of strlen
+ // Ignore functions of the malloc family in custom namespaces
+}
+
+void ignore_std_malloc_non_std_strlen(char *name) {
+ char *new_name = (char *)std::malloc(non_std::strlen(name + 1));
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:28: warning: addition operator is applied to the argument of strlen
+ // Ignore functions of the strlen family in custom namespaces
+}
+
+void bad_new_strlen(char *name) {
+ char *new_name = new char[std::strlen(name + 1)];
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: addition operator is applied to the argument of strlen
+ // CHECK-FIXES: {{^ char \*new_name = new char\[}}std::strlen(name) + 1{{\];$}}
+}
+
+void good_new_strlen(char *name) {
+ char *new_name = new char[std::strlen(name) + 1];
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:20: warning: addition operator is applied to the argument of strlen
+}
+
+class C {
+ char c;
+public:
+ static void *operator new[](std::size_t count) {
+ return ::operator new(count);
+ }
+};
+
+void bad_custom_new_strlen(char *name) {
+ C *new_name = new C[std::strlen(name + 1)];
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: addition operator is applied to the argument of strlen
+ // CHECK-FIXES: {{^ C \*new_name = new C\[}}std::strlen(name) + 1{{\];$}}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-misplaced-widening-cast-explicit-only.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-misplaced-widening-cast-explicit-only.cpp
new file mode 100644
index 0000000..ed2fd40
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-misplaced-widening-cast-explicit-only.cpp
@@ -0,0 +1,82 @@
+// RUN: %check_clang_tidy %s bugprone-misplaced-widening-cast %t -- -config="{CheckOptions: [{key: bugprone-misplaced-widening-cast.CheckImplicitCasts, value: 0}]}" --
+
+void func(long arg) {}
+
+void assign(int a, int b) {
+ long l;
+
+ l = a * b;
+ l = (long)(a * b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: either cast from 'int' to 'long' is ineffective, or there is loss of precision before the conversion [bugprone-misplaced-widening-cast]
+ l = (long)a * b;
+
+ l = a << 8;
+ l = (long)(a << 8);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: either cast from 'int' to 'long'
+ l = (long)b << 8;
+
+ l = static_cast<long>(a * b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: either cast from 'int' to 'long'
+}
+
+void compare(int a, int b, long c) {
+ bool l;
+
+ l = a * b == c;
+ l = c == a * b;
+ l = (long)(a * b) == c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: either cast from 'int' to 'long'
+ l = c == (long)(a * b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: either cast from 'int' to 'long'
+ l = (long)a * b == c;
+ l = c == (long)a * b;
+}
+
+void init(unsigned int n) {
+ long l1 = n << 8;
+ long l2 = (long)(n << 8);
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: either cast from 'unsigned int' to 'long'
+ long l3 = (long)n << 8;
+}
+
+void call(unsigned int n) {
+ func(n << 8);
+ func((long)(n << 8));
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: either cast from 'unsigned int' to 'long'
+ func((long)n << 8);
+}
+
+long ret(int a) {
+ if (a < 0) {
+ return a * 1000;
+ } else if (a > 0) {
+ return (long)(a * 1000);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: either cast from 'int' to 'long'
+ } else {
+ return (long)a * 1000;
+ }
+}
+
+// Shall not generate an assert. https://bugs.llvm.org/show_bug.cgi?id=33660
+template <class> class A {
+ enum Type {};
+ static char *m_fn1() { char p = (Type)(&p - m_fn1()); }
+};
+
+enum DaysEnum {
+ MON,
+ TUE,
+ WED,
+ THR,
+ FRI,
+ SAT,
+ SUN
+};
+
+// Do not warn for int to enum casts.
+void nextDay(DaysEnum day) {
+ if (day < SUN)
+ day = (DaysEnum)(day + 1);
+ if (day < SUN)
+ day = static_cast<DaysEnum>(day + 1);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-misplaced-widening-cast-implicit-enabled.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-misplaced-widening-cast-implicit-enabled.cpp
new file mode 100644
index 0000000..5487b33
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-misplaced-widening-cast-implicit-enabled.cpp
@@ -0,0 +1,101 @@
+// RUN: %check_clang_tidy %s bugprone-misplaced-widening-cast %t -- -config="{CheckOptions: [{key: bugprone-misplaced-widening-cast.CheckImplicitCasts, value: 1}]}" --
+
+void func(long arg) {}
+
+void assign(int a, int b) {
+ long l;
+
+ l = a * b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: either cast from 'int' to 'long' is ineffective, or there is loss of precision before the conversion [bugprone-misplaced-widening-cast]
+ l = (long)(a * b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: either cast from 'int' to 'long'
+ l = (long)a * b;
+
+ l = a << 8;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: either cast from 'int' to 'long'
+ l = (long)(a << 8);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: either cast from 'int' to 'long'
+ l = (long)b << 8;
+
+ l = static_cast<long>(a * b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: either cast from 'int' to 'long'
+}
+
+void compare(int a, int b, long c) {
+ bool l;
+
+ l = a * b == c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: either cast from 'int' to 'long'
+ l = c == a * b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: either cast from 'int' to 'long'
+ l = (long)(a * b) == c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: either cast from 'int' to 'long'
+ l = c == (long)(a * b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: either cast from 'int' to 'long'
+ l = (long)a * b == c;
+ l = c == (long)a * b;
+}
+
+void init(unsigned int n) {
+ long l1 = n << 8;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: either cast from 'unsigned int' to 'long'
+ long l2 = (long)(n << 8);
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: either cast from 'unsigned int' to 'long'
+ long l3 = (long)n << 8;
+}
+
+void call(unsigned int n) {
+ func(n << 8);
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: either cast from 'unsigned int' to 'long'
+ func((long)(n << 8));
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: either cast from 'unsigned int' to 'long'
+ func((long)n << 8);
+}
+
+long ret(int a) {
+ if (a < 0) {
+ return a * 1000;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: either cast from 'int' to 'long'
+ } else if (a > 0) {
+ return (long)(a * 1000);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: either cast from 'int' to 'long'
+ } else {
+ return (long)a * 1000;
+ }
+}
+
+void dontwarn1(unsigned char a, int i, unsigned char *p) {
+ long l;
+ // The result is a 9 bit value, there is no truncation in the implicit cast.
+ l = (long)(a + 15);
+ // The result is a 12 bit value, there is no truncation in the implicit cast.
+ l = (long)(a << 4);
+ // The result is a 3 bit value, there is no truncation in the implicit cast.
+ l = (long)((i % 5) + 1);
+ // The result is a 16 bit value, there is no truncation in the implicit cast.
+ l = (long)(((*p) << 8) + *(p + 1));
+}
+
+template <class T> struct DontWarn2 {
+ void assign(T a, T b) {
+ long l;
+ l = (long)(a * b);
+ }
+};
+DontWarn2<int> DW2;
+
+// Cast is not suspicious when casting macro.
+#define A (X<<2)
+long macro1(int X) {
+ return (long)A;
+}
+
+// Don't warn about cast in macro.
+#define B(X,Y) (long)(X*Y)
+long macro2(int x, int y) {
+ return B(x,y);
+}
+
+void floatingpoint(float a, float b) {
+ double d = (double)(a * b); // Currently we don't warn for this.
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-move-forwarding-reference.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-move-forwarding-reference.cpp
new file mode 100644
index 0000000..befca29
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-move-forwarding-reference.cpp
@@ -0,0 +1,125 @@
+// RUN: %check_clang_tidy %s bugprone-move-forwarding-reference %t -- -- -std=c++14 -fno-delayed-template-parsing
+
+namespace std {
+template <typename> struct remove_reference;
+
+template <typename _Tp> struct remove_reference { typedef _Tp type; };
+
+template <typename _Tp> struct remove_reference<_Tp &> { typedef _Tp type; };
+
+template <typename _Tp> struct remove_reference<_Tp &&> { typedef _Tp type; };
+
+template <typename _Tp>
+constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t);
+
+} // namespace std
+
+// Standard case.
+template <typename T, typename U> void f1(U &&SomeU) {
+ T SomeT(std::move(SomeU));
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: forwarding reference passed to
+ // CHECK-FIXES: T SomeT(std::forward<U>(SomeU));
+}
+
+// Ignore parentheses around the argument to std::move().
+template <typename T, typename U> void f2(U &&SomeU) {
+ T SomeT(std::move((SomeU)));
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: forwarding reference passed to
+ // CHECK-FIXES: T SomeT(std::forward<U>((SomeU)));
+}
+
+// Handle the case correctly where std::move() is being used through a using
+// declaration.
+template <typename T, typename U> void f3(U &&SomeU) {
+ using std::move;
+ T SomeT(move(SomeU));
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: forwarding reference passed to
+ // CHECK-FIXES: T SomeT(std::forward<U>(SomeU));
+}
+
+// Handle the case correctly where a global specifier is prepended to
+// std::move().
+template <typename T, typename U> void f4(U &&SomeU) {
+ T SomeT(::std::move(SomeU));
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: forwarding reference passed to
+ // CHECK-FIXES: T SomeT(::std::forward<U>(SomeU));
+}
+
+// Create a correct fix if there are spaces around the scope resolution
+// operator.
+template <typename T, typename U> void f5(U &&SomeU) {
+ {
+ T SomeT(:: std :: move(SomeU));
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: forwarding reference passed to
+ // CHECK-FIXES: T SomeT(::std::forward<U>(SomeU));
+ }
+ {
+ T SomeT(std :: move(SomeU));
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: forwarding reference passed to
+ // CHECK-FIXES: T SomeT(std::forward<U>(SomeU));
+ }
+}
+
+// Ignore const rvalue reference parameters.
+template <typename T, typename U> void f6(const U &&SomeU) {
+ T SomeT(std::move(SomeU));
+}
+
+// Ignore the case where the argument to std::move() is a lambda parameter (and
+// thus not actually a parameter of the function template).
+template <typename T, typename U> void f7() {
+ [](U &&SomeU) { T SomeT(std::move(SomeU)); };
+}
+
+// Ignore the case where the argument is a lvalue reference.
+template <typename T, typename U> void f8(U &SomeU) {
+ T SomeT(std::move(SomeU));
+}
+
+// Ignore the case where the template parameter is a class template parameter
+// (i.e. no template argument deduction is taking place).
+template <typename T, typename U> class SomeClass {
+ void f(U &&SomeU) { T SomeT(std::move(SomeU)); }
+};
+
+// Ignore the case where the function parameter in the template isn't an rvalue
+// reference but the template argument is explicitly set to be an rvalue
+// reference.
+class A {};
+template <typename T> void foo(T);
+void f8() {
+ A a;
+ foo<A &&>(std::move(a));
+}
+
+// A warning is output, but no fix is suggested, if a macro is used to rename
+// std::move.
+#define MOVE(x) std::move((x))
+template <typename T, typename U> void f9(U &&SomeU) {
+ T SomeT(MOVE(SomeU));
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: forwarding reference passed to
+}
+
+// Same result if the argument is passed outside of the macro.
+#undef MOVE
+#define MOVE std::move
+template <typename T, typename U> void f10(U &&SomeU) {
+ T SomeT(MOVE(SomeU));
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: forwarding reference passed to
+}
+
+// Same result if the macro does not include the "std" namespace.
+#undef MOVE
+#define MOVE move
+template <typename T, typename U> void f11(U &&SomeU) {
+ T SomeT(std::MOVE(SomeU));
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: forwarding reference passed to
+}
+
+// Handle the case correctly where the forwarding reference is a parameter of a
+// generic lambda.
+template <typename T> void f12() {
+ [] (auto&& x) { T SomeT(std::move(x)); };
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: forwarding reference passed to
+ // CHECK-FIXES: [] (auto&& x) { T SomeT(std::forward<decltype(x)>(x)); }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-multiple-statement-macro.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-multiple-statement-macro.cpp
new file mode 100644
index 0000000..5b88d8d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-multiple-statement-macro.cpp
@@ -0,0 +1,85 @@
+// RUN: %check_clang_tidy %s bugprone-multiple-statement-macro %t
+
+void F();
+
+#define BAD_MACRO(x) \
+ F(); \
+ F()
+
+#define GOOD_MACRO(x) \
+ do { \
+ F(); \
+ F(); \
+ } while (0)
+
+#define GOOD_MACRO2(x) F()
+
+#define GOOD_MACRO3(x) F();
+
+#define MACRO_ARG_MACRO(X) \
+ if (54) \
+ X(2)
+
+#define ALL_IN_MACRO(X) \
+ if (43) \
+ F(); \
+ F()
+
+#define GOOD_NESTED(x) \
+ if (x) \
+ GOOD_MACRO3(x); \
+ F();
+
+#define IF(x) if(x)
+
+void positives() {
+ if (1)
+ BAD_MACRO(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: multiple statement macro used without braces; some statements will be unconditionally executed [bugprone-multiple-statement-macro]
+ if (1) {
+ } else
+ BAD_MACRO(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: multiple statement macro used
+ while (1)
+ BAD_MACRO(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: multiple statement macro used
+ for (;;)
+ BAD_MACRO(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: multiple statement macro used
+
+ MACRO_ARG_MACRO(BAD_MACRO);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: multiple statement macro used
+ MACRO_ARG_MACRO(F(); int);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: multiple statement macro used
+ IF(1) BAD_MACRO(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: multiple statement macro used
+}
+
+void negatives() {
+ if (1) {
+ BAD_MACRO(1);
+ } else {
+ BAD_MACRO(1);
+ }
+ while (1) {
+ BAD_MACRO(1);
+ }
+ for (;;) {
+ BAD_MACRO(1);
+ }
+
+ if (1)
+ GOOD_MACRO(1);
+ if (1) {
+ GOOD_MACRO(1);
+ }
+ if (1)
+ GOOD_MACRO2(1);
+ if (1)
+ GOOD_MACRO3(1);
+
+ MACRO_ARG_MACRO(GOOD_MACRO);
+ ALL_IN_MACRO(1);
+
+ IF(1) GOOD_MACRO(1);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-parent-virtual-call.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-parent-virtual-call.cpp
new file mode 100755
index 0000000..ad84588
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-parent-virtual-call.cpp
@@ -0,0 +1,179 @@
+// RUN: %check_clang_tidy %s bugprone-parent-virtual-call %t
+
+extern int foo();
+
+class A {
+public:
+ A() = default;
+ virtual ~A() = default;
+
+ virtual int virt_1() { return foo() + 1; }
+ virtual int virt_2() { return foo() + 2; }
+
+ int non_virt() { return foo() + 3; }
+ static int stat() { return foo() + 4; }
+};
+
+class B : public A {
+public:
+ B() = default;
+
+ // Nothing to fix: calls to direct parent.
+ int virt_1() override { return A::virt_1() + 3; }
+ int virt_2() override { return A::virt_2() + 4; }
+};
+
+class C : public B {
+public:
+ int virt_1() override { return A::virt_1() + B::virt_1(); }
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'A::virt_1' refers to a member overridden in subclass; did you mean 'B'? [bugprone-parent-virtual-call]
+ // CHECK-FIXES: int virt_1() override { return B::virt_1() + B::virt_1(); }
+ int virt_2() override { return A::virt_1() + B::virt_1(); }
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'A::virt_1' {{.*}}; did you mean 'B'? {{.*}}
+ // CHECK-FIXES: int virt_2() override { return B::virt_1() + B::virt_1(); }
+
+ // Test that non-virtual and static methods are not affected by this cherker.
+ int method_c() { return A::stat() + A::non_virt(); }
+};
+
+// Check aliased type names
+using A1 = A;
+typedef A A2;
+#define A3 A
+
+class C2 : public B {
+public:
+ int virt_1() override { return A1::virt_1() + A2::virt_1() + A3::virt_1(); }
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'A1::virt_1' {{.*}}; did you mean 'B'? {{.*}}
+ // CHECK-MESSAGES: :[[@LINE-2]]:49: warning: qualified name 'A2::virt_1' {{.*}}; did you mean 'B'? {{.*}}
+ // CHECK-MESSAGES: :[[@LINE-3]]:64: warning: qualified name 'A3::virt_1' {{.*}}; did you mean 'B'? {{.*}}
+ // CHECK-FIXES: int virt_1() override { return B::virt_1() + B::virt_1() + B::virt_1(); }
+};
+
+// Test that the check affects grand-grand..-parent calls too.
+class D : public C {
+public:
+ int virt_1() override { return A::virt_1() + B::virt_1() + D::virt_1(); }
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'A::virt_1' {{.*}}; did you mean 'C'? {{.*}}
+ // CHECK-MESSAGES: :[[@LINE-2]]:48: warning: qualified name 'B::virt_1' {{.*}}; did you mean 'C'? {{.*}}
+ // CHECK-FIXES: int virt_1() override { return C::virt_1() + C::virt_1() + D::virt_1(); }
+ int virt_2() override { return A::virt_1() + B::virt_1() + D::virt_1(); }
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'A::virt_1' {{.*}}; did you mean 'C'? {{.*}}
+ // CHECK-MESSAGES: :[[@LINE-2]]:48: warning: qualified name 'B::virt_1' {{.*}}; did you mean 'C'? {{.*}}
+ // CHECK-FIXES: int virt_2() override { return C::virt_1() + C::virt_1() + D::virt_1(); }
+};
+
+// Test classes in namespaces.
+namespace {
+class BN : public A {
+public:
+ int virt_1() override { return A::virt_1() + 3; }
+ int virt_2() override { return A::virt_2() + 4; }
+};
+} // namespace
+
+namespace N1 {
+class A {
+public:
+ A() = default;
+ virtual int virt_1() { return foo() + 1; }
+ virtual int virt_2() { return foo() + 2; }
+};
+} // namespace N1
+
+namespace N2 {
+class BN : public N1::A {
+public:
+ int virt_1() override { return A::virt_1() + 3; }
+ int virt_2() override { return A::virt_2() + 4; }
+};
+} // namespace N2
+
+class CN : public BN {
+public:
+ int virt_1() override { return A::virt_1() + BN::virt_1(); }
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'A::virt_1' {{.*}}; did you mean 'BN'? {{.*}}
+ // CHECK-FIXES: int virt_1() override { return BN::virt_1() + BN::virt_1(); }
+ int virt_2() override { return A::virt_1() + BN::virt_1(); }
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'A::virt_1' {{.*}}; did you mean 'BN'? {{.*}}
+ // CHECK-FIXES: int virt_2() override { return BN::virt_1() + BN::virt_1(); }
+};
+
+class CNN : public N2::BN {
+public:
+ int virt_1() override { return N1::A::virt_1() + N2::BN::virt_1(); }
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'N1::A::virt_1' {{.*}}; did you mean 'N2::BN'? {{.*}}
+ // CHECK-FIXES: int virt_1() override { return N2::BN::virt_1() + N2::BN::virt_1(); }
+ int virt_2() override { return N1::A::virt_1() + N2::BN::virt_1(); }
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'N1::A::virt_1' {{.*}}; did you mean 'N2::BN'? {{.*}}
+ // CHECK-FIXES: int virt_2() override { return N2::BN::virt_1() + N2::BN::virt_1(); }
+};
+
+// Test multiple inheritance fixes
+class AA {
+public:
+ AA() = default;
+ virtual ~AA() = default;
+
+ virtual int virt_1() { return foo() + 1; }
+ virtual int virt_2() { return foo() + 2; }
+
+ int non_virt() { return foo() + 3; }
+ static int stat() { return foo() + 4; }
+};
+
+class BB_1 : virtual public AA {
+public:
+ BB_1() = default;
+
+ // Nothing to fix: calls to parent.
+ int virt_1() override { return AA::virt_1() + 3; }
+ int virt_2() override { return AA::virt_2() + 4; }
+};
+
+class BB_2 : virtual public AA {
+public:
+ BB_2() = default;
+ int virt_1() override { return AA::virt_1() + 3; }
+};
+
+class CC : public BB_1, public BB_2 {
+public:
+ int virt_1() override { return AA::virt_1() + 3; }
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'AA::virt_1' refers to a member overridden in subclasses; did you mean 'BB_1' or 'BB_2'? {{.*}}
+ // No fix available due to multiple choice of parent class.
+};
+
+// Test that virtual method is not diagnosed as not overridden in parent.
+class BI : public A {
+public:
+ BI() = default;
+};
+
+class CI : BI {
+ int virt_1() override { return A::virt_1(); }
+};
+
+// Test templated classes.
+template <class F> class BF : public A {
+public:
+ int virt_1() override { return A::virt_1() + 3; }
+};
+
+// Test templated parent class.
+class CF : public BF<int> {
+public:
+ int virt_1() override { return A::virt_1(); }
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'A::virt_1' {{.*}}; did you mean 'BF'? {{.*}}
+};
+
+// Test both templated class and its parent class.
+template <class F> class DF : public BF<F> {
+public:
+ DF() = default;
+ int virt_1() override { return A::virt_1(); }
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'A::virt_1' {{.*}}; did you mean 'BF'? {{.*}}
+};
+
+// Just to instantiate DF<F>.
+int bar() { return (new DF<int>())->virt_1(); }
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-sizeof-container.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-sizeof-container.cpp
new file mode 100644
index 0000000..27798d6
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-sizeof-container.cpp
@@ -0,0 +1,103 @@
+// RUN: %check_clang_tidy %s bugprone-sizeof-container %t -- -- -std=c++11 -target x86_64-unknown-unknown
+
+namespace std {
+
+typedef unsigned int size_t;
+
+template <typename T>
+struct basic_string {
+ size_t size() const;
+};
+
+template <typename T>
+basic_string<T> operator+(const basic_string<T> &, const T *);
+
+typedef basic_string<char> string;
+
+template <typename T>
+struct vector {
+ size_t size() const;
+};
+
+// std::bitset<> is not a container. sizeof() is reasonable for it.
+template <size_t N>
+struct bitset {
+ size_t size() const;
+};
+
+// std::array<> is, well, an array. sizeof() is reasonable for it.
+template <typename T, size_t N>
+struct array {
+ size_t size() const;
+};
+
+class fake_container1 {
+ size_t size() const; // non-public
+};
+
+struct fake_container2 {
+ size_t size(); // non-const
+};
+
+}
+
+using std::size_t;
+
+#define ARRAYSIZE(a) \
+ ((sizeof(a) / sizeof(*(a))) / static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
+
+#define ARRAYSIZE2(a) \
+ (((sizeof(a)) / (sizeof(*(a)))) / static_cast<size_t>(!((sizeof(a)) % (sizeof(*(a))))))
+
+struct string {
+ std::size_t size() const;
+};
+
+template<typename T>
+void g(T t) {
+ (void)sizeof(t);
+}
+
+void f() {
+ string s1;
+ std::string s2;
+ std::vector<int> v;
+
+ int a = 42 + sizeof(s1);
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: sizeof() doesn't return the size of the container; did you mean .size()? [bugprone-sizeof-container]
+ a = 123 * sizeof(s2);
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: sizeof() doesn't return the size
+ a = 45 + sizeof(s2 + "asdf");
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: sizeof() doesn't return the size
+ a = sizeof(v);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: sizeof() doesn't return the size
+ a = sizeof(std::vector<int>{});
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: sizeof() doesn't return the size
+
+ a = sizeof(a);
+ a = sizeof(int);
+ a = sizeof(std::string);
+ a = sizeof(std::vector<int>);
+
+ g(s1);
+ g(s2);
+ g(v);
+
+ std::fake_container1 fake1;
+ std::fake_container2 fake2;
+ std::bitset<7> std_bitset;
+ std::array<int, 3> std_array;
+
+ a = sizeof(fake1);
+ a = sizeof(fake2);
+ a = sizeof(std_bitset);
+ a = sizeof(std_array);
+
+
+ std::string arr[3];
+ a = ARRAYSIZE(arr);
+ a = ARRAYSIZE2(arr);
+ a = sizeof(arr) / sizeof(arr[0]);
+
+ (void)a;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-sizeof-expression.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-sizeof-expression.cpp
new file mode 100644
index 0000000..683ad08
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-sizeof-expression.cpp
@@ -0,0 +1,256 @@
+// RUN: %check_clang_tidy %s bugprone-sizeof-expression %t -- -config="{CheckOptions: [{key: bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression, value: 1}]}" --
+
+class C {
+ int size() { return sizeof(this); }
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(this)'
+};
+
+#define LEN 8
+
+int X;
+extern int A[10];
+extern short B[10];
+
+#pragma pack(1)
+struct S { char a, b, c; };
+
+enum E { E_VALUE = 0 };
+enum class EC { VALUE = 0 };
+
+bool AsBool() { return false; }
+int AsInt() { return 0; }
+E AsEnum() { return E_VALUE; }
+EC AsEnumClass() { return EC::VALUE; }
+S AsStruct() { return {}; }
+
+struct M {
+ int AsInt() { return 0; }
+ E AsEnum() { return E_VALUE; }
+ S AsStruct() { return {}; }
+};
+
+int ReturnOverload(int) { return {}; }
+S ReturnOverload(S) { return {}; }
+
+template <class T>
+T ReturnTemplate(T) { return {}; }
+
+template <class T>
+bool TestTrait1() {
+ return sizeof(ReturnOverload(T{})) == sizeof(A);
+}
+
+template <class T>
+bool TestTrait2() {
+ return sizeof(ReturnTemplate(T{})) == sizeof(A);
+}
+
+template <class T>
+bool TestTrait3() {
+ return sizeof(ReturnOverload(0)) == sizeof(T{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
+}
+
+template <class T>
+bool TestTrait4() {
+ return sizeof(ReturnTemplate(0)) == sizeof(T{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
+}
+
+bool TestTemplates() {
+ bool b = true;
+ b &= TestTrait1<int>();
+ b &= TestTrait1<S>();
+ b &= TestTrait2<int>();
+ b &= TestTrait2<S>();
+ b &= TestTrait3<int>();
+ b &= TestTrait3<S>();
+ b &= TestTrait4<int>();
+ b &= TestTrait4<S>();
+ return b;
+}
+
+int Test1(const char* ptr) {
+ int sum = 0;
+ sum += sizeof(LEN);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(K)'
+ sum += sizeof(LEN + 1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(K)'
+ sum += sizeof(sum, LEN);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(..., ...)'
+ sum += sizeof(AsBool());
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
+ sum += sizeof(AsInt());
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
+ sum += sizeof(AsEnum());
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
+ sum += sizeof(AsEnumClass());
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
+ sum += sizeof(M{}.AsInt());
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
+ sum += sizeof(M{}.AsEnum());
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
+ sum += sizeof(sizeof(X));
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
+ sum += sizeof(LEN + sizeof(X));
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
+ sum += sizeof(LEN + LEN + sizeof(X));
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
+ sum += sizeof(LEN + (LEN + sizeof(X)));
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
+ sum += sizeof(LEN + -sizeof(X));
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
+ sum += sizeof(LEN + - + -sizeof(X));
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
+ sum += sizeof(char) / sizeof(char);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)'
+ sum += sizeof(A) / sizeof(S);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator
+ sum += sizeof(char) / sizeof(int);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator
+ sum += sizeof(char) / sizeof(A);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator
+ sum += sizeof(B[0]) / sizeof(A);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator
+ sum += sizeof(ptr) / sizeof(char);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(T*)/sizeof(T)'
+ sum += sizeof(ptr) / sizeof(ptr[0]);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(T*)/sizeof(T)'
+ sum += sizeof(ptr) / sizeof(char*);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(P*)/sizeof(Q*)'
+ sum += sizeof(ptr) / sizeof(void*);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(P*)/sizeof(Q*)'
+ sum += sizeof(ptr) / sizeof(const void volatile*);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(P*)/sizeof(Q*)'
+ sum += sizeof(ptr) / sizeof(char);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(T*)/sizeof(T)'
+ sum += sizeof(ptr) / sizeof(ptr[0]);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(T*)/sizeof(T)'
+ sum += sizeof(int) * sizeof(char);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious 'sizeof' by 'sizeof' multiplication
+ sum += sizeof(ptr) * sizeof(ptr[0]);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious 'sizeof' by 'sizeof' multiplication
+ sum += sizeof(int) * (2 * sizeof(char));
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious 'sizeof' by 'sizeof' multiplication
+ sum += (2 * sizeof(char)) * sizeof(int);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious 'sizeof' by 'sizeof' multiplication
+ if (sizeof(A) < 0x100000) sum += 42;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: suspicious comparison of 'sizeof(expr)' to a constant
+ if (sizeof(A) <= 0xFFFFFFFEU) sum += 42;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: suspicious comparison of 'sizeof(expr)' to a constant
+ return sum;
+}
+
+typedef char MyChar;
+typedef const MyChar MyConstChar;
+
+int CE0 = sizeof sizeof(char);
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))'
+int CE1 = sizeof +sizeof(char);
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))'
+int CE2 = sizeof sizeof(const char*);
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))'
+int CE3 = sizeof sizeof(const volatile char* const*);
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))'
+int CE4 = sizeof sizeof(MyConstChar);
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))'
+
+int Test2(MyConstChar* A) {
+ int sum = 0;
+ sum += sizeof(MyConstChar) / sizeof(char);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)'
+ sum += sizeof(MyConstChar) / sizeof(MyChar);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)'
+ sum += sizeof(A[0]) / sizeof(char);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)'
+ return sum;
+}
+
+template <int T>
+int Foo() { int A[T]; return sizeof(T); }
+// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: suspicious usage of 'sizeof(K)'
+template <typename T>
+int Bar() { T A[5]; return sizeof(A[0]) / sizeof(T); }
+// CHECK-MESSAGES: :[[@LINE-1]]:28: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)'
+int Test3() { return Foo<42>() + Bar<char>(); }
+
+static const char* kABC = "abc";
+static const wchar_t* kDEF = L"def";
+int Test4(const char A[10]) {
+ int sum = 0;
+ sum += sizeof(kABC);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(char*)'
+ sum += sizeof(kDEF);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(char*)'
+ return sum;
+}
+
+int Test5() {
+ typedef int Array10[10];
+
+ struct MyStruct {
+ Array10 arr;
+ Array10* ptr;
+ };
+ typedef const MyStruct TMyStruct;
+
+ static TMyStruct kGlocalMyStruct = {};
+ static TMyStruct volatile * kGlocalMyStructPtr = &kGlocalMyStruct;
+
+ MyStruct S;
+ Array10 A10;
+
+ int sum = 0;
+ sum += sizeof(&S.arr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+ sum += sizeof(&kGlocalMyStruct.arr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+ sum += sizeof(&kGlocalMyStructPtr->arr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+ sum += sizeof(S.arr + 0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+ sum += sizeof(+ S.arr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+ sum += sizeof((int*)S.arr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+
+ sum += sizeof(S.ptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+ sum += sizeof(kGlocalMyStruct.ptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+ sum += sizeof(kGlocalMyStructPtr->ptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+
+ sum += sizeof(&kGlocalMyStruct);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+ sum += sizeof(&S);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+ sum += sizeof(&A10);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+
+ return sum;
+}
+
+int ValidExpressions() {
+ int A[] = {1, 2, 3, 4};
+ static const char str[] = "hello";
+ static const char* ptr[] { "aaa", "bbb", "ccc" };
+ int sum = 0;
+ if (sizeof(A) < 10)
+ sum += sizeof(A);
+ sum += sizeof(int);
+ sum += sizeof(AsStruct());
+ sum += sizeof(M{}.AsStruct());
+ sum += sizeof(A[sizeof(A) / sizeof(int)]);
+ sum += sizeof(&A[sizeof(A) / sizeof(int)]);
+ sum += sizeof(sizeof(0)); // Special case: sizeof size_t.
+ sum += sizeof(void*);
+ sum += sizeof(void const *);
+ sum += sizeof(void const *) / 4;
+ sum += sizeof(str);
+ sum += sizeof(str) / sizeof(char);
+ sum += sizeof(str) / sizeof(str[0]);
+ sum += sizeof(ptr) / sizeof(ptr[0]);
+ sum += sizeof(ptr) / sizeof(*(ptr));
+ return sum;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-string-constructor.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-string-constructor.cpp
new file mode 100644
index 0000000..3ab4f42
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-string-constructor.cpp
@@ -0,0 +1,67 @@
+// RUN: %check_clang_tidy %s bugprone-string-constructor %t
+
+namespace std {
+template <typename T>
+class allocator {};
+template <typename T>
+class char_traits {};
+template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C> >
+struct basic_string {
+ basic_string();
+ basic_string(const C*, unsigned int size);
+ basic_string(const C *, const A &allocator = A());
+ basic_string(unsigned int size, C c);
+};
+typedef basic_string<char> string;
+typedef basic_string<wchar_t> wstring;
+}
+
+const char* kText = "";
+const char kText2[] = "";
+extern const char kText3[];
+
+void Test() {
+ std::string str('x', 4);
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: string constructor parameters are probably swapped; expecting string(count, character) [bugprone-string-constructor]
+ // CHECK-FIXES: std::string str(4, 'x');
+ std::wstring wstr(L'x', 4);
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: string constructor parameters are probably swapped
+ // CHECK-FIXES: std::wstring wstr(4, L'x');
+ std::string s0(0, 'x');
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor creating an empty string
+ std::string s1(-4, 'x');
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: negative value used as length parameter
+ std::string s2(0x1000000, 'x');
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter
+
+ std::string q0("test", 0);
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor creating an empty string
+ std::string q1(kText, -4);
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: negative value used as length parameter
+ std::string q2("test", 200);
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger then string literal size
+ std::string q3(kText, 200);
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger then string literal size
+ std::string q4(kText2, 200);
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger then string literal size
+ std::string q5(kText3, 0x1000000);
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter
+ std::string q6(nullptr);
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructing string from nullptr is undefined behaviour
+ std::string q7 = 0;
+ // CHECK-MESSAGES: [[@LINE-1]]:20: warning: constructing string from nullptr is undefined behaviour
+}
+
+std::string StringFromZero() {
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: constructing string from nullptr is undefined behaviour
+}
+
+void Valid() {
+ std::string empty();
+ std::string str(4, 'x');
+ std::wstring wstr(4, L'x');
+ std::string s1("test", 4);
+ std::string s2("test", 3);
+ std::string s3("test");
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-string-integer-assignment.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-string-integer-assignment.cpp
new file mode 100644
index 0000000..c4e13fc
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-string-integer-assignment.cpp
@@ -0,0 +1,53 @@
+// RUN: %check_clang_tidy %s bugprone-string-integer-assignment %t
+
+namespace std {
+template<typename T>
+struct basic_string {
+ basic_string& operator=(T);
+ basic_string& operator=(basic_string);
+ basic_string& operator+=(T);
+ basic_string& operator+=(basic_string);
+};
+
+typedef basic_string<char> string;
+typedef basic_string<wchar_t> wstring;
+}
+
+typedef int MyArcaneChar;
+
+int main() {
+ std::string s;
+ std::wstring ws;
+ int x = 5;
+
+ s = 6;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: an integer is interpreted as a character code when assigning {{.*}} [bugprone-string-integer-assignment]
+// CHECK-FIXES: {{^}} s = '6';{{$}}
+ s = 66;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: an integer is interpreted as a chara
+// CHECK-FIXES: {{^}} s = "66";{{$}}
+ s = x;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: an integer is interpreted as a chara
+// CHECK-FIXES: {{^}} s = std::to_string(x);{{$}}
+ s = 'c';
+ s = static_cast<char>(6);
+
+// +=
+ ws += 6;
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: an integer is interpreted as a chara
+// CHECK-FIXES: {{^}} ws += L'6';{{$}}
+ ws += 66;
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: an integer is interpreted as a chara
+// CHECK-FIXES: {{^}} ws += L"66";{{$}}
+ ws += x;
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: an integer is interpreted as a chara
+// CHECK-FIXES: {{^}} ws += std::to_wstring(x);{{$}}
+ ws += L'c';
+ ws += (wchar_t)6;
+
+ std::basic_string<MyArcaneChar> as;
+ as = 6;
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: an integer is interpreted as a chara
+// CHECK-FIXES: {{^}} as = 6;{{$}}
+
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-string-literal-with-embedded-nul.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-string-literal-with-embedded-nul.cpp
new file mode 100644
index 0000000..f939f52
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-string-literal-with-embedded-nul.cpp
@@ -0,0 +1,85 @@
+// RUN: %check_clang_tidy %s bugprone-string-literal-with-embedded-nul %t
+
+namespace std {
+template <typename T>
+class allocator {};
+template <typename T>
+class char_traits {};
+template <typename C, typename T, typename A>
+struct basic_string {
+ typedef basic_string<C, T, A> _Type;
+ basic_string();
+ basic_string(const C *p, const A &a = A());
+
+ _Type& operator+=(const C* s);
+ _Type& operator=(const C* s);
+};
+
+typedef basic_string<char, std::char_traits<char>, std::allocator<char>> string;
+typedef basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t>> wstring;
+}
+
+bool operator==(const std::string&, const char*);
+bool operator==(const char*, const std::string&);
+
+
+const char Valid[] = "This is valid \x12.";
+const char Strange[] = "This is strange \0x12 and must be fixed";
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: suspicious embedded NUL character [bugprone-string-literal-with-embedded-nul]
+
+const char textA[] = "\0x01\0x02\0x03\0x04";
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious embedded NUL character
+const wchar_t textW[] = L"\0x01\0x02\0x03\0x04";
+// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: suspicious embedded NUL character
+
+const char A[] = "\0";
+const char B[] = "\0x";
+const char C[] = "\0x1";
+const char D[] = "\0x11";
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: suspicious embedded NUL character
+
+const wchar_t E[] = L"\0";
+const wchar_t F[] = L"\0x";
+const wchar_t G[] = L"\0x1";
+const wchar_t H[] = L"\0x11";
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: suspicious embedded NUL character
+
+const char I[] = "\000\000\000\000";
+const char J[] = "\0\0\0\0\0\0";
+const char K[] = "";
+
+const char L[] = "\0x12" "\0x12" "\0x12" "\0x12";
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: suspicious embedded NUL character
+
+void TestA() {
+ std::string str1 = "abc\0def";
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: truncated string literal
+ std::string str2 = "\0";
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: truncated string literal
+ std::string str3("\0");
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: truncated string literal
+ std::string str4{"\x00\x01\x02\x03"};
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: truncated string literal
+
+ std::string str;
+ str += "abc\0def";
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: truncated string literal
+ str = "abc\0def";
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: truncated string literal
+
+ if (str == "abc\0def") return;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: truncated string literal
+ if ("abc\0def" == str) return;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: truncated string literal
+}
+
+void TestW() {
+ std::wstring str1 = L"abc\0def";
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: truncated string literal
+ std::wstring str2 = L"\0";
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: truncated string literal
+ std::wstring str3(L"\0");
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: truncated string literal
+ std::wstring str4{L"\x00\x01\x02\x03"};
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: truncated string literal
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-enum-usage-strict.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-enum-usage-strict.cpp
new file mode 100644
index 0000000..cf0ec59
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-enum-usage-strict.cpp
@@ -0,0 +1,98 @@
+// RUN: %check_clang_tidy %s bugprone-suspicious-enum-usage %t -- -config="{CheckOptions: [{key: bugprone-suspicious-enum-usage.StrictMode, value: 1}]}" --
+
+enum A {
+ A = 1,
+ B = 2,
+ C = 4,
+ D = 8,
+ E = 16,
+ F = 32,
+ G = 63
+};
+
+// CHECK-NOTES: :[[@LINE+2]]:1: warning: enum type seems like a bitmask (contains mostly power-of-2 literals) but a literal is not power-of-2
+// CHECK-NOTES: :76:7: note: used here as a bitmask
+enum X {
+ X = 8,
+ Y = 16,
+ Z = 4,
+ ZZ = 3
+ // CHECK-NOTES: :[[@LINE-1]]:3: warning: enum type seems like a bitmask (contains mostly power-of-2 literals), but this literal is not a power-of-2 [bugprone-suspicious-enum-usage]
+// CHECK-NOTES: :70:13: note: used here as a bitmask
+};
+// CHECK-NOTES: :[[@LINE+2]]:1: warning: enum type seems like a bitmask (contains mostly power-of-2 literals) but some literals are not power-of-2
+// CHECK-NOTES: :73:8: note: used here as a bitmask
+enum PP {
+ P = 2,
+ Q = 3,
+ // CHECK-NOTES: :[[@LINE-1]]:3: warning: enum type seems like a bitmask (contains mostly power-of-2 literals), but this literal is not a power-of-2
+ // CHECK-NOTES: :65:11: note: used here as a bitmask
+ R = 4,
+ S = 8,
+ T = 16,
+ U = 31
+};
+
+enum {
+ H,
+ I,
+ J,
+ K,
+ L
+};
+
+enum Days {
+ Monday,
+ Tuesday,
+ Wednesday,
+ Thursday,
+ Friday,
+ Saturday,
+ Sunday
+};
+
+Days bestDay() {
+ return Friday;
+}
+
+int trigger() {
+ if (bestDay() | A)
+ return 1;
+ // CHECK-NOTES: :[[@LINE-2]]:17: warning: enum values are from different enum types
+ if (I | Y)
+ return 1;
+ // CHECK-NOTES: :[[@LINE-2]]:9: warning: enum values are from different enum types
+ if (P + Q == R)
+ return 1;
+ else if ((S | R) == T)
+ return 1;
+ else
+ int k = ZZ | Z;
+ unsigned p = R;
+ PP pp = Q;
+ p |= pp;
+
+ enum X x = Z;
+ p = x | Z;
+ return 0;
+}
+
+int dont_trigger() {
+ int a = 1, b = 5;
+ int c = a + b;
+ int d = c | H, e = b * a;
+ a = B | C;
+ b = X | Z;
+
+ unsigned bitflag;
+ enum A aa = B;
+ bitflag = aa | C;
+
+ if (Tuesday != Monday + 1 ||
+ Friday - Thursday != 1 ||
+ Sunday + Wednesday == (Sunday | Wednesday))
+ return 1;
+ if (H + I + L == 42)
+ return 1;
+ return 42;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-enum-usage.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-enum-usage.cpp
new file mode 100644
index 0000000..314e434
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-enum-usage.cpp
@@ -0,0 +1,96 @@
+// RUN: %check_clang_tidy %s bugprone-suspicious-enum-usage %t -- -config="{CheckOptions: [{key: bugprone-suspicious-enum-usage.StrictMode, value: 0}]}" --
+
+enum Empty {
+};
+
+enum A {
+ A = 1,
+ B = 2,
+ C = 4,
+ D = 8,
+ E = 16,
+ F = 32,
+ G = 63
+};
+
+enum X {
+ X = 8,
+ Y = 16,
+ Z = 4
+};
+
+enum {
+ P = 2,
+ Q = 3,
+ R = 4,
+ S = 8,
+ T = 16
+};
+
+enum {
+ H,
+ I,
+ J,
+ K,
+ L
+};
+
+enum Days {
+ Monday,
+ Tuesday,
+ Wednesday,
+ Thursday,
+ Friday,
+ Saturday,
+ Sunday
+};
+
+Days bestDay() {
+ return Friday;
+}
+
+int trigger() {
+ Empty EmptyVal;
+ int emptytest = EmptyVal | B;
+ if (bestDay() | A)
+ return 1;
+ // CHECK-NOTES: :[[@LINE-2]]:17: warning: enum values are from different enum types
+ if (I | Y)
+ return 1;
+ // CHECK-NOTES: :[[@LINE-2]]:9: warning: enum values are from different enum types
+}
+
+int dont_trigger() {
+ unsigned p;
+ p = Q | P;
+
+ if (A + G == E)
+ return 1;
+ else if ((Q | R) == T)
+ return 1;
+ else
+ int k = T | Q;
+
+ Empty EmptyVal;
+ int emptytest = EmptyVal | B;
+
+ int a = 1, b = 5;
+ int c = a + b;
+ int d = c | H, e = b * a;
+ a = B | C;
+ b = X | Z;
+
+ if (Tuesday != Monday + 1 ||
+ Friday - Thursday != 1 ||
+ Sunday + Wednesday == (Sunday | Wednesday))
+ return 1;
+ if (H + I + L == 42)
+ return 1;
+ return 42;
+}
+
+namespace PR34400 {
+enum { E1 = 0 };
+enum { E2 = -1 };
+enum { l = E1 | E2 };
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-memset-usage.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-memset-usage.cpp
new file mode 100644
index 0000000..f33ae5a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-memset-usage.cpp
@@ -0,0 +1,77 @@
+// RUN: %check_clang_tidy %s bugprone-suspicious-memset-usage %t
+
+void *memset(void *, int, __SIZE_TYPE__);
+
+namespace std {
+ using ::memset;
+}
+
+template <typename T>
+void mtempl(int *ptr) {
+ memset(ptr, '0', sizeof(T));
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: memset fill value is char '0', potentially mistaken for int 0 [bugprone-suspicious-memset-usage]
+// CHECK-FIXES: memset(ptr, 0, sizeof(T));
+ memset(ptr, 256, sizeof(T));
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: memset fill value is out of unsigned character range, gets truncated [bugprone-suspicious-memset-usage]
+ memset(0, sizeof(T), 0);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped arguments [bugprone-suspicious-memset-usage]
+// CHECK-FIXES: memset(0, 0, sizeof(T));
+ memset(0, sizeof(int), 0);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped arguments [bugprone-suspicious-memset-usage]
+// CHECK-FIXES: memset(0, 0, sizeof(int));
+}
+
+void foo(int xsize, int ysize) {
+ int i[5] = {1, 2, 3, 4, 5};
+ char ca[3] = {'a', 'b', 'c'};
+ int *p = i;
+ int l = 5;
+ char z = '1';
+ char *c = &z;
+ int v = 0;
+
+ memset(p, '0', l);
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: memset fill value is char '0', potentially mistaken for int 0 [bugprone-suspicious-memset-usage]
+// CHECK-FIXES: memset(p, 0, l);
+
+ memset(p, 0xabcd, l);
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: memset fill value is out of unsigned character range, gets truncated [bugprone-suspicious-memset-usage]
+
+ memset(p, sizeof(int), 0);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped arguments [bugprone-suspicious-memset-usage]
+// CHECK-FIXES: memset(p, 0, sizeof(int));
+ std::memset(p, sizeof(int), 0x00);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped arguments [bugprone-suspicious-memset-usage]
+// CHECK-FIXES: std::memset(p, 0x00, sizeof(int));
+
+#define M_CHAR_ZERO memset(p, '0', l);
+ M_CHAR_ZERO
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset fill value is char '0', potentially mistaken for int 0 [bugprone-suspicious-memset-usage]
+
+#define M_OUTSIDE_RANGE memset(p, 0xabcd, l);
+ M_OUTSIDE_RANGE
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset fill value is out of unsigned character range, gets truncated [bugprone-suspicious-memset-usage]
+
+#define M_ZERO_LENGTH memset(p, sizeof(int), 0);
+ M_ZERO_LENGTH
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped arguments [bugprone-suspicious-memset-usage]
+
+ memset(p, '2', l);
+ memset(p, 0, l);
+ memset(c, '0', 1);
+ memset(ca, '0', sizeof(ca));
+
+ memset(p, 0x00, l);
+ mtempl<int>(p);
+
+ memset(p, sizeof(int), v + 1);
+ memset(p, 0xcd, 1);
+
+ // Don't warn when the fill char and the length are both known to be
+ // zero. No bug is possible.
+ memset(p, 0, v);
+
+ // -1 is clearly not a length by virtue of being negative, so no warning
+ // despite v == 0.
+ memset(p, -1, v);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-missing-comma.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-missing-comma.cpp
new file mode 100644
index 0000000..f039310
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-missing-comma.cpp
@@ -0,0 +1,82 @@
+// RUN: %check_clang_tidy %s bugprone-suspicious-missing-comma %t
+
+const char* Cartoons[] = {
+ "Bugs Bunny",
+ "Homer Simpson",
+ "Mickey Mouse",
+ "Bart Simpson",
+ "Charlie Brown" // There is a missing comma here.
+ "Fred Flintstone",
+ "Popeye",
+};
+// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: suspicious string literal, probably missing a comma [bugprone-suspicious-missing-comma]
+
+const wchar_t* Colors[] = {
+ L"Red", L"Yellow", L"Blue", L"Green", L"Purple", L"Rose", L"White", L"Black"
+};
+
+// The following array should not trigger any warnings. There is more than 5
+// elements, but they are all concatenated string literals.
+const char* HttpCommands[] = {
+ "GET / HTTP/1.0\r\n"
+ "\r\n",
+
+ "GET /index.html HTTP/1.0\r\n"
+ "\r\n",
+
+ "GET /favicon.ico HTTP/1.0\r\n"
+ "header: dummy"
+ "\r\n",
+
+ "GET /index.html-en HTTP/1.0\r\n"
+ "\r\n",
+
+ "GET /index.html-fr HTTP/1.0\r\n"
+ "\r\n",
+
+ "GET /index.html-es HTTP/1.0\r\n"
+ "\r\n",
+};
+
+// This array is too small to trigger a warning.
+const char* SmallArray[] = {
+ "a" "b", "c"
+};
+
+// Parentheses should be enough to avoid warnings.
+const char* ParentheseArray[] = {
+ ("a" "b"), "c",
+ ("d"
+ "e"
+ "f"),
+ "g", "h", "i", "j", "k", "l"
+};
+
+// Indentation should be enough to avoid warnings.
+const char* CorrectlyIndentedArray[] = {
+ "This is a long message "
+ "which is spanning over multiple lines."
+ "And this should be fine.",
+ "a", "b", "c", "d", "e", "f",
+ "g", "h", "i", "j", "k", "l"
+};
+
+const char* IncorrectlyIndentedArray[] = {
+ "This is a long message "
+ "which is spanning over multiple lines."
+ "And this should be fine.",
+ "a", "b", "c", "d", "e", "f",
+ "g", "h", "i", "j", "k", "l"
+};
+// CHECK-MESSAGES: :[[@LINE-6]]:3: warning: suspicious string literal, probably missing a comma [bugprone-suspicious-missing-comma]
+
+const char* TooManyConcatenatedTokensArray[] = {
+ "Dummy line",
+ "Dummy line",
+ "a" "b" "c" "d" "e" "f",
+ "g" "h" "i" "j" "k" "l",
+ "Dummy line",
+ "Dummy line",
+ "Dummy line",
+ "Dummy line",
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-semicolon-fail.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-semicolon-fail.cpp
new file mode 100644
index 0000000..45fa226
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-semicolon-fail.cpp
@@ -0,0 +1,28 @@
+// RUN: not clang-tidy %s \
+// RUN: -checks="-*,bugprone-suspicious-semicolon" -- -DERROR 2>&1 \
+// RUN: | FileCheck %s -check-prefix=CHECK-ERROR \
+// RUN: -implicit-check-not="{{warning|error}}:"
+// RUN: not clang-tidy %s \
+// RUN: -checks="-*,bugprone-suspicious-semicolon,clang-diagnostic*" \
+// RUN: -- -DWERROR -Wno-everything -Werror=unused-variable 2>&1 \
+// RUN: | FileCheck %s -check-prefix=CHECK-WERROR \
+// RUN: -implicit-check-not="{{warning|error}}:"
+
+// Note: This test verifies that, the checker does not emit any warning for
+// files that do not compile.
+
+bool g();
+
+void f() {
+ if (g());
+ // CHECK-WERROR: :[[@LINE-1]]:11: warning: potentially unintended semicolon [bugprone-suspicious-semicolon]
+#if ERROR
+ int a
+ // CHECK-ERROR: :[[@LINE-1]]:8: error: expected ';' at end of declaration [clang-diagnostic-error]
+#elif WERROR
+ int a;
+ // CHECK-WERROR: :[[@LINE-1]]:7: error: unused variable 'a' [clang-diagnostic-unused-variable]
+#else
+#error "One of ERROR or WERROR should be defined.
+#endif
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-semicolon.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-semicolon.cpp
new file mode 100644
index 0000000..4f9f4c5
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-semicolon.cpp
@@ -0,0 +1,117 @@
+// RUN: %check_clang_tidy %s bugprone-suspicious-semicolon %t
+
+int x = 5;
+
+void nop();
+
+void correct1()
+{
+ if(x < 5) nop();
+}
+
+void correct2()
+{
+ if(x == 5)
+ nop();
+}
+
+void correct3()
+{
+ if(x > 5)
+ {
+ nop();
+ }
+}
+
+void fail1()
+{
+ if(x > 5); nop();
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: potentially unintended semicolon [bugprone-suspicious-semicolon]
+ // CHECK-FIXES: if(x > 5) nop();
+}
+
+void fail2()
+{
+ if(x == 5);
+ nop();
+ // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: potentially unintended semicolon [bugprone-suspicious-semicolon]
+ // CHECK-FIXES: if(x == 5){{$}}
+}
+
+void fail3()
+{
+ if(x < 5);
+ {
+ nop();
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:11: warning: potentially unintended semicolon
+ // CHECK-FIXES: if(x < 5){{$}}
+}
+
+void correct4()
+{
+ while(x % 5 == 1);
+ nop();
+}
+
+void correct5()
+{
+ for(int i = 0; i < x; ++i)
+ ;
+}
+
+void fail4()
+{
+ for(int i = 0; i < x; ++i);
+ nop();
+ // CHECK-MESSAGES: :[[@LINE-2]]:28: warning: potentially unintended semicolon
+ // CHECK-FIXES: for(int i = 0; i < x; ++i){{$}}
+}
+
+void fail5()
+{
+ if(x % 5 == 1);
+ nop();
+ // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: potentially unintended semicolon
+ // CHECK-FIXES: if(x % 5 == 1){{$}}
+}
+
+void fail6() {
+ int a = 0;
+ if (a != 0) {
+ } else if (a != 1);
+ a = 2;
+ // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: potentially unintended semicolon
+ // CHECK-FIXES: } else if (a != 1){{$}}
+}
+
+void fail7() {
+ if (true)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: potentially unintended semicolon
+}
+
+void correct6()
+{
+ do; while(false);
+}
+
+int correct7()
+{
+ int t_num = 0;
+ char c = 'b';
+ char *s = "a";
+ if (s == "(" || s != "'" || c == '"') {
+ t_num += 3;
+ return (c == ')' && c == '\'');
+ }
+
+ return 0;
+}
+
+void correct8() {
+ if (true)
+ ;
+ else {
+ }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-string-compare.c b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-string-compare.c
new file mode 100644
index 0000000..3b3175a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-string-compare.c
@@ -0,0 +1,79 @@
+// RUN: %check_clang_tidy %s bugprone-suspicious-string-compare %t -- \
+// RUN: -config='{CheckOptions: \
+// RUN: [{key: bugprone-suspicious-string-compare.WarnOnImplicitComparison, value: 1}, \
+// RUN: {key: bugprone-suspicious-string-compare.WarnOnLogicalNotComparison, value: 1}]}' \
+// RUN: -- -std=c99
+
+static const char A[] = "abc";
+
+int strcmp(const char *, const char *);
+
+int test_warning_patterns() {
+ if (strcmp(A, "a"))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result [bugprone-suspicious-string-compare]
+ // CHECK-FIXES: if (strcmp(A, "a") != 0)
+
+ if (strcmp(A, "a") != 0 ||
+ strcmp(A, "b"))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result
+ // CHECK-FIXES: strcmp(A, "b") != 0)
+
+ if (strcmp(A, "a") == 1)
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
+
+ if (strcmp(A, "a") == -1)
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
+
+ if (strcmp(A, "a") < '0')
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
+
+ if (strcmp(A, "a") < 0.)
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' has suspicious implicit cast
+
+ if (!strcmp(A, "a"))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:8: warning: function 'strcmp' is compared using logical not operator
+ // CHECK-FIXES: if (strcmp(A, "a") == 0)
+}
+
+void test_structure_patterns() {
+ if (strcmp(A, "a")) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: function 'strcmp' is called without explicitly comparing result
+ // CHECK-FIXES: if (strcmp(A, "a") != 0) {}
+
+ while (strcmp(A, "a")) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: function 'strcmp' is called without explicitly comparing result
+ // CHECK-FIXES: while (strcmp(A, "a") != 0) {}
+
+ for (;strcmp(A, "a");) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:9: warning: function 'strcmp' is called without explicitly comparing result
+ // CHECK-FIXES: for (;strcmp(A, "a") != 0;) {}
+}
+
+int test_valid_patterns() {
+ // The following cases are valid.
+ if (strcmp(A, "a") < 0) return 0;
+ if (strcmp(A, "a") == 0) return 0;
+ if (strcmp(A, "a") <= 0) return 0;
+ if (strcmp(A, "a") == strcmp(A, "b")) return 0;
+ return 1;
+}
+
+int wrapper(const char* a, const char* b) {
+ return strcmp(a, b);
+}
+
+int assignment_wrapper(const char* a, const char* b) {
+ int cmp = strcmp(a, b);
+ return cmp;
+}
+
+int condexpr_wrapper(const char* a, const char* b) {
+ return (a < b) ? strcmp(a, b) : strcmp(b, a);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-string-compare.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-string-compare.cpp
new file mode 100644
index 0000000..c1c24ff
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-suspicious-string-compare.cpp
@@ -0,0 +1,337 @@
+// RUN: %check_clang_tidy %s bugprone-suspicious-string-compare %t -- \
+// RUN: -config='{CheckOptions: \
+// RUN: [{key: bugprone-suspicious-string-compare.WarnOnImplicitComparison, value: 1}, \
+// RUN: {key: bugprone-suspicious-string-compare.WarnOnLogicalNotComparison, value: 1}]}' \
+// RUN: --
+
+typedef __SIZE_TYPE__ size;
+
+struct locale_t {
+ void* dummy;
+} locale;
+
+static const char A[] = "abc";
+static const unsigned char U[] = "abc";
+static const unsigned char V[] = "xyz";
+static const wchar_t W[] = L"abc";
+
+int strlen(const char *);
+
+int memcmp(const void *, const void *, size);
+int wmemcmp(const wchar_t *, const wchar_t *, size);
+int memicmp(const void *, const void *, size);
+int _memicmp(const void *, const void *, size);
+int _memicmp_l(const void *, const void *, size, locale_t);
+
+int strcmp(const char *, const char *);
+int strncmp(const char *, const char *, size);
+int strcasecmp(const char *, const char *);
+int strncasecmp(const char *, const char *, size);
+int stricmp(const char *, const char *);
+int strcmpi(const char *, const char *);
+int strnicmp(const char *, const char *, size);
+int _stricmp(const char *, const char * );
+int _strnicmp(const char *, const char *, size);
+int _stricmp_l(const char *, const char *, locale_t);
+int _strnicmp_l(const char *, const char *, size, locale_t);
+
+int wcscmp(const wchar_t *, const wchar_t *);
+int wcsncmp(const wchar_t *, const wchar_t *, size);
+int wcscasecmp(const wchar_t *, const wchar_t *);
+int wcsicmp(const wchar_t *, const wchar_t *);
+int wcsnicmp(const wchar_t *, const wchar_t *, size);
+int _wcsicmp(const wchar_t *, const wchar_t *);
+int _wcsnicmp(const wchar_t *, const wchar_t *, size);
+int _wcsicmp_l(const wchar_t *, const wchar_t *, locale_t);
+int _wcsnicmp_l(const wchar_t *, const wchar_t *, size, locale_t);
+
+int _mbscmp(const unsigned char *, const unsigned char *);
+int _mbsncmp(const unsigned char *, const unsigned char *, size);
+int _mbsnbcmp(const unsigned char *, const unsigned char *, size);
+int _mbsnbicmp(const unsigned char *, const unsigned char *, size);
+int _mbsicmp(const unsigned char *, const unsigned char *);
+int _mbsnicmp(const unsigned char *, const unsigned char *, size);
+int _mbscmp_l(const unsigned char *, const unsigned char *, locale_t);
+int _mbsncmp_l(const unsigned char *, const unsigned char *, size, locale_t);
+int _mbsicmp_l(const unsigned char *, const unsigned char *, locale_t);
+int _mbsnicmp_l(const unsigned char *, const unsigned char *, size, locale_t);
+int _mbsnbcmp_l(const unsigned char *, const unsigned char *, size, locale_t);
+int _mbsnbicmp_l(const unsigned char *, const unsigned char *, size, locale_t);
+
+int test_warning_patterns() {
+ if (strcmp(A, "a"))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result [bugprone-suspicious-string-compare]
+ // CHECK-FIXES: if (strcmp(A, "a") != 0)
+
+ if (strcmp(A, "a") == 0 ||
+ strcmp(A, "b"))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result
+ // CHECK-FIXES: strcmp(A, "b") != 0)
+
+ if (strcmp(A, "a") == 1)
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
+
+ if (strcmp(A, "a") == -1)
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
+
+ if (strcmp(A, "a") == true)
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
+
+ if (strcmp(A, "a") < '0')
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
+
+ if (strcmp(A, "a") < 0.)
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' has suspicious implicit cast
+}
+
+int test_valid_patterns() {
+ // The following cases are valid.
+ if (strcmp(A, "a") < 0)
+ return 0;
+ if (strcmp(A, "a") == 0)
+ return 0;
+ if (strcmp(A, "a") <= 0)
+ return 0;
+
+ if (wcscmp(W, L"a") < 0)
+ return 0;
+ if (wcscmp(W, L"a") == 0)
+ return 0;
+ if (wcscmp(W, L"a") <= 0)
+ return 0;
+
+ return 1;
+}
+
+int test_implicit_compare_with_functions() {
+
+ if (memcmp(A, "a", 1))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'memcmp' is called without explicitly comparing result
+ // CHECK-FIXES: memcmp(A, "a", 1) != 0)
+
+ if (wmemcmp(W, L"a", 1))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wmemcmp' is called without explicitly comparing result
+ // CHECK-FIXES: wmemcmp(W, L"a", 1) != 0)
+
+ if (memicmp(A, "a", 1))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'memicmp' is called without explicitly comparing result
+ // CHECK-FIXES: memicmp(A, "a", 1) != 0)
+
+ if (_memicmp(A, "a", 1))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_memicmp' is called without explicitly comparing result
+ // CHECK-FIXES: _memicmp(A, "a", 1) != 0)
+
+ if (_memicmp_l(A, "a", 1, locale))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_memicmp_l' is called without explicitly comparing result
+ // CHECK-FIXES: _memicmp_l(A, "a", 1, locale) != 0)
+
+ if (strcmp(A, "a"))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result
+ // CHECK-FIXES: strcmp(A, "a") != 0)
+
+ if (strncmp(A, "a", 1))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strncmp' is called without explicitly comparing result
+ // CHECK-FIXES: strncmp(A, "a", 1) != 0)
+
+ if (strcasecmp(A, "a"))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcasecmp' is called without explicitly comparing result
+ // CHECK-FIXES: strcasecmp(A, "a") != 0)
+
+ if (strncasecmp(A, "a", 1))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strncasecmp' is called without explicitly comparing result
+ // CHECK-FIXES: strncasecmp(A, "a", 1) != 0)
+
+ if (stricmp(A, "a"))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'stricmp' is called without explicitly comparing result
+ // CHECK-FIXES: stricmp(A, "a") != 0)
+
+ if (strcmpi(A, "a"))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmpi' is called without explicitly comparing result
+ // CHECK-FIXES: strcmpi(A, "a") != 0)
+
+ if (_stricmp(A, "a"))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_stricmp' is called without explicitly comparing result
+ // CHECK-FIXES: _stricmp(A, "a") != 0)
+
+ if (strnicmp(A, "a", 1))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strnicmp' is called without explicitly comparing result
+ // CHECK-FIXES: strnicmp(A, "a", 1) != 0)
+
+ if (_strnicmp(A, "a", 1))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_strnicmp' is called without explicitly comparing result
+ // CHECK-FIXES: _strnicmp(A, "a", 1) != 0)
+
+ if (_stricmp_l(A, "a", locale))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_stricmp_l' is called without explicitly comparing result
+ // CHECK-FIXES: _stricmp_l(A, "a", locale) != 0)
+
+ if (_strnicmp_l(A, "a", 1, locale))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_strnicmp_l' is called without explicitly comparing result
+ // CHECK-FIXES: _strnicmp_l(A, "a", 1, locale) != 0)
+
+ if (wcscmp(W, L"a"))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcscmp' is called without explicitly comparing result
+ // CHECK-FIXES: wcscmp(W, L"a") != 0)
+
+ if (wcsncmp(W, L"a", 1))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcsncmp' is called without explicitly comparing result
+ // CHECK-FIXES: wcsncmp(W, L"a", 1) != 0)
+
+ if (wcscasecmp(W, L"a"))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcscasecmp' is called without explicitly comparing result
+ // CHECK-FIXES: wcscasecmp(W, L"a") != 0)
+
+ if (wcsicmp(W, L"a"))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcsicmp' is called without explicitly comparing result
+ // CHECK-FIXES: wcsicmp(W, L"a") != 0)
+
+ if (_wcsicmp(W, L"a"))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_wcsicmp' is called without explicitly comparing result
+ // CHECK-FIXES: _wcsicmp(W, L"a") != 0)
+
+ if (_wcsicmp_l(W, L"a", locale))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_wcsicmp_l' is called without explicitly comparing result
+ // CHECK-FIXES: _wcsicmp_l(W, L"a", locale) != 0)
+
+ if (wcsnicmp(W, L"a", 1))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcsnicmp' is called without explicitly comparing result
+ // CHECK-FIXES: wcsnicmp(W, L"a", 1) != 0)
+
+ if (_wcsnicmp(W, L"a", 1))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_wcsnicmp' is called without explicitly comparing result
+ // CHECK-FIXES: _wcsnicmp(W, L"a", 1) != 0)
+
+ if (_wcsnicmp_l(W, L"a", 1, locale))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_wcsnicmp_l' is called without explicitly comparing result
+ // CHECK-FIXES: _wcsnicmp_l(W, L"a", 1, locale) != 0)
+
+ if (_mbscmp(U, V))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbscmp' is called without explicitly comparing result
+ // CHECK-FIXES: _mbscmp(U, V) != 0)
+
+ if (_mbsncmp(U, V, 1))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsncmp' is called without explicitly comparing result
+ // CHECK-FIXES: _mbsncmp(U, V, 1) != 0)
+
+ if (_mbsnbcmp(U, V, 1))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnbcmp' is called without explicitly comparing result
+ // CHECK-FIXES: _mbsnbcmp(U, V, 1) != 0)
+
+ if (_mbsnbicmp(U, V, 1))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnbicmp' is called without explicitly comparing result
+ // CHECK-FIXES: _mbsnbicmp(U, V, 1) != 0)
+
+ if (_mbsicmp(U, V))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsicmp' is called without explicitly comparing result
+ // CHECK-FIXES: _mbsicmp(U, V) != 0)
+
+ if (_mbsnicmp(U, V, 1))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnicmp' is called without explicitly comparing result
+ // CHECK-FIXES: _mbsnicmp(U, V, 1) != 0)
+
+ if (_mbscmp_l(U, V, locale))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbscmp_l' is called without explicitly comparing result
+ // CHECK-FIXES: _mbscmp_l(U, V, locale) != 0)
+
+ if (_mbsncmp_l(U, V, 1, locale))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsncmp_l' is called without explicitly comparing result
+ // CHECK-FIXES: _mbsncmp_l(U, V, 1, locale) != 0)
+
+ if (_mbsicmp_l(U, V, locale))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsicmp_l' is called without explicitly comparing result
+ // CHECK-FIXES: _mbsicmp_l(U, V, locale) != 0)
+
+ if (_mbsnicmp_l(U, V, 1, locale))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnicmp_l' is called without explicitly comparing result
+ // CHECK-FIXES: _mbsnicmp_l(U, V, 1, locale) != 0)
+
+ if (_mbsnbcmp_l(U, V, 1, locale))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnbcmp_l' is called without explicitly comparing result
+ // CHECK-FIXES: _mbsnbcmp_l(U, V, 1, locale) != 0)
+
+ if (_mbsnbicmp_l(U, V, 1, locale))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnbicmp_l' is called without explicitly comparing result
+ // CHECK-FIXES: _mbsnbicmp_l(U, V, 1, locale) != 0)
+
+ return 1;
+}
+
+int strcmp_wrapper1(const char* a, const char* b) {
+ return strcmp(a, b);
+}
+
+int strcmp_wrapper2(const char* a, const char* b) {
+ return (a && b) ? strcmp(a, b) : 0;
+}
+
+#define macro_strncmp(s1, s2, n) \
+ (__extension__ (__builtin_constant_p (n) \
+ && ((__builtin_constant_p (s1) \
+ && strlen (s1) < ((size) (n))) \
+ || (__builtin_constant_p (s2) \
+ && strlen (s2) < ((size) (n)))) \
+ ? strcmp (s1, s2) : strncmp (s1, s2, n)))
+
+int strncmp_macro(const char* a, const char* b) {
+ if (macro_strncmp(a, b, 4))
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result
+
+ if (macro_strncmp(a, b, 4) == 2)
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
+
+ if (macro_strncmp(a, b, 4) <= .0)
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' has suspicious implicit cast
+
+ if (macro_strncmp(a, b, 4) + 0)
+ return 0;
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: results of function 'strcmp' used by operator '+'
+
+ return 1;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-swapped-arguments.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-swapped-arguments.cpp
new file mode 100644
index 0000000..06fb2d8
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-swapped-arguments.cpp
@@ -0,0 +1,53 @@
+// RUN: %check_clang_tidy %s bugprone-swapped-arguments %t
+
+void F(int, double);
+
+int SomeFunction();
+
+template <typename T, typename U>
+void G(T a, U b) {
+ F(a, b); // no-warning
+ F(2.0, 4);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: argument with implicit conversion from 'int' to 'double' followed by argument converted from 'double' to 'int', potentially swapped arguments.
+// CHECK-FIXES: F(4, 2.0)
+}
+
+void foo() {
+ F(1.0, 3);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: argument with implicit conversion from 'int' to 'double' followed by argument converted from 'double' to 'int', potentially swapped arguments.
+// CHECK-FIXES: F(3, 1.0)
+
+#define M(x, y) x##y()
+
+ double b = 1.0;
+ F(b, M(Some, Function));
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: argument with implicit conversion from 'int' to 'double' followed by argument converted from 'double' to 'int', potentially swapped arguments.
+// CHECK-FIXES: F(M(Some, Function), b);
+
+#define N F(b, SomeFunction())
+
+ N;
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: argument with implicit conversion from 'int' to 'double' followed by argument converted from 'double' to 'int', potentially swapped arguments.
+// In macro, don't emit fixits.
+// CHECK-FIXES: #define N F(b, SomeFunction())
+
+ G(b, 3);
+ G(3, 1.0);
+ G(0, 0);
+
+ F(1.0, 1.0); // no-warning
+ F(3, 1.0); // no-warning
+ F(true, false); // no-warning
+ F(0, 'c'); // no-warning
+
+#define APPLY(f, x, y) f(x, y)
+ APPLY(F, 1.0, 3);
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: argument with implicit conversion from 'int' to 'double' followed by argument converted from 'double' to 'int', potentially swapped arguments.
+// CHECK-FIXES: APPLY(F, 3, 1.0);
+
+#define PARAMS 1.0, 3
+#define CALL(P) F(P)
+ CALL(PARAMS);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: argument with implicit conversion from 'int' to 'double' followed by argument converted from 'double' to 'int', potentially swapped arguments.
+// In macro, don't emit fixits.
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-terminating-continue.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-terminating-continue.cpp
new file mode 100644
index 0000000..4bdcbc4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-terminating-continue.cpp
@@ -0,0 +1,65 @@
+// RUN: %check_clang_tidy %s bugprone-terminating-continue %t
+
+void f() {
+ do {
+ continue;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'continue' in loop with false condition is equivalent to 'break' [bugprone-terminating-continue]
+ // CHECK-FIXES: break;
+ } while(false);
+
+ do {
+ continue;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'continue' in loop with false condition is equivalent to 'break' [bugprone-terminating-continue]
+ // CHECK-FIXES: break;
+ } while(0);
+
+ do {
+ continue;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'continue' in loop with false condition is equivalent to 'break' [bugprone-terminating-continue]
+ // CHECK-FIXES: break;
+ } while(nullptr);
+
+ do {
+ continue;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'continue' in loop with false condition is equivalent to 'break' [bugprone-terminating-continue]
+ // CHECK-FIXES: break;
+ } while(__null);
+
+
+ do {
+ int x = 1;
+ if (x > 0) continue;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'continue' in loop with false condition is equivalent to 'break' [bugprone-terminating-continue]
+ // CHECK-FIXES: if (x > 0) break;
+ } while (false);
+}
+
+void g() {
+ do {
+ do {
+ continue;
+ int x = 1;
+ } while (1 == 1);
+ } while (false);
+
+ do {
+ for (int i = 0; i < 1; ++i) {
+ continue;
+ int x = 1;
+ }
+ } while (false);
+
+ do {
+ while (true) {
+ continue;
+ int x = 1;
+ }
+ } while (false);
+
+ int v[] = {1,2,3,34};
+ do {
+ for (int n : v) {
+ if (n>2) continue;
+ }
+ } while (false);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-throw-keyword-missing.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-throw-keyword-missing.cpp
new file mode 100644
index 0000000..93ecf06
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-throw-keyword-missing.cpp
@@ -0,0 +1,167 @@
+// RUN: %check_clang_tidy %s bugprone-throw-keyword-missing %t -- -- -fexceptions
+
+namespace std {
+
+// std::string declaration (taken from test/clang-tidy/readability-redundant-string-cstr-msvc.cpp).
+template <typename T>
+class allocator {};
+template <typename T>
+class char_traits {};
+template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C>>
+struct basic_string {
+ basic_string();
+ basic_string(const basic_string &);
+ // MSVC headers define two constructors instead of using optional arguments.
+ basic_string(const C *);
+ basic_string(const C *, const A &);
+ ~basic_string();
+};
+typedef basic_string<char> string;
+typedef basic_string<wchar_t> wstring;
+
+// std::exception and std::runtime_error declaration.
+struct exception {
+ exception();
+ exception(const exception &other);
+ virtual ~exception();
+};
+
+struct runtime_error : public exception {
+ explicit runtime_error(const std::string &what_arg);
+};
+
+} // namespace std
+
+// The usage of this class should never emit a warning.
+struct RegularClass {};
+
+// Class name contains the substring "exception", in certain cases using this class should emit a warning.
+struct RegularException {
+ RegularException() {}
+
+ // Constructors with a single argument are treated differently (cxxFunctionalCastExpr).
+ RegularException(int) {}
+};
+
+// --------------
+
+void stdExceptionNotTrownTest(int i) {
+ if (i < 0)
+ // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception object created but not thrown; did you mean 'throw {{.*}}'? [bugprone-throw-keyword-missing]
+ std::exception();
+
+ if (i > 0)
+ // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception
+ std::runtime_error("Unexpected argument");
+}
+
+void stdExceptionThrownTest(int i) {
+ if (i < 0)
+ throw std::exception();
+
+ if (i > 0)
+ throw std::runtime_error("Unexpected argument");
+}
+
+void regularClassNotThrownTest(int i) {
+ if (i < 0)
+ RegularClass();
+}
+
+void regularClassThrownTest(int i) {
+ if (i < 0)
+ throw RegularClass();
+}
+
+void nameContainsExceptionNotThrownTest(int i) {
+ if (i < 0)
+ // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception
+ RegularException();
+
+ if (i > 0)
+ // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception
+ RegularException(5);
+}
+
+void nameContainsExceptionThrownTest(int i) {
+ if (i < 0)
+ throw RegularException();
+
+ if (i > 0)
+ throw RegularException(5);
+}
+
+template <class Exception>
+void f(int i, Exception excToBeThrown) {}
+
+void funcCallWithTempExcTest() {
+ f(5, RegularException());
+}
+
+// Global variable initilization test.
+RegularException exc = RegularException();
+RegularException *excptr = new RegularException();
+
+void localVariableInitTest() {
+ RegularException exc = RegularException();
+ RegularException *excptr = new RegularException();
+}
+
+class CtorInitializerListTest {
+ RegularException exc;
+
+ CtorInitializerListTest() : exc(RegularException()) {}
+
+ CtorInitializerListTest(int) try : exc(RegularException()) {
+ // Constructor body
+ } catch (...) {
+ // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception
+ RegularException();
+ }
+
+ CtorInitializerListTest(float);
+};
+
+CtorInitializerListTest::CtorInitializerListTest(float) try : exc(RegularException()) {
+ // Constructor body
+} catch (...) {
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: suspicious exception
+ RegularException();
+}
+
+RegularException funcReturningExceptionTest(int i) {
+ return RegularException();
+}
+
+void returnedValueTest() {
+ funcReturningExceptionTest(3);
+}
+
+struct ClassBracedInitListTest {
+ ClassBracedInitListTest(RegularException exc) {}
+};
+
+void foo(RegularException, ClassBracedInitListTest) {}
+
+void bracedInitListTest() {
+ RegularException exc{};
+ ClassBracedInitListTest test = {RegularException()};
+ foo({}, {RegularException()});
+}
+
+typedef std::exception ERROR_BASE;
+class RegularError : public ERROR_BASE {};
+
+void typedefTest() {
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: suspicious exception
+ RegularError();
+}
+
+struct ExceptionRAII {
+ ExceptionRAII() {}
+ ~ExceptionRAII() {}
+};
+
+void exceptionRAIITest() {
+ ExceptionRAII E;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-too-small-loop-variable.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-too-small-loop-variable.cpp
new file mode 100644
index 0000000..f11dd49
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-too-small-loop-variable.cpp
@@ -0,0 +1,251 @@
+// RUN: %check_clang_tidy %s bugprone-too-small-loop-variable %t -- -- --target=x86_64-linux
+
+long size() { return 294967296l; }
+
+////////////////////////////////////////////////////////////////////////////////
+/// Test cases correctly caught by bugprone-too-small-loop-variable.
+
+void voidBadForLoop() {
+ for (int i = 0; i < size(); ++i) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: loop variable has narrower type 'int' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]
+ }
+}
+
+void voidBadForLoop2() {
+ for (int i = 0; i < size() + 10; ++i) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: loop variable has narrower type 'int' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]
+ }
+}
+
+void voidBadForLoop3() {
+ for (int i = 0; i <= size() - 1; ++i) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: loop variable has narrower type 'int' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]
+ }
+}
+
+void voidBadForLoop4() {
+ for (int i = 0; size() > i; ++i) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: loop variable has narrower type 'int' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]
+ }
+}
+
+void voidBadForLoop5() {
+ for (int i = 0; size() - 1 >= i; ++i) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: loop variable has narrower type 'int' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]
+ }
+}
+
+void voidBadForLoop6() {
+ int i = 0;
+ for (; i < size(); ++i) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: loop variable has narrower type 'int' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]
+ }
+}
+
+void voidForLoopUnsignedBound() {
+ unsigned size = 3147483647;
+ for (int i = 0; i < size; ++i) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: loop variable has narrower type 'int' than iteration's upper bound 'unsigned int' [bugprone-too-small-loop-variable]
+ }
+}
+
+// The iteration's upper bound has a template dependent value.
+template <long size>
+void doSomething() {
+ for (short i = 0; i < size; ++i) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: loop variable has narrower type 'short' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]
+ }
+}
+
+// The iteration's upper bound has a template dependent type.
+template <class T>
+void doSomething() {
+ for (T i = 0; i < size(); ++i) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: loop variable has narrower type 'short' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]
+ }
+}
+
+void voidForLoopInstantiation() {
+ // This line does not trigger the warning.
+ doSomething<long>();
+ // This one triggers the warning.
+ doSomething<short>();
+}
+
+// A suspicious function used in a macro.
+#define SUSPICIOUS_SIZE (size())
+void voidBadForLoopWithMacroBound() {
+ for (short i = 0; i < SUSPICIOUS_SIZE; ++i) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: loop variable has narrower type 'short' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Correct loops: we should not warn here.
+
+// A simple use case when both expressions have the same type.
+void voidGoodForLoop() {
+ for (long i = 0; i < size(); ++i) { // no warning
+ }
+}
+
+// Other use case where both expressions have the same type,
+// but short expressions are converted to int by the compare operator.
+void voidGoodForLoop2() {
+ short loopCond = 10;
+ for (short i = 0; i < loopCond; ++i) { // no warning
+ }
+}
+
+// Because of the integer literal, the iteration's upper bound is int, but we suppress the warning here.
+void voidForLoopShortPlusLiteral() {
+ short size = 30000;
+ for (short i = 0; i <= (size - 1); ++i) { // no warning
+ }
+}
+
+// Addition of two short variables results in an int value, but we suppress this to avoid false positives.
+void voidForLoopShortPlusShort() {
+ short size = 256;
+ short increment = 14;
+ for (short i = 0; i < size + increment; ++i) { // no warning
+ }
+}
+
+// In this test case we have different integer types, but here the loop variable has the bigger type.
+// The iteration's bound is cast implicitly, not the loop variable.
+void voidForLoopBoundImplicitCast() {
+ short start = 256;
+ short end = 14;
+ for (int i = start; i >= end; --i) { // no warning
+ }
+}
+
+// Range based loop and other iterator based loops are ignored by this check.
+void voidRangeBasedForLoop() {
+ int array[] = {1, 2, 3, 4, 5};
+ for (const int &i : array) { // no warning
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Future possibilites to improve the check.
+
+// False positive: because of the int literal, iteration's upper bound has int type.
+void voidForLoopFalsePositive() {
+ short size = 30000;
+ bool cond = false;
+ for (short i = 0; i < (cond ? 0 : size); ++i) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: loop variable has narrower type 'short' than iteration's upper bound 'int' [bugprone-too-small-loop-variable]
+ }
+}
+
+void voidForLoopFalsePositive2() {
+ short size = 30000;
+ bool cond = false;
+ for (short i = 0; i < (!cond ? size : 0); ++i) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: loop variable has narrower type 'short' than iteration's upper bound 'int' [bugprone-too-small-loop-variable]
+ }
+}
+
+// False positive: The loop bound expression contains nested binary operators.
+void voidForLoopFalsePositive3() {
+ short number = 30000;
+ for (short i = 0; i < ((number & 0x7f) + 1); ++i) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: loop variable has narrower type 'short' than iteration's upper bound 'int' [bugprone-too-small-loop-variable]
+ }
+}
+
+// TODO: handle while loop.
+void voidBadWhileLoop() {
+ short i = 0;
+ while (i < size()) { // missing warning
+ ++i;
+ }
+}
+
+// TODO: handle do-while loop.
+void voidBadDoWhileLoop() {
+ short i = 0;
+ do {
+ ++i;
+ } while (i < size()); // missing warning
+}
+
+// TODO: handle complex loop conditions.
+void voidComplexForCond() {
+ bool additionalCond = true;
+ for (int i = 0; i < size() && additionalCond; ++i) { // missing warning
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Suspicious test cases ingored by this check.
+
+// Test case with a reverse iteration.
+// This is caught by -Wimplicit-int-conversion.
+void voidReverseForLoop() {
+ for (short i = size() - 1; i >= 0; --i) { // no warning
+ }
+}
+
+// Macro defined literals are used inside the loop condition.
+#define SIZE 125
+#define SIZE2 (SIZE + 1)
+void voidForLoopWithMacroBound() {
+ for (short i = 0; i < SIZE2; ++i) { // no warning
+ }
+}
+
+// A suspicious loop is not caught if the iteration's upper bound is a literal.
+void voidForLoopWithLiteralBound() {
+ for (short i = 0; i < 125; ++i) { // no warning
+ }
+}
+
+// The used literal leads to an infinite loop.
+// This is caught by -Wtautological-constant-out-of-range-compare.
+void voidForLoopWithBigLiteralBound() {
+ for (short i = 0; i < 294967296l; ++i) { // no warning
+ }
+}
+
+enum eSizeType {
+ START,
+ Y,
+ END
+};
+
+// A suspicious loop is not caught if the iteration's upper bound is an enum value.
+void voidForLoopWithEnumBound() {
+ for (short i = eSizeType::START; i < eSizeType::END; ++i) { // no warning
+ }
+}
+
+enum eSizeType2 : long {
+ START2 = 294967296l,
+ Y2,
+ END2
+};
+
+// The used enum value leads to an infinite loop.
+// This is caught by -Wtautological-constant-out-of-range-compare.
+void voidForLoopWithBigEnumBound() {
+ for (short i = eSizeType2::START2; i < eSizeType2::END2; ++i) { // no warning
+ }
+}
+
+// A suspicious loop is not caught if the iteration's upper bound is a constant variable.
+void voidForLoopWithConstBound() {
+ const long size = 252l;
+ for (short i = 0; i < size; ++i) { // no warning
+ }
+}
+
+// The used constant variable leads to an infinite loop.
+// This is caught by -Wtautological-constant-out-of-range-compare.
+void voidForLoopWithBigConstBound() {
+ const long size = 294967296l;
+ for (short i = 0; i < size; ++i) { // no warning
+ }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-undefined-memory-manipulation.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-undefined-memory-manipulation.cpp
new file mode 100644
index 0000000..8055010
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-undefined-memory-manipulation.cpp
@@ -0,0 +1,213 @@
+// RUN: %check_clang_tidy %s bugprone-undefined-memory-manipulation %t
+
+void *memset(void *, int, __SIZE_TYPE__);
+void *memcpy(void *, const void *, __SIZE_TYPE__);
+void *memmove(void *, const void *, __SIZE_TYPE__);
+
+namespace std {
+using ::memcpy;
+using ::memmove;
+using ::memset;
+}
+
+namespace types {
+// TriviallyCopyable types:
+struct Plain {
+ int n;
+};
+
+enum E {
+ X,
+ Y,
+ Z
+};
+
+struct Base {
+ float b;
+};
+
+struct Derived : Base {
+ bool d;
+};
+
+// not TriviallyCopyable types:
+struct Destruct {
+ ~Destruct() {}
+};
+
+struct Copy {
+ Copy() {}
+ Copy(const Copy &) {}
+};
+
+struct Move {
+ Move() {}
+ Move(Move &&) {}
+};
+
+struct VirtualFunc {
+ virtual void f() {}
+};
+
+struct VirtualBase : virtual Base {
+ int vb;
+};
+
+// Incomplete type, assume it is TriviallyCopyable.
+struct NoDef;
+
+} // end namespace types
+
+void f(types::NoDef *s) {
+ memset(s, 0, 5);
+}
+
+template <typename T>
+void memset_temp(T *b) {
+ memset(b, 0, sizeof(T));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc' is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+}
+
+template <typename S, typename T>
+void memcpy_temp(S *a, T *b) {
+ memcpy(a, b, sizeof(T));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualFunc'
+}
+
+template <typename S, typename T>
+void memmove_temp(S *a, T *b) {
+ memmove(a, b, sizeof(T));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualFunc'
+}
+
+namespace aliases {
+using Copy2 = types::Copy;
+typedef types::Move Move2;
+}
+
+void notTriviallyCopyable() {
+ types::Plain p; // TriviallyCopyable for variety
+ types::Destruct d;
+ types::Copy c;
+ types::Move m;
+ types::VirtualFunc vf;
+ types::VirtualBase vb;
+
+ memset(&vf, 0, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc'
+ memset(&d, 0, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Destruct'
+ memset(&c, 0, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Copy'
+ std::memset(&m, 0, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Move'
+ ::memset(&vb, 0, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualBase'
+
+ memcpy(&p, &vf, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualFunc'
+ memcpy(&p, &d, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::Destruct'
+ memcpy(&c, &p, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Copy'
+ std::memcpy(&m, &p, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Move'
+ ::memcpy(&vb, &p, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualBase'
+
+ memmove(&vf, &p, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc'
+ memmove(&d, &p, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Destruct'
+ memmove(&p, &c, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::Copy'
+ std::memmove(&p, &m, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::Move'
+ ::memmove(&p, &vb, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualBase'
+
+#define MEMSET memset(&vf, 0, sizeof(int));
+ MEMSET
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc'
+#define MEMCPY memcpy(&d, &p, sizeof(int));
+ MEMCPY
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Destruct'
+#define MEMMOVE memmove(&p, &c, sizeof(int));
+ MEMMOVE
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::Copy'
+
+ memset_temp<types::VirtualFunc>(&vf);
+ memcpy_temp<types::Plain, types::VirtualFunc>(&p, &vf);
+ memmove_temp<types::Plain, types::VirtualFunc>(&p, &vf);
+
+ aliases::Copy2 c2;
+ aliases::Move2 m2;
+ memset(&c2, 0, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'aliases::Copy2'
+ memset(&m2, 0, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'aliases::Move2'
+
+ typedef aliases::Copy2 Copy3;
+ typedef aliases::Copy2 *PCopy2;
+ typedef Copy3 *PCopy3;
+ Copy3 c3;
+ PCopy2 pc2;
+ PCopy3 pc3;
+ memset(&c3, 0, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'Copy3'
+ memset(pc2, 0, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'aliases::Copy2'
+ memset(pc3, 0, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'Copy3'
+}
+
+void triviallyCopyable() {
+ types::Plain p;
+ types::Base base;
+ types::Derived derived;
+
+ int i = 5;
+ int ia[3] = {1, 2, 3};
+ float f = 3.14;
+ float fa[3] = {1.1, 2.2, 3.3};
+ bool b = false;
+ bool ba[2] = {true, false};
+ types::E e = types::X;
+ p.n = 2;
+
+ memset(&p, 0, sizeof(int));
+ memset(&base, 0, sizeof(float));
+ memset(&derived, 0, sizeof(bool));
+ memset(&i, 0, sizeof(int));
+ memset(ia, 0, sizeof(int));
+ memset(&f, 0, sizeof(float));
+ memset(fa, 0, sizeof(float));
+ memset(&b, 0, sizeof(bool));
+ memset(ba, 0, sizeof(bool));
+ memset(&e, 0, sizeof(int));
+ memset(&p.n, 0, sizeof(int));
+
+ memcpy(&p, &p, sizeof(int));
+ memcpy(&base, &base, sizeof(float));
+ memcpy(&derived, &derived, sizeof(bool));
+ memcpy(&i, &i, sizeof(int));
+ memcpy(ia, ia, sizeof(int));
+ memcpy(&f, &f, sizeof(float));
+ memcpy(fa, fa, sizeof(float));
+ memcpy(&b, &b, sizeof(bool));
+ memcpy(ba, ba, sizeof(bool));
+ memcpy(&e, &e, sizeof(int));
+ memcpy(&p.n, &p.n, sizeof(int));
+
+ memmove(&p, &p, sizeof(int));
+ memmove(&base, &base, sizeof(float));
+ memmove(&derived, &derived, sizeof(bool));
+ memmove(&i, &i, sizeof(int));
+ memmove(ia, ia, sizeof(int));
+ memmove(&f, &f, sizeof(float));
+ memmove(fa, fa, sizeof(float));
+ memmove(&b, &b, sizeof(bool));
+ memmove(ba, ba, sizeof(bool));
+ memmove(&e, &e, sizeof(int));
+ memmove(&p.n, &p.n, sizeof(int));
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-undelegated-constructor-cxx98.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-undelegated-constructor-cxx98.cpp
new file mode 100644
index 0000000..f859f24
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-undelegated-constructor-cxx98.cpp
@@ -0,0 +1,23 @@
+// RUN: clang-tidy %s -checks=-*,bugprone-undelegated-constructor -- -std=c++98 | count 0
+
+// Note: this test expects no diagnostics, but FileCheck cannot handle that,
+// hence the use of | count 0.
+
+struct Ctor;
+Ctor foo();
+
+struct Ctor {
+ Ctor();
+ Ctor(int);
+ Ctor(int, int);
+ Ctor(Ctor *i) {
+ Ctor();
+ Ctor(0);
+ Ctor(1, 2);
+ foo();
+ }
+};
+
+Ctor::Ctor() {
+ Ctor(1);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-undelegated-constructor.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-undelegated-constructor.cpp
new file mode 100644
index 0000000..09b20ac
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-undelegated-constructor.cpp
@@ -0,0 +1,54 @@
+// RUN: %check_clang_tidy %s bugprone-undelegated-constructor %t
+
+struct Ctor;
+Ctor foo();
+
+struct Ctor {
+ Ctor();
+ Ctor(int);
+ Ctor(int, int);
+ Ctor(Ctor *i) {
+ Ctor();
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: did you intend to call a delegated constructor? A temporary object is created here instead [bugprone-undelegated-constructor]
+ Ctor(0);
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: did you intend to call a delegated constructor?
+ Ctor(1, 2);
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: did you intend to call a delegated constructor?
+ foo();
+ }
+};
+
+Ctor::Ctor() {
+ Ctor(1);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: did you intend to call a delegated constructor?
+}
+
+Ctor::Ctor(int i) : Ctor(i, 1) {} // properly delegated.
+
+struct Dtor {
+ Dtor();
+ Dtor(int);
+ Dtor(int, int);
+ Dtor(Ctor *i) {
+ Dtor();
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: did you intend to call a delegated constructor?
+ Dtor(0);
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: did you intend to call a delegated constructor?
+ Dtor(1, 2);
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: did you intend to call a delegated constructor?
+ }
+ ~Dtor();
+};
+
+struct Base {};
+struct Derived : public Base {
+ Derived() { Base(); }
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: did you intend to call a delegated constructor?
+};
+
+template <typename T>
+struct TDerived : public Base {
+ TDerived() { Base(); }
+};
+
+TDerived<int> t;
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-unused-raii.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-unused-raii.cpp
new file mode 100644
index 0000000..91ade52
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-unused-raii.cpp
@@ -0,0 +1,68 @@
+// RUN: %check_clang_tidy %s bugprone-unused-raii %t
+
+struct Foo {
+ Foo();
+ Foo(int);
+ Foo(int, int);
+ ~Foo();
+};
+
+struct Bar {
+ Bar();
+};
+
+struct FooBar {
+ FooBar();
+ Foo f;
+};
+
+template <typename T>
+void qux() {
+ T(42);
+}
+
+template <typename T>
+struct TFoo {
+ TFoo(T);
+ ~TFoo();
+};
+
+Foo f();
+
+struct Ctor {
+ Ctor(int);
+ Ctor() {
+ Ctor(0); // TODO: warn here.
+ }
+};
+
+void test() {
+ Foo(42);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: object destroyed immediately after creation; did you mean to name the object?
+// CHECK-FIXES: Foo give_me_a_name(42);
+ Foo(23, 42);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: object destroyed immediately after creation; did you mean to name the object?
+// CHECK-FIXES: Foo give_me_a_name(23, 42);
+ Foo();
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: object destroyed immediately after creation; did you mean to name the object?
+// CHECK-FIXES: Foo give_me_a_name;
+ TFoo<int>(23);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: object destroyed immediately after creation; did you mean to name the object?
+// CHECK-FIXES: TFoo<int> give_me_a_name(23);
+
+ FooBar();
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: object destroyed immediately after creation; did you mean to name the object?
+// CHECK-FIXES: FooBar give_me_a_name;
+
+ Bar();
+ f();
+ qux<Foo>();
+
+#define M Foo();
+ M
+
+ {
+ Foo();
+ }
+ Foo();
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-unused-return-value-custom.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-unused-return-value-custom.cpp
new file mode 100644
index 0000000..53ace63
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-unused-return-value-custom.cpp
@@ -0,0 +1,108 @@
+// RUN: %check_clang_tidy %s bugprone-unused-return-value %t \
+// RUN: -config='{CheckOptions: \
+// RUN: [{key: bugprone-unused-return-value.CheckedFunctions, \
+// RUN: value: "::fun;::ns::Outer::Inner::memFun;::ns::Type::staticFun;::ns::ClassTemplate::memFun;::ns::ClassTemplate::staticFun"}]}' \
+// RUN: --
+
+namespace std {
+
+template <typename T>
+T *launder(T *);
+
+} // namespace std
+
+namespace ns {
+
+struct Outer {
+ struct Inner {
+ bool memFun();
+ };
+};
+
+using AliasName = Outer;
+
+struct Derived : public Outer::Inner {};
+
+struct Retval {
+ int *P;
+ Retval() { P = new int; }
+ ~Retval() { delete P; }
+};
+
+struct Type {
+ Retval memFun();
+ static Retval staticFun();
+};
+
+template <typename T>
+struct ClassTemplate {
+ Retval memFun();
+ static Retval staticFun();
+};
+
+} // namespace ns
+
+int fun();
+void fun(int);
+
+void warning() {
+ fun();
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: the value returned by this function should be used
+ // CHECK-NOTES: [[@LINE-2]]:3: note: cast the expression to void to silence this warning
+
+ (fun());
+ // CHECK-NOTES: [[@LINE-1]]:4: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:4: note: cast {{.*}} this warning
+
+ ns::Outer::Inner ObjA1;
+ ObjA1.memFun();
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+ ns::AliasName::Inner ObjA2;
+ ObjA2.memFun();
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+ ns::Derived ObjA3;
+ ObjA3.memFun();
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+ ns::Type::staticFun();
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+ ns::ClassTemplate<int> ObjA4;
+ ObjA4.memFun();
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+ ns::ClassTemplate<int>::staticFun();
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+}
+
+void noWarning() {
+ auto R1 = fun();
+
+ ns::Outer::Inner ObjB1;
+ auto R2 = ObjB1.memFun();
+
+ auto R3 = ns::Type::staticFun();
+
+ ns::ClassTemplate<int> ObjB2;
+ auto R4 = ObjB2.memFun();
+
+ auto R5 = ns::ClassTemplate<int>::staticFun();
+
+ // test calling a void overload of a checked function
+ fun(5);
+
+ // test discarding return value of functions that are not configured to be checked
+ int I = 1;
+ std::launder(&I);
+
+ ns::Type ObjB3;
+ ObjB3.memFun();
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-unused-return-value.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-unused-return-value.cpp
new file mode 100644
index 0000000..797f56d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-unused-return-value.cpp
@@ -0,0 +1,238 @@
+// RUN: %check_clang_tidy %s bugprone-unused-return-value %t -- -- -fexceptions
+
+namespace std {
+
+struct future {};
+
+enum class launch {
+ async,
+ deferred
+};
+
+template <typename Function, typename... Args>
+future async(Function &&, Args &&...);
+
+template <typename Function, typename... Args>
+future async(launch, Function &&, Args &&...);
+
+template <typename ForwardIt, typename T>
+ForwardIt remove(ForwardIt, ForwardIt, const T &);
+
+template <typename ForwardIt, typename UnaryPredicate>
+ForwardIt remove_if(ForwardIt, ForwardIt, UnaryPredicate);
+
+template <typename ForwardIt>
+ForwardIt unique(ForwardIt, ForwardIt);
+
+template <typename T>
+struct default_delete;
+
+template <typename T, typename Deleter = std::default_delete<T>>
+struct unique_ptr {
+ T *release() noexcept;
+};
+
+template <typename T>
+struct char_traits;
+
+template <typename T>
+struct allocator;
+
+template <typename CharT,
+ typename Traits = char_traits<CharT>,
+ typename Allocator = allocator<CharT>>
+struct basic_string {
+ bool empty() const;
+};
+
+typedef basic_string<char> string;
+
+template <typename T, typename Allocator = std::allocator<T>>
+struct vector {
+ bool empty() const noexcept;
+};
+
+// the check should be able to match std lib calls even if the functions are
+// declared inside inline namespaces
+inline namespace v1 {
+
+template <typename T>
+T *launder(T *);
+
+} // namespace v1
+} // namespace std
+
+struct Foo {
+ void f();
+};
+
+int increment(int i) {
+ return i + 1;
+}
+
+void useFuture(const std::future &fut);
+
+void warning() {
+ std::async(increment, 42);
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: the value returned by this function should be used
+ // CHECK-NOTES: [[@LINE-2]]:3: note: cast the expression to void to silence this warning
+
+ std::async(std::launch::async, increment, 42);
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+ Foo F;
+ std::launder(&F);
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+ std::remove(nullptr, nullptr, 1);
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+ std::remove_if(nullptr, nullptr, nullptr);
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+ std::unique(nullptr, nullptr);
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+ std::unique_ptr<Foo> UPtr;
+ UPtr.release();
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+ std::string Str;
+ Str.empty();
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+ std::vector<Foo> Vec;
+ Vec.empty();
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+ // test discarding return values inside different kinds of statements
+
+ auto Lambda = [] { std::remove(nullptr, nullptr, 1); };
+ // CHECK-NOTES: [[@LINE-1]]:22: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:22: note: cast {{.*}} this warning
+
+ if (true)
+ std::remove(nullptr, nullptr, 1);
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+ else if (true)
+ std::remove(nullptr, nullptr, 1);
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+ else
+ std::remove(nullptr, nullptr, 1);
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+
+ while (true)
+ std::remove(nullptr, nullptr, 1);
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+
+ do
+ std::remove(nullptr, nullptr, 1);
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+ while (true);
+
+ for (;;)
+ std::remove(nullptr, nullptr, 1);
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+
+ for (std::remove(nullptr, nullptr, 1);;)
+ // CHECK-NOTES: [[@LINE-1]]:8: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:8: note: cast {{.*}} this warning
+ ;
+
+ for (;; std::remove(nullptr, nullptr, 1))
+ // CHECK-NOTES: [[@LINE-1]]:11: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:11: note: cast {{.*}} this warning
+ ;
+
+ for (auto C : "foo")
+ std::remove(nullptr, nullptr, 1);
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+
+ switch (1) {
+ case 1:
+ std::remove(nullptr, nullptr, 1);
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+ break;
+ default:
+ std::remove(nullptr, nullptr, 1);
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+ break;
+ }
+
+ try {
+ std::remove(nullptr, nullptr, 1);
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+ } catch (...) {
+ std::remove(nullptr, nullptr, 1);
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+ // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+ }
+}
+
+void noWarning() {
+ auto AsyncRetval1 = std::async(increment, 42);
+ auto AsyncRetval2 = std::async(std::launch::async, increment, 42);
+
+ Foo FNoWarning;
+ auto LaunderRetval = std::launder(&FNoWarning);
+
+ auto RemoveRetval = std::remove(nullptr, nullptr, 1);
+
+ auto RemoveIfRetval = std::remove_if(nullptr, nullptr, nullptr);
+
+ auto UniqueRetval = std::unique(nullptr, nullptr);
+
+ std::unique_ptr<Foo> UPtrNoWarning;
+ auto ReleaseRetval = UPtrNoWarning.release();
+
+ std::string StrNoWarning;
+ auto StrEmptyRetval = StrNoWarning.empty();
+
+ std::vector<Foo> VecNoWarning;
+ auto VecEmptyRetval = VecNoWarning.empty();
+
+ // test using the return value in different kinds of expressions
+ useFuture(std::async(increment, 42));
+ std::launder(&FNoWarning)->f();
+ delete std::launder(&FNoWarning);
+
+ if (std::launder(&FNoWarning))
+ ;
+ for (; std::launder(&FNoWarning);)
+ ;
+ while (std::launder(&FNoWarning))
+ ;
+ do
+ ;
+ while (std::launder(&FNoWarning));
+ switch (std::unique(1, 1))
+ ;
+
+ // cast to void should allow ignoring the return value
+ (void)std::async(increment, 42);
+
+ // test discarding return value of functions that are not configured to be checked
+ increment(1);
+
+ // test that the check is disabled inside GNU statement expressions
+ ({ std::async(increment, 42); });
+ auto StmtExprRetval = ({ std::async(increment, 42); });
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-use-after-move.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-use-after-move.cpp
new file mode 100644
index 0000000..dd37aec
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-use-after-move.cpp
@@ -0,0 +1,1241 @@
+// RUN: %check_clang_tidy %s bugprone-use-after-move %t -- -- -std=c++17 -fno-delayed-template-parsing
+
+typedef decltype(nullptr) nullptr_t;
+
+namespace std {
+typedef unsigned size_t;
+
+template <typename T>
+struct unique_ptr {
+ unique_ptr();
+ T *get() const;
+ explicit operator bool() const;
+ void reset(T *ptr);
+ T &operator*() const;
+ T *operator->() const;
+ T& operator[](size_t i) const;
+};
+
+template <typename T>
+struct shared_ptr {
+ shared_ptr();
+ T *get() const;
+ explicit operator bool() const;
+ void reset(T *ptr);
+ T &operator*() const;
+ T *operator->() const;
+};
+
+template <typename T>
+struct weak_ptr {
+ weak_ptr();
+ bool expired() const;
+};
+
+#define DECLARE_STANDARD_CONTAINER(name) \
+ template <typename T> \
+ struct name { \
+ name(); \
+ void clear(); \
+ bool empty(); \
+ }
+
+#define DECLARE_STANDARD_CONTAINER_WITH_ASSIGN(name) \
+ template <typename T> \
+ struct name { \
+ name(); \
+ void clear(); \
+ bool empty(); \
+ void assign(size_t, const T &); \
+ }
+
+DECLARE_STANDARD_CONTAINER_WITH_ASSIGN(basic_string);
+DECLARE_STANDARD_CONTAINER_WITH_ASSIGN(vector);
+DECLARE_STANDARD_CONTAINER_WITH_ASSIGN(deque);
+DECLARE_STANDARD_CONTAINER_WITH_ASSIGN(forward_list);
+DECLARE_STANDARD_CONTAINER_WITH_ASSIGN(list);
+DECLARE_STANDARD_CONTAINER(set);
+DECLARE_STANDARD_CONTAINER(map);
+DECLARE_STANDARD_CONTAINER(multiset);
+DECLARE_STANDARD_CONTAINER(multimap);
+DECLARE_STANDARD_CONTAINER(unordered_set);
+DECLARE_STANDARD_CONTAINER(unordered_map);
+DECLARE_STANDARD_CONTAINER(unordered_multiset);
+DECLARE_STANDARD_CONTAINER(unordered_multimap);
+
+typedef basic_string<char> string;
+
+template <typename>
+struct remove_reference;
+
+template <typename _Tp>
+struct remove_reference {
+ typedef _Tp type;
+};
+
+template <typename _Tp>
+struct remove_reference<_Tp &> {
+ typedef _Tp type;
+};
+
+template <typename _Tp>
+struct remove_reference<_Tp &&> {
+ typedef _Tp type;
+};
+
+template <typename _Tp>
+constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) noexcept {
+ return static_cast<typename remove_reference<_Tp>::type &&>(__t);
+}
+
+} // namespace std
+
+class A {
+public:
+ A();
+ A(const A &);
+ A(A &&);
+
+ A &operator=(const A &);
+ A &operator=(A &&);
+
+ void foo() const;
+ int getInt() const;
+
+ operator bool() const;
+
+ int i;
+};
+
+template <class T>
+class AnnotatedContainer {
+public:
+ AnnotatedContainer();
+
+ void foo() const;
+ [[clang::reinitializes]] void clear();
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// General tests.
+
+// Simple case.
+void simple() {
+ A a;
+ a.foo();
+ A other_a = std::move(a);
+ a.foo();
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:15: note: move occurred here
+}
+
+// A warning should only be emitted for one use-after-move.
+void onlyFlagOneUseAfterMove() {
+ A a;
+ a.foo();
+ A other_a = std::move(a);
+ a.foo();
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:15: note: move occurred here
+ a.foo();
+}
+
+void moveAfterMove() {
+ // Move-after-move also counts as a use.
+ {
+ A a;
+ std::move(a);
+ std::move(a);
+ // CHECK-NOTES: [[@LINE-1]]:15: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+ }
+ // This is also true if the move itself turns into the use on the second loop
+ // iteration.
+ {
+ A a;
+ for (int i = 0; i < 10; ++i) {
+ std::move(a);
+ // CHECK-NOTES: [[@LINE-1]]:17: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-2]]:7: note: move occurred here
+ // CHECK-NOTES: [[@LINE-3]]:17: note: the use happens in a later loop
+ }
+ }
+}
+
+// Checks also works on function parameters that have a use-after move.
+void parameters(A a) {
+ std::move(a);
+ a.foo();
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:3: note: move occurred here
+}
+
+void standardSmartPtr() {
+ // std::unique_ptr<>, std::shared_ptr<> and std::weak_ptr<> are guaranteed to
+ // be null after a std::move. So the check only flags accesses that would
+ // dereference the pointer.
+ {
+ std::unique_ptr<A> ptr;
+ std::move(ptr);
+ ptr.get();
+ static_cast<bool>(ptr);
+ *ptr;
+ // CHECK-NOTES: [[@LINE-1]]:6: warning: 'ptr' used after it was moved
+ // CHECK-NOTES: [[@LINE-5]]:5: note: move occurred here
+ }
+ {
+ std::unique_ptr<A> ptr;
+ std::move(ptr);
+ ptr->foo();
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: 'ptr' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+ }
+ {
+ std::unique_ptr<A> ptr;
+ std::move(ptr);
+ ptr[0];
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: 'ptr' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+ }
+ {
+ std::shared_ptr<A> ptr;
+ std::move(ptr);
+ ptr.get();
+ static_cast<bool>(ptr);
+ *ptr;
+ // CHECK-NOTES: [[@LINE-1]]:6: warning: 'ptr' used after it was moved
+ // CHECK-NOTES: [[@LINE-5]]:5: note: move occurred here
+ }
+ {
+ std::shared_ptr<A> ptr;
+ std::move(ptr);
+ ptr->foo();
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: 'ptr' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+ }
+ {
+ // std::weak_ptr<> cannot be dereferenced directly, so we only check that
+ // member functions may be called on it after a move.
+ std::weak_ptr<A> ptr;
+ std::move(ptr);
+ ptr.expired();
+ }
+ // Make sure we recognize std::unique_ptr<> or std::shared_ptr<> if they're
+ // wrapped in a typedef.
+ {
+ typedef std::unique_ptr<A> PtrToA;
+ PtrToA ptr;
+ std::move(ptr);
+ ptr.get();
+ }
+ {
+ typedef std::shared_ptr<A> PtrToA;
+ PtrToA ptr;
+ std::move(ptr);
+ ptr.get();
+ }
+ // And we don't get confused if the template argument is a little more
+ // involved.
+ {
+ struct B {
+ typedef A AnotherNameForA;
+ };
+ std::unique_ptr<B::AnotherNameForA> ptr;
+ std::move(ptr);
+ ptr.get();
+ }
+ // Make sure we treat references to smart pointers correctly.
+ {
+ std::unique_ptr<A> ptr;
+ std::unique_ptr<A>& ref_to_ptr = ptr;
+ std::move(ref_to_ptr);
+ ref_to_ptr.get();
+ }
+ {
+ std::unique_ptr<A> ptr;
+ std::unique_ptr<A>&& rvalue_ref_to_ptr = std::move(ptr);
+ std::move(rvalue_ref_to_ptr);
+ rvalue_ref_to_ptr.get();
+ }
+ // We don't give any special treatment to types that are called "unique_ptr"
+ // or "shared_ptr" but are not in the "::std" namespace.
+ {
+ struct unique_ptr {
+ void get();
+ } ptr;
+ std::move(ptr);
+ ptr.get();
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: 'ptr' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+ }
+}
+
+// The check also works in member functions.
+class Container {
+ void useAfterMoveInMemberFunction() {
+ A a;
+ std::move(a);
+ a.foo();
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+ }
+};
+
+// We see the std::move() if it's inside a declaration.
+void moveInDeclaration() {
+ A a;
+ A another_a(std::move(a));
+ a.foo();
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+}
+
+// We see the std::move if it's inside an initializer list. Initializer lists
+// are a special case because they cause ASTContext::getParents() to return
+// multiple parents for certain nodes in their subtree. This is because
+// RecursiveASTVisitor visits both the syntactic and semantic forms of
+// InitListExpr, and the parent-child relationships are different between the
+// two forms.
+void moveInInitList() {
+ struct S {
+ A a;
+ };
+ A a;
+ S s{std::move(a)};
+ a.foo();
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:7: note: move occurred here
+}
+
+void lambdas() {
+ // Use-after-moves inside a lambda should be detected.
+ {
+ A a;
+ auto lambda = [a] {
+ std::move(a);
+ a.foo();
+ // CHECK-NOTES: [[@LINE-1]]:7: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:7: note: move occurred here
+ };
+ }
+ // This is just as true if the variable was declared inside the lambda.
+ {
+ auto lambda = [] {
+ A a;
+ std::move(a);
+ a.foo();
+ // CHECK-NOTES: [[@LINE-1]]:7: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:7: note: move occurred here
+ };
+ }
+ // But don't warn if the move happened inside the lambda but the use happened
+ // outside -- because
+ // - the 'a' inside the lambda is a copy, and
+ // - we don't know when the lambda will get called anyway
+ {
+ A a;
+ auto lambda = [a] {
+ std::move(a);
+ };
+ a.foo();
+ }
+ // Warn if the use consists of a capture that happens after a move.
+ {
+ A a;
+ std::move(a);
+ auto lambda = [a]() { a.foo(); };
+ // CHECK-NOTES: [[@LINE-1]]:20: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+ }
+ // ...even if the capture was implicit.
+ {
+ A a;
+ std::move(a);
+ auto lambda = [=]() { a.foo(); };
+ // CHECK-NOTES: [[@LINE-1]]:20: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+ }
+ // Same tests but for capture by reference.
+ {
+ A a;
+ std::move(a);
+ auto lambda = [&a]() { a.foo(); };
+ // CHECK-NOTES: [[@LINE-1]]:21: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+ }
+ {
+ A a;
+ std::move(a);
+ auto lambda = [&]() { a.foo(); };
+ // CHECK-NOTES: [[@LINE-1]]:20: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+ }
+ // But don't warn if the move happened after the capture.
+ {
+ A a;
+ auto lambda = [a]() { a.foo(); };
+ std::move(a);
+ }
+ // ...and again, same thing with an implicit move.
+ {
+ A a;
+ auto lambda = [=]() { a.foo(); };
+ std::move(a);
+ }
+ // Same tests but for capture by reference.
+ {
+ A a;
+ auto lambda = [&a]() { a.foo(); };
+ std::move(a);
+ }
+ {
+ A a;
+ auto lambda = [&]() { a.foo(); };
+ std::move(a);
+ }
+}
+
+// Use-after-moves are detected in uninstantiated templates if the moved type
+// is not a dependent type.
+template <class T>
+void movedTypeIsNotDependentType() {
+ T t;
+ A a;
+ std::move(a);
+ a.foo();
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:3: note: move occurred here
+}
+
+// And if the moved type is a dependent type, the use-after-move is detected if
+// the template is instantiated.
+template <class T>
+void movedTypeIsDependentType() {
+ T t;
+ std::move(t);
+ t.foo();
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: 't' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:3: note: move occurred here
+}
+template void movedTypeIsDependentType<A>();
+
+// We handle the case correctly where the move consists of an implicit call
+// to a conversion operator.
+void implicitConversionOperator() {
+ struct Convertible {
+ operator A() && { return A(); }
+ };
+ void takeA(A a);
+
+ Convertible convertible;
+ takeA(std::move(convertible));
+ convertible;
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: 'convertible' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:9: note: move occurred here
+}
+
+// Using decltype on an expression is not a use.
+void decltypeIsNotUse() {
+ A a;
+ std::move(a);
+ decltype(a) other_a;
+}
+
+// Ignore moves or uses that occur as part of template arguments.
+template <int>
+class ClassTemplate {
+public:
+ void foo(A a);
+};
+template <int>
+void functionTemplate(A a);
+void templateArgIsNotUse() {
+ {
+ // A pattern like this occurs in the EXPECT_EQ and ASSERT_EQ macros in
+ // Google Test.
+ A a;
+ ClassTemplate<sizeof(A(std::move(a)))>().foo(std::move(a));
+ }
+ {
+ A a;
+ functionTemplate<sizeof(A(std::move(a)))>(std::move(a));
+ }
+}
+
+// Ignore moves of global variables.
+A global_a;
+void ignoreGlobalVariables() {
+ std::move(global_a);
+ global_a.foo();
+}
+
+// Ignore moves of member variables.
+class IgnoreMemberVariables {
+ A a;
+ static A static_a;
+
+ void f() {
+ std::move(a);
+ a.foo();
+
+ std::move(static_a);
+ static_a.foo();
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Tests involving control flow.
+
+void useAndMoveInLoop() {
+ // Warn about use-after-moves if they happen in a later loop iteration than
+ // the std::move().
+ {
+ A a;
+ for (int i = 0; i < 10; ++i) {
+ a.foo();
+ // CHECK-NOTES: [[@LINE-1]]:7: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE+2]]:7: note: move occurred here
+ // CHECK-NOTES: [[@LINE-3]]:7: note: the use happens in a later loop
+ std::move(a);
+ }
+ }
+ // However, this case shouldn't be flagged -- the scope of the declaration of
+ // 'a' is important.
+ {
+ for (int i = 0; i < 10; ++i) {
+ A a;
+ a.foo();
+ std::move(a);
+ }
+ }
+ // Same as above, except that we have an unrelated variable being declared in
+ // the same declaration as 'a'. This case is interesting because it tests that
+ // the synthetic DeclStmts generated by the CFG are sequenced correctly
+ // relative to the other statements.
+ {
+ for (int i = 0; i < 10; ++i) {
+ A a, other;
+ a.foo();
+ std::move(a);
+ }
+ }
+ // Don't warn if we return after the move.
+ {
+ A a;
+ for (int i = 0; i < 10; ++i) {
+ a.foo();
+ if (a.getInt() > 0) {
+ std::move(a);
+ return;
+ }
+ }
+ }
+}
+
+void differentBranches(int i) {
+ // Don't warn if the use is in a different branch from the move.
+ {
+ A a;
+ if (i > 0) {
+ std::move(a);
+ } else {
+ a.foo();
+ }
+ }
+ // Same thing, but with a ternary operator.
+ {
+ A a;
+ i > 0 ? (void)std::move(a) : a.foo();
+ }
+ // A variation on the theme above.
+ {
+ A a;
+ a.getInt() > 0 ? a.getInt() : A(std::move(a)).getInt();
+ }
+ // Same thing, but with a switch statement.
+ {
+ A a;
+ switch (i) {
+ case 1:
+ std::move(a);
+ break;
+ case 2:
+ a.foo();
+ break;
+ }
+ }
+ // However, if there's a fallthrough, we do warn.
+ {
+ A a;
+ switch (i) {
+ case 1:
+ std::move(a);
+ case 2:
+ a.foo();
+ // CHECK-NOTES: [[@LINE-1]]:7: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-4]]:7: note: move occurred here
+ break;
+ }
+ }
+}
+
+// False positive: A use-after-move is flagged even though the "if (b)" and
+// "if (!b)" are mutually exclusive.
+void mutuallyExclusiveBranchesFalsePositive(bool b) {
+ A a;
+ if (b) {
+ std::move(a);
+ }
+ if (!b) {
+ a.foo();
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-5]]:5: note: move occurred here
+ }
+}
+
+// Destructors marked [[noreturn]] are handled correctly in the control flow
+// analysis. (These are used in some styles of assertion macros.)
+class FailureLogger {
+public:
+ FailureLogger();
+ [[noreturn]] ~FailureLogger();
+ void log(const char *);
+};
+#define ASSERT(x) \
+ while (x) \
+ FailureLogger().log(#x)
+bool operationOnA(A);
+void noreturnDestructor() {
+ A a;
+ // The while loop in the ASSERT() would ordinarily have the potential to cause
+ // a use-after-move because the second iteration of the loop would be using a
+ // variable that had been moved from in the first iteration. Check that the
+ // CFG knows that the second iteration of the loop is never reached because
+ // the FailureLogger destructor is marked [[noreturn]].
+ ASSERT(operationOnA(std::move(a)));
+}
+#undef ASSERT
+
+////////////////////////////////////////////////////////////////////////////////
+// Tests for reinitializations
+
+template <class T>
+void swap(T &a, T &b) {
+ T tmp = std::move(a);
+ a = std::move(b);
+ b = std::move(tmp);
+}
+void assignments(int i) {
+ // Don't report a use-after-move if the variable was assigned to in the
+ // meantime.
+ {
+ A a;
+ std::move(a);
+ a = A();
+ a.foo();
+ }
+ // The assignment should also be recognized if move, assignment and use don't
+ // all happen in the same block (but the assignment is still guaranteed to
+ // prevent a use-after-move).
+ {
+ A a;
+ if (i == 1) {
+ std::move(a);
+ a = A();
+ }
+ if (i == 2) {
+ a.foo();
+ }
+ }
+ {
+ A a;
+ if (i == 1) {
+ std::move(a);
+ }
+ if (i == 2) {
+ a = A();
+ a.foo();
+ }
+ }
+ // The built-in assignment operator should also be recognized as a
+ // reinitialization. (std::move() may be called on built-in types in template
+ // code.)
+ {
+ int a1 = 1, a2 = 2;
+ swap(a1, a2);
+ }
+ // A std::move() after the assignment makes the variable invalid again.
+ {
+ A a;
+ std::move(a);
+ a = A();
+ std::move(a);
+ a.foo();
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+ }
+ // Report a use-after-move if we can't be sure that the variable was assigned
+ // to.
+ {
+ A a;
+ std::move(a);
+ if (i < 10) {
+ a = A();
+ }
+ if (i > 5) {
+ a.foo();
+ // CHECK-NOTES: [[@LINE-1]]:7: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-7]]:5: note: move occurred here
+ }
+ }
+}
+
+// Passing the object to a function through a non-const pointer or reference
+// counts as a re-initialization.
+void passByNonConstPointer(A *);
+void passByNonConstReference(A &);
+void passByNonConstPointerIsReinit() {
+ {
+ A a;
+ std::move(a);
+ passByNonConstPointer(&a);
+ a.foo();
+ }
+ {
+ A a;
+ std::move(a);
+ passByNonConstReference(a);
+ a.foo();
+ }
+}
+
+// Passing the object through a const pointer or reference counts as a use --
+// since the called function cannot reinitialize the object.
+void passByConstPointer(const A *);
+void passByConstReference(const A &);
+void passByConstPointerIsUse() {
+ {
+ // Declaring 'a' as const so that no ImplicitCastExpr is inserted into the
+ // AST -- we wouldn't want the check to rely solely on that to detect a
+ // const pointer argument.
+ const A a;
+ std::move(a);
+ passByConstPointer(&a);
+ // CHECK-NOTES: [[@LINE-1]]:25: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+ }
+ const A a;
+ std::move(a);
+ passByConstReference(a);
+ // CHECK-NOTES: [[@LINE-1]]:24: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:3: note: move occurred here
+}
+
+// Clearing a standard container using clear() is treated as a
+// re-initialization.
+void standardContainerClearIsReinit() {
+ {
+ std::string container;
+ std::move(container);
+ container.clear();
+ container.empty();
+ }
+ {
+ std::vector<int> container;
+ std::move(container);
+ container.clear();
+ container.empty();
+
+ auto container2 = container;
+ std::move(container2);
+ container2.clear();
+ container2.empty();
+ }
+ {
+ std::deque<int> container;
+ std::move(container);
+ container.clear();
+ container.empty();
+ }
+ {
+ std::forward_list<int> container;
+ std::move(container);
+ container.clear();
+ container.empty();
+ }
+ {
+ std::list<int> container;
+ std::move(container);
+ container.clear();
+ container.empty();
+ }
+ {
+ std::set<int> container;
+ std::move(container);
+ container.clear();
+ container.empty();
+ }
+ {
+ std::map<int> container;
+ std::move(container);
+ container.clear();
+ container.empty();
+ }
+ {
+ std::multiset<int> container;
+ std::move(container);
+ container.clear();
+ container.empty();
+ }
+ {
+ std::multimap<int> container;
+ std::move(container);
+ container.clear();
+ container.empty();
+ }
+ {
+ std::unordered_set<int> container;
+ std::move(container);
+ container.clear();
+ container.empty();
+ }
+ {
+ std::unordered_map<int> container;
+ std::move(container);
+ container.clear();
+ container.empty();
+ }
+ {
+ std::unordered_multiset<int> container;
+ std::move(container);
+ container.clear();
+ container.empty();
+ }
+ {
+ std::unordered_multimap<int> container;
+ std::move(container);
+ container.clear();
+ container.empty();
+ }
+ // This should also work for typedefs of standard containers.
+ {
+ typedef std::vector<int> IntVector;
+ IntVector container;
+ std::move(container);
+ container.clear();
+ container.empty();
+ }
+ // But it shouldn't work for non-standard containers.
+ {
+ // This might be called "vector", but it's not in namespace "std".
+ struct vector {
+ void clear() {}
+ } container;
+ std::move(container);
+ container.clear();
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: 'container' used after it was
+ // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+ }
+ // An intervening clear() on a different container does not reinitialize.
+ {
+ std::vector<int> container1, container2;
+ std::move(container1);
+ container2.clear();
+ container1.empty();
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: 'container1' used after it was
+ // CHECK-NOTES: [[@LINE-4]]:5: note: move occurred here
+ }
+}
+
+// Clearing a standard container using assign() is treated as a
+// re-initialization.
+void standardContainerAssignIsReinit() {
+ {
+ std::string container;
+ std::move(container);
+ container.assign(0, ' ');
+ container.empty();
+ }
+ {
+ std::vector<int> container;
+ std::move(container);
+ container.assign(0, 0);
+ container.empty();
+ }
+ {
+ std::deque<int> container;
+ std::move(container);
+ container.assign(0, 0);
+ container.empty();
+ }
+ {
+ std::forward_list<int> container;
+ std::move(container);
+ container.assign(0, 0);
+ container.empty();
+ }
+ {
+ std::list<int> container;
+ std::move(container);
+ container.clear();
+ container.empty();
+ }
+ // But it doesn't work for non-standard containers.
+ {
+ // This might be called "vector", but it's not in namespace "std".
+ struct vector {
+ void assign(std::size_t, int) {}
+ } container;
+ std::move(container);
+ container.assign(0, 0);
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: 'container' used after it was
+ // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+ }
+ // An intervening assign() on a different container does not reinitialize.
+ {
+ std::vector<int> container1, container2;
+ std::move(container1);
+ container2.assign(0, 0);
+ container1.empty();
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: 'container1' used after it was
+ // CHECK-NOTES: [[@LINE-4]]:5: note: move occurred here
+ }
+}
+
+// Resetting the standard smart pointer types using reset() is treated as a
+// re-initialization. (We don't test std::weak_ptr<> because it can't be
+// dereferenced directly.)
+void standardSmartPointerResetIsReinit() {
+ {
+ std::unique_ptr<A> ptr;
+ std::move(ptr);
+ ptr.reset(new A);
+ *ptr;
+ }
+ {
+ std::shared_ptr<A> ptr;
+ std::move(ptr);
+ ptr.reset(new A);
+ *ptr;
+ }
+}
+
+void reinitAnnotation() {
+ {
+ AnnotatedContainer<int> obj;
+ std::move(obj);
+ obj.foo();
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: 'obj' used after it was
+ // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+ }
+ {
+ AnnotatedContainer<int> obj;
+ std::move(obj);
+ obj.clear();
+ obj.foo();
+ }
+ {
+ // Calling clear() on a different object to the one that was moved is not
+ // considered a reinitialization.
+ AnnotatedContainer<int> obj1, obj2;
+ std::move(obj1);
+ obj2.clear();
+ obj1.foo();
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: 'obj1' used after it was
+ // CHECK-NOTES: [[@LINE-4]]:5: note: move occurred here
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Tests related to order of evaluation within expressions
+
+// Relative sequencing of move and use.
+void passByRvalueReference(int i, A &&a);
+void passByValue(int i, A a);
+void passByValue(A a, int i);
+A g(A, A &&);
+int intFromA(A &&);
+int intFromInt(int);
+void sequencingOfMoveAndUse() {
+ // This case is fine because the move only happens inside
+ // passByRvalueReference(). At this point, a.getInt() is guaranteed to have
+ // been evaluated.
+ {
+ A a;
+ passByRvalueReference(a.getInt(), std::move(a));
+ }
+ // However, if we pass by value, the move happens when the move constructor is
+ // called to create a temporary, and this happens before the call to
+ // passByValue(). Because the order in which arguments are evaluated isn't
+ // defined, the move may happen before the call to a.getInt().
+ //
+ // Check that we warn about a potential use-after move for both orderings of
+ // a.getInt() and std::move(a), independent of the order in which the
+ // arguments happen to get evaluated by the compiler.
+ {
+ A a;
+ passByValue(a.getInt(), std::move(a));
+ // CHECK-NOTES: [[@LINE-1]]:17: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-2]]:29: note: move occurred here
+ // CHECK-NOTES: [[@LINE-3]]:17: note: the use and move are unsequenced
+ }
+ {
+ A a;
+ passByValue(std::move(a), a.getInt());
+ // CHECK-NOTES: [[@LINE-1]]:31: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-2]]:17: note: move occurred here
+ // CHECK-NOTES: [[@LINE-3]]:31: note: the use and move are unsequenced
+ }
+ // An even more convoluted example.
+ {
+ A a;
+ g(g(a, std::move(a)), g(a, std::move(a)));
+ // CHECK-NOTES: [[@LINE-1]]:9: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-2]]:27: note: move occurred here
+ // CHECK-NOTES: [[@LINE-3]]:9: note: the use and move are unsequenced
+ // CHECK-NOTES: [[@LINE-4]]:29: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-5]]:7: note: move occurred here
+ // CHECK-NOTES: [[@LINE-6]]:29: note: the use and move are unsequenced
+ }
+ // This case is fine because the actual move only happens inside the call to
+ // operator=(). a.getInt(), by necessity, is evaluated before that call.
+ {
+ A a;
+ A vec[1];
+ vec[a.getInt()] = std::move(a);
+ }
+ // However, in the following case, the move happens before the assignment, and
+ // so the order of evaluation is not guaranteed.
+ {
+ A a;
+ int v[3];
+ v[a.getInt()] = intFromA(std::move(a));
+ // CHECK-NOTES: [[@LINE-1]]:7: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-2]]:21: note: move occurred here
+ // CHECK-NOTES: [[@LINE-3]]:7: note: the use and move are unsequenced
+ }
+ {
+ A a;
+ int v[3];
+ v[intFromA(std::move(a))] = intFromInt(a.i);
+ // CHECK-NOTES: [[@LINE-1]]:44: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-2]]:7: note: move occurred here
+ // CHECK-NOTES: [[@LINE-3]]:44: note: the use and move are unsequenced
+ }
+}
+
+// Relative sequencing of move and reinitialization. If the two are unsequenced,
+// we conservatively assume that the move happens after the reinitialization,
+// i.e. the that object does not get reinitialized after the move.
+A MutateA(A a);
+void passByValue(A a1, A a2);
+void sequencingOfMoveAndReinit() {
+ // Move and reinitialization as function arguments (which are indeterminately
+ // sequenced). Again, check that we warn for both orderings.
+ {
+ A a;
+ passByValue(std::move(a), (a = A()));
+ a.foo();
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:17: note: move occurred here
+ }
+ {
+ A a;
+ passByValue((a = A()), std::move(a));
+ a.foo();
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:28: note: move occurred here
+ }
+ // Common usage pattern: Move the object to a function that mutates it in some
+ // way, then reassign the result to the object. This pattern is fine.
+ {
+ A a;
+ a = MutateA(std::move(a));
+ a.foo();
+ }
+}
+
+// Relative sequencing of reinitialization and use. If the two are unsequenced,
+// we conservatively assume that the reinitialization happens after the use,
+// i.e. that the object is not reinitialized at the point in time when it is
+// used.
+void sequencingOfReinitAndUse() {
+ // Reinitialization and use in function arguments. Again, check both possible
+ // orderings.
+ {
+ A a;
+ std::move(a);
+ passByValue(a.getInt(), (a = A()));
+ // CHECK-NOTES: [[@LINE-1]]:17: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+ }
+ {
+ A a;
+ std::move(a);
+ passByValue((a = A()), a.getInt());
+ // CHECK-NOTES: [[@LINE-1]]:28: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+ }
+}
+
+// The comma operator sequences its operands.
+void commaOperatorSequences() {
+ {
+ A a;
+ A(std::move(a))
+ , (a = A());
+ a.foo();
+ }
+ {
+ A a;
+ (a = A()), A(std::move(a));
+ a.foo();
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-3]]:16: note: move occurred here
+ }
+}
+
+// An initializer list sequences its initialization clauses.
+void initializerListSequences() {
+ {
+ struct S1 {
+ int i;
+ A a;
+ };
+ A a;
+ S1 s1{a.getInt(), std::move(a)};
+ }
+ {
+ struct S2 {
+ A a;
+ int i;
+ };
+ A a;
+ S2 s2{std::move(a), a.getInt()};
+ // CHECK-NOTES: [[@LINE-1]]:25: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-2]]:11: note: move occurred here
+ }
+}
+
+// A declaration statement containing multiple declarations sequences the
+// initializer expressions.
+void declarationSequences() {
+ {
+ A a;
+ A a1 = a, a2 = std::move(a);
+ }
+ {
+ A a;
+ A a1 = std::move(a), a2 = a;
+ // CHECK-NOTES: [[@LINE-1]]:31: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-2]]:12: note: move occurred here
+ }
+}
+
+// The logical operators && and || sequence their operands.
+void logicalOperatorsSequence() {
+ {
+ A a;
+ if (a.getInt() > 0 && A(std::move(a)).getInt() > 0) {
+ A().foo();
+ }
+ }
+ // A variation: Negate the result of the && (which pushes the && further down
+ // into the AST).
+ {
+ A a;
+ if (!(a.getInt() > 0 && A(std::move(a)).getInt() > 0)) {
+ A().foo();
+ }
+ }
+ {
+ A a;
+ if (A(std::move(a)).getInt() > 0 && a.getInt() > 0) {
+ // CHECK-NOTES: [[@LINE-1]]:41: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-2]]:9: note: move occurred here
+ A().foo();
+ }
+ }
+ {
+ A a;
+ if (a.getInt() > 0 || A(std::move(a)).getInt() > 0) {
+ A().foo();
+ }
+ }
+ {
+ A a;
+ if (A(std::move(a)).getInt() > 0 || a.getInt() > 0) {
+ // CHECK-NOTES: [[@LINE-1]]:41: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-2]]:9: note: move occurred here
+ A().foo();
+ }
+ }
+}
+
+// A range-based for sequences the loop variable declaration before the body.
+void forRangeSequences() {
+ A v[2] = {A(), A()};
+ for (A &a : v) {
+ std::move(a);
+ }
+}
+
+// If a variable is declared in an if, while or switch statement, the init
+// statement (for if and switch) is sequenced before the variable declaration,
+// which in turn is sequenced before the evaluation of the condition.
+void ifWhileAndSwitchSequenceInitDeclAndCondition() {
+ for (int i = 0; i < 10; ++i) {
+ A a1;
+ if (A a2 = std::move(a1)) {
+ std::move(a2);
+ }
+ }
+ for (int i = 0; i < 10; ++i) {
+ A a1;
+ if (A a2 = std::move(a1); A a3 = std::move(a2)) {
+ std::move(a3);
+ }
+ }
+ while (A a = A()) {
+ std::move(a);
+ }
+ for (int i = 0; i < 10; ++i) {
+ A a1;
+ switch (A a2 = a1; A a3 = std::move(a2)) {
+ case true:
+ std::move(a3);
+ }
+ }
+}
+
+// Some statements in templates (e.g. null, break and continue statements) may
+// be shared between the uninstantiated and instantiated versions of the
+// template and therefore have multiple parents. Make sure the sequencing code
+// handles this correctly.
+template <class> void nullStatementSequencesInTemplate() {
+ int c = 0;
+ (void)c;
+ ;
+ std::move(c);
+}
+template void nullStatementSequencesInTemplate<int>();
+
+namespace PR33020 {
+class D {
+ ~D();
+};
+struct A {
+ D d;
+};
+class B {
+ A a;
+};
+template <typename T>
+class C : T, B {
+ void m_fn1() {
+ int a;
+ std::move(a);
+ C c;
+ }
+};
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-virtual-near-miss.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-virtual-near-miss.cpp
new file mode 100644
index 0000000..553d2f4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/bugprone-virtual-near-miss.cpp
@@ -0,0 +1,133 @@
+// RUN: %check_clang_tidy %s bugprone-virtual-near-miss %t
+
+class NoDefinedClass1;
+class NoDefinedClass2;
+
+struct Base {
+ virtual void func();
+ virtual void gunk();
+ virtual ~Base();
+ virtual Base &operator=(const Base &);
+ virtual NoDefinedClass1 *f();
+};
+
+struct Derived : Base {
+ // Should not warn "do you want to override 'gunk'?", because gunk is already
+ // overriden by this class.
+ virtual void funk();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Derived::funk' has a similar name and the same signature as virtual method 'Base::func'; did you mean to override it? [bugprone-virtual-near-miss]
+ // CHECK-FIXES: virtual void func();
+
+ void func2();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Derived::func2' has {{.*}} 'Base::func'
+ // CHECK-FIXES: void func();
+
+ void func22(); // Should not warn.
+
+ void gunk(); // Should not warn: gunk is override.
+
+ void fun();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Derived::fun' has {{.*}} 'Base::func'
+ // CHECK-FIXES: void func();
+
+ Derived &operator==(const Base &); // Should not warn: operators are ignored.
+
+ virtual NoDefinedClass2 *f1(); // Should not crash: non-defined class return type is ignored.
+};
+
+template <typename T>
+struct TBase {
+ virtual void tfunc(T t);
+};
+
+template <typename T>
+struct TDerived : TBase<T> {
+ virtual void tfunk(T t);
+ // Should not apply fix for template.
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: method 'TDerived<double>::tfunk' has {{.*}} 'TBase<double>::tfunc'
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: method 'TDerived<int>::tfunk' has {{.*}} 'TBase<int>::tfunc'
+ // CHECK-FIXES: virtual void tfunk(T t);
+};
+
+TDerived<int> T1;
+TDerived<double> T2;
+
+// Should not fix macro definition
+#define MACRO1 void funcM()
+// CHECK-FIXES: #define MACRO1 void funcM()
+#define MACRO2(m) void m()
+// CHECK-FIXES: #define MACRO2(m) void m()
+
+struct DerivedMacro : Base {
+ MACRO1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'DerivedMacro::funcM' has {{.*}} 'Base::func'
+ // CHECK-FIXES: MACRO1;
+
+ MACRO2(func3);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'DerivedMacro::func3' has {{.*}} 'Base::func'
+ // CHECK-FIXES: MACRO2(func);
+};
+
+typedef Derived derived_type;
+
+class Father {
+public:
+ Father();
+ virtual void func();
+ virtual Father *create(int i);
+ virtual Base &&generate();
+ virtual Base *canonical(Derived D);
+};
+
+class Mother {
+public:
+ Mother();
+ static void method();
+ virtual int method(int argc, const char **argv);
+ virtual int method(int argc) const;
+ virtual int decay(const char *str);
+};
+
+class Child : private Father, private Mother {
+public:
+ Child();
+
+ virtual void func2();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::func2' has {{.*}} 'Father::func'
+ // CHECK-FIXES: virtual void func();
+
+ int methoe(int x, char **strs); // Should not warn: parameter types don't match.
+
+ int methoe(int x);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::methoe' has {{.*}} 'Mother::method'
+ // CHECK-FIXES: int method(int x);
+
+ void methof(int x, const char **strs); // Should not warn: return types don't match.
+
+ int methoh(int x, const char **strs);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::methoh' has {{.*}} 'Mother::method'
+ // CHECK-FIXES: int method(int x, const char **strs);
+
+ virtual Child *creat(int i);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::creat' has {{.*}} 'Father::create'
+ // CHECK-FIXES: virtual Child *create(int i);
+
+ virtual Derived &&generat();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::generat' has {{.*}} 'Father::generate'
+ // CHECK-FIXES: virtual Derived &&generate();
+
+ int decaz(const char str[]);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::decaz' has {{.*}} 'Mother::decay'
+ // CHECK-FIXES: int decay(const char str[]);
+
+ operator bool();
+
+ derived_type *canonica(derived_type D);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::canonica' has {{.*}} 'Father::canonical'
+ // CHECK-FIXES: derived_type *canonical(derived_type D);
+
+private:
+ void funk();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::funk' has {{.*}} 'Father::func'
+ // CHECK-FIXES: void func();
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-dcl21-cpp.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-dcl21-cpp.cpp
new file mode 100644
index 0000000..c975f70
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-dcl21-cpp.cpp
@@ -0,0 +1,134 @@
+// RUN: %check_clang_tidy %s cert-dcl21-cpp %t
+
+class A {};
+
+A operator++(A &, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator++' returns a non-constant object instead of a constant object type [cert-dcl21-cpp]
+// CHECK-FIXES: {{^}}const A operator++(A &, int);
+
+A operator--(A &, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator--' returns a no
+// CHECK-FIXES: {{^}}const A operator--(A &, int);
+
+class B {};
+
+B &operator++(B &);
+const B operator++(B &, int);
+
+B &operator--(B &);
+const B operator--(B &, int);
+
+
+class D {
+D &operator++();
+const D operator++(int);
+
+D &operator--();
+const D operator--(int);
+};
+
+class C {
+C operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator++' returns a no
+// CHECK-FIXES: {{^}}const C operator++(int);
+
+C operator--(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator--' returns a no
+// CHECK-FIXES: {{^}}const C operator--(int);
+};
+
+class E {};
+
+E &operator++(E &, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator++' returns a reference instead of a constant object type [cert-dcl21-cpp]
+// CHECK-FIXES: {{^}}const E operator++(E &, int);
+
+E &operator--(E &, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator--' returns a re
+// CHECK-FIXES: {{^}}const E operator--(E &, int);
+
+class G {
+G &operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}}const G operator++(int);
+
+G &operator--(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator--' returns a re
+// CHECK-FIXES: {{^}}const G operator--(int);
+};
+
+class F {};
+
+const F &operator++(F &, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}}const F operator++(F &, int);
+
+const F &operator--(F &, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator--' returns a re
+// CHECK-FIXES: {{^}}const F operator--(F &, int);
+
+class H {
+const H &operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}}const H operator++(int);
+
+const H &operator--(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator--' returns a re
+// CHECK-FIXES: {{^}}const H operator--(int);
+};
+
+
+#define FROM_MACRO P&
+class P {
+const FROM_MACRO operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}}const FROM_MACRO operator++(int);
+};
+
+
+template<typename T>
+class Q {
+const Q &operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}}const Q<T> operator++(int);
+
+const Q &operator--(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator--' returns a re
+// CHECK-FIXES: {{^}}const Q<T> operator--(int);
+};
+
+void foobar() {
+ Q<int> a;
+ Q<float> b;
+ (void)a;
+ (void)b;
+}
+
+struct S {};
+typedef S& SRef;
+
+SRef operator++(SRef, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}}SRef operator++(SRef, int);
+
+struct T {
+ typedef T& TRef;
+
+ TRef operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}} TRef operator++(int);
+};
+
+struct U {
+ typedef const U& ConstURef;
+
+ ConstURef& operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}} ConstURef& operator++(int);
+};
+
+struct V {
+ V *operator++(int);
+ V *const operator--(int);
+};
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-dcl58-cpp.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-dcl58-cpp.cpp
new file mode 100644
index 0000000..34ee368
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-dcl58-cpp.cpp
@@ -0,0 +1,67 @@
+// RUN: %check_clang_tidy %s cert-dcl58-cpp %t -- -- -std=c++1z -I %S/Inputs/Headers
+
+#include "system-header-simulation.h"
+
+namespace A {
+ namespace B {
+ int b;
+ }
+}
+
+namespace A {
+ namespace B {
+ int c;
+ }
+}
+
+namespace posix {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: modification of 'posix' namespace can result in undefined behavior [cert-dcl58-cpp]
+ namespace vmi {
+ }
+}
+
+namespace std {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: modification of 'std' namespace can
+ int stdInt;
+}
+
+namespace foobar {
+ namespace std {
+ int bar;
+ }
+}
+
+namespace posix::a {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: modification of 'posix' namespace
+}
+
+enum class MyError {
+ ErrorA,
+ ErrorB
+};
+
+namespace std {
+template <>
+struct is_error_code_enum<MyError> : std::true_type {};
+
+template<>
+void swap<MyError>(MyError &a, MyError &b);
+}
+
+enum class MyError2 {
+ Error2A,
+ Error2B
+};
+
+namespace std {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: modification of 'std' namespace
+template <>
+struct is_error_code_enum<MyError2> : std::true_type {};
+
+int foobar;
+}
+
+using namespace std;
+
+int x;
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-env33-c.c b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-env33-c.c
new file mode 100644
index 0000000..5846b49
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-env33-c.c
@@ -0,0 +1,20 @@
+// RUN: %check_clang_tidy %s cert-env33-c %t
+
+typedef struct FILE {} FILE;
+
+extern int system(const char *);
+extern FILE *popen(const char *, const char *);
+extern FILE *_popen(const char *, const char *);
+
+void f(void) {
+ // It is permissible to check for the presence of a command processor.
+ system(0);
+
+ system("test");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling 'system' uses a command processor [cert-env33-c]
+
+ popen("test", "test");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling 'popen' uses a command processor
+ _popen("test", "test");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling '_popen' uses a command processor
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-err34-c.c b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-err34-c.c
new file mode 100644
index 0000000..e2cfc21
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-err34-c.c
@@ -0,0 +1,103 @@
+// RUN: %check_clang_tidy %s cert-err34-c %t -- -- -std=c11
+
+typedef __SIZE_TYPE__ size_t;
+typedef signed ptrdiff_t;
+typedef long long intmax_t;
+typedef unsigned long long uintmax_t;
+typedef void * FILE;
+
+extern FILE *stdin;
+
+extern int fscanf(FILE * restrict stream, const char * restrict format, ...);
+extern int scanf(const char * restrict format, ...);
+extern int sscanf(const char * restrict s, const char * restrict format, ...);
+
+extern double atof(const char *nptr);
+extern int atoi(const char *nptr);
+extern long int atol(const char *nptr);
+extern long long int atoll(const char *nptr);
+
+void f1(const char *in) {
+ int i;
+ long long ll;
+ unsigned int ui;
+ unsigned long long ull;
+ intmax_t im;
+ uintmax_t uim;
+ float f;
+ double d;
+ long double ld;
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
+ sscanf(in, "%d", &i);
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead [cert-err34-c]
+ fscanf(stdin, "%lld", &ll);
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoul' instead [cert-err34-c]
+ sscanf(in, "%u", &ui);
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoull' instead [cert-err34-c]
+ fscanf(stdin, "%llu", &ull);
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoimax' instead [cert-err34-c]
+ scanf("%jd", &im);
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoumax' instead [cert-err34-c]
+ fscanf(stdin, "%ju", &uim);
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtof' instead [cert-err34-c]
+ sscanf(in, "%f", &f); // to float
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtod' instead [cert-err34-c]
+ fscanf(stdin, "%lg", &d);
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtold' instead [cert-err34-c]
+ sscanf(in, "%Le", &ld);
+
+ // These are conversions with other modifiers
+ short s;
+ char c;
+ size_t st;
+ ptrdiff_t pt;
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
+ scanf("%hhd", &c);
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
+ scanf("%hd", &s);
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
+ scanf("%zu", &st);
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
+ scanf("%td", &pt);
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
+ scanf("%o", ui);
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
+ scanf("%X", ui);
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
+ scanf("%x", ui);
+}
+
+void f2(const char *in) {
+ // CHECK-MESSAGES: :[[@LINE+1]]:11: warning: 'atoi' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
+ int i = atoi(in); // to int
+ // CHECK-MESSAGES: :[[@LINE+1]]:12: warning: 'atol' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
+ long l = atol(in); // to long
+ // CHECK-MESSAGES: :[[@LINE+1]]:18: warning: 'atoll' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead [cert-err34-c]
+ long long ll = atoll(in); // to long long
+ // CHECK-MESSAGES: :[[@LINE+1]]:14: warning: 'atof' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtod' instead [cert-err34-c]
+ double d = atof(in); // to double
+}
+
+void f3(void) {
+ int i;
+ unsigned int u;
+ float f;
+ char str[32];
+
+ // Test that we don't report multiple infractions for a single call.
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
+ scanf("%d%u%f", &i, &u, &f);
+
+ // Test that we still catch infractions that are not the first specifier.
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
+ scanf("%s%d", str, &i);
+}
+
+void do_not_diagnose(void) {
+ char str[32];
+
+ scanf("%s", str); // Not a numerical conversion
+ scanf("%*d"); // Assignment suppressed
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-err34-c.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-err34-c.cpp
new file mode 100644
index 0000000..dde7dc1
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-err34-c.cpp
@@ -0,0 +1,43 @@
+// RUN: %check_clang_tidy %s cert-err34-c %t -- -- -std=c++11
+
+typedef void * FILE;
+
+extern FILE *stdin;
+
+extern int fscanf(FILE * stream, const char * format, ...);
+extern int sscanf(const char * s, const char * format, ...);
+
+extern double atof(const char *nptr);
+extern int atoi(const char *nptr);
+extern long int atol(const char *nptr);
+extern long long int atoll(const char *nptr);
+
+namespace std {
+using ::FILE; using ::stdin;
+using ::fscanf; using ::sscanf;
+using ::atof; using ::atoi; using ::atol; using ::atoll;
+}
+
+void f1(const char *in) {
+ int i;
+ long long ll;
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
+ std::sscanf(in, "%d", &i);
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead [cert-err34-c]
+ std::fscanf(std::stdin, "%lld", &ll);
+}
+
+void f2(const char *in) {
+ // CHECK-MESSAGES: :[[@LINE+1]]:11: warning: 'atoi' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
+ int i = std::atoi(in); // to int
+ // CHECK-MESSAGES: :[[@LINE+1]]:12: warning: 'atol' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
+ long l = std::atol(in); // to long
+
+ using namespace std;
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:18: warning: 'atoll' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead [cert-err34-c]
+ long long ll = atoll(in); // to long long
+ // CHECK-MESSAGES: :[[@LINE+1]]:14: warning: 'atof' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtod' instead [cert-err34-c]
+ double d = atof(in); // to double
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-flp30-c.c b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-flp30-c.c
new file mode 100644
index 0000000..eee16be
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-flp30-c.c
@@ -0,0 +1,19 @@
+// RUN: %check_clang_tidy %s cert-flp30-c %t
+
+float g(void);
+
+void func(void) {
+ for (float x = 0.1f; x <= 1.0f; x += 0.1f) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: loop induction expression should not have floating-point type [cert-flp30-c]
+
+ float f = 1.0f;
+ for (; f > 0; --f) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: loop induction expression
+
+ for (;;g()) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: loop induction expression
+
+ for (int i = 0; i < 10; i += 1.0f) {}
+
+ for (int i = 0; i < 10; ++i) {}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-limited-randomness.c b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-limited-randomness.c
new file mode 100644
index 0000000..c8009b5
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-limited-randomness.c
@@ -0,0 +1,13 @@
+// RUN: %check_clang_tidy %s cert-msc30-c %t
+
+extern int rand(void);
+int nonrand();
+
+int cTest() {
+ int i = rand();
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: rand() has limited randomness [cert-msc30-c]
+
+ int k = nonrand();
+
+ return 0;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-limited-randomness.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-limited-randomness.cpp
new file mode 100644
index 0000000..845b735
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-limited-randomness.cpp
@@ -0,0 +1,28 @@
+// RUN: %check_clang_tidy %s cert-msc50-cpp %t
+
+int rand();
+int rand(int);
+
+namespace std {
+using ::rand;
+}
+
+namespace nonstd {
+ int rand();
+}
+
+void testFunction1() {
+ int i = std::rand();
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: rand() has limited randomness; use C++11 random library instead [cert-msc50-cpp]
+
+ int j = ::rand();
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: rand() has limited randomness; use C++11 random library instead [cert-msc50-cpp]
+
+ int k = rand(i);
+
+ int l = nonstd::rand();
+
+ int m = rand();
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: rand() has limited randomness; use C++11 random library instead [cert-msc50-cpp]
+}
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-msc32-c.c b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-msc32-c.c
new file mode 100644
index 0000000..6cc40fa
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-msc32-c.c
@@ -0,0 +1,27 @@
+// RUN: %check_clang_tidy %s cert-msc32-c %t -- -config="{CheckOptions: [{key: cert-msc32-c.DisallowedSeedTypes, value: 'some_type,time_t'}]}" -- -std=c99
+
+void srand(int seed);
+typedef int time_t;
+time_t time(time_t *t);
+
+void f() {
+ srand(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc32-c]
+
+ const int a = 1;
+ srand(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc32-c]
+
+ time_t t;
+ srand(time(&t)); // Disallowed seed type
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc32-c]
+}
+
+void g() {
+ typedef int user_t;
+ user_t a = 1;
+ srand(a);
+
+ int b = 1;
+ srand(b); // Can not evaluate as int
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-msc51-cpp.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-msc51-cpp.cpp
new file mode 100644
index 0000000..8a8d778
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-msc51-cpp.cpp
@@ -0,0 +1,210 @@
+// RUN: %check_clang_tidy %s cert-msc51-cpp %t -- -config="{CheckOptions: [{key: cert-msc51-cpp.DisallowedSeedTypes, value: 'some_type,time_t'}]}" -- -std=c++11
+
+namespace std {
+
+void srand(int seed);
+
+template <class UIntType, UIntType a, UIntType c, UIntType m>
+struct linear_congruential_engine {
+ linear_congruential_engine(int _ = 0);
+ void seed(int _ = 0);
+};
+using default_random_engine = linear_congruential_engine<unsigned int, 1, 2, 3>;
+
+using size_t = int;
+template <class UIntType, size_t w, size_t n, size_t m, size_t r,
+ UIntType a, size_t u, UIntType d, size_t s,
+ UIntType b, size_t t,
+ UIntType c, size_t l, UIntType f>
+struct mersenne_twister_engine {
+ mersenne_twister_engine(int _ = 0);
+ void seed(int _ = 0);
+};
+using mt19937 = mersenne_twister_engine<unsigned int, 32, 624, 397, 21, 0x9908b0df, 11, 0xffffffff, 7, 0x9d2c5680, 15, 0xefc60000, 18, 1812433253>;
+
+template <class UIntType, size_t w, size_t s, size_t r>
+struct subtract_with_carry_engine {
+ subtract_with_carry_engine(int _ = 0);
+ void seed(int _ = 0);
+};
+using ranlux24_base = subtract_with_carry_engine<unsigned int, 24, 10, 24>;
+
+template <class Engine, size_t p, size_t r>
+struct discard_block_engine {
+ discard_block_engine();
+ discard_block_engine(int _);
+ void seed();
+ void seed(int _);
+};
+using ranlux24 = discard_block_engine<ranlux24_base, 223, 23>;
+
+template <class Engine, size_t w, class UIntType>
+struct independent_bits_engine {
+ independent_bits_engine();
+ independent_bits_engine(int _);
+ void seed();
+ void seed(int _);
+};
+using independent_bits = independent_bits_engine<ranlux24_base, 223, int>;
+
+template <class Engine, size_t k>
+struct shuffle_order_engine {
+ shuffle_order_engine();
+ shuffle_order_engine(int _);
+ void seed();
+ void seed(int _);
+};
+using shuffle_order = shuffle_order_engine<ranlux24_base, 223>;
+
+struct random_device {
+ random_device();
+ int operator()();
+};
+} // namespace std
+
+using time_t = unsigned int;
+time_t time(time_t *t);
+
+void f() {
+ const int seed = 2;
+ time_t t;
+
+ std::srand(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ std::srand(seed);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ std::srand(time(&t));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+
+ // One instantiation for every engine
+ std::default_random_engine engine1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+ std::default_random_engine engine2(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ std::default_random_engine engine3(seed);
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ std::default_random_engine engine4(time(&t));
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+ engine1.seed();
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+ engine1.seed(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ engine1.seed(seed);
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ engine1.seed(time(&t));
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+
+ std::mt19937 engine5;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+ std::mt19937 engine6(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ std::mt19937 engine7(seed);
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ std::mt19937 engine8(time(&t));
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+ engine5.seed();
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+ engine5.seed(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ engine5.seed(seed);
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ engine5.seed(time(&t));
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+
+ std::ranlux24_base engine9;
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+ std::ranlux24_base engine10(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ std::ranlux24_base engine11(seed);
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ std::ranlux24_base engine12(time(&t));
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+ engine9.seed();
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+ engine9.seed(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ engine9.seed(seed);
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ engine9.seed(time(&t));
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+
+ std::ranlux24 engine13;
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+ std::ranlux24 engine14(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ std::ranlux24 engine15(seed);
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ std::ranlux24 engine16(time(&t));
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+ engine13.seed();
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+ engine13.seed(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ engine13.seed(seed);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ engine13.seed(time(&t));
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+
+ std::independent_bits engine17;
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+ std::independent_bits engine18(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ std::independent_bits engine19(seed);
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ std::independent_bits engine20(time(&t));
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+ engine17.seed();
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+ engine17.seed(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ engine17.seed(seed);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ engine17.seed(time(&t));
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+
+ std::shuffle_order engine21;
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+ std::shuffle_order engine22(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ std::shuffle_order engine23(seed);
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ std::shuffle_order engine24(time(&t));
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+ engine21.seed();
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+ engine21.seed(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ engine21.seed(seed);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+ engine21.seed(time(&t));
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+}
+
+struct A {
+ A(int _ = 0);
+ void seed(int _ = 0);
+};
+
+void g() {
+ int n = 1;
+ std::default_random_engine engine1(n);
+ std::mt19937 engine2(n);
+ std::ranlux24_base engine3(n);
+ std::ranlux24 engine4(n);
+ std::independent_bits engine5(n);
+ std::shuffle_order engine6(n);
+
+ std::random_device dev;
+ std::default_random_engine engine7(dev());
+ std::mt19937 engine8(dev());
+ std::ranlux24_base engine9(dev());
+ std::ranlux24 engine10(dev());
+ std::independent_bits engine11(dev());
+ std::shuffle_order engine12(dev());
+
+ A a1;
+ A a2(1);
+ a1.seed();
+ a1.seed(1);
+ a1.seed(n);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-oop11-cpp.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-oop11-cpp.cpp
new file mode 100644
index 0000000..650d6ec
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-oop11-cpp.cpp
@@ -0,0 +1,21 @@
+// RUN: %check_clang_tidy %s cert-oop11-cpp %t -- -- -std=c++11
+
+struct B {
+ B(B&&) noexcept = default;
+
+ B(const B &) = default;
+ B& operator=(const B&) = default;
+ ~B() {}
+};
+
+struct D {
+ B b;
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:14: warning: move constructor initializes class member by calling a copy constructor [cert-oop11-cpp]
+ D(D &&d) : b(d.b) {}
+
+ // This should not produce a diagnostic because it is not covered under
+ // the CERT guideline for OOP11-CPP. However, this will produce a diagnostic
+ // under performance-move-constructor-init.
+ D(B b) : b(b) {}
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-setlongjmp.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-setlongjmp.cpp
new file mode 100644
index 0000000..1bf5444
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-setlongjmp.cpp
@@ -0,0 +1,26 @@
+// RUN: %check_clang_tidy %s cert-err52-cpp %t -- -- -std=c++11
+
+typedef void *jmp_buf;
+extern int __setjmpimpl(jmp_buf);
+#define setjmp(x) __setjmpimpl(x)
+[[noreturn]] extern void longjmp(jmp_buf, int);
+
+namespace std {
+using ::jmp_buf;
+using ::longjmp;
+}
+
+static jmp_buf env;
+void g() {
+ std::longjmp(env, 1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not call 'longjmp'; consider using exception handling instead [cert-err52-cpp]
+ ::longjmp(env, 1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not call 'longjmp'; consider using exception handling instead
+ longjmp(env, 1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not call 'longjmp'; consider using exception handling instead
+}
+
+void f() {
+ (void)setjmp(env);
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not call 'setjmp'; consider using exception handling instead
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-static-object-exception.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-static-object-exception.cpp
new file mode 100644
index 0000000..b915252
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-static-object-exception.cpp
@@ -0,0 +1,275 @@
+// RUN: clang-tidy %s -checks="-*,cert-err58-cpp" -- -std=c++17 -target x86_64-pc-linux-gnu \
+// RUN: | FileCheck %s -check-prefix=CHECK-EXCEPTIONS \
+// RUN: -implicit-check-not="{{warning|error}}:"
+// RUN: clang-tidy %s -checks="-*,cert-err58-cpp" -- -DNONEXCEPTIONS -fno-exceptions -std=c++17 -target x86_64-pc-linux-gnu \
+// RUN: | FileCheck %s -allow-empty -check-prefix=CHECK-NONEXCEPTIONS \
+// RUN: -implicit-check-not="{{warning|error}}:"
+
+struct S {
+ S() noexcept(false);
+};
+
+struct T {
+ T() noexcept;
+};
+
+struct U {
+ U() {}
+};
+
+struct V {
+ explicit V(const char *) {} // Can throw
+};
+
+struct Cleanup {
+ ~Cleanup() {}
+};
+
+struct W {
+ W(Cleanup c = {}) noexcept(false);
+};
+
+struct X {
+ X(S = {}) noexcept;
+};
+
+struct Y {
+ S s;
+};
+
+struct Z {
+ T t;
+};
+
+int f();
+int g() noexcept(false);
+int h() noexcept(true);
+
+struct UserConv_Bad {
+ operator int() noexcept(false);
+};
+
+struct UserConv_Good {
+ operator int() noexcept;
+};
+
+UserConv_Bad some_bad_func() noexcept;
+UserConv_Good some_good_func() noexcept;
+
+S s;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 's' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
+// CHECK-EXCEPTIONS: 9:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+T t; // ok
+U u;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'u' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 17:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+V v("v");
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'v' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 21:12: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+W w;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'w' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 29:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+X x1(S{});
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'x1' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 9:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+X x2;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'x2' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 9:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+Y y;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'y' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 36:8: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+Z z;
+
+int i = f();
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:5: warning: initialization of 'i' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 44:5: note: possibly throwing function declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+int j = g();
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:5: warning: initialization of 'j' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 45:5: note: possibly throwing function declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+int k = h();
+int l = some_bad_func();
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:5: warning: initialization of 'l' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 49:3: note: possibly throwing function declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+int m = some_good_func();
+
+typedef decltype(sizeof(int)) size_t;
+inline void *operator new(size_t sz, void *here) noexcept { return here; }
+char n[sizeof(int)];
+int *o = new (n) int();
+int *p = new int();
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:6: warning: initialization of 'p' with static storage duration may throw an exception that cannot be caught
+// CHECK-NONEXCEPTIONS-NOT: warning:
+
+thread_local S s3;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 's3' with thread_local storage duration may throw an exception that cannot be caught
+// CHECK-NONEXCEPTIONS-NOT: warning:
+thread_local T t3; // ok
+thread_local U u3;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 'u3' with thread_local storage duration may throw an exception that cannot be caught
+// CHECK-NONEXCEPTIONS-NOT: warning:
+thread_local V v3("v");
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 'v3' with thread_local storage duration may throw an exception that cannot be caught
+// CHECK-NONEXCEPTIONS-NOT: warning:
+thread_local W w3;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 'w3' with thread_local storage duration may throw an exception that cannot be caught
+// CHECK-NONEXCEPTIONS-NOT: warning:
+
+void f(S s1, T t1, U u1, V v1, W w1) { // ok, ok, ok, ok, ok
+ S s2; // ok
+ T t2; // ok
+ U u2; // ok
+ V v2("v"); // ok
+ W w2; // ok
+
+ thread_local S s3; // ok
+ thread_local T t3; // ok
+ thread_local U u3; // ok
+ thread_local V v3("v"); // ok
+ thread_local W w3; // ok
+
+ static S s4; // ok
+ static T t4; // ok
+ static U u4; // ok
+ static V v4("v"); // ok
+ static W w4; // ok
+}
+
+namespace {
+S s;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 's' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
+// CHECK-EXCEPTIONS: 9:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+T t; // ok
+U u;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'u' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 17:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+V v("v");
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'v' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 21:12: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+W w;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'w' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 29:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+
+thread_local S s3;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 's3' with thread_local storage duration may throw an exception that cannot be caught
+// CHECK-NONEXCEPTIONS-NOT: warning:
+thread_local T t3; // ok
+thread_local U u3;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 'u3' with thread_local storage duration may throw an exception that cannot be caught
+// CHECK-NONEXCEPTIONS-NOT: warning:
+thread_local V v3("v");
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 'v3' with thread_local storage duration may throw an exception that cannot be caught
+// CHECK-NONEXCEPTIONS-NOT: warning:
+thread_local W w3;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 'w3' with thread_local storage duration may throw an exception that cannot be caught
+// CHECK-NONEXCEPTIONS-NOT: warning:
+}; // namespace
+
+class Statics {
+ static S s; // warn when initialized
+ static T t; // ok
+ static U u; // warn when initialized
+ static V v; // warn when initialized
+ static W w; // warn when initialized
+
+ void f(S s, T t, U u, V v) {
+ S s2; // ok
+ T t2; // ok
+ U u2; // ok
+ V v2("v"); // ok
+ W w2; // ok
+
+ thread_local S s3; // ok
+ thread_local T t3; // ok
+ thread_local U u3; // ok
+ thread_local V v3("v"); // ok
+ thread_local W w3; // ok
+
+ static S s4; // ok
+ static T t4; // ok
+ static U u4; // ok
+ static V v4("v"); // ok
+ static W w4; // ok
+ }
+};
+
+S Statics::s;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:12: warning: initialization of 's' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
+// CHECK-EXCEPTIONS: 9:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+T Statics::t;
+U Statics::u;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:12: warning: initialization of 'u' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 17:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+V Statics::v("v");
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:12: warning: initialization of 'v' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 21:12: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+W Statics::w;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:12: warning: initialization of 'w' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 29:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+
+#ifndef NONEXCEPTIONS
+namespace pr35457 {
+constexpr int foo(int x) { if (x <= 0) throw 12; return x; }
+
+constexpr int bar = foo(1); // OK
+// CHECK-EXCEPTIONS-NOT: warning: initialization of 'bar' with static storage
+int baz = foo(0); // Not OK; throws at runtime when exceptions are enabled.
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:5: warning: initialization of 'baz' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
+// CHECK-EXCEPTIONS: :[[@LINE-6]]:15: note: possibly throwing function declared here
+} // namespace pr35457
+#endif // NONEXCEPTIONS
+
+namespace pr39777 {
+struct S { S(); };
+struct T { T() noexcept; };
+
+auto Okay1 = []{ S s; };
+auto Okay2 = []{ (void)new int; };
+auto NotOkay1 = []{ S s; return 12; }(); // Because the lambda call is not noexcept
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:6: warning: initialization of 'NotOkay1' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
+// CHECK-EXCEPTIONS: :[[@LINE-7]]:12: note: possibly throwing constructor declared here
+auto NotOkay2 = []() noexcept { S s; return 12; }(); // Because S::S() is not noexcept
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:6: warning: initialization of 'NotOkay2' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
+// CHECK-EXCEPTIONS: :[[@LINE-10]]:12: note: possibly throwing constructor declared here
+auto Okay3 = []() noexcept { T t; return t; }();
+
+struct U {
+ U() noexcept;
+ auto getBadLambda() const noexcept {
+ return []{ S s; return s; };
+ }
+};
+auto Okay4 = []{ U u; return u.getBadLambda(); }();
+auto NotOkay3 = []() noexcept { U u; return u.getBadLambda(); }()(); // Because the lambda returned and called is not noexcept
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:6: warning: initialization of 'NotOkay3' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
+// CHECK-EXCEPTIONS: :[[@LINE-6]]:12: note: possibly throwing function declared here
+
+#ifndef NONEXCEPTIONS
+struct Bad {
+ Bad() {
+ throw 12;
+ }
+};
+
+static auto NotOkay4 = [bad = Bad{}](){};
+// FIXME: the above should be diagnosed because the capture init can trigger
+// an exception when constructing the Bad object.
+#endif // NONEXCEPTIONS
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-throw-exception-type.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-throw-exception-type.cpp
new file mode 100644
index 0000000..2ff9be5
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-throw-exception-type.cpp
@@ -0,0 +1,127 @@
+// RUN: %check_clang_tidy %s cert-err60-cpp %t -- -- -std=c++11 -fcxx-exceptions
+
+struct S {};
+struct T : S {};
+struct U {
+ U() = default;
+ U(const U&) = default;
+};
+
+struct V {
+ V() = default;
+ V(const V&) noexcept;
+};
+
+struct W {
+ W() = default;
+ W(const W&) noexcept(false);
+};
+
+struct X {
+ X() = default;
+ X(const X&) {}
+};
+
+struct Y {
+ Y() = default;
+ Y(const Y&) throw();
+};
+
+struct Z {
+ Z() = default;
+ Z(const Z&) throw(int);
+};
+
+void g() noexcept(false);
+
+struct A {
+ A() = default;
+ A(const A&) noexcept(noexcept(g()));
+};
+
+struct B {
+ B() = default;
+ B(const B&) = default;
+ B(const A&) noexcept(false);
+};
+
+class C {
+ W M; // W is not no-throw copy constructible
+public:
+ C() = default;
+ C(const C&) = default;
+};
+
+struct D {
+ D() = default;
+ D(const D&) noexcept(false);
+ D(D&) noexcept(true);
+};
+
+struct E {
+ E() = default;
+ E(E&) noexcept(true);
+ E(const E&) noexcept(false);
+};
+
+struct Allocates {
+ int *x;
+ Allocates() : x(new int(0)) {}
+ Allocates(const Allocates &other) : x(new int(*other.x)) {}
+};
+
+struct OptionallyAllocates {
+ int *x;
+ OptionallyAllocates() : x(new int(0)) {}
+ OptionallyAllocates(const Allocates &other) noexcept(true) {
+ try {
+ x = new int(*other.x);
+ } catch (...) {
+ x = nullptr;
+ }
+ }
+};
+
+void f() {
+ throw 12; // ok
+ throw "test"; // ok
+ throw S(); // ok
+ throw T(); // ok
+ throw U(); // ok
+ throw V(); // ok
+ throw W(); // match, noexcept(false)
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible [cert-err60-cpp]
+ throw X(); // match, no noexcept clause, nontrivial
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
+ throw Y(); // ok
+ throw Z(); // match, throw(int)
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
+ throw A(); // match, noexcept(false)
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
+ throw B(); // ok
+ throw C(); // match, C has a member variable that makes it throwing on copy
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
+ throw D(); // match, has throwing copy constructor
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
+ throw E(); // match, has throwing copy constructor
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
+ throw Allocates(); // match, copy constructor throws
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
+ throw OptionallyAllocates(); // ok
+}
+
+namespace PR25574 {
+struct B {
+ B(const B&) noexcept;
+};
+
+struct D : B {
+ D();
+ virtual ~D() noexcept;
+};
+
+template <typename T>
+void f() {
+ throw D();
+}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-uppercase-literal-suffix-integer.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-uppercase-literal-suffix-integer.cpp
new file mode 100644
index 0000000..c19aacd
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-uppercase-literal-suffix-integer.cpp
@@ -0,0 +1,159 @@
+// RUN: %check_clang_tidy %s cert-dcl16-c %t -- -- -I %S
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
+// RUN: clang-tidy %t.cpp -checks='-*,cert-dcl16-c' -fix -- -I %S
+// RUN: clang-tidy %t.cpp -checks='-*,cert-dcl16-c' -warnings-as-errors='-*,cert-dcl16-c' -- -I %S
+
+#include "readability-uppercase-literal-suffix.h"
+
+void integer_suffix() {
+ static constexpr auto v0 = __LINE__; // synthetic
+ static_assert(v0 == 9 || v0 == 5, "");
+
+ static constexpr auto v1 = __cplusplus; // synthetic, long
+
+ static constexpr auto v2 = 1; // no literal
+ static_assert(is_same<decltype(v2), const int>::value, "");
+ static_assert(v2 == 1, "");
+
+ // Unsigned
+
+ static constexpr auto v3 = 1u;
+ static_assert(is_same<decltype(v3), const unsigned int>::value, "");
+ static_assert(v3 == 1, "");
+
+ static constexpr auto v4 = 1U; // OK.
+ static_assert(is_same<decltype(v4), const unsigned int>::value, "");
+ static_assert(v4 == 1, "");
+
+ // Long
+
+ static constexpr auto v5 = 1l;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'l', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v5 = 1l;
+ // CHECK-MESSAGES-NEXT: ^~
+ // CHECK-MESSAGES-NEXT: {{^ *}}L{{$}}
+ // CHECK-FIXES: static constexpr auto v5 = 1L;
+ static_assert(is_same<decltype(v5), const long>::value, "");
+ static_assert(v5 == 1, "");
+
+ static constexpr auto v6 = 1L; // OK.
+ static_assert(is_same<decltype(v6), const long>::value, "");
+ static_assert(v6 == 1, "");
+
+ // Long Long
+
+ static constexpr auto v7 = 1ll;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'll', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v7 = 1ll;
+ // CHECK-MESSAGES-NEXT: ^~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}LL{{$}}
+ // CHECK-FIXES: static constexpr auto v7 = 1LL;
+ static_assert(is_same<decltype(v7), const long long>::value, "");
+ static_assert(v7 == 1, "");
+
+ static constexpr auto v8 = 1LL; // OK.
+ static_assert(is_same<decltype(v8), const long long>::value, "");
+ static_assert(v8 == 1, "");
+
+ // Unsigned Long
+
+ static constexpr auto v9 = 1ul;
+ static_assert(is_same<decltype(v9), const unsigned long>::value, "");
+ static_assert(v9 == 1, "");
+
+ static constexpr auto v10 = 1uL;
+ static_assert(is_same<decltype(v10), const unsigned long>::value, "");
+ static_assert(v10 == 1, "");
+
+ static constexpr auto v11 = 1Ul;
+ static_assert(is_same<decltype(v11), const unsigned long>::value, "");
+ static_assert(v11 == 1, "");
+
+ static constexpr auto v12 = 1UL; // OK.
+ static_assert(is_same<decltype(v12), const unsigned long>::value, "");
+ static_assert(v12 == 1, "");
+
+ // Long Unsigned
+
+ static constexpr auto v13 = 1lu;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'lu', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v13 = 1lu;
+ // CHECK-MESSAGES-NEXT: ^~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}}
+ // CHECK-FIXES: static constexpr auto v13 = 1LU;
+ static_assert(is_same<decltype(v13), const unsigned long>::value, "");
+ static_assert(v13 == 1, "");
+
+ static constexpr auto v14 = 1Lu;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'Lu', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v14 = 1Lu;
+ // CHECK-MESSAGES-NEXT: ^~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}}
+ // CHECK-FIXES: static constexpr auto v14 = 1LU;
+ static_assert(is_same<decltype(v14), const unsigned long>::value, "");
+ static_assert(v14 == 1, "");
+
+ static constexpr auto v15 = 1lU;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'lU', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v15 = 1lU;
+ // CHECK-MESSAGES-NEXT: ^~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}}
+ // CHECK-FIXES: static constexpr auto v15 = 1LU;
+ static_assert(is_same<decltype(v15), const unsigned long>::value, "");
+ static_assert(v15 == 1, "");
+
+ static constexpr auto v16 = 1LU; // OK.
+ static_assert(is_same<decltype(v16), const unsigned long>::value, "");
+ static_assert(v16 == 1, "");
+
+ // Unsigned Long Long
+
+ static constexpr auto v17 = 1ull;
+ static_assert(is_same<decltype(v17), const unsigned long long>::value, "");
+ static_assert(v17 == 1, "");
+
+ static constexpr auto v18 = 1uLL;
+ static_assert(is_same<decltype(v18), const unsigned long long>::value, "");
+ static_assert(v18 == 1, "");
+
+ static constexpr auto v19 = 1Ull;
+ static_assert(is_same<decltype(v19), const unsigned long long>::value, "");
+ static_assert(v19 == 1, "");
+
+ static constexpr auto v20 = 1ULL; // OK.
+ static_assert(is_same<decltype(v20), const unsigned long long>::value, "");
+ static_assert(v20 == 1, "");
+
+ // Long Long Unsigned
+
+ static constexpr auto v21 = 1llu;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'llu', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v21 = 1llu;
+ // CHECK-MESSAGES-NEXT: ^~~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}LLU{{$}}
+ // CHECK-FIXES: static constexpr auto v21 = 1LLU;
+ static_assert(is_same<decltype(v21), const unsigned long long>::value, "");
+ static_assert(v21 == 1, "");
+
+ static constexpr auto v22 = 1LLu;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'LLu', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v22 = 1LLu;
+ // CHECK-MESSAGES-NEXT: ^~~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}LLU{{$}}
+ // CHECK-FIXES: static constexpr auto v22 = 1LLU;
+ static_assert(is_same<decltype(v22), const unsigned long long>::value, "");
+ static_assert(v22 == 1, "");
+
+ static constexpr auto v23 = 1llU;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'llU', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v23 = 1llU;
+ // CHECK-MESSAGES-NEXT: ^~~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}LLU{{$}}
+ // CHECK-FIXES: static constexpr auto v23 = 1LLU;
+ static_assert(is_same<decltype(v23), const unsigned long long>::value, "");
+ static_assert(v23 == 1, "");
+
+ static constexpr auto v24 = 1LLU; // OK.
+ static_assert(is_same<decltype(v24), const unsigned long long>::value, "");
+ static_assert(v24 == 1, "");
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-variadic-function-def.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-variadic-function-def.cpp
new file mode 100644
index 0000000..6b2421b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cert-variadic-function-def.cpp
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s cert-dcl50-cpp %t
+
+// Variadic function definitions are diagnosed.
+void f1(int, ...) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: do not define a C-style variadic function; consider using a function parameter pack or currying instead [cert-dcl50-cpp]
+
+// Variadic function *declarations* are not diagnosed.
+void f2(int, ...); // ok
+
+// Function parameter packs are good, however.
+template <typename Arg, typename... Ts>
+void f3(Arg F, Ts... Rest) {}
+
+struct S {
+ void f(int, ...); // ok
+ void f1(int, ...) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: do not define a C-style variadic function; consider using a function parameter pack or currying instead
+};
+
+// Function definitions that are extern "C" are good.
+extern "C" void f4(int, ...) {} // ok
+extern "C" {
+ void f5(int, ...) {} // ok
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/check_clang_tidy.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/check_clang_tidy.cpp
new file mode 100644
index 0000000..0e4c45d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/check_clang_tidy.cpp
@@ -0,0 +1,32 @@
+// RUN: %check_clang_tidy -check-suffix=USING-A %s misc-unused-using-decls %t -- -- -DUSING_A
+// RUN: %check_clang_tidy -check-suffix=USING-B %s misc-unused-using-decls %t -- -- -DUSING_B
+// RUN: %check_clang_tidy -check-suffix=USING-C,USING-D %s misc-unused-using-decls %t -- -- -DUSING_C_D
+// RUN: %check_clang_tidy -check-suffixes=USING-C,USING-D %s misc-unused-using-decls %t -- -- -DUSING_C_D
+// RUN: %check_clang_tidy %s misc-unused-using-decls %t
+
+namespace a {class A {}; class B {}; class C {}; class D {}; class E {};}
+namespace b {
+#if defined(USING_A)
+using a::A;
+#elif defined(USING_B)
+using a::B;
+#elif defined(USING_C_D)
+using a::C;
+using a::D;
+#else
+using a::E;
+#endif
+}
+namespace c {}
+// CHECK-MESSAGES-USING-A: warning: using decl 'A' {{.*}}
+// CHECK-MESSAGES-USING-B: warning: using decl 'B' {{.*}}
+// CHECK-MESSAGES-USING-C: warning: using decl 'C' {{.*}}
+// CHECK-MESSAGES-USING-D: warning: using decl 'D' {{.*}}
+// CHECK-MESSAGES: warning: using decl 'E' {{.*}}
+// CHECK-FIXES-USING-A-NOT: using a::A;$
+// CHECK-FIXES-USING-B-NOT: using a::B;$
+// CHECK-FIXES-USING-C-NOT: using a::C;$
+// CHECK-FIXES-USING-C-NOT: using a::D;$
+// CHECK-FIXES-USING-D-NOT: using a::C;$
+// CHECK-FIXES-USING-D-NOT: using a::D;$
+// CHECK-FIXES-NOT: using a::E;$
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/check_clang_tidy.py b/src/llvm-project/clang-tools-extra/test/clang-tidy/check_clang_tidy.py
new file mode 100755
index 0000000..9768011
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/check_clang_tidy.py
@@ -0,0 +1,208 @@
+#!/usr/bin/env python
+#
+#===- check_clang_tidy.py - ClangTidy Test Helper ------------*- python -*--===#
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+r"""
+ClangTidy Test Helper
+=====================
+
+This script runs clang-tidy in fix mode and verify fixes, messages or both.
+
+Usage:
+ check_clang_tidy.py [-resource-dir=<resource-dir>] \
+ [-assume-filename=<file-with-source-extension>] \
+ [-check-suffix=<comma-separated-file-check-suffixes>] \
+ [-check-suffixes=<comma-separated-file-check-suffixes>] \
+ <source-file> <check-name> <temp-file> \
+ -- [optional clang-tidy arguments]
+
+Example:
+ // RUN: %check_clang_tidy %s llvm-include-order %t -- -- -isystem %S/Inputs
+"""
+
+import argparse
+import os
+import re
+import subprocess
+import sys
+
+
+def write_file(file_name, text):
+ with open(file_name, 'w') as f:
+ f.write(text)
+ f.truncate()
+
+def csv(string):
+ return string.split(',')
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-expect-clang-tidy-error', action='store_true')
+ parser.add_argument('-resource-dir')
+ parser.add_argument('-assume-filename')
+ parser.add_argument('input_file_name')
+ parser.add_argument('check_name')
+ parser.add_argument('temp_file_name')
+ parser.add_argument('-check-suffix', '-check-suffixes',
+ default=[''], type=csv,
+ help="comma-separated list of FileCheck suffixes")
+
+ args, extra_args = parser.parse_known_args()
+
+ resource_dir = args.resource_dir
+ assume_file_name = args.assume_filename
+ input_file_name = args.input_file_name
+ check_name = args.check_name
+ temp_file_name = args.temp_file_name
+ expect_clang_tidy_error = args.expect_clang_tidy_error
+
+ file_name_with_extension = assume_file_name or input_file_name
+ _, extension = os.path.splitext(file_name_with_extension)
+ if extension not in ['.c', '.hpp', '.m', '.mm']:
+ extension = '.cpp'
+ temp_file_name = temp_file_name + extension
+
+ clang_tidy_extra_args = extra_args
+ if len(clang_tidy_extra_args) == 0:
+ clang_tidy_extra_args = ['--']
+ if extension in ['.cpp', '.hpp', '.mm']:
+ clang_tidy_extra_args.append('--std=c++11')
+ if extension in ['.m', '.mm']:
+ clang_tidy_extra_args.extend(
+ ['-fobjc-abi-version=2', '-fobjc-arc'])
+
+ # Tests should not rely on STL being available, and instead provide mock
+ # implementations of relevant APIs.
+ clang_tidy_extra_args.append('-nostdinc++')
+
+ if resource_dir is not None:
+ clang_tidy_extra_args.append('-resource-dir=%s' % resource_dir)
+
+ with open(input_file_name, 'r') as input_file:
+ input_text = input_file.read()
+
+ check_fixes_prefixes = []
+ check_messages_prefixes = []
+ check_notes_prefixes = []
+
+ has_check_fixes = False
+ has_check_messages = False
+ has_check_notes = False
+
+ for check in args.check_suffix:
+ if check and not re.match('^[A-Z0-9\-]+$', check):
+ sys.exit('Only A..Z, 0..9 and "-" are ' +
+ 'allowed in check suffixes list, but "%s" was given' % (check))
+
+ file_check_suffix = ('-' + check) if check else ''
+ check_fixes_prefix = 'CHECK-FIXES' + file_check_suffix
+ check_messages_prefix = 'CHECK-MESSAGES' + file_check_suffix
+ check_notes_prefix = 'CHECK-NOTES' + file_check_suffix
+
+ has_check_fix = check_fixes_prefix in input_text
+ has_check_message = check_messages_prefix in input_text
+ has_check_note = check_notes_prefix in input_text
+
+ if has_check_note and has_check_message:
+ sys.exit('Please use either %s or %s but not both' %
+ (check_notes_prefix, check_messages_prefix))
+
+ if not has_check_fix and not has_check_message and not has_check_note:
+ sys.exit('%s, %s or %s not found in the input' %
+ (check_fixes_prefix, check_messages_prefix, check_notes_prefix))
+
+ has_check_fixes = has_check_fixes or has_check_fix
+ has_check_messages = has_check_messages or has_check_message
+ has_check_notes = has_check_notes or has_check_note
+
+ check_fixes_prefixes.append(check_fixes_prefix)
+ check_messages_prefixes.append(check_messages_prefix)
+ check_notes_prefixes.append(check_notes_prefix)
+
+ assert has_check_fixes or has_check_messages or has_check_notes
+ # Remove the contents of the CHECK lines to avoid CHECKs matching on
+ # themselves. We need to keep the comments to preserve line numbers while
+ # avoiding empty lines which could potentially trigger formatting-related
+ # checks.
+ cleaned_test = re.sub('// *CHECK-[A-Z0-9\-]*:[^\r\n]*', '//', input_text)
+
+ write_file(temp_file_name, cleaned_test)
+
+ original_file_name = temp_file_name + ".orig"
+ write_file(original_file_name, cleaned_test)
+
+ args = ['clang-tidy', temp_file_name, '-fix', '--checks=-*,' + check_name] + \
+ clang_tidy_extra_args
+ if expect_clang_tidy_error:
+ args.insert(0, 'not')
+ print('Running ' + repr(args) + '...')
+ try:
+ clang_tidy_output = \
+ subprocess.check_output(args, stderr=subprocess.STDOUT).decode()
+ except subprocess.CalledProcessError as e:
+ print('clang-tidy failed:\n' + e.output.decode())
+ raise
+
+ print('------------------------ clang-tidy output -----------------------\n' +
+ clang_tidy_output +
+ '\n------------------------------------------------------------------')
+
+ try:
+ diff_output = subprocess.check_output(
+ ['diff', '-u', original_file_name, temp_file_name],
+ stderr=subprocess.STDOUT)
+ except subprocess.CalledProcessError as e:
+ diff_output = e.output
+
+ print('------------------------------ Fixes -----------------------------\n' +
+ diff_output.decode() +
+ '\n------------------------------------------------------------------')
+
+ if has_check_fixes:
+ try:
+ subprocess.check_output(
+ ['FileCheck', '-input-file=' + temp_file_name, input_file_name,
+ '-check-prefixes=' + ','.join(check_fixes_prefixes),
+ '-strict-whitespace'],
+ stderr=subprocess.STDOUT)
+ except subprocess.CalledProcessError as e:
+ print('FileCheck failed:\n' + e.output.decode())
+ raise
+
+ if has_check_messages:
+ messages_file = temp_file_name + '.msg'
+ write_file(messages_file, clang_tidy_output)
+ try:
+ subprocess.check_output(
+ ['FileCheck', '-input-file=' + messages_file, input_file_name,
+ '-check-prefixes=' + ','.join(check_messages_prefixes),
+ '-implicit-check-not={{warning|error}}:'],
+ stderr=subprocess.STDOUT)
+ except subprocess.CalledProcessError as e:
+ print('FileCheck failed:\n' + e.output.decode())
+ raise
+
+ if has_check_notes:
+ notes_file = temp_file_name + '.notes'
+ filtered_output = [line for line in clang_tidy_output.splitlines()
+ if not "note: FIX-IT applied" in line]
+ write_file(notes_file, '\n'.join(filtered_output))
+ try:
+ subprocess.check_output(
+ ['FileCheck', '-input-file=' + notes_file, input_file_name,
+ '-check-prefixes=' + ','.join(check_notes_prefixes),
+ '-implicit-check-not={{note|warning|error}}:'],
+ stderr=subprocess.STDOUT)
+ except subprocess.CalledProcessError as e:
+ print('FileCheck failed:\n' + e.output.decode())
+ raise
+
+if __name__ == '__main__':
+ main()
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-__clang_analyzer__macro.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-__clang_analyzer__macro.cpp
new file mode 100644
index 0000000..0fda1a3
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-__clang_analyzer__macro.cpp
@@ -0,0 +1,5 @@
+// RUN: clang-tidy %s -checks=-*,modernize-use-nullptr -- | count 0
+
+#if !defined(__clang_analyzer__)
+#error __clang_analyzer__ is not defined
+#endif
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-diff.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-diff.cpp
new file mode 100644
index 0000000..146287b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-diff.cpp
@@ -0,0 +1,27 @@
+// REQUIRES: shell
+// RUN: sed 's/placeholder_for_f/f/' %s > %t.cpp
+// RUN: clang-tidy -checks=-*,modernize-use-override %t.cpp -- -std=c++11 | FileCheck -check-prefix=CHECK-SANITY %s
+// RUN: not diff -U0 %s %t.cpp | %clang_tidy_diff -checks=-*,modernize-use-override -- -std=c++11 2>&1 | FileCheck %s
+// RUN: not diff -U0 %s %t.cpp | %clang_tidy_diff -checks=-*,modernize-use-override -quiet -- -std=c++11 2>&1 | FileCheck -check-prefix=CHECK-QUIET %s
+// RUN: mkdir -p %T/compilation-database-test/
+// RUN: echo '[{"directory": "%T", "command": "clang++ -o test.o -std=c++11 %t.cpp", "file": "%t.cpp"}]' > %T/compilation-database-test/compile_commands.json
+// RUN: not diff -U0 %s %t.cpp | %clang_tidy_diff -checks=-*,modernize-use-override -path %T/compilation-database-test 2>&1 | FileCheck -check-prefix=CHECK %s
+struct A {
+ virtual void f() {}
+ virtual void g() {}
+};
+// CHECK-NOT: warning:
+// CHECK-QUIET-NOT: warning:
+struct B : public A {
+ void placeholder_for_f() {}
+// CHECK-SANITY: [[@LINE-1]]:8: warning: annotate this
+// CHECK: [[@LINE-2]]:8: warning: annotate this
+// CHECK-QUIET: [[@LINE-3]]:8: warning: annotate this
+ void g() {}
+// CHECK-SANITY: [[@LINE-1]]:8: warning: annotate this
+// CHECK-NOT: warning:
+// CHECK-QUIET-NOT: warning:
+};
+// CHECK-SANITY-NOT: Suppressed
+// CHECK: Suppressed 1 warnings (1 due to line filter).
+// CHECK-QUIET-NOT: Suppressed
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-enable-check-profile-one-tu.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-enable-check-profile-one-tu.cpp
new file mode 100644
index 0000000..df4cb93
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-enable-check-profile-one-tu.cpp
@@ -0,0 +1,24 @@
+// RUN: clang-tidy -enable-check-profile -checks='-*,readability-function-size' %s -- 2>&1 | FileCheck --match-full-lines -implicit-check-not='{{warning:|error:}}' %s
+
+// CHECK: ===-------------------------------------------------------------------------===
+// CHECK-NEXT: clang-tidy checks profiling
+// CHECK-NEXT: ===-------------------------------------------------------------------------===
+// CHECK-NEXT: Total Execution Time: {{.*}} seconds ({{.*}} wall clock)
+
+// CHECK: {{.*}} --- Name ---
+// CHECK-NEXT: {{.*}} readability-function-size
+// CHECK-NEXT: {{.*}} Total
+
+// CHECK-NOT: ===-------------------------------------------------------------------------===
+// CHECK-NOT: clang-tidy checks profiling
+// CHECK-NOT: ===-------------------------------------------------------------------------===
+// CHECK-NOT: Total Execution Time: {{.*}} seconds ({{.*}} wall clock)
+
+// CHECK-NOT: {{.*}} --- Name ---
+// CHECK-NOT: {{.*}} readability-function-size
+// CHECK-NOT: {{.*}} Total
+
+class A {
+ A() {}
+ ~A() {}
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-enable-check-profile-two-tu.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-enable-check-profile-two-tu.cpp
new file mode 100644
index 0000000..30603a2
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-enable-check-profile-two-tu.cpp
@@ -0,0 +1,33 @@
+// RUN: clang-tidy -enable-check-profile -checks='-*,readability-function-size' %s %s -- 2>&1 | FileCheck --match-full-lines -implicit-check-not='{{warning:|error:}}' %s
+
+// CHECK: ===-------------------------------------------------------------------------===
+// CHECK-NEXT: clang-tidy checks profiling
+// CHECK-NEXT: ===-------------------------------------------------------------------------===
+// CHECK-NEXT: Total Execution Time: {{.*}} seconds ({{.*}} wall clock)
+
+// CHECK: {{.*}} --- Name ---
+// CHECK-NEXT: {{.*}} readability-function-size
+// CHECK-NEXT: {{.*}} Total
+
+// CHECK: ===-------------------------------------------------------------------------===
+// CHECK-NEXT: clang-tidy checks profiling
+// CHECK-NEXT: ===-------------------------------------------------------------------------===
+// CHECK-NEXT: Total Execution Time: {{.*}} seconds ({{.*}} wall clock)
+
+// CHECK: {{.*}} --- Name ---
+// CHECK-NEXT: {{.*}} readability-function-size
+// CHECK-NEXT: {{.*}} Total
+
+// CHECK-NOT: ===-------------------------------------------------------------------------===
+// CHECK-NOT: clang-tidy checks profiling
+// CHECK-NOT: ===-------------------------------------------------------------------------===
+// CHECK-NOT: Total Execution Time: {{.*}} seconds ({{.*}} wall clock)
+
+// CHECK-NOT: {{.*}} --- Name ---
+// CHECK-NOT: {{.*}} readability-function-size
+// CHECK-NOT: {{.*}} Total
+
+class A {
+ A() {}
+ ~A() {}
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-mac-libcxx.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-mac-libcxx.cpp
new file mode 100644
index 0000000..153a5d6
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-mac-libcxx.cpp
@@ -0,0 +1,17 @@
+// Clang on MacOS can find libc++ living beside the installed compiler.
+// This test makes sure clang-tidy emulates this properly.
+//
+// RUN: rm -rf %t
+// RUN: mkdir %t
+//
+// Install the mock libc++ (simulates the libc++ directory structure).
+// RUN: cp -r %S/Inputs/mock-libcxx %t/
+//
+// Pretend clang is installed beside the mock library that we provided.
+// RUN: echo '[{"directory":"%t","command":"%t/mock-libcxx/bin/clang++ -stdlib=libc++ -target x86_64-apple-darwin -c test.cpp","file":"test.cpp"}]' | sed -e 's/\\/\//g' > %t/compile_commands.json
+// RUN: cp "%s" "%t/test.cpp"
+// RUN: clang-tidy -header-filter='.*' -system-headers -checks='-*,modernize-use-using' "%t/test.cpp" | FileCheck %s
+// CHECK: mock_vector:{{[0-9]+}}:{{[0-9]+}}: warning: use 'using' instead of 'typedef'
+
+#include <mock_vector>
+typedef vector* vec_ptr;
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-run-with-database.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-run-with-database.cpp
new file mode 100644
index 0000000..f8c05a3
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-run-with-database.cpp
@@ -0,0 +1,29 @@
+// RUN: mkdir -p %T/compilation-database-test/include
+// RUN: mkdir -p %T/compilation-database-test/a
+// RUN: mkdir -p %T/compilation-database-test/b
+// RUN: echo 'int *AA = 0;' > %T/compilation-database-test/a/a.cpp
+// RUN: echo 'int *AB = 0;' > %T/compilation-database-test/a/b.cpp
+// RUN: echo 'int *BB = 0;' > %T/compilation-database-test/b/b.cpp
+// RUN: echo 'int *BC = 0;' > %T/compilation-database-test/b/c.cpp
+// RUN: echo 'int *HP = 0;' > %T/compilation-database-test/include/header.h
+// RUN: echo '#include "header.h"' > %T/compilation-database-test/b/d.cpp
+// RUN: sed 's|test_dir|%/T/compilation-database-test|g' %S/Inputs/compilation-database/template.json > %T/compile_commands.json
+
+// Regression test: shouldn't crash.
+// RUN: not clang-tidy --checks=-*,modernize-use-nullptr -p %T %T/compilation-database-test/b/not-exist -header-filter=.* 2>&1 | FileCheck %s -check-prefix=CHECK-NOT-EXIST
+// CHECK-NOT-EXIST: Error while processing {{.*[/\\]}}not-exist.
+// CHECK-NOT-EXIST: unable to handle compilation
+// CHECK-NOT-EXIST: Found compiler error
+
+// RUN: clang-tidy --checks=-*,modernize-use-nullptr -p %T %T/compilation-database-test/a/a.cpp %T/compilation-database-test/a/b.cpp %T/compilation-database-test/b/b.cpp %T/compilation-database-test/b/c.cpp %T/compilation-database-test/b/d.cpp -header-filter=.* -fix
+// RUN: FileCheck -input-file=%T/compilation-database-test/a/a.cpp %s -check-prefix=CHECK-FIX1
+// RUN: FileCheck -input-file=%T/compilation-database-test/a/b.cpp %s -check-prefix=CHECK-FIX2
+// RUN: FileCheck -input-file=%T/compilation-database-test/b/b.cpp %s -check-prefix=CHECK-FIX3
+// RUN: FileCheck -input-file=%T/compilation-database-test/b/c.cpp %s -check-prefix=CHECK-FIX4
+// RUN: FileCheck -input-file=%T/compilation-database-test/include/header.h %s -check-prefix=CHECK-FIX5
+
+// CHECK-FIX1: int *AA = nullptr;
+// CHECK-FIX2: int *AB = nullptr;
+// CHECK-FIX3: int *BB = nullptr;
+// CHECK-FIX4: int *BC = nullptr;
+// CHECK-FIX5: int *HP = nullptr;
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-store-check-profile-one-tu.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-store-check-profile-one-tu.cpp
new file mode 100644
index 0000000..832723b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/clang-tidy-store-check-profile-one-tu.cpp
@@ -0,0 +1,37 @@
+// RUN: rm -rf %T/out
+// RUN: clang-tidy -enable-check-profile -checks='-*,readability-function-size' -store-check-profile=%T/out %s -- 2>&1 | not FileCheck --match-full-lines -implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK-CONSOLE %s
+// RUN: cat %T/out/*-clang-tidy-store-check-profile-one-tu.cpp.json | FileCheck --match-full-lines -implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK-FILE %s
+// RUN: rm -rf %T/out
+// RUN: clang-tidy -enable-check-profile -checks='-*,readability-function-size' -store-check-profile=%T/out %s -- 2>&1
+// RUN: cat %T/out/*-clang-tidy-store-check-profile-one-tu.cpp.json | FileCheck --match-full-lines -implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK-FILE %s
+
+// CHECK-CONSOLE-NOT: ===-------------------------------------------------------------------------===
+// CHECK-CONSOLE-NOT: {{.*}} --- Name ---
+// CHECK-CONSOLE-NOT: {{.*}} readability-function-size
+// CHECK-CONSOLE-NOT: {{.*}} Total
+// CHECK-CONSOLE-NOT: ===-------------------------------------------------------------------------===
+
+// CHECK-FILE: {
+// CHECK-FILE-NEXT:"file": "{{.*}}clang-tidy-store-check-profile-one-tu.cpp",
+// CHECK-FILE-NEXT:"timestamp": "{{[0-9]+}}-{{[0-9]+}}-{{[0-9]+}} {{[0-9]+}}:{{[0-9]+}}:{{[0-9]+}}.{{[0-9]+}}",
+// CHECK-FILE-NEXT:"profile": {
+// CHECK-FILE-NEXT: "time.clang-tidy.readability-function-size.wall": {{.*}}{{[0-9]}}.{{[0-9]+}}e{{[-+]}}{{[0-9]}}{{[0-9]}},
+// CHECK-FILE-NEXT: "time.clang-tidy.readability-function-size.user": {{.*}}{{[0-9]}}.{{[0-9]+}}e{{[-+]}}{{[0-9]}}{{[0-9]}},
+// CHECK-FILE-NEXT: "time.clang-tidy.readability-function-size.sys": {{.*}}{{[0-9]}}.{{[0-9]+}}e{{[-+]}}{{[0-9]}}{{[0-9]}}
+// CHECK-FILE-NEXT: }
+// CHECK-FILE-NEXT: }
+
+// CHECK-FILE-NOT: {
+// CHECK-FILE-NOT: "file": {{.*}}clang-tidy-store-check-profile-one-tu.cpp{{.*}},
+// CHECK-FILE-NOT: "timestamp": "{{[0-9]+}}-{{[0-9]+}}-{{[0-9]+}} {{[0-9]+}}:{{[0-9]+}}:{{[0-9]+}}.{{[0-9]+}}",
+// CHECK-FILE-NOT: "profile": {
+// CHECK-FILE-NOT: "time.clang-tidy.readability-function-size.wall": {{.*}}{{[0-9]}}.{{[0-9]+}}e{{[-+]}}{{[0-9]}}{{[0-9]}},
+// CHECK-FILE-NOT: "time.clang-tidy.readability-function-size.user": {{.*}}{{[0-9]}}.{{[0-9]+}}e{{[-+]}}{{[0-9]}}{{[0-9]}},
+// CHECK-FILE-NOT: "time.clang-tidy.readability-function-size.sys": {{.*}}{{[0-9]}}.{{[0-9]+}}e{{[-+]}}{{[0-9]}}{{[0-9]}}
+// CHECK-FILE-NOT: }
+// CHECK-FILE-NOT: }
+
+class A {
+ A() {}
+ ~A() {}
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/clean-up-code.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/clean-up-code.cpp
new file mode 100644
index 0000000..15873ed
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/clean-up-code.cpp
@@ -0,0 +1,14 @@
+// RUN: %check_clang_tidy %s misc-unused-using-decls %t
+// RUN: %check_clang_tidy %s misc-unused-using-decls %t -- -format-style=none --
+// RUN: %check_clang_tidy %s misc-unused-using-decls %t -- -format-style=llvm --
+namespace a { class A {}; }
+namespace b {
+using a::A;
+}
+namespace c {}
+// CHECK-MESSAGES: :[[@LINE-3]]:10: warning: using decl 'A' is unused [misc-unused-using-decls]
+// CHECK-FIXES: {{^namespace a { class A {}; }$}}
+// CHECK-FIXES-NOT: namespace
+// CHECK-FIXES: {{^namespace c {}$}}
+// FIXME: cleanupAroundReplacements leaves whitespace. Otherwise we could just
+// check the next line.
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/config-files.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/config-files.cpp
new file mode 100644
index 0000000..65ac54a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/config-files.cpp
@@ -0,0 +1,12 @@
+// RUN: clang-tidy -dump-config %S/Inputs/config-files/- -- | FileCheck %s -check-prefix=CHECK-BASE
+// CHECK-BASE: Checks: {{.*}}from-parent
+// CHECK-BASE: HeaderFilterRegex: parent
+// RUN: clang-tidy -dump-config %S/Inputs/config-files/1/- -- | FileCheck %s -check-prefix=CHECK-CHILD1
+// CHECK-CHILD1: Checks: {{.*}}from-child1
+// CHECK-CHILD1: HeaderFilterRegex: child1
+// RUN: clang-tidy -dump-config %S/Inputs/config-files/2/- -- | FileCheck %s -check-prefix=CHECK-CHILD2
+// CHECK-CHILD2: Checks: {{.*}}from-parent
+// CHECK-CHILD2: HeaderFilterRegex: parent
+// RUN: clang-tidy -dump-config -checks='from-command-line' -header-filter='from command line' %S/Inputs/config-files/- -- | FileCheck %s -check-prefix=CHECK-COMMAND-LINE
+// CHECK-COMMAND-LINE: Checks: {{.*}}from-parent,from-command-line
+// CHECK-COMMAND-LINE: HeaderFilterRegex: from command line
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-avoid-goto.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-avoid-goto.cpp
new file mode 100644
index 0000000..ee236bc
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-avoid-goto.cpp
@@ -0,0 +1,139 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-avoid-goto %t
+
+void noop() {}
+
+int main() {
+ noop();
+ goto jump_to_me;
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control
+ // CHECK-NOTES: [[@LINE+3]]:1: note: label defined here
+ noop();
+
+jump_to_me:;
+
+jump_backwards:;
+ noop();
+ goto jump_backwards;
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control
+ // CHECK-NOTES: [[@LINE-4]]:1: note: label defined here
+
+ goto jump_in_line;
+ ;
+jump_in_line:;
+ // CHECK-NOTES: [[@LINE-3]]:3: warning: avoid using 'goto' for flow control
+ // CHECK-NOTES: [[@LINE-2]]:1: note: label defined here
+
+ // Test the GNU extension https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
+some_label:;
+ void *dynamic_label = &&some_label;
+
+ // FIXME: `IndirectGotoStmt` is not detected.
+ goto *dynamic_label;
+}
+
+void forward_jump_out_nested_loop() {
+ int array[] = {1, 2, 3, 4, 5};
+ for (int i = 0; i < 10; ++i) {
+ noop();
+ for (int j = 0; j < 10; ++j) {
+ noop();
+ if (i + j > 10)
+ goto early_exit1;
+ }
+ noop();
+ }
+
+ for (int i = 0; i < 10; ++i) {
+ noop();
+ while (true) {
+ noop();
+ if (i > 5)
+ goto early_exit1;
+ }
+ noop();
+ }
+
+ for (auto value : array) {
+ noop();
+ for (auto number : array) {
+ noop();
+ if (number == 5)
+ goto early_exit1;
+ }
+ }
+
+ do {
+ noop();
+ do {
+ noop();
+ goto early_exit1;
+ } while (true);
+ } while (true);
+
+ do {
+ for (auto number : array) {
+ noop();
+ if (number == 2)
+ goto early_exit1;
+ }
+ } while (true);
+
+ // Jumping further results in error, because the variable declaration would
+ // be skipped.
+early_exit1:;
+
+ int i = 0;
+ while (true) {
+ noop();
+ while (true) {
+ noop();
+ if (i > 5)
+ goto early_exit2;
+ i++;
+ }
+ noop();
+ }
+
+ while (true) {
+ noop();
+ for (int j = 0; j < 10; ++j) {
+ noop();
+ if (j > 5)
+ goto early_exit2;
+ }
+ noop();
+ }
+
+ while (true) {
+ noop();
+ for (auto number : array) {
+ if (number == 1)
+ goto early_exit2;
+ noop();
+ }
+ }
+
+ while (true) {
+ noop();
+ do {
+ noop();
+ goto early_exit2;
+ } while (true);
+ }
+early_exit2:;
+}
+
+void jump_out_backwards() {
+
+before_the_loop:
+ noop();
+
+ for (int i = 0; i < 10; ++i) {
+ for (int j = 0; j < 10; ++j) {
+ if (i * j > 80)
+ goto before_the_loop;
+ // CHECK-NOTES: [[@LINE-1]]:9: warning: avoid using 'goto' for flow control
+ // CHECK-NOTES: [[@LINE-8]]:1: note: label defined here
+ }
+ }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-interfaces-global-init.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-interfaces-global-init.cpp
new file mode 100644
index 0000000..51f79e5
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-interfaces-global-init.cpp
@@ -0,0 +1,84 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-interfaces-global-init %t
+
+constexpr int makesInt() { return 3; }
+constexpr int takesInt(int i) { return i + 1; }
+constexpr int takesIntPtr(int *i) { return *i; }
+
+extern int ExternGlobal;
+static int GlobalScopeBadInit1 = ExternGlobal;
+// CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ExternGlobal'
+static int GlobalScopeBadInit2 = takesInt(ExternGlobal);
+// CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ExternGlobal'
+static int GlobalScopeBadInit3 = takesIntPtr(&ExternGlobal);
+// CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ExternGlobal'
+static int GlobalScopeBadInit4 = 3 * (ExternGlobal + 2);
+// CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ExternGlobal'
+
+namespace ns {
+static int NamespaceScope = makesInt();
+static int NamespaceScopeBadInit = takesInt(ExternGlobal);
+// CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ExternGlobal'
+
+struct A {
+ static int ClassScope;
+ static int ClassScopeBadInit;
+};
+
+int A::ClassScopeBadInit = takesInt(ExternGlobal);
+// CHECK-MESSAGES: [[@LINE-1]]:8: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ExternGlobal'
+
+static int FromClassBadInit = takesInt(A::ClassScope);
+// CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ClassScope'
+} // namespace ns
+
+// "const int B::I;" is fine, it just ODR-defines B::I. See [9.4.3] Static
+// members [class.static]. However the ODR-definitions are not in the right
+// order (C::I after C::J, see [3.6.2.3]).
+class B1 {
+ static const int I = 0;
+ static const int J = I;
+};
+const int B1::J;
+// CHECK-MESSAGES: [[@LINE-1]]:15: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'I'
+const int B1::I;
+
+void f() {
+ // This is fine, it's executed after dynamic initialization occurs.
+ static int G = takesInt(ExternGlobal);
+}
+
+// Declaration then definition then usage is fine.
+extern int ExternGlobal2;
+extern int ExternGlobal2;
+int ExternGlobal2 = 123;
+static int GlobalScopeGoodInit1 = ExternGlobal2;
+
+
+// Defined global variables are fine:
+static int GlobalScope = makesInt();
+static int GlobalScopeGoodInit2 = takesInt(GlobalScope);
+static int GlobalScope2 = takesInt(ns::NamespaceScope);
+// Enums are fine.
+enum Enum { kEnumValue = 1 };
+static int GlobalScopeFromEnum = takesInt(kEnumValue);
+
+// Leave constexprs alone.
+extern constexpr int GlobalScopeConstexpr = makesInt();
+static constexpr int GlobalScopeConstexprOk =
+ takesInt(GlobalScopeConstexpr);
+
+// This is a pretty common instance: People are usually not using constexpr, but
+// this is what they should write:
+static constexpr const char kValue[] = "value";
+constexpr int Fingerprint(const char *value) { return 0; }
+static int kFingerprint = Fingerprint(kValue);
+
+// This is fine because the ODR-definitions are in the right order (C::J after
+// C::I).
+class B2 {
+ static const int I = 0;
+ static const int J = I;
+};
+const int B2::I;
+const int B2::J;
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-macro-usage-caps-only.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-macro-usage-caps-only.cpp
new file mode 100644
index 0000000..a1d49bf
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-macro-usage-caps-only.cpp
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-macro-usage %t \
+// RUN: -config='{CheckOptions: \
+// RUN: [{key: cppcoreguidelines-macro-usage.CheckCapsOnly, value: 1}]}' --
+
+#ifndef INCLUDE_GUARD
+#define INCLUDE_GUARD
+
+#define problematic_constant 0
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro definition does not define the macro name 'problematic_constant' using all uppercase characters
+
+#define problematic_function(x, y) ((a) > (b) ? (a) : (b))
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro definition does not define the macro name 'problematic_function' using all uppercase characters
+
+#define problematic_variadic(...) (__VA_ARGS__)
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro definition does not define the macro name 'problematic_variadic' using all uppercase characters
+//
+#define problematic_variadic2(x, ...) (__VA_ARGS__)
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro definition does not define the macro name 'problematic_variadic2' using all uppercase characters
+
+#define OKISH_CONSTANT 42
+#define OKISH_FUNCTION(x, y) ((a) > (b) ? (a) : (b))
+#define OKISH_VARIADIC(...) (__VA_ARGS__)
+
+#endif
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-macro-usage-command-line-macros.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-macro-usage-command-line-macros.cpp
new file mode 100644
index 0000000..d4f9a0d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-macro-usage-command-line-macros.cpp
@@ -0,0 +1,8 @@
+// RUN: %check_clang_tidy -check-suffixes=NORMAL %s cppcoreguidelines-macro-usage %t -- -- -D_ZZZ_IM_A_MACRO
+// RUN: %check_clang_tidy -check-suffixes=NORMAL %s cppcoreguidelines-macro-usage %t -- -config='{CheckOptions: [{key: cppcoreguidelines-macro-usage.IgnoreCommandLineMacros, value: 1}]}' -- -D_ZZZ_IM_A_MACRO
+// RUN: %check_clang_tidy -check-suffixes=NORMAL,CL %s cppcoreguidelines-macro-usage %t -- -config='{CheckOptions: [{key: cppcoreguidelines-macro-usage.IgnoreCommandLineMacros, value: 0}]}' -- -D_ZZZ_IM_A_MACRO
+
+// CHECK-MESSAGES-CL: warning: macro '_ZZZ_IM_A_MACRO' used to declare a constant; consider using a 'constexpr' constant
+
+#define PROBLEMATIC_CONSTANT 0
+// CHECK-MESSAGES-NORMAL: [[@LINE-1]]:9: warning: macro 'PROBLEMATIC_CONSTANT' used to declare a constant; consider using a 'constexpr' constant
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-macro-usage-custom.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-macro-usage-custom.cpp
new file mode 100644
index 0000000..e25eae3
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-macro-usage-custom.cpp
@@ -0,0 +1,28 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-macro-usage %t \
+// RUN: -config='{CheckOptions: \
+// RUN: [{key: cppcoreguidelines-macro-usage.AllowedRegexp, value: "DEBUG_*|TEST_*"}]}' --
+
+#ifndef INCLUDE_GUARD
+#define INCLUDE_GUARD
+
+#define PROBLEMATIC_CONSTANT 0
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro 'PROBLEMATIC_CONSTANT' used to declare a constant; consider using a 'constexpr' constant
+
+#define PROBLEMATIC_FUNCTION(x, y) ((a) > (b) ? (a) : (b))
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: function-like macro 'PROBLEMATIC_FUNCTION' used; consider a 'constexpr' template function
+
+#define PROBLEMATIC_VARIADIC(...) (__VA_ARGS__)
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: variadic macro 'PROBLEMATIC_VARIADIC' used; consider using a 'constexpr' variadic template function
+
+#define PROBLEMATIC_VARIADIC2(x, ...) (__VA_ARGS__)
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: variadic macro 'PROBLEMATIC_VARIADIC2' used; consider using a 'constexpr' variadic template function
+
+#define DEBUG_CONSTANT 0
+#define DEBUG_FUNCTION(x, y) ((a) > (b) ? (a) : (b))
+#define DEBUG_VARIADIC(...) (__VA_ARGS__)
+#define TEST_CONSTANT 0
+#define TEST_FUNCTION(x, y) ((a) > (b) ? (a) : (b))
+#define TEST_VARIADIC(...) (__VA_ARGS__)
+#define TEST_VARIADIC2(x, ...) (__VA_ARGS__)
+
+#endif
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-macro-usage.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-macro-usage.cpp
new file mode 100644
index 0000000..a4948f5
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-macro-usage.cpp
@@ -0,0 +1,18 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-macro-usage %t
+
+#ifndef INCLUDE_GUARD
+#define INCLUDE_GUARD
+
+#define PROBLEMATIC_CONSTANT 0
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro 'PROBLEMATIC_CONSTANT' used to declare a constant; consider using a 'constexpr' constant
+
+#define PROBLEMATIC_FUNCTION(x, y) ((a) > (b) ? (a) : (b))
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: function-like macro 'PROBLEMATIC_FUNCTION' used; consider a 'constexpr' template function
+
+#define PROBLEMATIC_VARIADIC(...) (__VA_ARGS__)
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: variadic macro 'PROBLEMATIC_VARIADIC' used; consider using a 'constexpr' variadic template function
+
+#define PROBLEMATIC_VARIADIC2(x, ...) (__VA_ARGS__)
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: variadic macro 'PROBLEMATIC_VARIADIC2' used; consider using a 'constexpr' variadic template function
+
+#endif
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-long-is-32bits.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-long-is-32bits.cpp
new file mode 100644
index 0000000..dcf1848
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-long-is-32bits.cpp
@@ -0,0 +1,23 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \
+// RUN: -- -- -target x86_64-unknown-linux -m32
+
+static_assert(sizeof(int) * 8 == 32, "int is 32-bits");
+static_assert(sizeof(long) * 8 == 32, "long is 32-bits");
+static_assert(sizeof(long long) * 8 == 64, "long long is 64-bits");
+
+void narrow_integer_to_signed_integer_is_not_ok() {
+ int i; // i.e. int32_t
+ long l; // i.e. int32_t
+ long long ll; // i.e. int64_t
+
+ unsigned int ui; // i.e. uint32_t
+ unsigned long ul; // i.e. uint32_t
+ unsigned long long ull; // i.e. uint64_t
+
+ i = l; // int and long are the same type.
+ i = ll; // int64_t does not fit in an int32_t
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ ll = ul; // uint32_t fits into int64_t
+ ll = ull; // uint64_t does not fit in an int64_t
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-narrowingfloatingpoint-option.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-narrowingfloatingpoint-option.cpp
new file mode 100644
index 0000000..14840df
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-narrowingfloatingpoint-option.cpp
@@ -0,0 +1,57 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \
+// RUN: -- -- -target x86_64-unknown-linux -fsigned-char
+
+namespace floats {
+
+void narrow_constant_floating_point_to_int_not_ok(double d) {
+ int i = 0;
+ i += 0.5;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+ i += 0.5f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+ i *= 0.5f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+ i /= 0.5f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+ i += (double)0.5f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+ i += 2.0;
+ i += 2.0f;
+}
+
+double operator"" _double(unsigned long long);
+
+float narrow_double_to_float_return() {
+ return 0.5;
+}
+
+void narrow_double_to_float_not_ok(double d) {
+ float f;
+ f = d;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+ f = 15_double;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+ f += d;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+ f = narrow_double_to_float_return();
+}
+
+void narrow_fp_constants() {
+ float f;
+ f = 0.5; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+
+ f = __builtin_huge_valf(); // max float is not narrowing.
+ f = -__builtin_huge_valf(); // -max float is not narrowing.
+ f = __builtin_inff(); // float infinity is not narrowing.
+ f = __builtin_nanf("0"); // float NaN is not narrowing.
+
+ f = __builtin_huge_val(); // max double is not within-range of float.
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+ f = -__builtin_huge_val(); // -max double is not within-range of float.
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+ f = __builtin_inf(); // double infinity is not within-range of float.
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+ f = __builtin_nan("0"); // double NaN is not narrowing.
+}
+
+} // namespace floats
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-pedanticmode-option.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-pedanticmode-option.cpp
new file mode 100644
index 0000000..f28985d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-pedanticmode-option.cpp
@@ -0,0 +1,23 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \
+// RUN: -config="{CheckOptions: [ \
+// RUN: {key: "cppcoreguidelines-narrowing-conversions.PedanticMode", value: 1} \
+// RUN: ]}" \
+// RUN: -- -target x86_64-unknown-linux -fsigned-char
+
+namespace floats {
+
+void triggers_wrong_constant_type_warning(double d) {
+ int i = 0.0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: constant value should be of type of type 'int' instead of 'double' [cppcoreguidelines-narrowing-conversions]
+ i += 2.0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: constant value should be of type of type 'int' instead of 'double' [cppcoreguidelines-narrowing-conversions]
+ i += 2.0f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: constant value should be of type of type 'int' instead of 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void triggers_narrowing_warning_when_overflowing() {
+ unsigned short us = 65537.0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: narrowing conversion from constant 'double' to 'unsigned short' [cppcoreguidelines-narrowing-conversions]
+}
+
+} // namespace floats
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-unsigned-char.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-unsigned-char.cpp
new file mode 100644
index 0000000..6bd437f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-unsigned-char.cpp
@@ -0,0 +1,83 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \
+// RUN: -- -- -target x86_64-unknown-linux -funsigned-char
+
+void narrow_integer_to_unsigned_integer_is_ok() {
+ signed char sc;
+ short s;
+ int i;
+ long l;
+ long long ll;
+
+ char c;
+ unsigned short us;
+ unsigned int ui;
+ unsigned long ul;
+ unsigned long long ull;
+
+ ui = sc;
+ c = s;
+ c = i;
+ c = l;
+ c = ll;
+
+ c = c;
+ c = us;
+ c = ui;
+ c = ul;
+ c = ull;
+}
+
+void narrow_integer_to_signed_integer_is_not_ok() {
+ signed char sc;
+ short s;
+ int i;
+ long l;
+ long long ll;
+
+ char c;
+ unsigned short us;
+ unsigned int ui;
+ unsigned long ul;
+ unsigned long long ull;
+
+ sc = sc;
+ sc = s;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'short' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ sc = i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'int' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ sc = l;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'long' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ sc = ll;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'long long' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+
+ sc = c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'char' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ sc = us;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned short' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ sc = ui;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned int' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ sc = ul;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ sc = ull;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long long' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_constant_to_unsigned_integer_is_ok() {
+ char c1 = -128; // unsigned dst type is well defined.
+ char c2 = 127; // unsigned dst type is well defined.
+ char c3 = -129; // unsigned dst type is well defined.
+ char c4 = 128; // unsigned dst type is well defined.
+ unsigned char uc1 = 0;
+ unsigned char uc2 = 255;
+ unsigned char uc3 = -1; // unsigned dst type is well defined.
+ unsigned char uc4 = 256; // unsigned dst type is well defined.
+ signed char sc = 128;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: narrowing conversion from constant value 128 (0x00000080) of type 'int' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_conditional_operator_contant_to_unsigned_is_ok(bool b) {
+ // conversion to unsigned char type is well defined.
+ char c1 = b ? 1 : 0;
+ char c2 = b ? 1 : 256;
+ char c3 = b ? -1 : 0;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
new file mode 100644
index 0000000..cc817a0
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -0,0 +1,346 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \
+// RUN: -config="{CheckOptions: [ \
+// RUN: {key: "cppcoreguidelines-narrowing-conversions.WarnOnFloatingPointNarrowingConversion", value: 0}, \
+// RUN: ]}" \
+// RUN: -- -target x86_64-unknown-linux -fsigned-char
+
+float ceil(float);
+namespace std {
+double ceil(double);
+long double floor(long double);
+} // namespace std
+
+namespace floats {
+
+struct ConvertsToFloat {
+ operator float() const { return 0.5f; }
+};
+
+float operator"" _float(unsigned long long);
+
+void narrow_fp_to_int_not_ok(double d) {
+ int i = 0;
+ i = d;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+ i = 0.5f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+ i = static_cast<float>(d);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+ i = ConvertsToFloat();
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+ i = 15_float;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+ i += d;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+ i += 0.5;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+ i += 0.5f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+ i *= 0.5f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+ i /= 0.5f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+ i += (double)0.5f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+ i += 2.0;
+ i += 2.0f;
+}
+
+double operator"" _double(unsigned long long);
+
+float narrow_double_to_float_return() {
+ return 0.5; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+}
+
+void narrow_double_to_float_ok(double d) {
+ float f;
+ f = d;
+ f = 15_double;
+}
+
+void narrow_fp_constants() {
+ float f;
+ f = 0.5; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+
+ f = __builtin_huge_valf(); // max float is not narrowing.
+ f = -__builtin_huge_valf(); // -max float is not narrowing.
+ f = __builtin_inff(); // float infinity is not narrowing.
+ f = __builtin_nanf("0"); // float NaN is not narrowing.
+
+ f = __builtin_huge_val(); // max double is not within-range of float.
+ f = -__builtin_huge_val(); // -max double is not within-range of float.
+ f = __builtin_inf(); // double infinity is not within-range of float.
+ f = __builtin_nan("0"); // double NaN is not narrowing.
+}
+
+void narrow_double_to_float_not_ok_binary_ops(double d) {
+ float f;
+ f += 0.5; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+ f += 2.0; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+ f *= 0.5; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+ f /= 0.5; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+ f += (double)0.5f; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+ f += d; // We do not warn about floating point narrowing by default.
+}
+
+void narrow_fp_constant_to_bool_not_ok() {
+ bool b1 = 1.0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant 'double' to 'bool' [cppcoreguidelines-narrowing-conversions]
+ bool b2 = 1.0f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant 'float' to 'bool' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_integer_to_floating() {
+ {
+ long long ll; // 64 bits
+ float f = ll; // doesn't fit in 24 bits
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'long long' to 'float' [cppcoreguidelines-narrowing-conversions]
+ double d = ll; // doesn't fit in 53 bits.
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: narrowing conversion from 'long long' to 'double' [cppcoreguidelines-narrowing-conversions]
+ }
+ {
+ int i; // 32 bits
+ float f = i; // doesn't fit in 24 bits
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'int' to 'float' [cppcoreguidelines-narrowing-conversions]
+ double d = i; // fits in 53 bits.
+ }
+ {
+ short n1, n2;
+ float f = n1 + n2; // 'n1 + n2' is of type 'int' because of integer rules
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'int' to 'float' [cppcoreguidelines-narrowing-conversions]
+ }
+ {
+ short s; // 16 bits
+ float f = s; // fits in 24 bits
+ double d = s; // fits in 53 bits.
+ }
+}
+
+void narrow_integer_to_unsigned_integer_is_ok() {
+ char c;
+ short s;
+ int i;
+ long l;
+ long long ll;
+
+ unsigned char uc;
+ unsigned short us;
+ unsigned int ui;
+ unsigned long ul;
+ unsigned long long ull;
+
+ ui = c;
+ uc = s;
+ uc = i;
+ uc = l;
+ uc = ll;
+
+ uc = uc;
+ uc = us;
+ uc = ui;
+ uc = ul;
+ uc = ull;
+}
+
+void narrow_integer_to_signed_integer_is_not_ok() {
+ char c;
+ short s;
+ int i;
+ long l;
+ long long ll;
+
+ unsigned char uc;
+ unsigned short us;
+ unsigned int ui;
+ unsigned long ul;
+ unsigned long long ull;
+
+ c = c;
+ c = s;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'short' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ c = i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ c = l;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ c = ll;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+
+ c = uc;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned char' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ c = us;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned short' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ c = ui;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ c = ul;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ c = ull;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long long' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+
+ i = c;
+ i = s;
+ i = i;
+ i = l;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ i = ll;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+
+ i = uc;
+ i = us;
+ i = ui;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ i = ul;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ i = ull;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+
+ ll = c;
+ ll = s;
+ ll = i;
+ ll = l;
+ ll = ll;
+
+ ll = uc;
+ ll = us;
+ ll = ui;
+ ll = ul;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ ll = ull;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_constant_to_unsigned_integer_is_ok() {
+ unsigned char uc1 = 0;
+ unsigned char uc2 = 255;
+ unsigned char uc3 = -1; // unsigned dst type is well defined.
+ unsigned char uc4 = 256; // unsigned dst type is well defined.
+ unsigned short us1 = 0;
+ unsigned short us2 = 65535;
+ unsigned short us3 = -1; // unsigned dst type is well defined.
+ unsigned short us4 = 65536; // unsigned dst type is well defined.
+}
+
+void narrow_constant_to_signed_integer_is_not_ok() {
+ char c1 = -128;
+ char c2 = 127;
+ char c3 = -129;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant value -129 (0xFFFFFF7F) of type 'int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ char c4 = 128;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant value 128 (0x00000080) of type 'int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+
+ short s1 = -32768;
+ short s2 = 32767;
+ short s3 = -32769;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from constant value -32769 (0xFFFF7FFF) of type 'int' to signed type 'short' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ short s4 = 32768;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from constant value 32768 (0x00008000) of type 'int' to signed type 'short' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_conditional_operator_contant_to_unsigned_is_ok(bool b) {
+ // conversion to unsigned dst type is well defined.
+ unsigned char c1 = b ? 1 : 0;
+ unsigned char c2 = b ? 1 : 256;
+ unsigned char c3 = b ? -1 : 0;
+}
+
+void narrow_conditional_operator_contant_to_signed_is_not_ok(bool b) {
+ char uc1 = b ? 1 : 0;
+ char uc2 = b ? 1 : 128;
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: narrowing conversion from constant value 128 (0x00000080) of type 'int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ char uc3 = b ? -129 : 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: narrowing conversion from constant value -129 (0xFFFFFF7F) of type 'int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ unsigned long long ysize;
+ long long mirror = b ? -1 : ysize - 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: narrowing conversion from constant value 18446744073709551615 (0xFFFFFFFFFFFFFFFF) of type 'unsigned long long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ // CHECK-MESSAGES: :[[@LINE-2]]:37: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_constant_to_floating_point() {
+ float f_ok = 1ULL << 24; // fits in 24 bits mantissa.
+ float f_not_ok = (1ULL << 24) + 1ULL; // doesn't fit in 24 bits mantissa.
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: narrowing conversion from constant value 16777217 of type 'unsigned long long' to 'float' [cppcoreguidelines-narrowing-conversions]
+ double d_ok = 1ULL << 53; // fits in 53 bits mantissa.
+ double d_not_ok = (1ULL << 53) + 1ULL; // doesn't fit in 53 bits mantissa.
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: narrowing conversion from constant value 9007199254740993 of type 'unsigned long long' to 'double' [cppcoreguidelines-narrowing-conversions]
+}
+
+void casting_integer_to_bool_is_ok() {
+ int i;
+ while (i) {
+ }
+ for (; i;) {
+ }
+ if (i) {
+ }
+}
+
+void casting_float_to_bool_is_not_ok() {
+ float f;
+ while (f) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'float' to 'bool' [cppcoreguidelines-narrowing-conversions]
+ }
+ for (; f;) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'float' to 'bool' [cppcoreguidelines-narrowing-conversions]
+ }
+ if (f) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'bool' [cppcoreguidelines-narrowing-conversions]
+ }
+}
+
+void legitimate_comparison_do_not_warn(unsigned long long size) {
+ for (int i = 0; i < size; ++i) {
+ }
+}
+
+void ok(double d) {
+ int i = 0;
+ i = 1;
+ i = static_cast<int>(0.5);
+ i = static_cast<int>(d);
+ i = std::ceil(0.5);
+ i = ::std::floor(0.5);
+ {
+ using std::ceil;
+ i = ceil(0.5f);
+ }
+ i = ceil(0.5f);
+}
+
+void ok_binary_ops(double d) {
+ int i = 0;
+ i += 1;
+ i += static_cast<int>(0.5);
+ i += static_cast<int>(d);
+ i += (int)d;
+ i += std::ceil(0.5);
+ i += ::std::floor(0.5);
+ {
+ using std::ceil;
+ i += ceil(0.5f);
+ }
+ i += ceil(0.5f);
+}
+
+// We're bailing out in templates and macros.
+template <typename T1, typename T2>
+void f(T1 one, T2 two) {
+ one += two;
+}
+
+void template_context() {
+ f(1, 2);
+ f(1, .5f);
+ f(1, .5);
+ f(1, .5l);
+}
+
+#define DERP(i, j) (i += j)
+
+void macro_context() {
+ int i = 0;
+ DERP(i, 2);
+ DERP(i, .5f);
+ DERP(i, .5);
+ DERP(i, .5l);
+}
+
+} // namespace floats
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-no-malloc-custom.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-no-malloc-custom.cpp
new file mode 100644
index 0000000..89142fb
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-no-malloc-custom.cpp
@@ -0,0 +1,59 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-no-malloc %t \
+// RUN: -config='{CheckOptions: \
+// RUN: [{key: cppcoreguidelines-no-malloc.Allocations, value: "::malloc;::align_malloc;::calloc"},\
+// RUN: {key: cppcoreguidelines-no-malloc.Reallocations, value: "::realloc;::align_realloc"},\
+// RUN: {key: cppcoreguidelines-no-malloc.Deallocations, value: "::free;::align_free"}]}' \
+// RUN: --
+
+using size_t = __SIZE_TYPE__;
+
+void *malloc(size_t size);
+void *align_malloc(size_t size, unsigned short aligmnent);
+void *calloc(size_t num, size_t size);
+void *realloc(void *ptr, size_t size);
+void *align_realloc(void *ptr, size_t size, unsigned short alignment);
+void free(void *ptr);
+void *align_free(void *ptr);
+
+void malloced_array() {
+ int *array0 = (int *)malloc(sizeof(int) * 20);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+
+ int *zeroed = (int *)calloc(20, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+
+ int *aligned = (int *)align_malloc(20 * sizeof(int), 16);
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+
+ // reallocation memory, std::vector shall be used
+ char *realloced = (char *)realloc(array0, 50 * sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: do not manage memory manually; consider std::vector or std::string [cppcoreguidelines-no-malloc]
+
+ char *align_realloced = (char *)align_realloc(aligned, 50 * sizeof(int), 16);
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: do not manage memory manually; consider std::vector or std::string [cppcoreguidelines-no-malloc]
+
+ // freeing memory the bad way
+ free(realloced);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not manage memory manually; use RAII [cppcoreguidelines-no-malloc]
+
+ align_free(align_realloced);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not manage memory manually; use RAII [cppcoreguidelines-no-malloc]
+
+ // check if a call to malloc as function argument is found as well
+ free(malloc(20));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not manage memory manually; use RAII [cppcoreguidelines-no-malloc]
+ // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+}
+
+/// newing an array is still not good, but not relevant to this checker
+void newed_array() {
+ int *new_array = new int[10]; // OK(1)
+}
+
+void arbitrary_call() {
+ // we dont want every function to raise the warning even if malloc is in the name
+ malloced_array(); // OK(2)
+
+ // completly unrelated function call to malloc
+ newed_array(); // OK(3)
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-no-malloc-no-functions.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-no-malloc-no-functions.cpp
new file mode 100644
index 0000000..8b4d464
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-no-malloc-no-functions.cpp
@@ -0,0 +1,17 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-no-malloc %t \
+// RUN: -config='{CheckOptions: \
+// RUN: [{key: cppcoreguidelines-no-malloc.Allocations, value: "::malloc"},\
+// RUN: {key: cppcoreguidelines-no-malloc.Reallocations, value: ""},\
+// RUN: {key: cppcoreguidelines-no-malloc.Deallocations, value: ""}]}' \
+// RUN: --
+
+// Just ensure, the check will not crash, when no functions shall be checked.
+
+using size_t = __SIZE_TYPE__;
+
+void *malloc(size_t size);
+
+void malloced_array() {
+ int *array0 = (int *)malloc(sizeof(int) * 20);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-no-malloc.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-no-malloc.cpp
new file mode 100644
index 0000000..7b7ccf3
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-no-malloc.cpp
@@ -0,0 +1,42 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-no-malloc %t
+
+using size_t = __SIZE_TYPE__;
+
+void *malloc(size_t size);
+void *calloc(size_t num, size_t size);
+void *realloc(void *ptr, size_t size);
+void free(void *ptr);
+
+void malloced_array() {
+ int *array0 = (int *)malloc(sizeof(int) * 20);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+
+ int *zeroed = (int *)calloc(20, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+
+ // reallocation memory, std::vector shall be used
+ char *realloced = (char *)realloc(array0, 50 * sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: do not manage memory manually; consider std::vector or std::string [cppcoreguidelines-no-malloc]
+
+ // freeing memory the bad way
+ free(realloced);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not manage memory manually; use RAII [cppcoreguidelines-no-malloc]
+
+ // check if a call to malloc as function argument is found as well
+ free(malloc(20));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not manage memory manually; use RAII [cppcoreguidelines-no-malloc]
+ // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+}
+
+/// newing an array is still not good, but not relevant to this checker
+void newed_array() {
+ int *new_array = new int[10]; // OK(1)
+}
+
+void arbitrary_call() {
+ // we dont want every function to raise the warning even if malloc is in the name
+ malloced_array(); // OK(2)
+
+ // completly unrelated function call to malloc
+ newed_array(); // OK(3)
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-owning-memory-containers.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-owning-memory-containers.cpp
new file mode 100644
index 0000000..d39e697
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-owning-memory-containers.cpp
@@ -0,0 +1,62 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-owning-memory %t
+
+namespace gsl {
+template <typename T>
+using owner = T;
+}
+
+namespace std {
+
+// Not actually a vector, but more a dynamic, fixed size array. Just to demonstrate
+// functionality or the lack of the same.
+template <typename T>
+class vector {
+public:
+ vector(unsigned long size, T val) : data{new T[size]}, size{size} {
+ for (unsigned long i = 0ul; i < size; ++i) {
+ data[i] = val;
+ }
+ }
+
+ T *begin() { return data; }
+ T *end() { return &data[size]; }
+ T &operator[](unsigned long index) { return data[index]; }
+
+private:
+ T *data;
+ unsigned long size;
+};
+
+} // namespace std
+
+// All of the following codesnippets should be valid with appropriate 'owner<>' anaylsis,
+// but currently the type information of 'gsl::owner<>' gets lost in typededuction.
+int main() {
+ std::vector<gsl::owner<int *>> OwnerStdVector(100, nullptr);
+
+ // Rangebased looping in resource vector.
+ for (auto *Element : OwnerStdVector) {
+ Element = new int(42);
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: assigning newly created 'gsl::owner<>' to non-owner 'int *'
+ }
+ for (auto *Element : OwnerStdVector) {
+ delete Element;
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: deleting a pointer through a type that is not marked 'gsl::owner<>'; consider using a smart pointer instead
+ // CHECK-NOTES: [[@LINE-3]]:8: note: variable declared here
+ }
+
+ // Indexbased looping in resource vector.
+ for (int i = 0; i < 100; ++i) {
+ OwnerStdVector[i] = new int(42);
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: assigning newly created 'gsl::owner<>' to non-owner 'int *'
+ }
+ for (int i = 0; i < 100; ++i) {
+ delete OwnerStdVector[i];
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: deleting a pointer through a type that is not marked 'gsl::owner<>'; consider using a smart pointer instead
+ // CHECK-NOTES: [[@LINE-21]]:3: note: variable declared here
+ // A note gets emitted here pointing to the return value of the operator[] from the
+ // vector implementation. Maybe this is considered misleading.
+ }
+
+ return 0;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-owning-memory-legacy-functions.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-owning-memory-legacy-functions.cpp
new file mode 100644
index 0000000..5785e9f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-owning-memory-legacy-functions.cpp
@@ -0,0 +1,194 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-owning-memory %t \
+// RUN: -config='{CheckOptions: \
+// RUN: [{key: cppcoreguidelines-owning-memory.LegacyResourceProducers, value: "::malloc;::aligned_alloc;::realloc;::calloc;::fopen;::freopen;::tmpfile"}, \
+// RUN: {key: cppcoreguidelines-owning-memory.LegacyResourceConsumers, value: "::free;::realloc;::freopen;::fclose"}]}' \
+// RUN: -- -std=c++11 -nostdlib -nostdinc++
+
+namespace gsl {
+template <class T>
+using owner = T;
+} // namespace gsl
+
+extern "C" {
+using size_t = decltype(sizeof(void*));
+using FILE = int;
+
+void *malloc(size_t ByteCount);
+void *aligned_alloc(size_t Alignment, size_t Size);
+void *calloc(size_t Count, size_t SizeSingle);
+void *realloc(void *Resource, size_t NewByteCount);
+void free(void *Resource);
+
+FILE *tmpfile(void);
+FILE *fopen(const char *filename, const char *mode);
+FILE *freopen(const char *filename, const char *mode, FILE *stream);
+void fclose(FILE *Resource);
+}
+
+namespace std {
+using ::FILE;
+using ::size_t;
+
+using ::fclose;
+using ::fopen;
+using ::freopen;
+using ::tmpfile;
+
+using ::aligned_alloc;
+using ::calloc;
+using ::free;
+using ::malloc;
+using ::realloc;
+} // namespace std
+
+void nonOwningCall(int *Resource, size_t Size) {}
+void nonOwningCall(FILE *Resource) {}
+
+void consumesResource(gsl::owner<int *> Resource, size_t Size) {}
+void consumesResource(gsl::owner<FILE *> Resource) {}
+
+void testNonCasted(void *Resource) {}
+
+void testNonCastedOwner(gsl::owner<void *> Resource) {}
+
+FILE *fileFactory1() { return ::fopen("new_file.txt", "w"); }
+// CHECK-MESSAGES: [[@LINE-1]]:24: warning: returning a newly created resource of type 'FILE *' (aka 'int *') or 'gsl::owner<>' from a function whose return type is not 'gsl::owner<>'
+gsl::owner<FILE *> fileFactory2() { return std::fopen("new_file.txt", "w"); } // Ok
+
+int *arrayFactory1() { return (int *)std::malloc(100); }
+// CHECK-MESSAGES: [[@LINE-1]]:24: warning: returning a newly created resource of type 'int *' or 'gsl::owner<>' from a function whose return type is not 'gsl::owner<>'
+gsl::owner<int *> arrayFactory2() { return (int *)std::malloc(100); } // Ok
+void *dataFactory1() { return std::malloc(100); }
+// CHECK-MESSAGES: [[@LINE-1]]:24: warning: returning a newly created resource of type 'void *' or 'gsl::owner<>' from a function whose return type is not 'gsl::owner<>'
+gsl::owner<void *> dataFactory2() { return std::malloc(100); } // Ok
+
+void test_resource_creators() {
+ const unsigned int ByteCount = 25 * sizeof(int);
+ int Bad = 42;
+
+ int *IntArray1 = (int *)std::malloc(ByteCount);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+ int *IntArray2 = static_cast<int *>(std::malloc(ByteCount)); // Bad
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+ void *IntArray3 = std::malloc(ByteCount);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'void *' with a newly created 'gsl::owner<>'
+
+ int *IntArray4 = (int *)::malloc(ByteCount);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+ int *IntArray5 = static_cast<int *>(::malloc(ByteCount)); // Bad
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+ void *IntArray6 = ::malloc(ByteCount);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'void *' with a newly created 'gsl::owner<>'
+
+ gsl::owner<int *> IntArray7 = (int *)malloc(ByteCount); // Ok
+ gsl::owner<void *> IntArray8 = malloc(ByteCount); // Ok
+
+ gsl::owner<int *> IntArray9 = &Bad;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expected initialization with value of type 'gsl::owner<>'; got 'int *'
+
+ nonOwningCall((int *)malloc(ByteCount), 25);
+ // CHECK-MESSAGES: [[@LINE-1]]:24: warning: initializing non-owner argument of type 'int *' with a newly created 'gsl::owner<>'
+ nonOwningCall((int *)::malloc(ByteCount), 25);
+ // CHECK-MESSAGES: [[@LINE-1]]:24: warning: initializing non-owner argument of type 'int *' with a newly created 'gsl::owner<>'
+
+ consumesResource((int *)malloc(ByteCount), 25); // Ok
+ consumesResource((int *)::malloc(ByteCount), 25); // Ok
+
+ testNonCasted(malloc(ByteCount));
+ // CHECK-MESSAGES: [[@LINE-1]]:17: warning: initializing non-owner argument of type 'void *' with a newly created 'gsl::owner<>'
+ testNonCastedOwner(gsl::owner<void *>(malloc(ByteCount))); // Ok
+ testNonCastedOwner(malloc(ByteCount)); // Ok
+
+ FILE *File1 = std::fopen("test_name.txt", "w+");
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'FILE *' (aka 'int *') with a newly created 'gsl::owner<>'
+ FILE *File2 = ::fopen("test_name.txt", "w+");
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'FILE *' (aka 'int *') with a newly created 'gsl::owner<>'
+
+ gsl::owner<FILE *> File3 = ::fopen("test_name.txt", "w+"); // Ok
+
+ FILE *File4;
+ File4 = ::fopen("test_name.txt", "w+");
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: assigning newly created 'gsl::owner<>' to non-owner 'FILE *' (aka 'int *')
+
+ gsl::owner<FILE *> File5;
+ File5 = ::fopen("test_name.txt", "w+"); // Ok
+ File5 = File1;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expected assignment source to be of type 'gsl::owner<>'; got 'FILE *' (aka 'int *')
+
+ gsl::owner<FILE *> File6 = File1;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expected initialization with value of type 'gsl::owner<>'; got 'FILE *' (aka 'int *')
+
+ FILE *File7 = tmpfile();
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'FILE *' (aka 'int *') with a newly created 'gsl::owner<>'
+ gsl::owner<FILE *> File8 = tmpfile(); // Ok
+
+ nonOwningCall(::fopen("test_name.txt", "r"));
+ // CHECK-MESSAGES: [[@LINE-1]]:17: warning: initializing non-owner argument of type 'FILE *' (aka 'int *') with a newly created 'gsl::owner<>'
+ nonOwningCall(std::fopen("test_name.txt", "r"));
+ // CHECK-MESSAGES: [[@LINE-1]]:17: warning: initializing non-owner argument of type 'FILE *' (aka 'int *') with a newly created 'gsl::owner<>'
+
+ consumesResource(::fopen("test_name.txt", "r")); // Ok
+
+ int *HeapPointer3 = (int *)aligned_alloc(16ul, 4ul * 32ul);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+ gsl::owner<int *> HeapPointer4 = static_cast<int *>(aligned_alloc(16ul, 4ul * 32ul)); // Ok
+
+ void *HeapPointer5 = calloc(10ul, 4ul);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'void *' with a newly created 'gsl::owner<>'
+ gsl::owner<void *> HeapPointer6 = calloc(10ul, 4ul); // Ok
+}
+
+void test_legacy_consumers() {
+ int StackInteger = 42;
+
+ int *StackPointer = &StackInteger;
+ int *HeapPointer1 = (int *)malloc(100);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+ gsl::owner<int *> HeapPointer2 = (int *)malloc(100);
+
+ std::free(StackPointer);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: calling legacy resource function without passing a 'gsl::owner<>'
+ std::free(HeapPointer1);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: calling legacy resource function without passing a 'gsl::owner<>'
+ std::free(HeapPointer2); // Ok
+ // CHECK MESSAGES: [[@LINE-1]]:3: warning: calling legacy resource function without passing a 'gsl::owner<>'
+
+ // FIXME: the check complains about initialization of 'void *' with new created owner.
+ // This happens, because the argument of `free` is not marked as 'owner<>' (and cannot be),
+ // and the check will not figure out could be meant as owner.
+ // This property will probably never be fixed, because it is probably a rather rare
+ // use-case and 'owner<>' should be wrapped in RAII classes anyway!
+ std::free(std::malloc(100)); // Ok but silly :)
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: initializing non-owner argument of type 'void *' with a newly created 'gsl::owner<>'
+
+ // Demonstrate, that multi-argument functions are diagnosed as well.
+ std::realloc(StackPointer, 200);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: calling legacy resource function without passing a 'gsl::owner<>'
+ std::realloc(HeapPointer1, 200);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: calling legacy resource function without passing a 'gsl::owner<>'
+ std::realloc(HeapPointer2, 200); // Ok
+ std::realloc(std::malloc(100), 200); // Ok but silly
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: initializing non-owner argument of type 'void *' with a newly created 'gsl::owner<>'
+
+ fclose(fileFactory1());
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: calling legacy resource function without passing a 'gsl::owner<>'
+ fclose(fileFactory2()); // Ok, same as FIXME with `free(malloc(100))` applies here
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: initializing non-owner argument of type 'FILE *' (aka 'int *') with a newly created 'gsl::owner<>'
+
+ gsl::owner<FILE *> File1 = fopen("testfile.txt", "r"); // Ok
+ FILE *File2 = freopen("testfile.txt", "w", File1);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'FILE *' (aka 'int *') with a newly created 'gsl::owner<>'
+ // CHECK-MESSAGES: [[@LINE-2]]:17: warning: calling legacy resource function without passing a 'gsl::owner<>'
+ // FIXME: The warning for not passing and owner<> is a false positive since both the filename and the
+ // mode are not supposed to be owners but still pointers. The check is to coarse for
+ // this function. Maybe `freopen` gets special treatment.
+
+ gsl::owner<FILE *> File3 = freopen("testfile.txt", "w", File2); // Bad, File2 no owner
+ // CHECK-MESSAGES: [[@LINE-1]]:30: warning: calling legacy resource function without passing a 'gsl::owner<>'
+
+ FILE *TmpFile = tmpfile();
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'FILE *' (aka 'int *') with a newly created 'gsl::owner<>'
+ FILE *File6 = freopen("testfile.txt", "w", TmpFile); // Bad, both return and argument
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'FILE *' (aka 'int *') with a newly created 'gsl::owner<>'
+ // CHECK-MESSAGES: [[@LINE-2]]:17: warning: calling legacy resource function without passing a 'gsl::owner<>'
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-owning-memory.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-owning-memory.cpp
new file mode 100644
index 0000000..72b1380
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-owning-memory.cpp
@@ -0,0 +1,391 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-owning-memory %t
+
+namespace gsl {
+template <class T>
+using owner = T;
+} // namespace gsl
+
+template <typename T>
+class unique_ptr {
+public:
+ unique_ptr(gsl::owner<T> resource) : memory(resource) {}
+ unique_ptr(const unique_ptr<T> &) = default;
+
+ ~unique_ptr() { delete memory; }
+
+private:
+ gsl::owner<T> memory;
+};
+
+void takes_owner(gsl::owner<int *> owned_int) {
+}
+
+void takes_pointer(int *unowned_int) {
+}
+
+void takes_owner_and_more(int some_int, gsl::owner<int *> owned_int, float f) {
+}
+
+template <typename T>
+void takes_templated_owner(gsl::owner<T> owned_T) {
+}
+
+gsl::owner<int *> returns_owner1() { return gsl::owner<int *>(new int(42)); } // Ok
+gsl::owner<int *> returns_owner2() { return new int(42); } // Ok
+
+int *returns_no_owner1() { return nullptr; }
+int *returns_no_owner2() {
+ return new int(42);
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: returning a newly created resource of type 'int *' or 'gsl::owner<>' from a function whose return type is not 'gsl::owner<>'
+}
+int *returns_no_owner3() {
+ int *should_be_owner = new int(42);
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+ return should_be_owner;
+}
+int *returns_no_owner4() {
+ gsl::owner<int *> owner = new int(42);
+ return owner;
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: returning a newly created resource of type 'int *' or 'gsl::owner<>' from a function whose return type is not 'gsl::owner<>'
+}
+
+unique_ptr<int *> returns_no_owner5() {
+ return unique_ptr<int *>(new int(42)); // Ok
+}
+
+/// FIXME: CSA finds it, but the report is misleading. Ownersemantics can catch this
+/// by flow analysis similar to bugprone-use-after-move.
+void csa_not_finding_leak() {
+ gsl::owner<int *> o1 = new int(42); // Ok
+
+ gsl::owner<int *> o2 = o1; // Ok
+ o2 = new int(45); // conceptual leak, the memory from o1 is now leaked, since its considered moved in the guidelines
+
+ delete o2;
+ // actual leak occurs here, its found, but mixed
+ delete o1;
+}
+
+void test_assignment_and_initialization() {
+ int stack_int1 = 15;
+ int stack_int2;
+
+ gsl::owner<int *> owned_int1 = &stack_int1; // BAD
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: expected initialization with value of type 'gsl::owner<>'; got 'int *'
+
+ gsl::owner<int *> owned_int2;
+ owned_int2 = &stack_int2; // BAD since no owner, bad since uninitialized
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: expected assignment source to be of type 'gsl::owner<>'; got 'int *'
+
+ gsl::owner<int *> owned_int3 = new int(42); // Good
+ owned_int3 = nullptr; // Good
+
+ gsl::owner<int *> owned_int4(nullptr); // Ok
+ owned_int4 = new int(42); // Good
+
+ gsl::owner<int *> owned_int5 = owned_int3; // Good
+
+ gsl::owner<int *> owned_int6{nullptr}; // Ok
+ owned_int6 = owned_int4; // Good
+
+ // FIXME:, flow analysis for the case of reassignment. Value must be released before
+ owned_int6 = owned_int3; // BAD, because reassignment without resource release
+
+ auto owned_int7 = returns_owner1(); // Bad, since type deduction eliminates the owner wrapper
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+ // CHECK-NOTES: [[@LINE-2]]:3: note: type deduction did not result in an owner
+
+ const auto owned_int8 = returns_owner2(); // Bad, since type deduction eliminates the owner wrapper
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: initializing non-owner 'int *const' with a newly created 'gsl::owner<>'
+ // CHECK-NOTES: [[@LINE-2]]:3: note: type deduction did not result in an owner
+
+ gsl::owner<int *> owned_int9 = returns_owner1(); // Ok
+ int *unowned_int3 = returns_owner1(); // Bad
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+
+ gsl::owner<int *> owned_int10;
+ owned_int10 = returns_owner1(); // Ok
+
+ int *unowned_int4;
+ unowned_int4 = returns_owner1(); // Bad
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: assigning newly created 'gsl::owner<>' to non-owner 'int *'
+
+ gsl::owner<int *> owned_int11 = returns_no_owner1(); // Bad since no owner
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: expected initialization with value of type 'gsl::owner<>'; got 'int *'
+
+ gsl::owner<int *> owned_int12;
+ owned_int12 = returns_no_owner1(); // Bad since no owner
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: expected assignment source to be of type 'gsl::owner<>'; got 'int *'
+
+ int *unowned_int5 = returns_no_owner1(); // Ok
+ int *unowned_int6;
+ unowned_int6 = returns_no_owner1(); // Ok
+
+ int *unowned_int7 = new int(42); // Bad, since resource not assigned to an owner
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+
+ int *unowned_int8;
+ unowned_int8 = new int(42);
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: assigning newly created 'gsl::owner<>' to non-owner 'int *'
+
+ gsl::owner<int *> owned_int13 = nullptr; // Ok
+}
+
+void test_deletion() {
+ gsl::owner<int *> owned_int1 = new int(42);
+ delete owned_int1; // Good
+
+ gsl::owner<int *> owned_int2 = new int[42];
+ delete[] owned_int2; // Good
+
+ int *unowned_int1 = new int(42); // BAD, since new creates and owner
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+ delete unowned_int1; // BAD, since no owner
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: deleting a pointer through a type that is not marked 'gsl::owner<>'; consider using a smart pointer instead
+ // CHECK-NOTES: [[@LINE-4]]:3: note: variable declared here
+
+ int *unowned_int2 = new int[42]; // BAD, since new creates and owner
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+ delete[] unowned_int2; // BAD since no owner
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: deleting a pointer through a type that is not marked 'gsl::owner<>'; consider using a smart pointer instead
+ // CHECK-NOTES: [[@LINE-4]]:3: note: variable declared here
+
+ delete new int(42); // Technically ok, but stupid
+ delete[] new int[42]; // Technically ok, but stupid
+}
+
+void test_owner_function_calls() {
+ int stack_int = 42;
+ int *unowned_int1 = &stack_int;
+ takes_owner(&stack_int); // BAD
+ // CHECK-NOTES: [[@LINE-1]]:15: warning: expected argument of type 'gsl::owner<>'; got 'int *'
+ takes_owner(unowned_int1); // BAD
+ // CHECK-NOTES: [[@LINE-1]]:15: warning: expected argument of type 'gsl::owner<>'; got 'int *'
+
+ gsl::owner<int *> owned_int1 = new int(42);
+ takes_owner(owned_int1); // Ok
+
+ takes_owner_and_more(42, &stack_int, 42.0f); // BAD
+ // CHECK-NOTES: [[@LINE-1]]:28: warning: expected argument of type 'gsl::owner<>'; got 'int *'
+ takes_owner_and_more(42, unowned_int1, 42.0f); // BAD
+ // CHECK-NOTES: [[@LINE-1]]:28: warning: expected argument of type 'gsl::owner<>'; got 'int *'
+
+ takes_owner_and_more(42, new int(42), 42.0f); // Ok, since new is consumed by owner
+ takes_owner_and_more(42, owned_int1, 42.0f); // Ok, since owner as argument
+
+ takes_templated_owner(owned_int1); // Ok
+ takes_templated_owner(new int(42)); // Ok
+ takes_templated_owner(unowned_int1); // Bad
+ // CHECK-NOTES: [[@LINE-1]]:25: warning: expected argument of type 'gsl::owner<>'; got 'int *'
+
+ takes_owner(returns_owner1()); // Ok
+ takes_owner(returns_no_owner1()); // BAD
+ // CHECK-NOTES: [[@LINE-1]]:15: warning: expected argument of type 'gsl::owner<>'; got 'int *'
+}
+
+void test_unowned_function_calls() {
+ int stack_int = 42;
+ int *unowned_int1 = &stack_int;
+ gsl::owner<int *> owned_int1 = new int(42);
+
+ takes_pointer(&stack_int); // Ok
+ takes_pointer(unowned_int1); // Ok
+ takes_pointer(owned_int1); // Ok
+ takes_pointer(new int(42)); // Bad, since new creates and owner
+ // CHECK-NOTES: [[@LINE-1]]:17: warning: initializing non-owner argument of type 'int *' with a newly created 'gsl::owner<>'
+
+ takes_pointer(returns_owner1()); // Bad
+ // CHECK-NOTES: [[@LINE-1]]:17: warning: initializing non-owner argument of type 'int *' with a newly created 'gsl::owner<>'
+
+ takes_pointer(returns_no_owner1()); // Ok
+}
+
+// FIXME: Typedefing owner<> to something else does not work.
+// This might be necessary for code already having a similar typedef like owner<> and
+// replacing it with owner<>. This might be the same problem as with templates.
+// The canonical type will ignore the owner<> alias, since its a typedef as well.
+//
+// Check, if owners hidden by typedef are handled the same as 'obvious' owners.
+#if 0
+using heap_int = gsl::owner<int *>;
+typedef gsl::owner<float *> heap_float;
+
+// This tests only a subset, assuming that the check will either see through the
+// typedef or not (it doesn't!).
+void test_typedefed_values() {
+ // Modern typedef.
+ int StackInt1 = 42;
+ heap_int HeapInt1 = &StackInt1;
+ // CHECK MESSAGES: [[@LINE-1]]:3: warning: expected assignment source to be of type 'gsl::owner<>'; got 'int *'
+
+ //FIXME: Typedef not considered correctly here.
+ // heap_int HeapInt2 = new int(42); // Ok
+ takes_pointer(HeapInt1); // Ok
+ takes_owner(HeapInt1); // Ok
+
+ // Traditional typedef.
+ float StackFloat1 = 42.0f;
+ heap_float HeapFloat1 = &StackFloat1;
+ // CHECK MESSAGES: [[@LINE-1]]:3: warning: expected assignment source to be of type 'gsl::owner<>'; got 'float *'
+
+ //FIXME: Typedef not considered correctly here.
+ // heap_float HeapFloat2 = new float(42.0f);
+ HeapFloat2 = HeapFloat1; // Ok
+}
+#endif
+
+struct ArbitraryClass {};
+struct ClassWithOwner { // Does not define destructor, necessary with owner
+ ClassWithOwner() : owner_var(nullptr) {} // Ok
+
+ ClassWithOwner(ArbitraryClass &other) : owner_var(&other) {}
+ // CHECK-NOTES: [[@LINE-1]]:43: warning: expected initialization of owner member variable with value of type 'gsl::owner<>'; got 'ArbitraryClass *'
+
+ ClassWithOwner(gsl::owner<ArbitraryClass *> other) : owner_var(other) {} // Ok
+
+ ClassWithOwner(gsl::owner<ArbitraryClass *> data, int /* unused */) { // Ok
+ owner_var = data; // Ok
+ }
+
+ ClassWithOwner(ArbitraryClass *bad_data, int /* unused */, int /* unused */) {
+ owner_var = bad_data;
+ // CHECK-NOTES: [[@LINE-1]]:5: warning: expected assignment source to be of type 'gsl::owner<>'; got 'ArbitraryClass *'
+ }
+
+ ClassWithOwner(ClassWithOwner &&other) : owner_var{other.owner_var} {} // Ok
+
+ ClassWithOwner &operator=(ClassWithOwner &&other) {
+ owner_var = other.owner_var; // Ok
+ return *this;
+ }
+
+ // Returning means, that the owner is "moved", so the class should not access this
+ // variable anymore after this method gets called.
+ gsl::owner<ArbitraryClass *> buggy_but_returns_owner() { return owner_var; }
+
+ gsl::owner<ArbitraryClass *> owner_var;
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: member variable of type 'gsl::owner<>' requires the class 'ClassWithOwner' to implement a destructor to release the owned resource
+};
+
+class DefaultedDestructor { // Bad since default constructor with owner
+ ~DefaultedDestructor() = default; // Bad, since will not destroy the owner
+ gsl::owner<int *> Owner;
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: member variable of type 'gsl::owner<>' requires the class 'DefaultedDestructor' to implement a destructor to release the owned resource
+};
+
+struct DeletedDestructor {
+ ~DeletedDestructor() = delete;
+ gsl::owner<int *> Owner;
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: member variable of type 'gsl::owner<>' requires the class 'DeletedDestructor' to implement a destructor to release the owned resource
+};
+
+void test_class_with_owner() {
+ ArbitraryClass A;
+ ClassWithOwner C1; // Ok
+ ClassWithOwner C2{A}; // Bad, since the owner would be initialized with an non-owner, but catched in the class
+ ClassWithOwner C3{gsl::owner<ArbitraryClass *>(new ArbitraryClass)}; // Ok
+
+ const auto Owner1 = C3.buggy_but_returns_owner(); // BAD, deduces Owner1 to ArbitraryClass *const
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: initializing non-owner 'ArbitraryClass *const' with a newly created 'gsl::owner<>'
+ // CHECK-NOTES: [[@LINE-2]]:3: note: type deduction did not result in an owner
+
+ auto Owner2 = C2.buggy_but_returns_owner(); // BAD, deduces Owner2 to ArbitraryClass *
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: initializing non-owner 'ArbitraryClass *' with a newly created 'gsl::owner<>'
+ // CHECK-NOTES: [[@LINE-2]]:3: note: type deduction did not result in an owner
+
+ Owner2 = &A; // Ok, since type deduction did NOT result in owner<int*>
+
+ gsl::owner<ArbitraryClass *> Owner3 = C1.buggy_but_returns_owner(); // Ok, still an owner
+ Owner3 = &A; // Bad, since assignment of non-owner to owner
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: expected assignment source to be of type 'gsl::owner<>'; got 'ArbitraryClass *'
+}
+
+template <typename T>
+struct HeapArray { // Ok, since destructor with owner
+ HeapArray() : _data(nullptr), size(0) {} // Ok
+ HeapArray(int size) : _data(new int[size]), size(size) {} // Ok
+ HeapArray(int size, T val) {
+ _data = new int[size]; // Ok
+ size = size;
+ for (auto i = 0u; i < size; ++i)
+ _data[i] = val; // Ok
+ }
+ HeapArray(int size, T val, int *problematic) : _data{problematic}, size(size) {} // Bad
+ // CHECK-NOTES: [[@LINE-1]]:50: warning: expected initialization of owner member variable with value of type 'gsl::owner<>'; got 'void'
+ // FIXME: void is incorrect type, probably wrong thing matched
+
+ HeapArray(HeapArray &&other) : _data(other._data), size(other.size) { // Ok
+ other._data = nullptr; // Ok
+ other.size = 0;
+ }
+
+ HeapArray<T> &operator=(HeapArray<T> &&other) {
+ _data = other._data; // Ok, NOLINT warning here about bad types, why?
+ size = other.size;
+ return *this;
+ }
+
+ ~HeapArray() { delete[] _data; } // Ok
+
+ T *data() { return _data; } // Ok NOLINT, because it "looks" like a factory
+
+ gsl::owner<T *> _data;
+ unsigned int size;
+};
+
+void test_inner_template() {
+ HeapArray<int> Array1;
+ HeapArray<int> Array2(100);
+ HeapArray<int> Array3(100, 0);
+ HeapArray<int> Array4(100, 0, nullptr);
+
+ Array1 = static_cast<HeapArray<int> &&>(Array2);
+ HeapArray<int> Array5(static_cast<HeapArray<int> &&>(Array3));
+
+ int *NonOwningPtr = Array1.data(); // Ok
+ gsl::owner<int *> OwningPtr = Array1.data(); // Bad, since it does not return the owner
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: expected initialization with value of type 'gsl::owner<>'; got 'int *'
+}
+
+// FIXME: Typededuction removes the owner - wrapper, therefore gsl::owner can not be used
+// with Template classes like this. Is there a walkaround?
+template <typename T>
+struct TemplateValue {
+ TemplateValue() = default;
+ TemplateValue(T t) : val{t} {}
+
+ void setVal(const T &t) { val = t; }
+ const T getVal() const { return val; }
+
+ T val;
+};
+
+// FIXME: Same typededcution problems
+template <typename T>
+void template_function(T t) {
+ gsl::owner<int *> owner_t = t; // Probably bad, since type deduction still wrong
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: expected initialization with value of type 'gsl::owner<>'; got 'T'
+ // CHECK-NOTES: [[@LINE-2]]:3: warning: expected initialization with value of type 'gsl::owner<>'; got 'int *'
+}
+
+// FIXME: Same typededcution problems
+void test_templates() {
+ int stack_int = 42;
+ int *stack_ptr1 = &stack_int;
+
+ TemplateValue<gsl::owner<int *>> Owner0; // Ok, T should be owner, but is int*
+
+ TemplateValue<gsl::owner<int *>> Owner1(new int(42)); // Ok, T should be owner, but is int*
+ Owner1.setVal(&stack_int); // Bad since non-owner assignment
+ Owner1.setVal(stack_ptr1); // Bad since non-owner assignment
+ //Owner1.setVal(new int(42)); // Ok, but since type deduction is wrong, this one is considered harmful
+
+ int *stack_ptr2 = Owner1.getVal(); // Bad, initializing non-owner with owner
+
+ TemplateValue<int *> NonOwner1(new int(42)); // Bad, T is int *, hence dynamic memory to non-owner
+ gsl::owner<int *> IntOwner1 = NonOwner1.getVal(); // Bad, since owner initialized with non-owner
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: expected initialization with value of type 'gsl::owner<>'; got 'int *'
+
+ template_function(IntOwner1); // Ok, but not actually ok, since type deduction removes owner
+ template_function(stack_ptr1); // Bad, but type deduction gets it wrong
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp
new file mode 100644
index 0000000..2287e48
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp
@@ -0,0 +1,51 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-array-to-pointer-decay %t
+#include <stddef.h>
+
+namespace gsl {
+template <class T>
+class array_view {
+public:
+ template <class U, size_t N>
+ array_view(U (&arr)[N]);
+};
+}
+
+void pointerfun(int *p);
+void arrayfun(int p[]);
+void arrayviewfun(gsl::array_view<int> &p);
+size_t s();
+
+void f() {
+ int a[5];
+ pointerfun(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not implicitly decay an array into a pointer; consider using gsl::array_view or an explicit cast instead [cppcoreguidelines-pro-bounds-array-to-pointer-decay]
+ pointerfun((int *)a); // OK, explicit cast
+ arrayfun(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not implicitly decay an array into a pointer
+
+ pointerfun(a + s() - 10); // Convert to &a[g() - 10];
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not implicitly decay an array into a pointer
+
+ gsl::array_view<int> av(a);
+ arrayviewfun(av); // OK
+
+ int i = a[0]; // OK
+ int j = a[(1 + 2)];// OK
+ pointerfun(&a[0]); // OK
+
+ for (auto &e : a) // OK, iteration internally decays array to pointer
+ e = 1;
+}
+
+const char *g() {
+ return "clang"; // OK, decay string literal to pointer
+}
+const char *g2() {
+ return ("clang"); // OK, ParenExpr hides the literal-pointer decay
+}
+
+void f2(void *const *);
+void bug25362() {
+ void *a[2];
+ f2(static_cast<void *const*>(a)); // OK, explicit cast
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index-c++03.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index-c++03.cpp
new file mode 100644
index 0000000..ad9fcd9
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index-c++03.cpp
@@ -0,0 +1,11 @@
+// RUN: clang-tidy %s -checks=-*,cppcoreguidelines-pro-bounds-constant-array-index -- -std=c++03 | count 0
+
+// Note: this test expects no diagnostics, but FileCheck cannot handle that,
+// hence the use of | count 0.
+template <int index> struct B {
+ int get() {
+ // The next line used to crash the check (in C++03 mode only).
+ return x[index];
+ }
+ int x[3];
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index-gslheader.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index-gslheader.cpp
new file mode 100644
index 0000000..a88a2d9
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index-gslheader.cpp
@@ -0,0 +1,79 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-constant-array-index %t -- -config='{CheckOptions: [{key: cppcoreguidelines-pro-bounds-constant-array-index.GslHeader, value: "dir1/gslheader.h"}]}' -- -std=c++11
+// CHECK-FIXES: #include "dir1/gslheader.h"
+
+typedef __SIZE_TYPE__ size_t;
+
+namespace std {
+ template<typename T, size_t N>
+ struct array {
+ T& operator[](size_t n);
+ T& at(size_t n);
+ };
+}
+
+
+namespace gsl {
+ template<class T, size_t N>
+ T& at( T(&a)[N], size_t index );
+
+ template<class T, size_t N>
+ T& at( std::array<T, N> &a, size_t index );
+}
+
+constexpr int const_index(int base) {
+ return base + 3;
+}
+
+void f(std::array<int, 10> a, int pos) {
+ a [ pos / 2 /*comment*/] = 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead [cppcoreguidelines-pro-bounds-constant-array-index]
+ // CHECK-FIXES: gsl::at(a, pos / 2 /*comment*/) = 1;
+ int j = a[pos - 1];
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead
+ // CHECK-FIXES: int j = gsl::at(a, pos - 1);
+
+ a.at(pos-1) = 2; // OK, at() instead of []
+ gsl::at(a, pos-1) = 2; // OK, gsl::at() instead of []
+
+ a[-1] = 3;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index -1 is negative [cppcoreguidelines-pro-bounds-constant-array-index]
+ a[10] = 4;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements) [cppcoreguidelines-pro-bounds-constant-array-index]
+
+ a[const_index(7)] = 3;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements)
+
+ a[0] = 3; // OK, constant index and inside bounds
+ a[1] = 3; // OK, constant index and inside bounds
+ a[9] = 3; // OK, constant index and inside bounds
+ a[const_index(6)] = 3; // OK, constant index and inside bounds
+}
+
+void g() {
+ int a[10];
+ for (int i = 0; i < 10; ++i) {
+ a[i] = i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead
+ // CHECK-FIXES: gsl::at(a, i) = i;
+ gsl::at(a, i) = i; // OK, gsl::at() instead of []
+ }
+
+ a[-1] = 3; // flagged by clang-diagnostic-array-bounds
+ a[10] = 4; // flagged by clang-diagnostic-array-bounds
+ a[const_index(7)] = 3; // flagged by clang-diagnostic-array-bounds
+
+ a[0] = 3; // OK, constant index and inside bounds
+ a[1] = 3; // OK, constant index and inside bounds
+ a[9] = 3; // OK, constant index and inside bounds
+ a[const_index(6)] = 3; // OK, constant index and inside bounds
+}
+
+struct S {
+ int& operator[](int i);
+};
+
+void customOperator() {
+ S s;
+ int i = 0;
+ s[i] = 3; // OK, custom operator
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index.cpp
new file mode 100644
index 0000000..3519410
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index.cpp
@@ -0,0 +1,87 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-constant-array-index %t
+
+typedef __SIZE_TYPE__ size_t;
+
+namespace std {
+ template<typename T, size_t N>
+ struct array {
+ T& operator[](size_t n);
+ T& at(size_t n);
+ };
+}
+
+
+namespace gsl {
+ template<class T, size_t N>
+ T& at( T(&a)[N], size_t index );
+
+ template<class T, size_t N>
+ T& at( std::array<T, N> &a, size_t index );
+}
+
+constexpr int const_index(int base) {
+ return base + 3;
+}
+
+void f(std::array<int, 10> a, int pos) {
+ a [ pos / 2 /*comment*/] = 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead [cppcoreguidelines-pro-bounds-constant-array-index]
+ int j = a[pos - 1];
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead
+
+ a.at(pos-1) = 2; // OK, at() instead of []
+ gsl::at(a, pos-1) = 2; // OK, gsl::at() instead of []
+
+ a[-1] = 3;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index -1 is negative [cppcoreguidelines-pro-bounds-constant-array-index]
+ a[10] = 4;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements) [cppcoreguidelines-pro-bounds-constant-array-index]
+
+ a[const_index(7)] = 3;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements)
+
+ a[0] = 3; // OK, constant index and inside bounds
+ a[1] = 3; // OK, constant index and inside bounds
+ a[9] = 3; // OK, constant index and inside bounds
+ a[const_index(6)] = 3; // OK, constant index and inside bounds
+}
+
+void g() {
+ int a[10];
+ for (int i = 0; i < 10; ++i) {
+ a[i] = i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead
+ // CHECK-FIXES: gsl::at(a, i) = i;
+ gsl::at(a, i) = i; // OK, gsl::at() instead of []
+ }
+
+ a[-1] = 3; // flagged by clang-diagnostic-array-bounds
+ a[10] = 4; // flagged by clang-diagnostic-array-bounds
+ a[const_index(7)] = 3; // flagged by clang-diagnostic-array-bounds
+
+ a[0] = 3; // OK, constant index and inside bounds
+ a[1] = 3; // OK, constant index and inside bounds
+ a[9] = 3; // OK, constant index and inside bounds
+ a[const_index(6)] = 3; // OK, constant index and inside bounds
+}
+
+struct S {
+ int& operator[](int i);
+};
+
+void customOperator() {
+ S s;
+ int i = 0;
+ s[i] = 3; // OK, custom operator
+}
+
+struct A {
+ // The compiler-generated copy constructor uses an ArraySubscriptExpr. Don't warn.
+ int x[3];
+};
+
+void use_A() {
+ // Force the compiler to generate a copy constructor.
+ A a;
+ A a2(a);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic-pr36489.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic-pr36489.cpp
new file mode 100644
index 0000000..4710952
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic-pr36489.cpp
@@ -0,0 +1,53 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-pointer-arithmetic %t -- -- -std=c++14
+
+// Fix PR36489 and detect auto-deduced value correctly.
+char *getPtr();
+auto getPtrAuto() { return getPtr(); }
+decltype(getPtr()) getPtrDeclType();
+decltype(auto) getPtrDeclTypeAuto() { return getPtr(); }
+auto getPtrWithTrailingReturnType() -> char *;
+
+void auto_deduction_binary() {
+ auto p1 = getPtr() + 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: do not use pointer arithmetic
+ auto p2 = getPtrAuto() + 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: do not use pointer arithmetic
+ auto p3 = getPtrWithTrailingReturnType() + 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: do not use pointer arithmetic
+ auto p4 = getPtr();
+ auto *p5 = getPtr();
+ p4 = p4 + 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not use pointer arithmetic
+ p5 = p5 + 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not use pointer arithmetic
+ auto p6 = getPtrDeclType() + 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: do not use pointer arithmetic
+ auto p7 = getPtrDeclTypeAuto() + 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: do not use pointer arithmetic
+ auto *p8 = getPtrDeclType() + 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: do not use pointer arithmetic
+ auto *p9 = getPtrDeclTypeAuto() + 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: do not use pointer arithmetic
+}
+
+void auto_deduction_subscript() {
+ char p1 = getPtr()[2];
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
+ auto p2 = getPtr()[3];
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
+
+ char p3 = getPtrAuto()[4];
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
+ auto p4 = getPtrAuto()[5];
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
+
+ char p5 = getPtrWithTrailingReturnType()[6];
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
+ auto p6 = getPtrWithTrailingReturnType()[7];
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
+
+ auto p7 = getPtrDeclType()[8];
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
+ auto p8 = getPtrDeclTypeAuto()[9];
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
new file mode 100644
index 0000000..7cbc6dd
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
@@ -0,0 +1,89 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-pointer-arithmetic %t
+
+enum E {
+ ENUM_LITERAL = 1
+};
+
+int i = 4;
+int j = 1;
+int *p = 0;
+int *q = 0;
+
+void fail() {
+ q = p + 4;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+ p = q + i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+ p = q + ENUM_LITERAL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+
+ q = p - 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+ p = q - i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+ p = q - ENUM_LITERAL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+
+ p += 4;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+ p += i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+ p += ENUM_LITERAL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+
+ q -= 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+ q -= i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+ q -= ENUM_LITERAL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+
+ p++;
+ // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic
+ ++p;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic
+
+ p--;
+ // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic
+ --p;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic
+
+ i = p[1];
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use pointer arithmetic
+}
+
+struct S {
+ operator int() const;
+};
+
+void f(S &s) {
+ int *i;
+ i = i + s;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+}
+
+void f2(int i[]) {
+ i[1] = 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic
+}
+
+void okay() {
+ int a[3];
+ i = a[2]; // OK, access to array
+
+ p = q;
+ p = &i;
+
+ i++;
+ ++i;
+ i--;
+ --i;
+ i += 1;
+ i -= 1;
+ i = j + 1;
+ i = j - 1;
+
+ auto diff = p - q; // OK, result is arithmetic
+
+ for(int ii : a) ; // OK, pointer arithmetic generated by compiler
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-const-cast.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-const-cast.cpp
new file mode 100644
index 0000000..2d32e13
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-const-cast.cpp
@@ -0,0 +1,6 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-const-cast %t
+
+const int *i;
+int *j;
+void f() { j = const_cast<int *>(i); }
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-cstyle-cast.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-cstyle-cast.cpp
new file mode 100644
index 0000000..31f59e3
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-cstyle-cast.cpp
@@ -0,0 +1,141 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-cstyle-cast %t
+
+void reinterpretcast() {
+ int i = 0;
+ void *j;
+ j = (int*)j;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use C-style cast to convert between unrelated types [cppcoreguidelines-pro-type-cstyle-cast]
+}
+
+void constcast() {
+ int* i;
+ const int* j;
+ i = (int*)j;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use C-style cast to cast away constness
+ j = (const int*)i; // OK, const added
+ (void)j; // OK, not a const_cast
+}
+
+void const_and_reinterpret() {
+ int* i;
+ const void* j;
+ i = (int*)j;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use C-style cast to convert between unrelated types
+}
+
+class Base {
+};
+
+class Derived : public Base {
+};
+
+class Base2 {
+};
+
+class MultiDerived : public Base, public Base2 {
+};
+
+class PolymorphicBase {
+public:
+ virtual ~PolymorphicBase();
+};
+
+class PolymorphicDerived : public PolymorphicBase {
+};
+
+class PolymorphicMultiDerived : public Base, public PolymorphicBase {
+};
+
+void pointers() {
+
+ auto P0 = (Derived*)new Base();
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use C-style cast to downcast from a base to a derived class
+
+ const Base* B0;
+ auto PC0 = (const Derived*)(B0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use C-style cast to downcast from a base to a derived class
+
+ auto P1 = (Base*)new Derived(); // OK, upcast to a public base
+ auto P2 = (Base*)new MultiDerived(); // OK, upcast to a public base
+ auto P3 = (Base2*)new MultiDerived(); // OK, upcast to a public base
+}
+
+void pointers_polymorphic() {
+
+ auto PP0 = (PolymorphicDerived*)new PolymorphicBase();
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use C-style cast to downcast from a base to a derived class; use dynamic_cast instead
+ // CHECK-FIXES: auto PP0 = dynamic_cast<PolymorphicDerived*>(new PolymorphicBase());
+
+ const PolymorphicBase* B0;
+ auto PPC0 = (const PolymorphicDerived*)B0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: do not use C-style cast to downcast from a base to a derived class; use dynamic_cast instead
+ // CHECK-FIXES: auto PPC0 = dynamic_cast<const PolymorphicDerived*>(B0);
+
+
+ auto B1 = (PolymorphicBase*)new PolymorphicDerived(); // OK, upcast to a public base
+ auto B2 = (PolymorphicBase*)new PolymorphicMultiDerived(); // OK, upcast to a public base
+ auto B3 = (Base*)new PolymorphicMultiDerived(); // OK, upcast to a public base
+}
+
+void arrays() {
+ Base ArrayOfBase[10];
+ auto A0 = (Derived*)ArrayOfBase;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use C-style cast to downcast from a base to a derived class
+}
+
+void arrays_polymorphic() {
+ PolymorphicBase ArrayOfPolymorphicBase[10];
+ auto AP0 = (PolymorphicDerived*)ArrayOfPolymorphicBase;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use C-style cast to downcast from a base to a derived class; use dynamic_cast instead
+ // CHECK-FIXES: auto AP0 = dynamic_cast<PolymorphicDerived*>(ArrayOfPolymorphicBase);
+}
+
+void references() {
+ Base B0;
+ auto R0 = (Derived&)B0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use C-style cast to downcast from a base to a derived class
+ Base& RefToBase = B0;
+ auto R1 = (Derived&)RefToBase;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use C-style cast to downcast from a base to a derived class
+
+ const Base& ConstRefToBase = B0;
+ auto RC1 = (const Derived&)ConstRefToBase;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use C-style cast to downcast from a base to a derived class
+
+
+ Derived RD1;
+ auto R2 = (Base&)RD1; // OK, upcast to a public base
+}
+
+void references_polymorphic() {
+ PolymorphicBase B0;
+ auto RP0 = (PolymorphicDerived&)B0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use C-style cast to downcast from a base to a derived class; use dynamic_cast instead
+ // CHECK-FIXES: auto RP0 = dynamic_cast<PolymorphicDerived&>(B0);
+
+ PolymorphicBase& RefToPolymorphicBase = B0;
+ auto RP1 = (PolymorphicDerived&)RefToPolymorphicBase;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use C-style cast to downcast from a base to a derived class; use dynamic_cast instead
+ // CHECK-FIXES: auto RP1 = dynamic_cast<PolymorphicDerived&>(RefToPolymorphicBase);
+
+ const PolymorphicBase& ConstRefToPolymorphicBase = B0;
+ auto RPC2 = (const PolymorphicDerived&)(ConstRefToPolymorphicBase);
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: do not use C-style cast to downcast from a base to a derived class; use dynamic_cast instead
+ // CHECK-FIXES: auto RPC2 = dynamic_cast<const PolymorphicDerived&>(ConstRefToPolymorphicBase);
+
+ PolymorphicDerived d1;
+ auto RP2 = (PolymorphicBase&)d1; // OK, upcast to a public base
+}
+
+template<class B, class D>
+void templ() {
+ auto B0 = (B*)new D();
+}
+
+void templ_bad_call() {
+ templ<Derived, Base>(); //FIXME: this should trigger a warning
+}
+
+void templ_good_call() {
+ templ<Base, Derived>(); // OK, upcast to a public base
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-member-init-cxx2a.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-member-init-cxx2a.cpp
new file mode 100644
index 0000000..d3e3ade
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-member-init-cxx2a.cpp
@@ -0,0 +1,19 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-member-init %t -- -- -std=c++2a -fno-delayed-template-parsing
+
+struct PositiveBitfieldMember {
+ PositiveBitfieldMember() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F
+ unsigned F : 5;
+ // CHECK-FIXES: unsigned F : 5{};
+};
+
+struct NegativeUnnamedBitfieldMember {
+ NegativeUnnamedBitfieldMember() {}
+ unsigned : 5;
+};
+
+struct NegativeInitializedBitfieldMembers {
+ NegativeInitializedBitfieldMembers() : F(3) { G = 2; }
+ unsigned F : 5;
+ unsigned G : 5;
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-member-init-cxx98.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-member-init-cxx98.cpp
new file mode 100644
index 0000000..db97bb4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-member-init-cxx98.cpp
@@ -0,0 +1,116 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-member-init %t -- -- -std=c++98 -fno-delayed-template-parsing
+
+struct PositiveFieldBeforeConstructor {
+ int F;
+ PositiveFieldBeforeConstructor() /* some comment */ {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F
+ // CHECK-FIXES: PositiveFieldBeforeConstructor() : F() /* some comment */ {}
+};
+
+struct PositiveFieldAfterConstructor {
+ PositiveFieldAfterConstructor() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F, G, H
+ // CHECK-FIXES: PositiveFieldAfterConstructor() : F(), G(), H() {}
+ int F;
+ bool G /* with comment */;
+ int *H;
+ PositiveFieldBeforeConstructor IgnoredField;
+};
+
+struct PositiveSeparateDefinition {
+ PositiveSeparateDefinition();
+ int F;
+};
+
+PositiveSeparateDefinition::PositiveSeparateDefinition() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: constructor does not initialize these fields: F
+// CHECK-FIXES: PositiveSeparateDefinition::PositiveSeparateDefinition() : F() {}
+
+struct PositiveMixedFieldOrder {
+ PositiveMixedFieldOrder() : /* some comment */ J(0), L(0), M(0) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: I, K, N
+ // CHECK-FIXES: PositiveMixedFieldOrder() : I(), /* some comment */ J(0), K(), L(0), M(0), N() {}
+ int I;
+ int J;
+ int K;
+ int L;
+ int M;
+ int N;
+};
+
+struct PositiveAfterBaseInitializer : public PositiveMixedFieldOrder {
+ PositiveAfterBaseInitializer() : PositiveMixedFieldOrder() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F
+ // CHECK-FIXES: PositiveAfterBaseInitializer() : PositiveMixedFieldOrder(), F() {}
+ int F;
+};
+
+struct NegativeFieldInitialized {
+ int F;
+
+ NegativeFieldInitialized() : F() {}
+};
+
+struct NegativeFieldInitializedInDefinition {
+ int F;
+
+ NegativeFieldInitializedInDefinition();
+};
+
+NegativeFieldInitializedInDefinition::NegativeFieldInitializedInDefinition() : F() {}
+
+struct NegativeInitializedInBody {
+ NegativeInitializedInBody() { I = 0; }
+ int I;
+};
+
+struct NegativeAggregateType {
+ int X;
+ int Y;
+ int Z;
+};
+
+struct TrivialType {
+ int X;
+ int Y;
+};
+
+struct PositiveUninitializedBaseOrdering : public NegativeAggregateType,
+ public TrivialType {
+ PositiveUninitializedBaseOrdering() : NegativeAggregateType(), TrivialType(), B() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: A
+ // CHECK-FIXES: PositiveUninitializedBaseOrdering() : NegativeAggregateType(), TrivialType(), A(), B() {}
+
+ // This is somewhat pathological with the base class initializer at the end...
+ PositiveUninitializedBaseOrdering(int) : B(), TrivialType(), A() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: NegativeAggregateType
+ // CHECK-FIXES: PositiveUninitializedBaseOrdering(int) : B(), NegativeAggregateType(), TrivialType(), A() {}
+
+ PositiveUninitializedBaseOrdering(float) : NegativeAggregateType(), A() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: TrivialType
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: constructor does not initialize these fields: B
+ // CHECK-FIXES: PositiveUninitializedBaseOrdering(float) : NegativeAggregateType(), TrivialType(), A(), B() {}
+
+ int A, B;
+};
+
+template <class T>
+class PositiveTemplateBase : T {
+public:
+ PositiveTemplateBase() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: X
+ // CHECK-FIXES: PositiveTemplateBase() : X() {}
+
+ int X;
+};
+
+class PositiveIndirectMember {
+ struct {
+ int *A;
+ };
+
+ PositiveIndirectMember() : A() {}
+ PositiveIndirectMember(int) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: A
+ // CHECK-FIXES: PositiveIndirectMember(int) : A() {}
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-member-init-delayed.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-member-init-delayed.cpp
new file mode 100644
index 0000000..d3436ba
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-member-init-delayed.cpp
@@ -0,0 +1,32 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-member-init %t -- -- -fdelayed-template-parsing
+
+template <class T>
+struct PositiveFieldBeforeConstructor {
+ int F;
+ bool G /* with comment */;
+ int *H;
+ PositiveFieldBeforeConstructor() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F, G, H
+};
+// Explicit instantiation.
+template class PositiveFieldBeforeConstructor<int>;
+
+template <class T>
+struct PositiveFieldAfterConstructor {
+ PositiveFieldAfterConstructor() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F, G, H
+ int F;
+ bool G /* with comment */;
+ int *H;
+};
+// Explicit instantiation.
+template class PositiveFieldAfterConstructor<int>;
+
+// This declaration isn't used and won't be parsed 'delayed-template-parsing'.
+// The body of the declaration is 'null' and may cause crash if not handled
+// properly by checkers.
+template <class T>
+struct UnusedDelayedConstructor {
+ UnusedDelayedConstructor() {}
+ int F;
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-member-init.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-member-init.cpp
new file mode 100644
index 0000000..86f094d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-member-init.cpp
@@ -0,0 +1,502 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-member-init %t -- -- -std=c++11 -fno-delayed-template-parsing
+
+struct PositiveFieldBeforeConstructor {
+ int F;
+ // CHECK-FIXES: int F{};
+ PositiveFieldBeforeConstructor() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F
+ // CHECK-FIXES: PositiveFieldBeforeConstructor() {}
+};
+
+struct PositiveFieldAfterConstructor {
+ PositiveFieldAfterConstructor() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F, G
+ // CHECK-FIXES: PositiveFieldAfterConstructor() {}
+ int F;
+ // CHECK-FIXES: int F{};
+ bool G /* with comment */;
+ // CHECK-FIXES: bool G{} /* with comment */;
+ PositiveFieldBeforeConstructor IgnoredField;
+};
+
+struct PositiveSeparateDefinition {
+ PositiveSeparateDefinition();
+ int F;
+ // CHECK-FIXES: int F{};
+};
+
+PositiveSeparateDefinition::PositiveSeparateDefinition() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: constructor does not initialize these fields: F
+// CHECK-FIXES: PositiveSeparateDefinition::PositiveSeparateDefinition() {}
+
+struct PositiveMixedFieldOrder {
+ PositiveMixedFieldOrder() : J(0) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: I, K
+ // CHECK-FIXES: PositiveMixedFieldOrder() : J(0) {}
+ int I;
+ // CHECK-FIXES: int I{};
+ int J;
+ int K;
+ // CHECK-FIXES: int K{};
+};
+
+template <typename T>
+struct Template {
+ Template() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F
+ int F;
+ // CHECK-FIXES: int F{};
+ T T1;
+ // CHECK-FIXES: T T1;
+};
+
+void instantiate() {
+ Template<int> TInt;
+}
+
+struct NegativeFieldInitialized {
+ int F;
+
+ NegativeFieldInitialized() : F() {}
+};
+
+struct NegativeFieldInitializedInDefinition {
+ int F;
+
+ NegativeFieldInitializedInDefinition();
+};
+NegativeFieldInitializedInDefinition::NegativeFieldInitializedInDefinition() : F() {}
+
+struct NegativeInClassInitialized {
+ int F = 0;
+
+ NegativeInClassInitialized() {}
+};
+
+struct NegativeInClassInitializedDefaulted {
+ int F = 0;
+ NegativeInClassInitializedDefaulted() = default;
+};
+
+struct NegativeConstructorDelegated {
+ int F;
+
+ NegativeConstructorDelegated(int F) : F(F) {}
+ NegativeConstructorDelegated() : NegativeConstructorDelegated(0) {}
+};
+
+struct NegativeInitializedInBody {
+ NegativeInitializedInBody() { I = 0; }
+ int I;
+};
+
+struct A {};
+template <class> class AA;
+template <class T> class NegativeTemplateConstructor {
+ NegativeTemplateConstructor(const AA<T> &, A) {}
+ bool Bool{false};
+ // CHECK-FIXES: bool Bool{false};
+};
+
+#define UNINITIALIZED_FIELD_IN_MACRO_BODY(FIELD) \
+ struct UninitializedField##FIELD { \
+ UninitializedField##FIELD() {} \
+ int FIELD; \
+ }; \
+// Ensure FIELD is not initialized since fixes inside of macros are disabled.
+// CHECK-FIXES: int FIELD;
+
+UNINITIALIZED_FIELD_IN_MACRO_BODY(F);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: constructor does not initialize these fields: F
+UNINITIALIZED_FIELD_IN_MACRO_BODY(G);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: constructor does not initialize these fields: G
+
+#define UNINITIALIZED_FIELD_IN_MACRO_ARGUMENT(ARGUMENT) \
+ ARGUMENT
+
+UNINITIALIZED_FIELD_IN_MACRO_ARGUMENT(struct UninitializedFieldInMacroArg {
+ UninitializedFieldInMacroArg() {}
+ int Field;
+});
+// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: constructor does not initialize these fields: Field
+// Ensure FIELD is not initialized since fixes inside of macros are disabled.
+// CHECK-FIXES: int Field;
+
+struct NegativeAggregateType {
+ int X;
+ int Y;
+ int Z;
+};
+
+struct PositiveTrivialType {
+ PositiveTrivialType() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F
+
+ NegativeAggregateType F;
+ // CHECK-FIXES: NegativeAggregateType F{};
+};
+
+struct NegativeNonTrivialType {
+ PositiveTrivialType F;
+};
+
+static void PositiveUninitializedTrivialType() {
+ NegativeAggregateType X;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: uninitialized record type: 'X'
+ // CHECK-FIXES: NegativeAggregateType X{};
+
+ NegativeAggregateType A[10]; // Don't warn because this isn't an object type.
+}
+
+static void NegativeInitializedTrivialType() {
+ NegativeAggregateType X{};
+ NegativeAggregateType Y = {};
+ NegativeAggregateType Z = NegativeAggregateType();
+ NegativeAggregateType A[10]{};
+ NegativeAggregateType B[10] = {};
+ int C; // No need to initialize this because we don't have a constructor.
+ int D[8];
+ NegativeAggregateType E = {0, 1, 2};
+ NegativeAggregateType F({});
+}
+
+struct NonTrivialType {
+ NonTrivialType() = default;
+ NonTrivialType(const NonTrivialType &RHS) : X(RHS.X), Y(RHS.Y) {}
+
+ int X;
+ int Y;
+};
+
+static void PositiveNonTrivialTypeWithCopyConstructor() {
+ NonTrivialType T;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: uninitialized record type: 'T'
+ // CHECK-FIXES: NonTrivialType T{};
+
+ NonTrivialType A[8];
+ // Don't warn because this isn't an object type
+}
+
+struct ComplexNonTrivialType {
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: constructor does not initialize these fields: Y
+ NegativeFieldInitialized X;
+ int Y;
+ // CHECK-FIXES: int Y{};
+};
+
+static void PositiveComplexNonTrivialType() {
+ ComplexNonTrivialType T;
+}
+
+struct NegativeStaticMember {
+ static NonTrivialType X;
+ static NonTrivialType Y;
+ static constexpr NonTrivialType Z{};
+};
+
+NonTrivialType NegativeStaticMember::X;
+NonTrivialType NegativeStaticMember::Y{};
+
+struct PositiveMultipleConstructors {
+ PositiveMultipleConstructors() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: A, B
+
+ PositiveMultipleConstructors(int) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: A, B
+
+ PositiveMultipleConstructors(const PositiveMultipleConstructors &) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: A, B
+
+ // FIXME: The fix-its here collide providing an erroneous fix
+ int A, B;
+ // CHECK-FIXES: int A{}{}{}, B{}{}{};
+};
+
+typedef struct {
+ int Member;
+} CStyleStruct;
+
+struct PositiveUninitializedBase : public NegativeAggregateType, CStyleStruct {
+ PositiveUninitializedBase() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: NegativeAggregateType, CStyleStruct
+ // CHECK-FIXES: PositiveUninitializedBase() : NegativeAggregateType(), CStyleStruct() {}
+};
+
+struct PositiveUninitializedBaseOrdering : public NegativeAggregateType,
+ public NonTrivialType {
+ PositiveUninitializedBaseOrdering() : B() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: NegativeAggregateType, NonTrivialType
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: constructor does not initialize these fields: A
+ // CHECK-FIXES: PositiveUninitializedBaseOrdering() : NegativeAggregateType(), NonTrivialType(), B() {}
+
+ // This is somewhat pathological with the base class initializer at the end...
+ PositiveUninitializedBaseOrdering(int) : B(), NonTrivialType(), A() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: NegativeAggregateType
+ // CHECK-FIXES: PositiveUninitializedBaseOrdering(int) : B(), NegativeAggregateType(), NonTrivialType(), A() {}
+
+ PositiveUninitializedBaseOrdering(float) : B(), NegativeAggregateType(), A() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: NonTrivialType
+ // CHECK-FIXES: PositiveUninitializedBaseOrdering(float) : B(), NegativeAggregateType(), NonTrivialType(), A() {}
+
+ int A, B;
+ // CHECK-FIXES: int A{}, B;
+};
+
+// We shouldn't need to initialize anything because PositiveUninitializedBase
+// has a user-defined constructor.
+struct NegativeUninitializedBase : public PositiveUninitializedBase {
+ NegativeUninitializedBase() {}
+};
+
+struct InheritedAggregate : public NegativeAggregateType {
+ int F;
+};
+
+static InheritedAggregate NegativeGlobal;
+
+enum TestEnum {
+ A,
+ B,
+ C
+};
+
+enum class TestScopedEnum {
+ A,
+ B,
+ C
+};
+
+struct PositiveEnumType {
+ PositiveEnumType() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: X, Y
+ // No proposed fixes, as we don't know whether value initialization for these
+ // enums really makes sense.
+
+ TestEnum X;
+ TestScopedEnum Y;
+};
+
+extern "C" {
+struct NegativeCStruct {
+ int X, Y, Z;
+};
+
+static void PositiveCStructVariable() {
+ NegativeCStruct X;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: uninitialized record type: 'X'
+ // CHECK-FIXES: NegativeCStruct X{};
+}
+}
+
+static void NegativeStaticVariable() {
+ static NegativeCStruct S;
+ (void)S;
+}
+
+union NegativeUnionInClass {
+ NegativeUnionInClass() {} // No message as a union can only initialize one member.
+ int X = 0;
+ float Y;
+};
+
+union PositiveUnion {
+ PositiveUnion() : X() {} // No message as a union can only initialize one member.
+ PositiveUnion(int) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: union constructor should initialize one of these fields: X, Y
+
+ int X;
+ // CHECK-FIXES: int X{};
+
+ // Make sure we don't give Y an initializer.
+ float Y;
+ // CHECK-FIXES-NOT: float Y{};
+};
+
+union PositiveUnionReversed {
+ PositiveUnionReversed() : X() {} // No message as a union can only initialize one member.
+ PositiveUnionReversed(int) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: union constructor should initialize one of these fields: Y, X
+
+ // Make sure we don't give Y an initializer.
+ TestEnum Y;
+ // CHECK-FIXES-NOT: TestEnum Y{};
+
+ int X;
+ // CHECK-FIXES: int X{};
+};
+
+struct PositiveAnonymousUnionAndStruct {
+ PositiveAnonymousUnionAndStruct() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: A, B, Y, Z, C, D, E, F, X
+
+ union {
+ int A;
+ // CHECK-FIXES: int A{};
+ short B;
+ };
+
+ struct {
+ int Y;
+ // CHECK-FIXES: int Y{};
+ char *Z;
+ // CHECK-FIXES: char *Z{};
+
+ struct {
+ short C;
+ // CHECK-FIXES: short C{};
+ double D;
+ // CHECK-FIXES: double D{};
+ };
+
+ union {
+ long E;
+ // CHECK-FIXES: long E{};
+ float F;
+ };
+ };
+ int X;
+ // CHECK-FIXES: int X{};
+};
+
+// This check results in a CXXConstructorDecl with no body.
+struct NegativeDeletedConstructor : NegativeAggregateType {
+ NegativeDeletedConstructor() = delete;
+
+ Template<int> F;
+};
+
+// This pathological template fails to compile if actually instantiated. It
+// results in the check seeing a null RecordDecl when examining the base class
+// initializer list.
+template <typename T>
+class PositiveSelfInitialization : NegativeAggregateType
+{
+ PositiveSelfInitialization() : PositiveSelfInitialization() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: NegativeAggregateType
+ // CHECK-FIXES: PositiveSelfInitialization() : NegativeAggregateType(), PositiveSelfInitialization() {}
+};
+
+class PositiveIndirectMember {
+ struct {
+ int *A;
+ // CHECK-FIXES: int *A{};
+ };
+
+ PositiveIndirectMember() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: A
+};
+
+void Bug30487()
+{
+ NegativeInClassInitializedDefaulted s;
+}
+
+struct PositiveVirtualMethod {
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: constructor does not initialize these fields: F
+ int F;
+ // CHECK-FIXES: int F{};
+ virtual int f() = 0;
+};
+
+struct PositiveVirtualDestructor {
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: constructor does not initialize these fields: F
+ PositiveVirtualDestructor() = default;
+ int F;
+ // CHECK-FIXES: int F{};
+ virtual ~PositiveVirtualDestructor() {}
+};
+
+struct PositiveVirtualBase : public virtual NegativeAggregateType {
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: constructor does not initialize these bases: NegativeAggregateType
+ // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: constructor does not initialize these fields: F
+ int F;
+ // CHECK-FIXES: int F{};
+};
+
+template <typename T>
+struct PositiveTemplateVirtualDestructor {
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: constructor does not initialize these fields: F
+ T Val;
+ int F;
+ // CHECK-FIXES: int F{};
+ virtual ~PositiveTemplateVirtualDestructor() = default;
+};
+
+template struct PositiveTemplateVirtualDestructor<int>;
+
+#define UNINITIALIZED_FIELD_IN_MACRO_BODY_VIRTUAL(FIELD) \
+ struct UninitializedFieldVirtual##FIELD { \
+ int FIELD; \
+ virtual ~UninitializedFieldVirtual##FIELD() {} \
+ }; \
+// Ensure FIELD is not initialized since fixes inside of macros are disabled.
+// CHECK-FIXES: int FIELD;
+
+UNINITIALIZED_FIELD_IN_MACRO_BODY_VIRTUAL(F);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: constructor does not initialize these fields: F
+UNINITIALIZED_FIELD_IN_MACRO_BODY_VIRTUAL(G);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: constructor does not initialize these fields: G
+
+struct NegativeEmpty {
+};
+
+static void NegativeEmptyVar() {
+ NegativeEmpty e;
+ (void)e;
+}
+
+struct NegativeEmptyMember {
+ NegativeEmptyMember() {}
+ NegativeEmpty e;
+};
+
+struct NegativeEmptyBase : NegativeEmpty {
+ NegativeEmptyBase() {}
+};
+
+struct NegativeEmptyArrayMember {
+ NegativeEmptyArrayMember() {}
+ char e[0];
+};
+
+struct NegativeIncompleteArrayMember {
+ NegativeIncompleteArrayMember() {}
+ char e[];
+};
+
+template <typename T> class NoCrash {
+ class B : public NoCrash {
+ template <typename U> B(U u) {}
+ };
+};
+
+struct PositiveBitfieldMember {
+ PositiveBitfieldMember() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F
+ unsigned F : 5;
+ // CHECK-FIXES-NOT: unsigned F : 5{};
+};
+
+struct NegativeUnnamedBitfieldMember {
+ NegativeUnnamedBitfieldMember() {}
+ unsigned : 5;
+};
+
+struct NegativeInitializedBitfieldMembers {
+ NegativeInitializedBitfieldMembers() : F(3) { G = 2; }
+ unsigned F : 5;
+ unsigned G : 5;
+};
+
+struct NegativeImplicitInheritedCtorBase {
+ NegativeImplicitInheritedCtorBase(unsigned F) : F(F) {}
+ unsigned F;
+};
+
+struct NegativeImplicitInheritedCtor : NegativeImplicitInheritedCtorBase {
+ using NegativeImplicitInheritedCtorBase::NegativeImplicitInheritedCtorBase;
+};
+
+void Bug33557() {
+ NegativeImplicitInheritedCtor I(5);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp
new file mode 100644
index 0000000..5420810
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp
@@ -0,0 +1,6 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-reinterpret-cast %t
+
+int i = 0;
+void *j;
+void f() { j = reinterpret_cast<void *>(i); }
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use reinterpret_cast [cppcoreguidelines-pro-type-reinterpret-cast]
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-static-cast-downcast.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-static-cast-downcast.cpp
new file mode 100644
index 0000000..7a6c027
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-static-cast-downcast.cpp
@@ -0,0 +1,118 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-static-cast-downcast %t
+
+class Base {
+};
+
+class Derived : public Base {
+};
+
+class Base2 {
+};
+
+class MultiDerived : public Base, public Base2 {
+};
+
+class PolymorphicBase {
+public:
+ virtual ~PolymorphicBase();
+};
+
+class PolymorphicDerived : public PolymorphicBase {
+};
+
+class PolymorphicMultiDerived : public Base, public PolymorphicBase {
+};
+
+void pointers() {
+
+ auto P0 = static_cast<Derived*>(new Base());
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+
+ const Base* B0;
+ auto PC0 = static_cast<const Derived*>(B0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+
+ auto P1 = static_cast<Base*>(new Derived()); // OK, upcast to a public base
+ auto P2 = static_cast<Base*>(new MultiDerived()); // OK, upcast to a public base
+ auto P3 = static_cast<Base2*>(new MultiDerived()); // OK, upcast to a public base
+}
+
+void pointers_polymorphic() {
+
+ auto PP0 = static_cast<PolymorphicDerived*>(new PolymorphicBase());
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead [cppcoreguidelines-pro-type-static-cast-downcast]
+ // CHECK-FIXES: auto PP0 = dynamic_cast<PolymorphicDerived*>(new PolymorphicBase());
+
+ const PolymorphicBase* B0;
+ auto PPC0 = static_cast<const PolymorphicDerived*>(B0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead [cppcoreguidelines-pro-type-static-cast-downcast]
+ // CHECK-FIXES: auto PPC0 = dynamic_cast<const PolymorphicDerived*>(B0);
+
+
+ auto B1 = static_cast<PolymorphicBase*>(new PolymorphicDerived()); // OK, upcast to a public base
+ auto B2 = static_cast<PolymorphicBase*>(new PolymorphicMultiDerived()); // OK, upcast to a public base
+ auto B3 = static_cast<Base*>(new PolymorphicMultiDerived()); // OK, upcast to a public base
+}
+
+void arrays() {
+ Base ArrayOfBase[10];
+ auto A0 = static_cast<Derived*>(ArrayOfBase);
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+}
+
+void arrays_polymorphic() {
+ PolymorphicBase ArrayOfPolymorphicBase[10];
+ auto AP0 = static_cast<PolymorphicDerived*>(ArrayOfPolymorphicBase);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead
+ // CHECK-FIXES: auto AP0 = dynamic_cast<PolymorphicDerived*>(ArrayOfPolymorphicBase);
+}
+
+void references() {
+ Base B0;
+ auto R0 = static_cast<Derived&>(B0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+ Base& RefToBase = B0;
+ auto R1 = static_cast<Derived&>(RefToBase);
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+
+ const Base& ConstRefToBase = B0;
+ auto RC1 = static_cast<const Derived&>(ConstRefToBase);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+
+
+ Derived RD1;
+ auto R2 = static_cast<Base&>(RD1); // OK, upcast to a public base
+}
+
+void references_polymorphic() {
+ PolymorphicBase B0;
+ auto RP0 = static_cast<PolymorphicDerived&>(B0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead
+ // CHECK-FIXES: auto RP0 = dynamic_cast<PolymorphicDerived&>(B0);
+
+ PolymorphicBase& RefToPolymorphicBase = B0;
+ auto RP1 = static_cast<PolymorphicDerived&>(RefToPolymorphicBase);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead [cppcoreguidelines-pro-type-static-cast-downcast]
+ // CHECK-FIXES: auto RP1 = dynamic_cast<PolymorphicDerived&>(RefToPolymorphicBase);
+
+ const PolymorphicBase& ConstRefToPolymorphicBase = B0;
+ auto RPC2 = static_cast<const PolymorphicDerived&>(ConstRefToPolymorphicBase);
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead [cppcoreguidelines-pro-type-static-cast-downcast]
+ // CHECK-FIXES: auto RPC2 = dynamic_cast<const PolymorphicDerived&>(ConstRefToPolymorphicBase);
+
+ PolymorphicDerived d1;
+ auto RP2 = static_cast<PolymorphicBase&>(d1); // OK, upcast to a public base
+}
+
+template<class B, class D>
+void templ() {
+ auto B0 = static_cast<B*>(new D());
+}
+
+void templ_bad_call() {
+ templ<Derived, Base>(); //FIXME: this should trigger a warning
+}
+
+void templ_good_call() {
+ templ<Base, Derived>(); // OK, upcast to a public base
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-union-access.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-union-access.cpp
new file mode 100644
index 0000000..6abc22b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-union-access.cpp
@@ -0,0 +1,41 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-union-access %t
+
+union U {
+ bool union_member1;
+ char union_member2;
+} u;
+
+struct S {
+ int non_union_member;
+ union {
+ bool union_member;
+ };
+ union {
+ char union_member2;
+ } u;
+} s;
+
+
+void f(char);
+void f2(U);
+void f3(U&);
+void f4(U*);
+
+void check()
+{
+ u.union_member1 = true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not access members of unions; use (boost::)variant instead [cppcoreguidelines-pro-type-union-access]
+ auto b = u.union_member2;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not access members of unions; use (boost::)variant instead
+ auto a = &s.union_member;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: do not access members of unions; use (boost::)variant instead
+ f(s.u.union_member2);
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not access members of unions; use (boost::)variant instead
+
+ s.non_union_member = 2; // OK
+
+ U u2 = u; // OK
+ f2(u); // OK
+ f3(u); // OK
+ f4(&u); // OK
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-vararg.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-vararg.cpp
new file mode 100644
index 0000000..021322a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-type-vararg.cpp
@@ -0,0 +1,51 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-vararg %t
+
+void f(int i);
+void f_vararg(int i, ...);
+
+struct C {
+ void g_vararg(...);
+ void g(const char*);
+} c;
+
+template<typename... P>
+void cpp_vararg(P... p);
+
+void check() {
+ f_vararg(1, 7, 9);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not call c-style vararg functions [cppcoreguidelines-pro-type-vararg]
+ c.g_vararg("foo");
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not call c-style vararg functions
+
+ f(3); // OK
+ c.g("foo"); // OK
+ cpp_vararg(1, 7, 9); // OK
+}
+
+// ... as a parameter is allowed (e.g. for SFINAE)
+template <typename T>
+void CallFooIfAvailableImpl(T& t, ...) {
+ // nothing
+}
+template <typename T>
+void CallFooIfAvailableImpl(T& t, decltype(t.foo())*) {
+ t.foo();
+}
+template <typename T>
+void CallFooIfAvailable(T& t) {
+ CallFooIfAvailableImpl(t, 0); // OK to call variadic function when the argument is a literal 0
+}
+
+#include <stdarg.h>
+void my_printf(const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not call c-style vararg functions
+ va_list n;
+ va_copy(n, ap); // Don't warn, va_copy is anyway useless without va_start
+ int i = va_arg(ap, int);
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not use va_start/va_arg to define c-style vararg functions; use variadic templates instead
+ va_end(ap); // Don't warn, va_end is anyway useless without va_start
+}
+
+int my_vprintf(const char* format, va_list arg ); // OK to declare function taking va_list
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-slicing.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-slicing.cpp
new file mode 100644
index 0000000..6856f52
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-slicing.cpp
@@ -0,0 +1,100 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-slicing %t
+
+class Base {
+ int i;
+ void f() {}
+ virtual void g() {}
+};
+
+class DerivedWithMemberVariables : public Base {
+ void f();
+ int j;
+};
+
+class TwiceDerivedWithNoMemberVariables : public DerivedWithMemberVariables {
+ void f();
+};
+
+class DerivedWithOverride : public Base {
+ void f();
+ void g() override {}
+};
+
+class TwiceDerivedWithNoOverride : public DerivedWithOverride {
+ void f();
+};
+
+void TakesBaseByValue(Base base);
+
+DerivedWithMemberVariables ReturnsDerived();
+
+void positivesWithMemberVariables() {
+ DerivedWithMemberVariables b;
+ Base a{b};
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state [cppcoreguidelines-slicing]
+ a = b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state
+ TakesBaseByValue(b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state
+
+ TwiceDerivedWithNoMemberVariables c;
+ a = c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'TwiceDerivedWithNoMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state
+
+ a = ReturnsDerived();
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state
+}
+
+void positivesWithOverride() {
+ DerivedWithOverride b;
+ Base a{b};
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: slicing object from type 'DerivedWithOverride' to 'Base' discards override 'g'
+ a = b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedWithOverride' to 'Base' discards override 'g'
+ TakesBaseByValue(b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: slicing object from type 'DerivedWithOverride' to 'Base' discards override 'g'
+
+ TwiceDerivedWithNoOverride c;
+ a = c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedWithOverride' to 'Base' discards override 'g'
+}
+
+void TakesBaseByReference(Base &base);
+
+class DerivedThatAddsVirtualH : public Base {
+ virtual void h();
+};
+
+class DerivedThatOverridesH : public DerivedThatAddsVirtualH {
+ void h() override;
+};
+
+void negatives() {
+ // OK, simple copying from the same type.
+ Base a;
+ TakesBaseByValue(a);
+ DerivedWithMemberVariables b;
+ DerivedWithMemberVariables c{b};
+ b = c;
+
+ // OK, derived type does not have extra state.
+ TwiceDerivedWithNoMemberVariables d;
+ DerivedWithMemberVariables e{d};
+ e = d;
+
+ // OK, derived does not override any method.
+ TwiceDerivedWithNoOverride f;
+ DerivedWithOverride g{f};
+ g = f;
+
+ // OK, no copying.
+ TakesBaseByReference(d);
+ TakesBaseByReference(f);
+
+ // Derived type overrides methods, but these methods are not in the base type,
+ // so cannot be called accidentally. Right now this triggers, but we might
+ // want to allow it.
+ DerivedThatOverridesH h;
+ a = h;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedThatOverridesH' to 'Base' discards override 'h'
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-special-member-functions-cxx-03.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-special-member-functions-cxx-03.cpp
new file mode 100644
index 0000000..8fe5e42
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-special-member-functions-cxx-03.cpp
@@ -0,0 +1,26 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-special-member-functions %t -- -- -std=c++03
+
+class DefinesDestructor {
+ ~DefinesDestructor();
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesDestructor' defines a non-default destructor but does not define a copy constructor or a copy assignment operator [cppcoreguidelines-special-member-functions]
+
+class DefinesCopyConstructor {
+ DefinesCopyConstructor(const DefinesCopyConstructor &);
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesCopyConstructor' defines a copy constructor but does not define a destructor or a copy assignment operator [cppcoreguidelines-special-member-functions]
+
+class DefinesCopyAssignment {
+ DefinesCopyAssignment &operator=(const DefinesCopyAssignment &);
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesCopyAssignment' defines a copy assignment operator but does not define a destructor or a copy constructor [cppcoreguidelines-special-member-functions]
+
+class DefinesNothing {
+};
+
+class DefinesEverything {
+ DefinesEverything(const DefinesEverything &);
+ DefinesEverything &operator=(const DefinesEverything &);
+ ~DefinesEverything();
+};
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-special-member-functions-relaxed.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-special-member-functions-relaxed.cpp
new file mode 100644
index 0000000..4fff02d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-special-member-functions-relaxed.cpp
@@ -0,0 +1,71 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-special-member-functions %t -- -config="{CheckOptions: [{key: cppcoreguidelines-special-member-functions.AllowMissingMoveFunctions, value: 1}, {key: cppcoreguidelines-special-member-functions.AllowSoleDefaultDtor, value: 1}]}" --
+
+class DefinesDestructor {
+ ~DefinesDestructor();
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesDestructor' defines a non-default destructor but does not define a copy constructor or a copy assignment operator [cppcoreguidelines-special-member-functions]
+
+class DefinesDefaultedDestructor {
+ ~DefinesDefaultedDestructor() = default;
+};
+
+class DefinesCopyConstructor {
+ DefinesCopyConstructor(const DefinesCopyConstructor &);
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesCopyConstructor' defines a copy constructor but does not define a destructor or a copy assignment operator [cppcoreguidelines-special-member-functions]
+
+class DefinesCopyAssignment {
+ DefinesCopyAssignment &operator=(const DefinesCopyAssignment &);
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesCopyAssignment' defines a copy assignment operator but does not define a destructor or a copy constructor [cppcoreguidelines-special-member-functions]
+
+class DefinesMoveConstructor {
+ DefinesMoveConstructor(DefinesMoveConstructor &&);
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesMoveConstructor' defines a move constructor but does not define a destructor, a copy constructor, a copy assignment operator or a move assignment operator [cppcoreguidelines-special-member-functions]
+
+class DefinesMoveAssignment {
+ DefinesMoveAssignment &operator=(DefinesMoveAssignment &&);
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesMoveAssignment' defines a move assignment operator but does not define a destructor, a copy constructor, a copy assignment operator or a move constructor [cppcoreguidelines-special-member-functions]
+class DefinesNothing {
+};
+
+class DefinesEverything {
+ DefinesEverything(const DefinesEverything &);
+ DefinesEverything &operator=(const DefinesEverything &);
+ DefinesEverything(DefinesEverything &&);
+ DefinesEverything &operator=(DefinesEverything &&);
+ ~DefinesEverything();
+};
+
+class DeletesEverything {
+ DeletesEverything(const DeletesEverything &) = delete;
+ DeletesEverything &operator=(const DeletesEverything &) = delete;
+ DeletesEverything(DeletesEverything &&) = delete;
+ DeletesEverything &operator=(DeletesEverything &&) = delete;
+ ~DeletesEverything() = delete;
+};
+
+class DeletesCopyDefaultsMove {
+ DeletesCopyDefaultsMove(const DeletesCopyDefaultsMove &) = delete;
+ DeletesCopyDefaultsMove &operator=(const DeletesCopyDefaultsMove &) = delete;
+ DeletesCopyDefaultsMove(DeletesCopyDefaultsMove &&) = default;
+ DeletesCopyDefaultsMove &operator=(DeletesCopyDefaultsMove &&) = default;
+ ~DeletesCopyDefaultsMove() = default;
+};
+
+template <typename T>
+struct TemplateClass {
+ TemplateClass() = default;
+ TemplateClass(const TemplateClass &);
+ TemplateClass &operator=(const TemplateClass &);
+ TemplateClass(TemplateClass &&);
+ TemplateClass &operator=(TemplateClass &&);
+ ~TemplateClass();
+};
+
+// Multiple instantiations of a class template will trigger multiple matches for defined special members.
+// This should not cause problems.
+TemplateClass<int> InstantiationWithInt;
+TemplateClass<double> InstantiationWithDouble;
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-special-member-functions.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-special-member-functions.cpp
new file mode 100644
index 0000000..013ba86
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/cppcoreguidelines-special-member-functions.cpp
@@ -0,0 +1,72 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-special-member-functions %t
+
+class DefinesDestructor {
+ ~DefinesDestructor();
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesDestructor' defines a non-default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions]
+
+class DefinesDefaultedDestructor {
+ ~DefinesDefaultedDestructor() = default;
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesDefaultedDestructor' defines a default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions]
+
+class DefinesCopyConstructor {
+ DefinesCopyConstructor(const DefinesCopyConstructor &);
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesCopyConstructor' defines a copy constructor but does not define a destructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions]
+
+class DefinesCopyAssignment {
+ DefinesCopyAssignment &operator=(const DefinesCopyAssignment &);
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesCopyAssignment' defines a copy assignment operator but does not define a destructor, a copy constructor, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions]
+
+class DefinesMoveConstructor {
+ DefinesMoveConstructor(DefinesMoveConstructor &&);
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesMoveConstructor' defines a move constructor but does not define a destructor, a copy constructor, a copy assignment operator or a move assignment operator [cppcoreguidelines-special-member-functions]
+
+class DefinesMoveAssignment {
+ DefinesMoveAssignment &operator=(DefinesMoveAssignment &&);
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesMoveAssignment' defines a move assignment operator but does not define a destructor, a copy constructor, a copy assignment operator or a move constructor [cppcoreguidelines-special-member-functions]
+class DefinesNothing {
+};
+
+class DefinesEverything {
+ DefinesEverything(const DefinesEverything &);
+ DefinesEverything &operator=(const DefinesEverything &);
+ DefinesEverything(DefinesEverything &&);
+ DefinesEverything &operator=(DefinesEverything &&);
+ ~DefinesEverything();
+};
+
+class DeletesEverything {
+ DeletesEverything(const DeletesEverything &) = delete;
+ DeletesEverything &operator=(const DeletesEverything &) = delete;
+ DeletesEverything(DeletesEverything &&) = delete;
+ DeletesEverything &operator=(DeletesEverything &&) = delete;
+ ~DeletesEverything() = delete;
+};
+
+class DeletesCopyDefaultsMove {
+ DeletesCopyDefaultsMove(const DeletesCopyDefaultsMove &) = delete;
+ DeletesCopyDefaultsMove &operator=(const DeletesCopyDefaultsMove &) = delete;
+ DeletesCopyDefaultsMove(DeletesCopyDefaultsMove &&) = default;
+ DeletesCopyDefaultsMove &operator=(DeletesCopyDefaultsMove &&) = default;
+ ~DeletesCopyDefaultsMove() = default;
+};
+
+template <typename T>
+struct TemplateClass {
+ TemplateClass() = default;
+ TemplateClass(const TemplateClass &);
+ TemplateClass &operator=(const TemplateClass &);
+ TemplateClass(TemplateClass &&);
+ TemplateClass &operator=(TemplateClass &&);
+ ~TemplateClass();
+};
+
+// Multiple instantiations of a class template will trigger multiple matches for defined special members.
+// This should not cause problems.
+TemplateClass<int> InstantiationWithInt;
+TemplateClass<double> InstantiationWithDouble;
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/custom-diagnostics.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/custom-diagnostics.cpp
new file mode 100644
index 0000000..8183770
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/custom-diagnostics.cpp
@@ -0,0 +1,27 @@
+// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-shadow,clang-diagnostic-float-conversion' %s -- | count 0
+//
+// Enable warnings using -config:
+// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-shadow,clang-diagnostic-float-conversion' \
+// RUN: -config='{ExtraArgs: ["-Wshadow","-Wno-unused-variable"], ExtraArgsBefore: ["-Wno-shadow","-Wfloat-conversion","-Wunused-variable"]}' %s -- \
+// RUN: | FileCheck -implicit-check-not='{{warning:|error:}}' %s
+//
+// ... -extra-arg:
+// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-shadow,clang-diagnostic-float-conversion' \
+// RUN: -extra-arg=-Wshadow -extra-arg=-Wno-unused-variable \
+// RUN: -extra-arg-before=-Wno-shadow -extra-arg-before=-Wfloat-conversion \
+// RUN: -extra-arg-before=-Wunused-variable %s -- \
+// RUN: | FileCheck -implicit-check-not='{{warning:|error:}}' %s
+//
+// ... a combination of -config and -extra-arg(-before):
+// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-shadow,clang-diagnostic-float-conversion' \
+// RUN: -config='{ExtraArgs: ["-Wno-unused-variable"], ExtraArgsBefore: ["-Wno-shadow","-Wfloat-conversion"]}' \
+// RUN: -extra-arg=-Wshadow -extra-arg-before=-Wunused-variable %s -- \
+// RUN: | FileCheck -implicit-check-not='{{warning:|error:}}' %s
+
+void f(float x) {
+ int a;
+ { int a; }
+ // CHECK: :[[@LINE-1]]:9: warning: declaration shadows a local variable [clang-diagnostic-shadow]
+ int b = x;
+ // CHECK: :[[@LINE-1]]:11: warning: implicit conversion turns floating-point number into integer: 'float' to 'int' [clang-diagnostic-float-conversion]
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/deduplication.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/deduplication.cpp
new file mode 100644
index 0000000..056fe4e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/deduplication.cpp
@@ -0,0 +1,10 @@
+// RUN: %check_clang_tidy %s google-explicit-constructor %t
+
+template<typename T>
+struct A { A(T); };
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: single-argument constructors must be marked explicit
+
+void f() {
+ A<int> a(0);
+ A<double> b(0);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/diagnostic.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/diagnostic.cpp
new file mode 100644
index 0000000..0df6e2a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/diagnostic.cpp
@@ -0,0 +1,52 @@
+// RUN: not clang-tidy -checks='-*,modernize-use-override' %s.nonexistent.cpp -- | FileCheck -check-prefix=CHECK1 -implicit-check-not='{{warning:|error:}}' %s
+// RUN: not clang-tidy -checks='-*,clang-diagnostic-*,google-explicit-constructor' %s -- -fan-unknown-option | FileCheck -check-prefix=CHECK2 -implicit-check-not='{{warning:|error:}}' %s
+// RUN: not clang-tidy -checks='-*,google-explicit-constructor,clang-diagnostic-literal-conversion' %s -- -fan-unknown-option | FileCheck -check-prefix=CHECK3 -implicit-check-not='{{warning:|error:}}' %s
+// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-macro-redefined' %s -- -DMACRO_FROM_COMMAND_LINE | FileCheck -check-prefix=CHECK4 -implicit-check-not='{{warning:|error:}}' %s
+// RUN: not clang-tidy -checks='-*,modernize-use-override' %s -- -DCOMPILATION_ERROR | FileCheck -check-prefix=CHECK6 -implicit-check-not='{{warning:|error:}}' %s
+//
+// Now repeat the tests and ensure no other errors appear on stderr:
+// RUN: not clang-tidy -checks='-*,modernize-use-override' %s.nonexistent.cpp -- 2>&1 | FileCheck -check-prefix=CHECK1 -implicit-check-not='{{warning:|error:}}' %s
+// RUN: not clang-tidy -checks='-*,clang-diagnostic-*,google-explicit-constructor' %s -- -fan-unknown-option 2>&1 | FileCheck -check-prefix=CHECK2 -implicit-check-not='{{warning:|error:}}' %s
+// RUN: not clang-tidy -checks='-*,google-explicit-constructor,clang-diagnostic-literal-conversion' %s -- -fan-unknown-option 2>&1 | FileCheck -check-prefix=CHECK3 -implicit-check-not='{{warning:|error:}}' %s
+// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-macro-redefined' %s -- -DMACRO_FROM_COMMAND_LINE 2>&1 | FileCheck -check-prefix=CHECK4 -implicit-check-not='{{warning:|error:}}' %s
+// RUN: not clang-tidy -checks='-*,modernize-use-override' %s -- -DCOMPILATION_ERROR 2>&1 | FileCheck -check-prefix=CHECK6 -implicit-check-not='{{warning:|error:}}' %s
+//
+// Now create a directory with a compilation database file and ensure we don't
+// use it after failing to parse commands from the command line:
+//
+// RUN: mkdir -p %T/diagnostics/
+// RUN: echo '[{"directory": "%/T/diagnostics/","command": "clang++ -fan-option-from-compilation-database -c %/T/diagnostics/input.cpp", "file": "%/T/diagnostics/input.cpp"}]' > %T/diagnostics/compile_commands.json
+// RUN: cat %s > %T/diagnostics/input.cpp
+// RUN: not clang-tidy -checks='-*,modernize-use-override' %T/diagnostics/nonexistent.cpp -- 2>&1 | FileCheck -check-prefix=CHECK1 -implicit-check-not='{{warning:|error:}}' %s
+// RUN: not clang-tidy -checks='-*,clang-diagnostic-*,google-explicit-constructor' %T/diagnostics/input.cpp -- -fan-unknown-option 2>&1 | FileCheck -check-prefix=CHECK2 -implicit-check-not='{{warning:|error:}}' %s
+// RUN: not clang-tidy -checks='-*,google-explicit-constructor,clang-diagnostic-literal-conversion' %T/diagnostics/input.cpp -- -fan-unknown-option 2>&1 | FileCheck -check-prefix=CHECK3 -implicit-check-not='{{warning:|error:}}' %s
+// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-macro-redefined' %T/diagnostics/input.cpp -- -DMACRO_FROM_COMMAND_LINE 2>&1 | FileCheck -check-prefix=CHECK4 -implicit-check-not='{{warning:|error:}}' %s
+// RUN: not clang-tidy -checks='-*,clang-diagnostic-*,google-explicit-constructor' %T/diagnostics/input.cpp 2>&1 | FileCheck -check-prefix=CHECK5 -implicit-check-not='{{warning:|error:}}' %s
+// RUN: not clang-tidy -checks='-*,modernize-use-override' %T/diagnostics/input.cpp -- -DCOMPILATION_ERROR 2>&1 | FileCheck -check-prefix=CHECK6 -implicit-check-not='{{warning:|error:}}' %s
+
+// CHECK1: error: no input files [clang-diagnostic-error]
+// CHECK1: error: no such file or directory: '{{.*}}nonexistent.cpp' [clang-diagnostic-error]
+// CHECK1: error: unable to handle compilation{{.*}} [clang-diagnostic-error]
+// CHECK2: error: unknown argument: '-fan-unknown-option' [clang-diagnostic-error]
+// CHECK3: error: unknown argument: '-fan-unknown-option' [clang-diagnostic-error]
+// CHECK5: error: unknown argument: '-fan-option-from-compilation-database' [clang-diagnostic-error]
+
+// CHECK2: :[[@LINE+3]]:9: warning: implicit conversion from 'double' to 'int' changes value from 1.5 to 1 [clang-diagnostic-literal-conversion]
+// CHECK3: :[[@LINE+2]]:9: warning: implicit conversion from 'double' to 'int' changes value
+// CHECK5: :[[@LINE+1]]:9: warning: implicit conversion from 'double' to 'int' changes value
+int a = 1.5;
+
+// CHECK2: :[[@LINE+3]]:11: warning: single-argument constructors must be marked explicit
+// CHECK3: :[[@LINE+2]]:11: warning: single-argument constructors must be marked explicit
+// CHECK5: :[[@LINE+1]]:11: warning: single-argument constructors must be marked explicit
+class A { A(int) {} };
+
+#define MACRO_FROM_COMMAND_LINE
+// CHECK4: :[[@LINE-1]]:9: warning: 'MACRO_FROM_COMMAND_LINE' macro redefined
+
+#ifdef COMPILATION_ERROR
+void f(int a) {
+ &(a + 1);
+ // CHECK6: :[[@LINE-1]]:3: error: cannot take the address of an rvalue of type 'int' [clang-diagnostic-error]
+}
+#endif
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/enable-alpha-checks.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/enable-alpha-checks.cpp
new file mode 100644
index 0000000..74bdfdb
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/enable-alpha-checks.cpp
@@ -0,0 +1,8 @@
+// REQUIRES: static-analyzer
+
+// Check if '-allow-enabling-analyzer-alpha-checkers' is visible for users.
+// RUN: clang-tidy -help | not grep 'allow-enabling-analyzer-alpha-checkers'
+
+// Check if '-allow-enabling-analyzer-alpha-checkers' enables alpha checks.
+// RUN: clang-tidy -checks=* -list-checks | not grep 'clang-analyzer-alpha'
+// RUN: clang-tidy -checks=* -list-checks -allow-enabling-analyzer-alpha-checkers | grep 'clang-analyzer-alpha'
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/explain-checks.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/explain-checks.cpp
new file mode 100644
index 0000000..9bff30c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/explain-checks.cpp
@@ -0,0 +1,12 @@
+// RUN: clang-tidy -checks=-*,modernize-use-nullptr -explain-config | FileCheck --check-prefix=CHECK-MESSAGE1 %s
+// RUN: clang-tidy -config="{Checks: '-*,modernize-use-nullptr'}" -explain-config | FileCheck --check-prefix=CHECK-MESSAGE2 %s
+// RUN: clang-tidy -checks=modernize-use-nullptr -config="{Checks: '-*,modernize-use-nullptr'}" -explain-config | FileCheck --check-prefix=CHECK-MESSAGE3 %s
+// RUN: clang-tidy -checks=modernize-use-nullptr -config="{Checks: '-*,-modernize-use-nullptr'}" %S/Inputs/explain-config/a.cc -explain-config -- | FileCheck --check-prefix=CHECK-MESSAGE4 %s
+// RUN: clang-tidy -checks=modernize-use-nullptr -config="{Checks: '-*,modernize-*'}" -explain-config | FileCheck --check-prefix=CHECK-MESSAGE5 %s
+// RUN: clang-tidy -explain-config %S/Inputs/explain-config/a.cc -- | grep "'modernize-use-nullptr' is enabled in the .*[/\\]Inputs[/\\]explain-config[/\\].clang-tidy."
+
+// CHECK-MESSAGE1: 'modernize-use-nullptr' is enabled in the command-line option '-checks'.
+// CHECK-MESSAGE2: 'modernize-use-nullptr' is enabled in the command-line option '-config'.
+// CHECK-MESSAGE3: 'modernize-use-nullptr' is enabled in the command-line option '-checks'.
+// CHECK-MESSAGE4: 'modernize-use-nullptr' is enabled in the command-line option '-checks'.
+// CHECK-MESSAGE5: 'modernize-use-nullptr' is enabled in the command-line option '-checks'.
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/export-diagnostics.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/export-diagnostics.cpp
new file mode 100644
index 0000000..5eda204
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/export-diagnostics.cpp
@@ -0,0 +1,28 @@
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t-input.cpp
+// RUN: clang-tidy %t-input.cpp -checks='-*,google-explicit-constructor,clang-diagnostic-missing-prototypes' -export-fixes=%t.yaml -- -Wmissing-prototypes > %t.msg 2>&1
+// RUN: FileCheck -input-file=%t.msg -check-prefix=CHECK-MESSAGES %s -implicit-check-not='{{warning|error|note}}:'
+// RUN: FileCheck -input-file=%t.yaml -check-prefix=CHECK-YAML %s
+#define X(n) void n ## n() {}
+X(f)
+
+// CHECK-MESSAGES: -input.cpp:2:1: warning: no previous prototype for function 'ff' [clang-diagnostic-missing-prototypes]
+// CHECK-MESSAGES: -input.cpp:1:19: note: expanded from macro 'X'
+// CHECK-MESSAGES: {{^}}note: expanded from here{{$}}
+
+// CHECK-YAML: ---
+// CHECK-YAML-NEXT: MainSourceFile: '{{.*}}-input.cpp'
+// CHECK-YAML-NEXT: Diagnostics:
+// CHECK-YAML-NEXT: - DiagnosticName: clang-diagnostic-missing-prototypes
+// CHECK-YAML-NEXT: Message: 'no previous prototype for function ''ff'''
+// CHECK-YAML-NEXT: FileOffset: 30
+// CHECK-YAML-NEXT: FilePath: '{{.*}}-input.cpp'
+// CHECK-YAML-NEXT: Notes:
+// CHECK-YAML-NEXT: - Message: 'expanded from macro ''X'''
+// CHECK-YAML-NEXT: FilePath: '{{.*}}-input.cpp'
+// CHECK-YAML-NEXT: FileOffset: 18
+// CHECK-YAML-NEXT: - Message: expanded from here
+// CHECK-YAML-NEXT: FilePath: ''
+// CHECK-YAML-NEXT: FileOffset: 0
+// CHECK-YAML-NEXT: Replacements: []
+// CHECK-YAML-NEXT: ...
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/export-relpath.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/export-relpath.cpp
new file mode 100644
index 0000000..5bfd41f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/export-relpath.cpp
@@ -0,0 +1,19 @@
+// RUN: rm -rf %T/clang-tidy/export-relpath
+// RUN: mkdir -p %T/clang-tidy/export-relpath/subdir
+// RUN: cp %s %T/clang-tidy/export-relpath/subdir/source.cpp
+// RUN: echo '[{ "directory": "%/T/clang-tidy/export-relpath/subdir", "command": "clang++ source.cpp", "file": "%/T/clang-tidy/export-relpath/subdir/source.cpp"}]' > %T/clang-tidy/export-relpath/subdir/compile_commands.json
+//
+// Check that running clang-tidy in './subdir' and storing results
+// in './fixes.yaml' works as expected.
+//
+// RUN: cd %T/clang-tidy/export-relpath
+// RUN: clang-tidy -p subdir subdir/source.cpp -checks='-*,google-explicit-constructor,llvm-namespace-comment' -export-fixes=./fixes.yaml
+// RUN: FileCheck -input-file=%T/clang-tidy/export-relpath/fixes.yaml -check-prefix=CHECK-YAML %s
+
+namespace i {
+void f(); // So that the namespace isn't empty.
+}
+// CHECK-YAML: ReplacementText: ' // namespace i'
+
+class A { A(int i); };
+// CHECK-YAML: ReplacementText: 'explicit '
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/extra-args.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/extra-args.cpp
new file mode 100644
index 0000000..d65aacc
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/extra-args.cpp
@@ -0,0 +1,7 @@
+// RUN: clang-tidy -checks='-*,modernize-use-override' \
+// RUN: -config='{ExtraArgs: ["-DTEST4"], ExtraArgsBefore: ["-DTEST1"]}' \
+// RUN: -extra-arg=-DTEST3 -extra-arg-before=-DTEST2 %s -- -v 2>&1 \
+// RUN: | FileCheck -implicit-check-not='{{warning:|error:}}' %s
+
+// CHECK: {{^}}clang Invocation:{{$}}
+// CHECK-NEXT: {{"-D" "TEST1" .*"-D" "TEST2" .*"-D" "TEST3" .*"-D" "TEST4"}}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/file-filter.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/file-filter.cpp
new file mode 100644
index 0000000..9ee5cad
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/file-filter.cpp
@@ -0,0 +1,73 @@
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='' %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck %s
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='' -quiet %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK-QUIET %s
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='.*' %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='.*' -quiet %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK2-QUIET %s
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='header2\.h' %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='header2\.h' -quiet %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK3-QUIET %s
+// FIXME: "-I %S/Inputs/file-filter/system/.." must be redundant.
+// On Win32, file-filter/system\system-header1.h precedes
+// file-filter\header*.h due to code order between '/' and '\\'.
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='.*' -system-headers %s -- -I %S/Inputs/file-filter/system/.. -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='.*' -system-headers -quiet %s -- -I %S/Inputs/file-filter/system/.. -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK4-QUIET %s
+
+#include "header1.h"
+// CHECK-NOT: warning:
+// CHECK-QUIET-NOT: warning:
+// CHECK2: header1.h:1:12: warning: single-argument constructors must be marked explicit
+// CHECK2-QUIET: header1.h:1:12: warning: single-argument constructors must be marked explicit
+// CHECK3-NOT: warning:
+// CHECK3-QUIET-NOT: warning:
+// CHECK4: header1.h:1:12: warning: single-argument constructors
+// CHECK4-QUIET: header1.h:1:12: warning: single-argument constructors
+
+#include "header2.h"
+// CHECK-NOT: warning:
+// CHECK-QUIET-NOT: warning:
+// CHECK2: header2.h:1:12: warning: single-argument constructors
+// CHECK2-QUIET: header2.h:1:12: warning: single-argument constructors
+// CHECK3: header2.h:1:12: warning: single-argument constructors
+// CHECK3-QUIET: header2.h:1:12: warning: single-argument constructors
+// CHECK4: header2.h:1:12: warning: single-argument constructors
+// CHECK4-QUIET: header2.h:1:12: warning: single-argument constructors
+
+#include <system-header.h>
+// CHECK-NOT: warning:
+// CHECK-QUIET-NOT: warning:
+// CHECK2-NOT: warning:
+// CHECK2-QUIET-NOT: warning:
+// CHECK3-NOT: warning:
+// CHECK3-QUIET-NOT: warning:
+// CHECK4: system-header.h:1:12: warning: single-argument constructors
+// CHECK4-QUIET: system-header.h:1:12: warning: single-argument constructors
+
+class A { A(int); };
+// CHECK: :[[@LINE-1]]:11: warning: single-argument constructors
+// CHECK-QUIET: :[[@LINE-2]]:11: warning: single-argument constructors
+// CHECK2: :[[@LINE-3]]:11: warning: single-argument constructors
+// CHECK2-QUIET: :[[@LINE-4]]:11: warning: single-argument constructors
+// CHECK3: :[[@LINE-5]]:11: warning: single-argument constructors
+// CHECK3-QUIET: :[[@LINE-6]]:11: warning: single-argument constructors
+// CHECK4: :[[@LINE-7]]:11: warning: single-argument constructors
+// CHECK4-QUIET: :[[@LINE-8]]:11: warning: single-argument constructors
+
+// CHECK-NOT: warning:
+// CHECK-QUIET-NOT: warning:
+// CHECK2-NOT: warning:
+// CHECK2-QUIET-NOT: warning:
+// CHECK3-NOT: warning:
+// CHECK3-QUIET-NOT: warning:
+// CHECK4-NOT: warning:
+// CHECK4-QUIET-NOT: warning:
+
+// CHECK: Suppressed 3 warnings (3 in non-user code)
+// CHECK: Use -header-filter=.* to display errors from all non-system headers.
+// CHECK-QUIET-NOT: Suppressed
+// CHECK2: Suppressed 1 warnings (1 in non-user code)
+// CHECK2: Use -header-filter=.* {{.*}}
+// CHECK2-QUIET-NOT: Suppressed
+// CHECK3: Suppressed 2 warnings (2 in non-user code)
+// CHECK3: Use -header-filter=.* {{.*}}
+// CHECK3-QUIET-NOT: Suppressed
+// CHECK4-NOT: Suppressed {{.*}} warnings
+// CHECK4-NOT: Use -header-filter=.* {{.*}}
+// CHECK4-QUIET-NOT: Suppressed
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/fix-errors.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/fix-errors.cpp
new file mode 100644
index 0000000..0c02616
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/fix-errors.cpp
@@ -0,0 +1,15 @@
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
+// RUN: not clang-tidy %t.cpp -checks='-*,google-explicit-constructor' -fix -- > %t.msg 2>&1
+// RUN: FileCheck -input-file=%t.cpp -check-prefix=CHECK-FIX %s
+// RUN: FileCheck -input-file=%t.msg -check-prefix=CHECK-MESSAGES %s
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
+// RUN: clang-tidy %t.cpp -checks='-*,google-explicit-constructor' -fix-errors -- > %t.msg 2>&1
+// RUN: FileCheck -input-file=%t.cpp -check-prefix=CHECK-FIX2 %s
+// RUN: FileCheck -input-file=%t.msg -check-prefix=CHECK-MESSAGES2 %s
+
+class A { A(int i); }
+// CHECK-FIX: class A { A(int i); }{{$}}
+// CHECK-MESSAGES: Fixes have NOT been applied.
+// CHECK-FIX2: class A { explicit A(int i); };
+// CHECK-MESSAGES2: note: FIX-IT applied suggested code changes
+// CHECK-MESSAGES2: clang-tidy applied 2 of 2 suggested fixes.
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/fix.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/fix.cpp
new file mode 100644
index 0000000..db6bc22
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/fix.cpp
@@ -0,0 +1,18 @@
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
+// RUN: clang-tidy %t.cpp -checks='-*,google-explicit-constructor,llvm-namespace-comment' -fix -export-fixes=%t.yaml -- > %t.msg 2>&1
+// RUN: FileCheck -input-file=%t.cpp %s
+// RUN: FileCheck -input-file=%t.msg -check-prefix=CHECK-MESSAGES %s
+// RUN: FileCheck -input-file=%t.yaml -check-prefix=CHECK-YAML %s
+
+namespace i {
+void f(); // So that the namespace isn't empty.
+}
+// CHECK: } // namespace i
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-YAML: ReplacementText: ' // namespace i'
+
+class A { A(int i); };
+// CHECK: class A { explicit A(int i); };
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-MESSAGES: clang-tidy applied 2 of 2 suggested fixes.
+// CHECK-YAML: ReplacementText: 'explicit '
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-default-arguments.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-default-arguments.cpp
new file mode 100644
index 0000000..23f269a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-default-arguments.cpp
@@ -0,0 +1,80 @@
+// RUN: %check_clang_tidy %s fuchsia-default-arguments %t
+
+int foo(int value = 5) { return value; }
+// CHECK-NOTES: [[@LINE-1]]:9: warning: declaring a parameter with a default argument is disallowed [fuchsia-default-arguments]
+// CHECK-FIXES: int foo(int value) { return value; }
+
+int f() {
+ foo();
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: calling a function that uses a default argument is disallowed [fuchsia-default-arguments]
+ // CHECK-NOTES: [[@LINE-7]]:9: note: default parameter was declared here
+}
+
+int bar(int value) { return value; }
+
+int n() {
+ foo(0);
+ bar(0);
+}
+
+class Baz {
+public:
+ int a(int value = 5) { return value; }
+ // CHECK-NOTES: [[@LINE-1]]:9: warning: declaring a parameter with a default argument is disallowed [fuchsia-default-arguments]
+ // CHECK-FIXES: int a(int value) { return value; }
+
+ int b(int value) { return value; }
+};
+
+class Foo {
+ // Fix should be suggested in declaration
+ int a(int value = 53);
+ // CHECK-NOTES: [[@LINE-1]]:9: warning: declaring a parameter with a default argument is disallowed [fuchsia-default-arguments]
+ // CHECK-FIXES: int a(int value);
+};
+
+// Fix shouldn't be suggested in implementation
+int Foo::a(int value) {
+ return value;
+}
+
+// Elided functions
+void f(int = 5) {};
+// CHECK-NOTES: [[@LINE-1]]:8: warning: declaring a parameter with a default argument is disallowed [fuchsia-default-arguments]
+// CHECK-FIXES: void f(int) {};
+
+void g(int) {};
+
+// Should not suggest fix for macro-defined parameters
+#define D(val) = val
+
+void h(int i D(5));
+// CHECK-NOTES: [[@LINE-1]]:8: warning: declaring a parameter with a default argument is disallowed [fuchsia-default-arguments]
+// CHECK-FIXES-NOT: void h(int i);
+
+void x(int i);
+void x(int i = 12);
+// CHECK-NOTES: [[@LINE-1]]:8: warning: declaring a parameter with a default argument is disallowed [fuchsia-default-arguments]
+// CHECK-FIXES: void x(int i);
+
+void x(int i) {}
+
+struct S {
+ void x(int i);
+};
+
+void S::x(int i = 12) {}
+// CHECK-NOTES: [[@LINE-1]]:11: warning: declaring a parameter with a default argument is disallowed [fuchsia-default-arguments]
+// CHECK-FIXES: void S::x(int i) {}
+
+int main() {
+ S s;
+ s.x();
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: calling a function that uses a default argument is disallowed [fuchsia-default-arguments]
+ // CHECK-NOTES: [[@LINE-8]]:11: note: default parameter was declared here
+ // CHECK-NEXT: void S::x(int i = 12) {}
+ x();
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: calling a function that uses a default argument is disallowed [fuchsia-default-arguments]
+ // CHECK-NOTES: [[@LINE-18]]:8: note: default parameter was declared here
+ // CHECK-NEXT: void x(int i = 12);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-multiple-inheritance.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-multiple-inheritance.cpp
new file mode 100644
index 0000000..fd2ed14
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-multiple-inheritance.cpp
@@ -0,0 +1,147 @@
+// RUN: %check_clang_tidy %s fuchsia-multiple-inheritance %t
+
+class Base_A {
+public:
+ virtual int foo() { return 0; }
+};
+
+class Base_B {
+public:
+ virtual int bar() { return 0; }
+};
+
+class Base_A_child : public Base_A {
+public:
+ virtual int baz() { return 0; }
+};
+
+class Interface_A {
+public:
+ virtual int foo() = 0;
+};
+
+class Interface_B {
+public:
+ virtual int bar() = 0;
+};
+
+class Interface_C {
+public:
+ virtual int blat() = 0;
+};
+
+class Interface_A_with_member {
+public:
+ virtual int foo() = 0;
+ int val = 0;
+};
+
+class Interface_with_A_Parent : public Base_A {
+public:
+ virtual int baz() = 0;
+};
+
+// Inherits from multiple concrete classes.
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting mulitple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance]
+// CHECK-NEXT: class Bad_Child1 : public Base_A, Base_B {};
+class Bad_Child1 : public Base_A, Base_B {};
+
+// CHECK-MESSAGES: [[@LINE+1]]:1: warning: inheriting mulitple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance]
+class Bad_Child2 : public Base_A, Interface_A_with_member {
+ virtual int foo() override { return 0; }
+};
+
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting mulitple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance]
+// CHECK-NEXT: class Bad_Child3 : public Interface_with_A_Parent, Base_B {
+class Bad_Child3 : public Interface_with_A_Parent, Base_B {
+ virtual int baz() override { return 0; }
+};
+
+// Easy cases of single inheritance
+class Simple_Child1 : public Base_A {};
+class Simple_Child2 : public Interface_A {
+ virtual int foo() override { return 0; }
+};
+
+// Valid uses of multiple inheritance
+class Good_Child1 : public Interface_A, Interface_B {
+ virtual int foo() override { return 0; }
+ virtual int bar() override { return 0; }
+};
+
+class Good_Child2 : public Base_A, Interface_B {
+ virtual int bar() override { return 0; }
+};
+
+class Good_Child3 : public Base_A_child, Interface_C, Interface_B {
+ virtual int bar() override { return 0; }
+ virtual int blat() override { return 0; }
+};
+
+struct B1 { int x; };
+struct B2 { int x;};
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting mulitple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance]
+// CHECK-NEXT: struct D : B1, B2 {};
+struct D1 : B1, B2 {};
+
+struct Base1 { virtual void foo() = 0; };
+struct V1 : virtual Base1 {};
+struct V2 : virtual Base1 {};
+struct D2 : V1, V2 {};
+
+struct Base2 { virtual void foo(); };
+struct V3 : virtual Base2 {};
+struct V4 : virtual Base2 {};
+struct D3 : V3, V4 {};
+
+struct Base3 {};
+struct V5 : virtual Base3 { virtual void f(); };
+struct V6 : virtual Base3 { virtual void g(); };
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting mulitple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance]
+// CHECK-NEXT: struct D4 : V5, V6 {};
+struct D4 : V5, V6 {};
+
+struct Base4 {};
+struct V7 : virtual Base4 { virtual void f() = 0; };
+struct V8 : virtual Base4 { virtual void g() = 0; };
+struct D5 : V7, V8 {};
+
+struct Base5 { virtual void f() = 0; };
+struct V9 : virtual Base5 { virtual void f(); };
+struct V10 : virtual Base5 { virtual void g() = 0; };
+struct D6 : V9, V10 {};
+
+struct Base6 { virtual void f(); };
+struct Base7 { virtual void g(); };
+struct V15 : virtual Base6 { virtual void f() = 0; };
+struct V16 : virtual Base7 { virtual void g() = 0; };
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting mulitple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance]
+// CHECK-NEXT: struct D9 : V15, V16 {};
+struct D9 : V15, V16 {};
+
+struct Static_Base { static void foo(); };
+struct V11 : virtual Static_Base {};
+struct V12 : virtual Static_Base {};
+struct D7 : V11, V12 {};
+
+struct Static_Base_2 {};
+struct V13 : virtual Static_Base_2 { static void f(); };
+struct V14 : virtual Static_Base_2 { static void g(); };
+struct D8 : V13, V14 {};
+
+template<typename T> struct A : T {};
+template<typename T> struct B : virtual T {};
+
+template<typename> struct C {};
+template<typename T> struct D : C<T> {};
+
+// Check clang_tidy does not crash on this code.
+template <class T>
+struct WithTemplBase : T {
+ WithTemplBase();
+};
+
+int test_no_crash() {
+ auto foo = []() {};
+ WithTemplBase<decltype(foo)>();
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-overloaded-operator.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-overloaded-operator.cpp
new file mode 100644
index 0000000..7f7a36e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-overloaded-operator.cpp
@@ -0,0 +1,23 @@
+// RUN: %check_clang_tidy %s fuchsia-overloaded-operator %t
+
+class A {
+public:
+ int operator+(int);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: overloading 'operator+' is disallowed
+};
+
+class B {
+public:
+ B &operator=(const B &Other);
+ // CHECK-MESSAGES-NOT: [[@LINE-1]]:3: warning: overloading 'operator=' is disallowed
+ B &operator=(B &&Other);
+ // CHECK-MESSAGES-NOT: [[@LINE-1]]:3: warning: overloading 'operator=' is disallowed
+};
+
+A operator-(const A &A1, const A &A2);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: overloading 'operator-' is disallowed
+
+void operator delete(void*, void*) throw();
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: overloading 'operator delete' is disallowed
+
+auto x = []{};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-restrict-system-includes-all.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-restrict-system-includes-all.cpp
new file mode 100644
index 0000000..21f4b68
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-restrict-system-includes-all.cpp
@@ -0,0 +1,10 @@
+// RUN: %check_clang_tidy %s fuchsia-restrict-system-includes %t \
+// RUN: -- -config="{CheckOptions: [{key: fuchsia-restrict-system-includes.Includes, value: ''}]}" \
+// RUN: -- -std=c++11 -I %S/Inputs/fuchsia-restrict-system-includes -isystem %S/Inputs/fuchsia-restrict-system-includes/system
+
+#include <cstdlib.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: system include cstdlib.h not allowed
+#include <cstdarg.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: system include cstdarg.h not allowed
+#include <t.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: system include t.h not allowed
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-restrict-system-includes-glob.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-restrict-system-includes-glob.cpp
new file mode 100644
index 0000000..334990d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-restrict-system-includes-glob.cpp
@@ -0,0 +1,9 @@
+// RUN: %check_clang_tidy %s fuchsia-restrict-system-includes %t \
+// RUN: -- -config="{CheckOptions: [{key: fuchsia-restrict-system-includes.Includes, value: 'cstd*'}]}" \
+// RUN: -- -std=c++11 -I %S/Inputs/fuchsia-restrict-system-includes -isystem %S/Inputs/fuchsia-restrict-system-includes/system
+
+#include <cstdlib.h>
+#include <cstdarg.h>
+#include <t.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: system include t.h not allowed
+// CHECK-FIXES-NOT: #include <t.h>
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-restrict-system-includes-headers.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-restrict-system-includes-headers.cpp
new file mode 100644
index 0000000..f392eac
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-restrict-system-includes-headers.cpp
@@ -0,0 +1,23 @@
+// RUN: rm -rf %T/Headers
+// RUN: mkdir %T/Headers
+// RUN: cp -r %S/Inputs/fuchsia-restrict-system-includes %T/Headers/fuchsia-restrict-system-includes
+// RUN: %check_clang_tidy %s fuchsia-restrict-system-includes %t \
+// RUN: -- -config="{CheckOptions: [{key: fuchsia-restrict-system-includes.Includes, value: 'transitive.h,s.h'}]}" \
+// RUN: -system-headers -header-filter=.* \
+// RUN: -- -std=c++11 -I %T/Headers/fuchsia-restrict-system-includes -isystem %T/Headers/fuchsia-restrict-system-includes/system
+// RUN: FileCheck -input-file=%T/Headers/fuchsia-restrict-system-includes/transitive2.h %s -check-prefix=CHECK-FIXES
+// RUN: rm -rf %T/Headers
+
+// transitive.h includes <r.h> and <t.h>
+#include <transitive.h>
+// CHECK-MESSAGES: :1:1: warning: system include r.h not allowed, transitively included from {{.*}}
+// CHECK-MESSAGES: :2:1: warning: system include t.h not allowed, transitively included from {{.*}}
+
+// transitive.h includes <s.h> and <t.h>
+#include "transitive2.h"
+// CHECK-MESSAGES: :2:1: warning: system include t.h not allowed, transitively included from {{.*}}
+// CHECK-FIXES-NOT: #include <t.h>
+
+int main() {
+ // f() is declared in r.h
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-restrict-system-includes.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-restrict-system-includes.cpp
new file mode 100644
index 0000000..e2ba710
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-restrict-system-includes.cpp
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s fuchsia-restrict-system-includes %t \
+// RUN: -- -config="{CheckOptions: [{key: fuchsia-restrict-system-includes.Includes, value: 's.h'}]}" \
+// RUN: -- -std=c++11 -I %S/Inputs/fuchsia-restrict-system-includes -isystem %S/Inputs/fuchsia-restrict-system-includes/system
+
+#include "a.h"
+
+#include <s.h>
+#include <t.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: system include t.h not allowed
+// CHECK-FIXES-NOT: #include <t.h>
+
+#include "s.h"
+#include "t.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: system include t.h not allowed
+// CHECK-FIXES-NOT: #include "t.h"
+
+#define foo <j.h>
+
+#include foo
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: system include j.h not allowed
+// CHECK-FIXES-NOT: #include foo
+
+#/* comment */ include /* comment */ foo
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: system include j.h not allowed
+// CHECK-FIXES-NOT: # /* comment */ include /* comment */ foo
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-statically-constructed-objects.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-statically-constructed-objects.cpp
new file mode 100644
index 0000000..006494e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-statically-constructed-objects.cpp
@@ -0,0 +1,91 @@
+// RUN: %check_clang_tidy %s fuchsia-statically-constructed-objects %t
+
+// Trivial static is fine
+static int i;
+
+class ClassWithNoCtor {};
+
+class ClassWithCtor {
+public:
+ ClassWithCtor(int Val) : Val(Val) {}
+private:
+ int Val;
+};
+
+class ClassWithConstexpr {
+public:
+ ClassWithConstexpr(int Val1, int Val2) : Val(Val1) {}
+ constexpr ClassWithConstexpr(int Val) : Val(Val) {}
+
+private:
+ int Val;
+};
+
+ClassWithNoCtor A;
+ClassWithConstexpr C(0);
+ClassWithConstexpr E(0, 1);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: static objects are disallowed; if possible, use a constexpr constructor instead [fuchsia-statically-constructed-objects]
+// CHECK-MESSAGES-NEXT: ClassWithConstexpr E(0, 1);
+ClassWithCtor G(0);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: static objects are disallowed; if possible, use a constexpr constructor instead [fuchsia-statically-constructed-objects]
+// CHECK-MESSAGES-NEXT: ClassWithCtor G(0);
+
+static ClassWithNoCtor A2;
+static ClassWithConstexpr C2(0);
+static ClassWithConstexpr E2(0, 1);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: static objects are disallowed; if possible, use a constexpr constructor instead [fuchsia-statically-constructed-objects]
+// CHECK-MESSAGES-NEXT: static ClassWithConstexpr E2(0, 1);
+static ClassWithCtor G2(0);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: static objects are disallowed; if possible, use a constexpr constructor instead [fuchsia-statically-constructed-objects]
+// CHECK-MESSAGES-NEXT: static ClassWithCtor G2(0);
+
+struct StructWithConstexpr { constexpr StructWithConstexpr(int Val) {} };
+struct StructWithNoCtor {};
+struct StructWithCtor { StructWithCtor(); };
+
+StructWithNoCtor SNoCtor;
+StructWithConstexpr SConstexpr(0);
+StructWithCtor SCtor;
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: static objects are disallowed; if possible, use a constexpr constructor instead [fuchsia-statically-constructed-objects]
+// CHECK-MESSAGES-NEXT: StructWithCtor SCtor;
+
+static StructWithConstexpr SConstexpr2(0);
+static StructWithNoCtor SNoCtor2;
+static StructWithCtor SCtor2;
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: static objects are disallowed; if possible, use a constexpr constructor instead [fuchsia-statically-constructed-objects]
+// CHECK-MESSAGES-NEXT: static StructWithCtor SCtor2;
+
+extern StructWithCtor SCtor3;
+
+class ClassWithStaticMember {
+private:
+ static StructWithNoCtor S;
+};
+
+ClassWithStaticMember Z();
+
+class S {
+ int Val;
+public:
+ constexpr S(int i) : Val(100 / i) {}
+ int getVal() const { return Val; }
+};
+
+static S s1(1);
+static S s2(0);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: static objects are disallowed; if possible, use a constexpr constructor instead [fuchsia-statically-constructed-objects]
+// CHECK-MESSAGES-NEXT: static S s2(0);
+
+extern int get_i();
+static S s3(get_i());
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: static objects are disallowed; if possible, use a constexpr constructor instead [fuchsia-statically-constructed-objects]
+// CHECK-MESSAGES-NEXT: static S s3(get_i());
+
+void f() {
+ // Locally static is fine
+ static int i;
+ static ClassWithNoCtor A2;
+ static ClassWithConstexpr C2(0);
+ static ClassWithConstexpr E2(0, 1);
+ static ClassWithCtor G2(0);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-trailing-return.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-trailing-return.cpp
new file mode 100644
index 0000000..f6c943a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-trailing-return.cpp
@@ -0,0 +1,23 @@
+// RUN: %check_clang_tidy %s fuchsia-trailing-return %t
+
+int add_one(const int arg) { return arg; }
+
+auto get_add_one() -> int (*)(const int) {
+ // CHECK-MESSAGES: [[@LINE-1]]:1: warning: a trailing return type is disallowed for this type of declaration
+ // CHECK-NEXT: auto get_add_one() -> int (*)(const int) {
+ return add_one;
+}
+
+auto lambda = [](double x, double y) {return x + y;};
+
+auto lambda2 = [](double x, double y) -> double {return x + y;};
+
+int main() {
+ get_add_one()(5);
+ return 0;
+}
+
+template <typename T1, typename T2>
+auto fn(const T1 &lhs, const T2 &rhs) -> decltype(lhs + rhs) {
+ return lhs + rhs;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-virtual-inheritance.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-virtual-inheritance.cpp
new file mode 100644
index 0000000..0c3311a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/fuchsia-virtual-inheritance.cpp
@@ -0,0 +1,42 @@
+// RUN: %check_clang_tidy %s fuchsia-virtual-inheritance %t
+
+class A {
+public:
+ A(int value) : val(value) {}
+
+ int do_A() { return val; }
+
+private:
+ int val;
+};
+
+class B : public virtual A {
+ // CHECK-MESSAGES: [[@LINE-1]]:1: warning: direct virtual inheritance is disallowed [fuchsia-virtual-inheritance]
+ // CHECK-NEXT: class B : public virtual A {
+public:
+ B() : A(0) {}
+ int do_B() { return 1 + do_A(); }
+};
+
+class C : public virtual A {
+ // CHECK-MESSAGES: [[@LINE-1]]:1: warning: direct virtual inheritance is disallowed [fuchsia-virtual-inheritance]
+ // CHECK-NEXT: class C : public virtual A {
+public:
+ C() : A(0) {}
+ int do_C() { return 2 + do_A(); }
+};
+
+class D : public B, public C {
+public:
+ D(int value) : A(value), B(), C() {}
+
+ int do_D() { return do_A() + do_B() + do_C(); }
+};
+
+int main() {
+ A *a = new A(0);
+ B *b = new B();
+ C *c = new C();
+ D *d = new D(0);
+ return 0;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/google-build-explicit-make-pair.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-build-explicit-make-pair.cpp
new file mode 100644
index 0000000..6dcd357
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-build-explicit-make-pair.cpp
@@ -0,0 +1,51 @@
+// RUN: %check_clang_tidy %s google-build-explicit-make-pair %t
+
+namespace std {
+template <class T1, class T2>
+struct pair {
+ pair(T1 x, T2 y) {}
+};
+
+template <class T1, class T2>
+pair<T1, T2> make_pair(T1 x, T2 y) {
+ return pair<T1, T2>(x, y);
+}
+}
+
+template <typename T>
+void templ(T a, T b) {
+ std::make_pair<T, unsigned>(a, b);
+ std::make_pair<int, int>(1, 2);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: for C++11-compatibility, omit template arguments from make_pair
+// CHECK-FIXES: std::make_pair(1, 2)
+}
+
+template <typename T>
+int t();
+
+void test(int i) {
+ std::make_pair<int, int>(i, i);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: for C++11-compatibility, omit template arguments from make_pair
+// CHECK-FIXES: std::make_pair(i, i)
+
+ std::make_pair<unsigned, int>(i, i);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: for C++11-compatibility, use pair directly
+// CHECK-FIXES: std::pair<unsigned, int>(i, i)
+
+ std::make_pair<int, unsigned>(i, i);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: for C++11-compatibility, use pair directly
+// CHECK-FIXES: std::pair<int, unsigned>(i, i)
+
+#define M std::make_pair<int, unsigned>(i, i);
+M
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: for C++11-compatibility, use pair directly
+// Can't fix in macros.
+// CHECK-FIXES: #define M std::make_pair<int, unsigned>(i, i);
+// CHECK-FIXES-NEXT: M
+
+ templ(i, i);
+ templ(1U, 2U);
+
+ std::make_pair(i, 1); // no-warning
+ std::make_pair(t<int>, 1);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/google-default-arguments.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-default-arguments.cpp
new file mode 100644
index 0000000..48d3f2d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-default-arguments.cpp
@@ -0,0 +1,29 @@
+// RUN: %check_clang_tidy %s google-default-arguments %t
+
+struct A {
+ virtual void f(int I, int J = 3);
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: default arguments on virtual or override methods are prohibited [google-default-arguments]
+};
+
+struct B : public A {
+ void f(int I, int J = 5);
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: default arguments on virtual or override methods are prohibited
+};
+
+struct C : public B {
+ void f(int I, int J = 5) override;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: default arguments on virtual or override methods are prohibited
+};
+
+// Negatives.
+struct D : public B {
+ void f(int I, int J) override;
+};
+
+struct X {
+ void f(int I, int J = 3);
+};
+
+struct Y : public X {
+ void f(int I, int J = 5);
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/google-explicit-constructor.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-explicit-constructor.cpp
new file mode 100644
index 0000000..921237a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-explicit-constructor.cpp
@@ -0,0 +1,188 @@
+// RUN: %check_clang_tidy %s google-explicit-constructor %t
+
+namespace std {
+ typedef decltype(sizeof(int)) size_t;
+
+ // libc++'s implementation
+ template <class _E>
+ class initializer_list
+ {
+ const _E* __begin_;
+ size_t __size_;
+
+ initializer_list(const _E* __b, size_t __s)
+ : __begin_(__b),
+ __size_(__s)
+ {}
+
+ public:
+ typedef _E value_type;
+ typedef const _E& reference;
+ typedef const _E& const_reference;
+ typedef size_t size_type;
+
+ typedef const _E* iterator;
+ typedef const _E* const_iterator;
+
+ initializer_list() : __begin_(nullptr), __size_(0) {}
+
+ size_t size() const {return __size_;}
+ const _E* begin() const {return __begin_;}
+ const _E* end() const {return __begin_ + __size_;}
+ };
+}
+
+struct A {
+ A() {}
+ A(int x, int y) {}
+
+ explicit A(void *x) {}
+ explicit A(void *x, void *y) {}
+ explicit operator bool() const { return true; }
+
+ operator double() const = delete;
+
+ explicit A(const A& a) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: copy constructor should not be declared explicit [google-explicit-constructor]
+ // CHECK-FIXES: {{^ }}A(const A& a) {}
+
+ A(int x1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors must be marked explicit to avoid unintentional implicit conversions [google-explicit-constructor]
+ // CHECK-FIXES: {{^ }}explicit A(int x1);
+
+ A(double x2, double y = 3.14) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructors that are callable with a single argument must be marked explicit to avoid unintentional implicit conversions [google-explicit-constructor]
+ // CHECK-FIXES: {{^ }}explicit A(double x2, double y = 3.14) {}
+
+ template <typename... T>
+ A(T&&... args);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructors that are callable with a single argument
+ // CHECK-FIXES: {{^ }}explicit A(T&&... args);
+};
+
+inline A::A(int x1) {}
+
+struct B {
+ B(std::initializer_list<int> list1) {}
+ B(const std::initializer_list<unsigned> &list2) {}
+ B(std::initializer_list<unsigned> &&list3) {}
+
+ operator bool() const { return true; }
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'operator bool' must be marked explicit to avoid unintentional implicit conversions [google-explicit-constructor]
+ // CHECK-FIXES: {{^ }}explicit operator bool() const { return true; }
+
+ operator double() const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'operator double' must be marked explicit to avoid unintentional implicit conversions [google-explicit-constructor]
+ // CHECK-FIXES: {{^ }}explicit operator double() const;
+
+ explicit B(::std::initializer_list<double> list4) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor should not be declared explicit [google-explicit-constructor]
+ // CHECK-FIXES: {{^ }}B(::std::initializer_list<double> list4) {}
+
+ explicit B(const ::std::initializer_list<char> &list5) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor
+ // CHECK-FIXES: {{^ }}B(const ::std::initializer_list<char> &list5) {}
+
+ explicit B(::std::initializer_list<char> &&list6) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor
+ // CHECK-FIXES: {{^ }}B(::std::initializer_list<char> &&list6) {}
+};
+
+inline B::operator double() const { return 0.0; }
+
+struct StructWithFnPointer {
+ void (*f)();
+} struct_with_fn_pointer = {[] {}};
+
+using namespace std;
+
+struct C {
+ C(initializer_list<int> list1) {}
+ C(const initializer_list<unsigned> &list2) {}
+ C(initializer_list<unsigned> &&list3) {}
+};
+
+template <typename T>
+struct C2 {
+ C2(initializer_list<int> list1) {}
+ C2(const initializer_list<unsigned> &list2) {}
+ C2(initializer_list<unsigned> &&list3) {}
+
+ explicit C2(initializer_list<double> list4) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor
+ // CHECK-FIXES: {{^ }}C2(initializer_list<double> list4) {}
+};
+
+template <typename T>
+struct C3 {
+ C3(initializer_list<T> list1) {}
+ C3(const std::initializer_list<T*> &list2) {}
+ C3(::std::initializer_list<T**> &&list3) {}
+
+ template <typename U>
+ C3(initializer_list<U> list3) {}
+};
+
+struct D {
+ template <typename T>
+ explicit D(T t) {}
+};
+
+template <typename T>
+struct E {
+ E(T *pt) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors
+ // CHECK-FIXES: {{^ }}explicit E(T *pt) {}
+ template <typename U>
+ E(U *pu) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors
+ // CHECK-FIXES: {{^ }}explicit E(U *pu) {}
+
+ explicit E(T t) {}
+ template <typename U>
+ explicit E(U u) {}
+};
+
+void f(std::initializer_list<int> list) {
+ D d(list);
+ E<decltype(list)> e(list);
+ E<int> e2(list);
+}
+
+template <typename T>
+struct F {};
+
+template<typename T>
+struct G {
+ operator bool() const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'operator bool' must be marked
+ // CHECK-FIXES: {{^}} explicit operator bool() const;
+ operator F<T>() const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'operator F<type-parameter-0-0>' must be marked
+ // CHECK-FIXES: {{^}} explicit operator F<T>() const;
+ template<typename U>
+ operator F<U>*() const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'operator F<type-parameter-1-0> *' must be marked
+ // CHECK-FIXES: {{^}} explicit operator F<U>*() const;
+};
+
+void f2() {
+ G<int> a;
+ (void)(F<int>)a;
+ if (a) {}
+ (void)(F<int>*)a;
+ (void)(F<int*>*)a;
+
+ G<double> b;
+ (void)(F<double>)b;
+ if (b) {}
+ (void)(F<double>*)b;
+ (void)(F<double*>*)b;
+}
+
+#define DEFINE_STRUCT_WITH_OPERATOR_BOOL(name) \
+ struct name { \
+ operator bool() const; \
+ }
+
+DEFINE_STRUCT_WITH_OPERATOR_BOOL(H);
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/google-module.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-module.cpp
new file mode 100644
index 0000000..494ac48
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-module.cpp
@@ -0,0 +1,10 @@
+// RUN: clang-tidy -checks='-*,google*' -config='{}' -dump-config - -- | FileCheck %s
+// CHECK: CheckOptions:
+// CHECK: {{- key: *google-readability-braces-around-statements.ShortStatementLines}}
+// CHECK-NEXT: {{value: *'1'}}
+// CHECK: {{- key: *google-readability-function-size.StatementThreshold}}
+// CHECK-NEXT: {{value: *'800'}}
+// CHECK: {{- key: *google-readability-namespace-comments.ShortNamespaceLines}}
+// CHECK-NEXT: {{value: *'10'}}
+// CHECK: {{- key: *google-readability-namespace-comments.SpacesBeforeComments}}
+// CHECK-NEXT: {{value: *'2'}}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/google-namespaces.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-namespaces.cpp
new file mode 100644
index 0000000..9bda3c0
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-namespaces.cpp
@@ -0,0 +1,52 @@
+// RUN: clang-tidy %s -checks='-*,google-build-namespaces,google-build-using-namespace' -header-filter='.*' -- | FileCheck %s -implicit-check-not="{{warning|error}}:"
+#include "Inputs/google-namespaces.h"
+// CHECK: warning: do not use unnamed namespaces in header files [google-build-namespaces]
+
+using namespace spaaaace;
+// CHECK: :[[@LINE-1]]:1: warning: do not use namespace using-directives; use using-declarations instead [google-build-using-namespace]
+
+using spaaaace::core; // no-warning
+
+namespace std {
+inline namespace literals {
+inline namespace chrono_literals {
+}
+inline namespace complex_literals {
+}
+inline namespace string_literals {
+}
+}
+}
+
+using namespace std::chrono_literals; // no-warning
+using namespace std::complex_literals; // no-warning
+using namespace std::literals; // no-warning
+using namespace std::literals::chrono_literals; // no-warning
+using namespace std::literals::complex_literals; // no-warning
+using namespace std::literals::string_literals; // no-warning
+using namespace std::string_literals; // no-warning
+
+namespace literals {}
+
+using namespace literals;
+// CHECK: :[[@LINE-1]]:1: warning: do not use namespace using-directives; use using-declarations instead [google-build-using-namespace]
+
+namespace foo {
+inline namespace literals {
+inline namespace bar_literals {}
+}
+}
+
+using namespace foo::literals;
+// CHECK: :[[@LINE-1]]:1: warning: do not use namespace using-directives; use using-declarations instead [google-build-using-namespace]
+
+using namespace foo::bar_literals;
+// CHECK: :[[@LINE-1]]:1: warning: do not use namespace using-directives; use using-declarations instead [google-build-using-namespace]
+
+using namespace foo::literals::bar_literals;
+// CHECK: :[[@LINE-1]]:1: warning: do not use namespace using-directives; use using-declarations instead [google-build-using-namespace]
+
+namespace foo_literals {}
+
+using namespace foo_literals;
+// CHECK: :[[@LINE-1]]:1: warning: do not use namespace using-directives; use using-declarations instead [google-build-using-namespace]
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/google-objc-avoid-throwing-exception.m b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-objc-avoid-throwing-exception.m
new file mode 100644
index 0000000..7fa32e7
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-objc-avoid-throwing-exception.m
@@ -0,0 +1,32 @@
+// RUN: %check_clang_tidy %s google-objc-avoid-throwing-exception %t
+@class NSString;
+
+@interface NSException
+
++ (void)raise:(NSString *)name format:(NSString *)format;
++ (void)raise:(NSString *)name format:(NSString *)format arguments:(NSString *)args; // using NSString type since va_list cannot be recognized here
+
+@end
+
+@interface NotException
+
++ (void)raise:(NSString *)name format:(NSString *)format;
+
+@end
+
+@implementation Foo
+- (void)f {
+ NSString *foo = @"foo";
+ @throw foo;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass in NSError ** instead of throwing exception to indicate Objective-C errors [google-objc-avoid-throwing-exception]
+}
+
+- (void)f2 {
+ [NSException raise:@"TestException" format:@"Test"];
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: pass in NSError ** instead of throwing exception to indicate Objective-C errors [google-objc-avoid-throwing-exception]
+ [NSException raise:@"TestException" format:@"Test %@" arguments:@"bar"];
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: pass in NSError ** instead of throwing exception to indicate Objective-C errors [google-objc-avoid-throwing-exception]
+ [NotException raise:@"NotException" format:@"Test"];
+}
+@end
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/google-objc-function-naming.m b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-objc-function-naming.m
new file mode 100644
index 0000000..d0336d2
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-objc-function-naming.m
@@ -0,0 +1,63 @@
+// RUN: %check_clang_tidy %s google-objc-function-naming %t
+
+typedef _Bool bool;
+
+static bool ispositive(int a) { return a > 0; }
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: static function named 'ispositive'
+// must be in Pascal case as required by Google Objective-C style guide
+// CHECK-FIXES: static bool Ispositive(int a) { return a > 0; }
+
+static bool is_positive(int a) { return a > 0; }
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: static function named 'is_positive'
+// must be in Pascal case as required by Google Objective-C style guide
+// CHECK-FIXES: static bool IsPositive(int a) { return a > 0; }
+
+static bool isPositive(int a) { return a > 0; }
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: static function named 'isPositive'
+// must be in Pascal case as required by Google Objective-C style guide
+// CHECK-FIXES: static bool IsPositive(int a) { return a > 0; }
+
+static bool Is_Positive(int a) { return a > 0; }
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: static function named 'Is_Positive'
+// must be in Pascal case as required by Google Objective-C style guide
+// CHECK-FIXES: static bool IsPositive(int a) { return a > 0; }
+
+static bool IsPositive(int a) { return a > 0; }
+
+bool ispalindrome(const char *str);
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function in global namespace named
+// 'ispalindrome' must have an appropriate prefix followed by Pascal case as
+// required by Google Objective-C style guide
+
+static const char *md5(const char *str) { return 0; }
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: static function named 'md5' must be
+// in Pascal case as required by Google Objective-C style guide
+// CHECK-FIXES: static const char *Md5(const char *str) { return 0; }
+
+static const char *MD5(const char *str) { return 0; }
+
+static const char *URL(void) { return "https://clang.llvm.org/"; }
+
+static const char *DEFURL(void) { return "https://clang.llvm.org/"; }
+
+static const char *DEFFooURL(void) { return "https://clang.llvm.org/"; }
+
+static const char *StringFromNSString(id str) { return ""; }
+
+void ABLog_String(const char *str);
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function in global namespace named
+// 'ABLog_String' must have an appropriate prefix followed by Pascal case as
+// required by Google Objective-C style guide
+
+void ABLogString(const char *str);
+
+bool IsPrime(int a);
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function in global namespace named
+// 'IsPrime' must have an appropriate prefix followed by Pascal case as required
+// by Google Objective-C style guide
+
+const char *ABURL(void) { return "https://clang.llvm.org/"; }
+
+const char *ABFooURL(void) { return "https://clang.llvm.org/"; }
+
+int main(int argc, const char **argv) { return 0; }
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/google-objc-function-naming.mm b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-objc-function-naming.mm
new file mode 100644
index 0000000..43c2d7e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-objc-function-naming.mm
@@ -0,0 +1,33 @@
+// RUN: %check_clang_tidy %s google-objc-function-naming %t
+
+void printSomething() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function in global namespace named
+// 'printSomething' must have an appropriate prefix followed by Pascal case as
+// required by Google Objective-C style guide
+
+void PrintSomething() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function in global namespace named
+// 'PrintSomething' must have an appropriate prefix followed by Pascal case as
+// required by Google Objective-C style guide
+
+void ABCBad_Name() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function in global namespace named
+// 'ABCBad_Name' must have an appropriate prefix followed by Pascal case as
+// required by Google Objective-C style guide
+
+namespace {
+
+int foo() { return 0; }
+
+}
+
+namespace bar {
+
+int convert() { return 0; }
+
+}
+
+class Baz {
+public:
+ int value() { return 0; }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/google-objc-global-variable-declaration.m b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-objc-global-variable-declaration.m
new file mode 100644
index 0000000..346ddec
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-objc-global-variable-declaration.m
@@ -0,0 +1,49 @@
+// RUN: %check_clang_tidy %s google-objc-global-variable-declaration %t
+
+@class NSString;
+static NSString* const myConstString = @"hello";
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: const global variable 'myConstString' must have a name which starts with an appropriate prefix [google-objc-global-variable-declaration]
+// CHECK-FIXES: static NSString* const kMyConstString = @"hello";
+
+static NSString* MyString = @"hi";
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: non-const global variable 'MyString' must have a name which starts with 'g[A-Z]' [google-objc-global-variable-declaration]
+// CHECK-FIXES: static NSString* gMyString = @"hi";
+
+NSString* globalString = @"test";
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: non-const global variable 'globalString' must have a name which starts with 'g[A-Z]' [google-objc-global-variable-declaration]
+// CHECK-FIXES: NSString* gGlobalString = @"test";
+
+static NSString* a = @"too simple";
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: non-const global variable 'a' must have a name which starts with 'g[A-Z]' [google-objc-global-variable-declaration]
+// CHECK-FIXES: static NSString* a = @"too simple";
+
+static NSString* noDef;
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: non-const global variable 'noDef' must have a name which starts with 'g[A-Z]' [google-objc-global-variable-declaration]
+// CHECK-FIXES: static NSString* gNoDef;
+
+static NSString* const _notAlpha = @"NotBeginWithAlpha";
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: const global variable '_notAlpha' must have a name which starts with an appropriate prefix [google-objc-global-variable-declaration]
+// CHECK-FIXES: static NSString* const _notAlpha = @"NotBeginWithAlpha";
+
+static NSString* const k_Alpha = @"SecondNotAlpha";
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: const global variable 'k_Alpha' must have a name which starts with an appropriate prefix [google-objc-global-variable-declaration]
+// CHECK-FIXES: static NSString* const k_Alpha = @"SecondNotAlpha";
+
+static NSString* const kGood = @"hello";
+static NSString* const XYGood = @"hello";
+static NSString* gMyIntGood = 0;
+
+extern NSString* const GTLServiceErrorDomain;
+
+enum GTLServiceError {
+ GTLServiceErrorQueryResultMissing = -3000,
+ GTLServiceErrorWaitTimedOut = -3001,
+};
+
+@implementation Foo
+- (void)f {
+ int x = 0;
+ static int bar;
+ static const int baz = 42;
+}
+@end
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/google-overloaded-unary-and.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-overloaded-unary-and.cpp
new file mode 100644
index 0000000..16893d2
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-overloaded-unary-and.cpp
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s google-runtime-operator %t
+
+struct Foo {
+ void *operator&();
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not overload unary operator&, it is dangerous. [google-runtime-operator]
+};
+
+template <typename T>
+struct TFoo {
+ T *operator&();
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not overload unary operator&
+};
+
+TFoo<int> tfoo;
+
+struct Bar;
+void *operator&(Bar &b);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not overload unary operator&
+
+// No warnings on binary operators.
+struct Qux {
+ void *operator&(Qux &q);
+};
+
+void *operator&(Qux &q, Qux &r);
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/google-readability-casting.c b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-readability-casting.c
new file mode 100644
index 0000000..488bcd7
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-readability-casting.c
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s google-readability-casting %t -- -- -x c
+// The testing script always adds .cpp extension to the input file name, so we
+// need to run clang-tidy directly in order to verify handling of .c files:
+// RUN: clang-tidy --checks=-*,google-readability-casting %s -- -x c++ | FileCheck %s -check-prefix=CHECK-MESSAGES -implicit-check-not='{{warning|error}}:'
+// RUN: cp %s %t.main_file.cpp
+// RUN: clang-tidy --checks=-*,google-readability-casting -header-filter='.*' %t.main_file.cpp -- -I%S -DTEST_INCLUDE -x c++ | FileCheck %s -check-prefix=CHECK-MESSAGES -implicit-check-not='{{warning|error}}:'
+
+#ifdef TEST_INCLUDE
+
+#undef TEST_INCLUDE
+#include "google-readability-casting.c"
+
+#else
+
+void f(const char *cpc) {
+ const char *cpc2 = (const char*)cpc;
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: redundant cast to the same type [google-readability-casting]
+ // CHECK-FIXES: const char *cpc2 = cpc;
+ char *pc = (char*)cpc;
+ typedef const char *Typedef1;
+ (Typedef1)cpc;
+}
+
+#endif
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/google-readability-casting.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-readability-casting.cpp
new file mode 100644
index 0000000..d36fef6
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-readability-casting.cpp
@@ -0,0 +1,323 @@
+// RUN: %check_clang_tidy %s google-readability-casting %t
+
+bool g() { return false; }
+
+enum Enum { Enum1 };
+struct X {};
+struct Y : public X {};
+
+void f(int a, double b, const char *cpc, const void *cpv, X *pX) {
+ const char *cpc2 = (const char*)cpc;
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: redundant cast to the same type [google-readability-casting]
+ // CHECK-FIXES: const char *cpc2 = cpc;
+
+ typedef const char *Typedef1;
+ typedef const char *Typedef2;
+ Typedef1 t1;
+ (Typedef2)t1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: C-style casts are discouraged; use static_cast (if needed, the cast may be redundant) [google-readability-casting]
+ // CHECK-FIXES: {{^}} static_cast<Typedef2>(t1);
+ (const char*)t1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: {{.*}}; use static_cast (if needed
+ // CHECK-FIXES: {{^}} static_cast<const char*>(t1);
+ (Typedef1)cpc;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: {{.*}}; use static_cast (if needed
+ // CHECK-FIXES: {{^}} static_cast<Typedef1>(cpc);
+ (Typedef1)t1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant cast to the same type
+ // CHECK-FIXES: {{^}} t1;
+
+ char *pc = (char*)cpc;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: C-style casts are discouraged; use const_cast [google-readability-casting]
+ // CHECK-FIXES: char *pc = const_cast<char*>(cpc);
+ typedef char Char;
+ Char *pChar = (Char*)pc;
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}}; use static_cast (if needed
+ // CHECK-FIXES: {{^}} Char *pChar = static_cast<Char*>(pc);
+
+ (Char)*cpc;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: {{.*}}; use static_cast (if needed
+ // CHECK-FIXES: {{^}} static_cast<Char>(*cpc);
+
+ (char)*pChar;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: {{.*}}; use static_cast (if needed
+ // CHECK-FIXES: {{^}} static_cast<char>(*pChar);
+
+ (const char*)cpv;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: {{.*}}; use static_cast [
+ // CHECK-FIXES: static_cast<const char*>(cpv);
+
+ char *pc2 = (char*)(cpc + 33);
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}; use const_cast [
+ // CHECK-FIXES: char *pc2 = const_cast<char*>(cpc + 33);
+
+ const char &crc = *cpc;
+ char &rc = (char&)crc;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}}; use const_cast [
+ // CHECK-FIXES: char &rc = const_cast<char&>(crc);
+
+ char &rc2 = (char&)*cpc;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}; use const_cast [
+ // CHECK-FIXES: char &rc2 = const_cast<char&>(*cpc);
+
+ char ** const* const* ppcpcpc;
+ char ****ppppc = (char****)ppcpcpc;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: {{.*}}; use const_cast [
+ // CHECK-FIXES: char ****ppppc = const_cast<char****>(ppcpcpc);
+
+ char ***pppc = (char***)*(ppcpcpc);
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: {{.*}}; use const_cast [
+ // CHECK-FIXES: char ***pppc = const_cast<char***>(*(ppcpcpc));
+
+ char ***pppc2 = (char***)(*ppcpcpc);
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: {{.*}}; use const_cast [
+ // CHECK-FIXES: char ***pppc2 = const_cast<char***>(*ppcpcpc);
+
+ char *pc5 = (char*)(const char*)(cpv);
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}; use const_cast [
+ // CHECK-MESSAGES: :[[@LINE-2]]:22: warning: {{.*}}; use static_cast [
+ // CHECK-FIXES: char *pc5 = const_cast<char*>(static_cast<const char*>(cpv));
+
+ int b1 = (int)b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}}; use static_cast [
+ // CHECK-FIXES: int b1 = static_cast<int>(b);
+ b1 = (const int&)b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast [
+ // CHECK-FIXES: b1 = (const int&)b;
+
+ b1 = (int) b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: {{.*}}; use static_cast {{.*}}
+ // CHECK-FIXES: b1 = static_cast<int>(b);
+
+ b1 = (int) b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: {{.*}}; use static_cast {{.*}}
+ // CHECK-FIXES: b1 = static_cast<int>(b);
+
+ b1 = (int) (b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: {{.*}}; use static_cast {{.*}}
+ // CHECK-FIXES: b1 = static_cast<int>(b);
+
+ b1 = (int) (b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: {{.*}}; use static_cast {{.*}}
+ // CHECK-FIXES: b1 = static_cast<int>(b);
+
+ Y *pB = (Y*)pX;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast [
+ Y &rB = (Y&)*pX;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast [
+
+ const char *pc3 = (const char*)cpv;
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: {{.*}}; use static_cast [
+ // CHECK-FIXES: const char *pc3 = static_cast<const char*>(cpv);
+
+ char *pc4 = (char*)cpv;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast [
+ // CHECK-FIXES: char *pc4 = (char*)cpv;
+
+ b1 = (int)Enum1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: {{.*}}; use static_cast [
+ // CHECK-FIXES: b1 = static_cast<int>(Enum1);
+
+ Enum e = (Enum)b1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}}; use static_cast [
+ // CHECK-FIXES: Enum e = static_cast<Enum>(b1);
+
+ e = (Enum)Enum1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant cast to the same type
+ // CHECK-FIXES: {{^}} e = Enum1;
+
+ e = (Enum)e;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant cast to the same type
+ // CHECK-FIXES: {{^}} e = e;
+
+ e = (Enum) e;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant cast to the same type
+ // CHECK-FIXES: {{^}} e = e;
+
+ e = (Enum) (e);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant cast to the same type
+ // CHECK-FIXES: {{^}} e = (e);
+
+ static const int kZero = 0;
+ (int)kZero;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant cast to the same type
+ // CHECK-FIXES: {{^}} kZero;
+
+ int b2 = int(b);
+ int b3 = static_cast<double>(b);
+ int b4 = b;
+ double aa = a;
+ (void)b2;
+ return (void)g();
+}
+
+template <typename T>
+void template_function(T t, int n) {
+ int i = (int)t;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast [
+ // CHECK-FIXES: int i = (int)t;
+ int j = (int)n;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant cast to the same type
+ // CHECK-FIXES: int j = n;
+}
+
+template <typename T>
+struct TemplateStruct {
+ void f(T t, int n) {
+ int k = (int)t;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast
+ // CHECK-FIXES: int k = (int)t;
+ int l = (int)n;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant cast to the same type
+ // CHECK-FIXES: int l = n;
+ }
+};
+
+void test_templates() {
+ template_function(1, 42);
+ template_function(1.0, 42);
+ TemplateStruct<int>().f(1, 42);
+ TemplateStruct<double>().f(1.0, 42);
+}
+
+extern "C" {
+void extern_c_code(const char *cpc) {
+ const char *cpc2 = (const char*)cpc;
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: redundant cast to the same type
+ // CHECK-FIXES: const char *cpc2 = cpc;
+ char *pc = (char*)cpc;
+}
+}
+
+#define CAST(type, value) (type)(value)
+void macros(double d) {
+ int i = CAST(int, d);
+}
+
+enum E { E1 = 1 };
+template <E e>
+struct A {
+ // Usage of template argument e = E1 is represented as (E)1 in the AST for
+ // some reason. We have a special treatment of this case to avoid warnings
+ // here.
+ static const E ee = e;
+};
+struct B : public A<E1> {};
+
+
+void overloaded_function();
+void overloaded_function(int);
+
+template<typename Fn>
+void g(Fn fn) {
+ fn();
+}
+
+void function_casts() {
+ typedef void (*FnPtrVoid)();
+ typedef void (&FnRefVoid)();
+ typedef void (&FnRefInt)(int);
+
+ g((void (*)())overloaded_function);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: C-style casts are discouraged; use static_cast [
+ // CHECK-FIXES: g(static_cast<void (*)()>(overloaded_function));
+ g((void (*)())&overloaded_function);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: C-style casts are discouraged; use static_cast [
+ // CHECK-FIXES: g(static_cast<void (*)()>(&overloaded_function));
+ g((void (&)())overloaded_function);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: C-style casts are discouraged; use static_cast [
+ // CHECK-FIXES: g(static_cast<void (&)()>(overloaded_function));
+
+ g((FnPtrVoid)overloaded_function);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: C-style casts are discouraged; use static_cast [
+ // CHECK-FIXES: g(static_cast<FnPtrVoid>(overloaded_function));
+ g((FnPtrVoid)&overloaded_function);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: C-style casts are discouraged; use static_cast [
+ // CHECK-FIXES: g(static_cast<FnPtrVoid>(&overloaded_function));
+ g((FnRefVoid)overloaded_function);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: C-style casts are discouraged; use static_cast [
+ // CHECK-FIXES: g(static_cast<FnRefVoid>(overloaded_function));
+
+ FnPtrVoid fn0 = (void (*)())&overloaded_function;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: C-style casts are discouraged; use static_cast [
+ // CHECK-FIXES: FnPtrVoid fn0 = static_cast<void (*)()>(&overloaded_function);
+ FnPtrVoid fn1 = (void (*)())overloaded_function;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: C-style casts are discouraged; use static_cast [
+ // CHECK-FIXES: FnPtrVoid fn1 = static_cast<void (*)()>(overloaded_function);
+ FnPtrVoid fn1a = (FnPtrVoid)overloaded_function;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: C-style casts are discouraged; use static_cast [
+ // CHECK-FIXES: FnPtrVoid fn1a = static_cast<FnPtrVoid>(overloaded_function);
+ FnRefInt fn2 = (void (&)(int))overloaded_function;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: C-style casts are discouraged; use static_cast [
+ // CHECK-FIXES: FnRefInt fn2 = static_cast<void (&)(int)>(overloaded_function);
+ auto fn3 = (void (*)())&overloaded_function;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: C-style casts are discouraged; use static_cast [
+ // CHECK-FIXES: auto fn3 = static_cast<void (*)()>(&overloaded_function);
+ auto fn4 = (void (*)())overloaded_function;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: C-style casts are discouraged; use static_cast [
+ // CHECK-FIXES: auto fn4 = static_cast<void (*)()>(overloaded_function);
+ auto fn5 = (void (&)(int))overloaded_function;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: C-style casts are discouraged; use static_cast [
+ // CHECK-FIXES: auto fn5 = static_cast<void (&)(int)>(overloaded_function);
+
+ void (*fn6)() = (void (*)())&overloaded_function;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: C-style casts are discouraged; use static_cast [
+ // CHECK-FIXES: void (*fn6)() = static_cast<void (*)()>(&overloaded_function);
+ void (*fn7)() = (void (*)())overloaded_function;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: C-style casts are discouraged; use static_cast [
+ // CHECK-FIXES: void (*fn7)() = static_cast<void (*)()>(overloaded_function);
+ void (*fn8)() = (FnPtrVoid)overloaded_function;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: C-style casts are discouraged; use static_cast [
+ // CHECK-FIXES: void (*fn8)() = static_cast<FnPtrVoid>(overloaded_function);
+ void (&fn9)(int) = (void (&)(int))overloaded_function;
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: C-style casts are discouraged; use static_cast [
+ // CHECK-FIXES: void (&fn9)(int) = static_cast<void (&)(int)>(overloaded_function);
+
+ void (*correct1)() = static_cast<void (*)()>(overloaded_function);
+ FnPtrVoid correct2 = static_cast<void (*)()>(&overloaded_function);
+ FnRefInt correct3 = static_cast<void (&)(int)>(overloaded_function);
+}
+
+struct S {
+ S(const char *);
+};
+struct ConvertibleToS {
+ operator S() const;
+};
+struct ConvertibleToSRef {
+ operator const S&() const;
+};
+
+void conversions() {
+ //auto s1 = (const S&)"";
+ // C HECK-MESSAGES: :[[@LINE-1]]:10: warning: C-style casts are discouraged; use static_cast [
+ // C HECK-FIXES: S s1 = static_cast<const S&>("");
+ auto s2 = (S)"";
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: C-style casts are discouraged; use constructor call syntax [
+ // CHECK-FIXES: auto s2 = S("");
+ auto s2a = (struct S)"";
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: C-style casts are discouraged; use static_cast [
+ // CHECK-FIXES: auto s2a = static_cast<struct S>("");
+ auto s2b = (const S)"";
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: C-style casts are discouraged; use static_cast [
+ // FIXME: This should be constructor call syntax: S("").
+ // CHECK-FIXES: auto s2b = static_cast<const S>("");
+ ConvertibleToS c;
+ auto s3 = (const S&)c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: C-style casts are discouraged; use static_cast/const_cast/reinterpret_cast [
+ // CHECK-FIXES: auto s3 = (const S&)c;
+ // FIXME: This should be a static_cast.
+ // C HECK-FIXES: auto s3 = static_cast<const S&>(c);
+ auto s4 = (S)c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: C-style casts are discouraged; use constructor call syntax [
+ // CHECK-FIXES: auto s4 = S(c);
+ ConvertibleToSRef cr;
+ auto s5 = (const S&)cr;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: C-style casts are discouraged; use static_cast/const_cast/reinterpret_cast [
+ // CHECK-FIXES: auto s5 = (const S&)cr;
+ // FIXME: This should be a static_cast.
+ // C HECK-FIXES: auto s5 = static_cast<const S&>(cr);
+ auto s6 = (S)cr;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: C-style casts are discouraged; use constructor call syntax [
+ // CHECK-FIXES: auto s6 = S(cr);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/google-readability-casting.mm b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-readability-casting.mm
new file mode 100644
index 0000000..b987dc2
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-readability-casting.mm
@@ -0,0 +1,179 @@
+// RUN: clang-tidy %s -checks=-*,google-readability-casting -- \
+// RUN: -xobjective-c++ -fobjc-abi-version=2 -fobjc-arc | count 0
+
+// Note: this test expects no diagnostics, but FileCheck cannot handle that,
+// hence the use of | count 0.
+
+bool g() { return false; }
+
+enum Enum { Enum1 };
+struct X {};
+struct Y : public X {};
+
+void f(int a, double b, const char *cpc, const void *cpv, X *pX) {
+
+ typedef const char *Typedef1;
+ typedef const char *Typedef2;
+ Typedef1 t1;
+ (Typedef2)t1;
+ (const char*)t1;
+ (Typedef1)cpc;
+
+ typedef char Char;
+ char *pc;
+ Char *pChar = (Char*)pc;
+
+ (Char)*cpc;
+
+ (char)*pChar;
+
+ (const char*)cpv;
+
+ char *pc2 = (char*)(cpc + 33);
+
+ const char &crc = *cpc;
+ char &rc = (char&)crc;
+
+ char &rc2 = (char&)*cpc;
+
+ char ** const* const* ppcpcpc;
+ char ****ppppc = (char****)ppcpcpc;
+
+ char ***pppc = (char***)*(ppcpcpc);
+
+ char ***pppc2 = (char***)(*ppcpcpc);
+
+ char *pc5 = (char*)(const char*)(cpv);
+
+ int b1 = (int)b;
+ b1 = (const int&)b;
+
+ b1 = (int) b;
+
+ b1 = (int) b;
+
+ b1 = (int) (b);
+
+ b1 = (int) (b);
+
+ Y *pB = (Y*)pX;
+ Y &rB = (Y&)*pX;
+
+ const char *pc3 = (const char*)cpv;
+
+ char *pc4 = (char*)cpv;
+
+ b1 = (int)Enum1;
+
+ Enum e = (Enum)b1;
+
+ int b2 = int(b);
+ int b3 = static_cast<double>(b);
+ int b4 = b;
+ double aa = a;
+ (void)b2;
+ return (void)g();
+}
+
+template <typename T>
+void template_function(T t, int n) {
+ int i = (int)t;
+}
+
+template <typename T>
+struct TemplateStruct {
+ void f(T t, int n) {
+ int k = (int)t;
+ }
+};
+
+void test_templates() {
+ template_function(1, 42);
+ template_function(1.0, 42);
+ TemplateStruct<int>().f(1, 42);
+ TemplateStruct<double>().f(1.0, 42);
+}
+
+extern "C" {
+void extern_c_code(const char *cpc) {
+ char *pc = (char*)cpc;
+}
+}
+
+#define CAST(type, value) (type)(value)
+void macros(double d) {
+ int i = CAST(int, d);
+}
+
+enum E { E1 = 1 };
+template <E e>
+struct A {
+ // Usage of template argument e = E1 is represented as (E)1 in the AST for
+ // some reason. We have a special treatment of this case to avoid warnings
+ // here.
+ static const E ee = e;
+};
+struct B : public A<E1> {};
+
+
+void overloaded_function();
+void overloaded_function(int);
+
+template<typename Fn>
+void g(Fn fn) {
+ fn();
+}
+
+void function_casts() {
+ typedef void (*FnPtrVoid)();
+ typedef void (&FnRefVoid)();
+ typedef void (&FnRefInt)(int);
+
+ g((void (*)())overloaded_function);
+ g((void (*)())&overloaded_function);
+ g((void (&)())overloaded_function);
+
+ g((FnPtrVoid)overloaded_function);
+ g((FnPtrVoid)&overloaded_function);
+ g((FnRefVoid)overloaded_function);
+
+ FnPtrVoid fn0 = (void (*)())&overloaded_function;
+ FnPtrVoid fn1 = (void (*)())overloaded_function;
+ FnPtrVoid fn1a = (FnPtrVoid)overloaded_function;
+ FnRefInt fn2 = (void (&)(int))overloaded_function;
+ auto fn3 = (void (*)())&overloaded_function;
+ auto fn4 = (void (*)())overloaded_function;
+ auto fn5 = (void (&)(int))overloaded_function;
+
+ void (*fn6)() = (void (*)())&overloaded_function;
+ void (*fn7)() = (void (*)())overloaded_function;
+ void (*fn8)() = (FnPtrVoid)overloaded_function;
+ void (&fn9)(int) = (void (&)(int))overloaded_function;
+
+ void (*correct1)() = static_cast<void (*)()>(overloaded_function);
+ FnPtrVoid correct2 = static_cast<void (*)()>(&overloaded_function);
+ FnRefInt correct3 = static_cast<void (&)(int)>(overloaded_function);
+}
+
+struct S {
+ S(const char *);
+};
+struct ConvertibleToS {
+ operator S() const;
+};
+struct ConvertibleToSRef {
+ operator const S&() const;
+};
+
+void conversions() {
+ //auto s1 = (const S&)"";
+ auto s2 = (S)"";
+ auto s2a = (struct S)"";
+ auto s2b = (const S)"";
+ ConvertibleToS c;
+ auto s3 = (const S&)c;
+ auto s4 = (S)c;
+ ConvertibleToSRef cr;
+ auto s5 = (const S&)cr;
+ auto s6 = (S)cr;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/google-readability-namespace-comments.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-readability-namespace-comments.cpp
new file mode 100644
index 0000000..9abb984
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-readability-namespace-comments.cpp
@@ -0,0 +1,54 @@
+// RUN: %check_clang_tidy %s google-readability-namespace-comments %t
+
+namespace n1 {
+namespace n2 {
+
+
+void f(); // So that the namespace isn't empty.
+
+
+// CHECK-MESSAGES: :[[@LINE+4]]:2: warning: namespace 'n2' not terminated with a closing comment [google-readability-namespace-comments]
+// CHECK-MESSAGES: :[[@LINE-7]]:11: note: namespace 'n2' starts here
+// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: namespace 'n1' not terminated with
+// CHECK-MESSAGES: :[[@LINE-10]]:11: note: namespace 'n1' starts here
+}}
+// CHECK-FIXES: } // namespace n2
+// CHECK-FIXES: } // namespace n1
+
+#define MACRO macro_expansion
+namespace MACRO {
+void f(); // So that the namespace isn't empty.
+// 1
+// 2
+// 3
+// 4
+// 5
+// 6
+// 7
+// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: namespace 'macro_expansion' not terminated with
+// CHECK-MESSAGES: :[[@LINE-10]]:11: note: namespace 'macro_expansion' starts here
+}
+// CHECK-FIXES: } // namespace macro_expansion
+
+namespace short1 {
+namespace short2 {
+// Namespaces covering 10 lines or fewer are exempt from this rule.
+
+
+
+
+
+}
+}
+
+namespace n3 {
+
+
+
+
+
+
+
+
+
+}; // namespace n3
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/google-readability-nested-namespace-comments.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-readability-nested-namespace-comments.cpp
new file mode 100644
index 0000000..d7765c6
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-readability-nested-namespace-comments.cpp
@@ -0,0 +1,17 @@
+// RUN: %check_clang_tidy %s google-readability-namespace-comments %t
+
+namespace n1::n2 {
+namespace n3 {
+
+// So that namespace is not empty.
+void f();
+
+
+// CHECK-MESSAGES: :[[@LINE+4]]:2: warning: namespace 'n3' not terminated with
+// CHECK-MESSAGES: :[[@LINE-7]]:11: note: namespace 'n3' starts here
+// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: namespace 'n1::n2' not terminated with a closing comment [google-readability-namespace-comments]
+// CHECK-MESSAGES: :[[@LINE-10]]:11: note: namespace 'n1::n2' starts here
+}}
+// CHECK-FIXES: } // namespace n3
+// CHECK-FIXES: } // namespace n1::n2
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/google-readability-todo.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-readability-todo.cpp
new file mode 100644
index 0000000..6b900aa
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-readability-todo.cpp
@@ -0,0 +1,26 @@
+// RUN: %check_clang_tidy %s google-readability-todo %t -- -config="{User: 'some user'}" --
+
+// TODOfix this1
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: missing username/bug in TODO
+// CHECK-FIXES: // TODO(some user): fix this1
+
+// TODO fix this2
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: missing username/bug in TODO
+// CHECK-FIXES: // TODO(some user): fix this2
+
+// TODO fix this3
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: missing username/bug in TODO
+// CHECK-FIXES: // TODO(some user): fix this3
+
+// TODO: fix this4
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: missing username/bug in TODO
+// CHECK-FIXES: // TODO(some user): fix this4
+
+// TODO(clang)fix this5
+
+// TODO(foo):shave yaks
+// TODO(bar):
+// TODO(foo): paint bikeshed
+// TODO(b/12345): find the holy grail
+// TODO (b/12345): allow spaces before parentheses
+// TODO(asdf) allow missing semicolon
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/google-runtime-int-std.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-runtime-int-std.cpp
new file mode 100644
index 0000000..c5d3112
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-runtime-int-std.cpp
@@ -0,0 +1,57 @@
+// RUN: %check_clang_tidy %s google-runtime-int %t -- \
+// RUN: -config='{CheckOptions: [ \
+// RUN: {key: google-runtime-int.UnsignedTypePrefix, value: "std::uint"}, \
+// RUN: {key: google-runtime-int.SignedTypePrefix, value: "std::int"}, \
+// RUN: {key: google-runtime-int.TypeSuffix, value: "_t"}, \
+// RUN: ]}' -- -std=c++11
+
+long a();
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: consider replacing 'long' with 'std::int{{..}}_t'
+
+typedef unsigned long long uint64; // NOLINT
+
+long b(long = 1);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: consider replacing 'long' with 'std::int{{..}}_t'
+// CHECK-MESSAGES: [[@LINE-2]]:8: warning: consider replacing 'long' with 'std::int{{..}}_t'
+
+template <typename T>
+void tmpl() {
+ T i;
+}
+
+short bar(const short, unsigned short) {
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: consider replacing 'short' with 'std::int16_t'
+// CHECK-MESSAGES: [[@LINE-2]]:17: warning: consider replacing 'short' with 'std::int16_t'
+// CHECK-MESSAGES: [[@LINE-3]]:24: warning: consider replacing 'unsigned short' with 'std::uint16_t'
+ long double foo = 42;
+ uint64 qux = 42;
+ unsigned short port;
+
+ const unsigned short bar = 0;
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: consider replacing 'unsigned short' with 'std::uint16_t'
+ long long *baar;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'long long' with 'std::int64_t'
+ const unsigned short &bara = bar;
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: consider replacing 'unsigned short' with 'std::uint16_t'
+ long const long moo = 1;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'long long' with 'std::int64_t'
+ long volatile long wat = 42;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'long long' with 'std::int64_t'
+ unsigned long y;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'unsigned long' with 'std::uint{{..}}_t'
+ unsigned long long **const *tmp;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'unsigned long long' with 'std::uint64_t'
+ unsigned long long **const *&z = tmp;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'unsigned long long' with 'std::uint64_t'
+ unsigned short porthole;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'unsigned short' with 'std::uint16_t'
+
+ uint64 cast = (short)42;
+// CHECK-MESSAGES: [[@LINE-1]]:18: warning: consider replacing 'short' with 'std::int16_t'
+
+#define l long
+ l x;
+
+ tmpl<short>();
+// CHECK-MESSAGES: [[@LINE-1]]:8: warning: consider replacing 'short' with 'std::int16_t'
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/google-runtime-int.c b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-runtime-int.c
new file mode 100644
index 0000000..8657e2d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-runtime-int.c
@@ -0,0 +1,27 @@
+// RUN: clang-tidy -checks=-*,google-runtime-int %s -- -x c 2>&1 | not grep 'warning:\|error:'
+
+long a();
+
+long b(long x);
+
+short bar(const short q, unsigned short w) {
+ long double foo;
+ unsigned short port;
+
+ const unsigned short bar;
+ long long *baar;
+ const unsigned short bara;
+ long const long moo;
+ long volatile long wat;
+ unsigned long y;
+ unsigned long long **const *tmp;
+ unsigned short porthole;
+
+ unsigned cast;
+ cast = (short)42;
+ return q;
+}
+
+void qux() {
+ short port;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/google-runtime-int.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-runtime-int.cpp
new file mode 100644
index 0000000..4bb73987
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-runtime-int.cpp
@@ -0,0 +1,91 @@
+// RUN: %check_clang_tidy %s google-runtime-int %t
+
+long a();
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: consider replacing 'long' with 'int{{..}}'
+
+typedef unsigned long long uint64; // NOLINT
+
+long b(long = 1);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: consider replacing 'long' with 'int{{..}}'
+// CHECK-MESSAGES: [[@LINE-2]]:8: warning: consider replacing 'long' with 'int{{..}}'
+
+template <typename T>
+void tmpl() {
+ T i;
+}
+
+short bar(const short, unsigned short) {
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: consider replacing 'short' with 'int16'
+// CHECK-MESSAGES: [[@LINE-2]]:17: warning: consider replacing 'short' with 'int16'
+// CHECK-MESSAGES: [[@LINE-3]]:24: warning: consider replacing 'unsigned short' with 'uint16'
+ long double foo = 42;
+ uint64 qux = 42;
+ unsigned short port;
+
+ const unsigned short bar = 0;
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: consider replacing 'unsigned short' with 'uint16'
+ long long *baar;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'long long' with 'int64'
+ const unsigned short &bara = bar;
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: consider replacing 'unsigned short' with 'uint16'
+ long const long moo = 1;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'long long' with 'int64'
+ long volatile long wat = 42;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'long long' with 'int64'
+ unsigned long y;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'unsigned long' with 'uint{{..}}'
+ unsigned long long **const *tmp;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'unsigned long long' with 'uint64'
+ unsigned long long **const *&z = tmp;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'unsigned long long' with 'uint64'
+ unsigned short porthole;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'unsigned short' with 'uint16'
+
+ uint64 cast = (short)42;
+// CHECK-MESSAGES: [[@LINE-1]]:18: warning: consider replacing 'short' with 'int16'
+
+#define l long
+ l x;
+
+ tmpl<short>();
+// CHECK-MESSAGES: [[@LINE-1]]:8: warning: consider replacing 'short' with 'int16'
+ return 0;
+}
+
+void p(unsigned short port);
+
+void qux() {
+ short port;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'short' with 'int16'
+}
+
+// FIXME: This shouldn't warn, as UD-literal operators require one of a handful
+// of types as an argument.
+struct some_value {};
+constexpr some_value operator"" _some_literal(unsigned long long int i);
+// CHECK-MESSAGES: [[@LINE-1]]:47: warning: consider replacing 'unsigned long long'
+
+struct A { A& operator=(const A&); };
+class B { A a[0]; };
+
+void fff() {
+ B a, b;
+ a = b;
+}
+
+__attribute__((__format__ (__printf__, 1, 2)))
+void myprintf(const char* s, ...);
+
+void doprint_no_warning() {
+ uint64 foo = 23;
+ myprintf("foo %lu %lu", (unsigned long)42, (unsigned long)foo);
+}
+
+void myprintf_no_attribute(const char* s, ...);
+
+void doprint_warning() {
+ uint64 foo = 23;
+ myprintf_no_attribute("foo %lu %lu", (unsigned long)42, (unsigned long)foo);
+// CHECK-MESSAGES: [[@LINE-1]]:41: warning: consider replacing 'unsigned long'
+// CHECK-MESSAGES: [[@LINE-2]]:60: warning: consider replacing 'unsigned long'
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/google-runtime-references.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-runtime-references.cpp
new file mode 100644
index 0000000..b9f84b6
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/google-runtime-references.cpp
@@ -0,0 +1,152 @@
+// RUN: %check_clang_tidy %s google-runtime-references %t -- \
+// RUN: -extra-arg="-std=c++11" \
+// RUN: -config="{CheckOptions: \
+// RUN: [{key: google-runtime-references.WhiteListTypes, \
+// RUN: value: 'whitelist::A; whitelist::B'}]}" --
+
+int a;
+int &b = a;
+int *c;
+void f1(int a);
+void f2(int *b);
+void f3(const int &c);
+void f4(int const &d);
+
+// Don't warn on implicit operator= in c++11 mode.
+class A {
+ virtual void f() {}
+};
+// Don't warn on rvalue-references.
+struct A2 {
+ A2(A2&&) = default;
+ void f(A2&&) {}
+};
+
+// Don't warn on iostream parameters.
+namespace xxx {
+class istream { };
+class ostringstream { };
+}
+void g1(xxx::istream &istr);
+void g1(xxx::ostringstream &istr);
+
+void g1(int &a);
+// CHECK-MESSAGES: [[@LINE-1]]:14: warning: non-const reference parameter 'a', make it const or use a pointer [google-runtime-references]
+
+struct s {};
+void g2(int a, int b, s c, s &d);
+// CHECK-MESSAGES: [[@LINE-1]]:31: warning: non-const reference parameter 'd', {{.*}}
+
+typedef int &ref;
+void g3(ref a);
+// CHECK-MESSAGES: [[@LINE-1]]:13: warning: non-const reference {{.*}}
+
+void g4(int &a, int &b, int &);
+// CHECK-MESSAGES: [[@LINE-1]]:14: warning: non-const reference parameter 'a', {{.*}}
+// CHECK-MESSAGES: [[@LINE-2]]:22: warning: non-const reference parameter 'b', {{.*}}
+// CHECK-MESSAGES: [[@LINE-3]]:30: warning: non-const reference parameter at index 2, {{.*}}
+
+class B {
+ B(B& a) {}
+// CHECK-MESSAGES: [[@LINE-1]]:8: warning: non-const reference {{.*}}
+ virtual void f(int &a) {}
+// CHECK-MESSAGES: [[@LINE-1]]:23: warning: non-const reference {{.*}}
+ void g(int &b);
+// CHECK-MESSAGES: [[@LINE-1]]:15: warning: non-const reference {{.*}}
+
+ // Don't warn on the parameter of stream extractors defined as members.
+ B& operator>>(int& val) { return *this; }
+};
+
+// Only warn on the first declaration of each function to reduce duplicate
+// warnings.
+void B::g(int &b) {}
+
+// Don't warn on the first parameter of stream inserters.
+A& operator<<(A& s, int&) { return s; }
+// CHECK-MESSAGES: [[@LINE-1]]:25: warning: non-const reference parameter at index 1, {{.*}}
+
+// Don't warn on either parameter of stream extractors. Both need to be
+// non-const references by convention.
+A& operator>>(A& input, int& val) { return input; }
+
+// Don't warn on lambdas.
+auto lambda = [] (int&) {};
+
+// Don't warn on typedefs, as we'll warn on the function itself.
+typedef int (*fp)(int &);
+
+// Don't warn on function references.
+typedef void F();
+void g5(const F& func) {}
+void g6(F& func) {}
+
+template<typename T>
+void g7(const T& t) {}
+
+template<typename T>
+void g8(T t) {}
+
+void f5() {
+ g5(f5);
+ g6(f5);
+ g7(f5);
+ g7<F&>(f5);
+ g8(f5);
+ g8<F&>(f5);
+}
+
+// Don't warn on dependent types.
+template<typename T>
+void g9(T& t) {}
+template<typename T>
+void g10(T t) {}
+
+void f6() {
+ int i;
+ float f;
+ g9<int>(i);
+ g9<const int>(i);
+ g9<int&>(i);
+ g10<int&>(i);
+ g10<float&>(f);
+}
+
+// Warn only on the overridden methods from the base class, as the child class
+// only implements the interface.
+class C : public B {
+ C();
+ virtual void f(int &a) {}
+};
+
+// Don't warn on operator<< with streams-like interface.
+A& operator<<(A& s, int) { return s; }
+
+// Don't warn on swap().
+void swap(C& c1, C& c2) {}
+
+// Don't warn on standalone operator++, operator--, operator+=, operator-=,
+// operator*=, etc. that all need non-const references to be functional.
+A& operator++(A& a) { return a; }
+A operator++(A& a, int) { return a; }
+A& operator--(A& a) { return a; }
+A operator--(A& a, int) { return a; }
+A& operator+=(A& a, const A& b) { return a; }
+A& operator-=(A& a, const A& b) { return a; }
+A& operator*=(A& a, const A& b) { return a; }
+A& operator/=(A& a, const A& b) { return a; }
+A& operator%=(A& a, const A& b) { return a; }
+A& operator<<=(A& a, const A& b) { return a; }
+A& operator>>=(A& a, const A& b) { return a; }
+A& operator|=(A& a, const A& b) { return a; }
+A& operator^=(A& a, const A& b) { return a; }
+A& operator&=(A& a, const A& b) { return a; }
+
+namespace whitelist {
+class A {};
+class B {};
+void f7(A &);
+void f8(B &);
+}
+void f9(whitelist::A &);
+void f10(whitelist::B &);
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-exception-baseclass.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-exception-baseclass.cpp
new file mode 100644
index 0000000..b5e405a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-exception-baseclass.cpp
@@ -0,0 +1,284 @@
+// RUN: %check_clang_tidy %s hicpp-exception-baseclass %t -- -- -fcxx-exceptions
+
+namespace std {
+class exception {};
+class invalid_argument : public exception {};
+} // namespace std
+
+class derived_exception : public std::exception {};
+class deep_hierarchy : public derived_exception {};
+class non_derived_exception {};
+class terrible_idea : public non_derived_exception, public derived_exception {};
+
+// FIXME: More complicated kinds of inheritance should be checked later, but there is
+// currently no way use ASTMatchers for this kind of task.
+#if 0
+class bad_inheritance : private std::exception {};
+class no_good_inheritance : protected std::exception {};
+class really_creative : public non_derived_exception, private std::exception {};
+#endif
+
+void problematic() {
+ try {
+ throw int(42);
+ // CHECK-NOTES: [[@LINE-1]]:11: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+ } catch (int e) {
+ }
+ throw int(42);
+ // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+
+ try {
+ throw 12;
+ // CHECK-NOTES: [[@LINE-1]]:11: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+ } catch (...) {
+ throw; // Ok, even if the type is not known, conforming code can never rethrow a non-std::exception object.
+ }
+
+ try {
+ throw non_derived_exception();
+ // CHECK-NOTES: [[@LINE-1]]:11: warning: throwing an exception whose type 'non_derived_exception' is not derived from 'std::exception'
+ // CHECK-NOTES: 10:1: note: type defined here
+ } catch (non_derived_exception &e) {
+ }
+ throw non_derived_exception();
+ // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'non_derived_exception' is not derived from 'std::exception'
+ // CHECK-NOTES: 10:1: note: type defined here
+
+// FIXME: More complicated kinds of inheritance should be checked later, but there is
+// currently no way use ASTMatchers for this kind of task.
+#if 0
+ // Handle private inheritance cases correctly.
+ try {
+ throw bad_inheritance();
+ // CHECK NOTES: [[@LINE-1]]:11: warning: throwing an exception whose type 'bad_inheritance' is not derived from 'std::exception'
+ // CHECK NOTES: 11:1: note: type defined here
+ throw no_good_inheritance();
+ // CHECK NOTES: [[@LINE-1]]:11: warning: throwing an exception whose type 'no_good_inheritance' is not derived from 'std::exception'
+ // CHECK NOTES: 12:1: note: type defined here
+ throw really_creative();
+ // CHECK NOTES: [[@LINE-1]]:11: warning: throwing an exception whose type 'really_creative' is not derived from 'std::exception'
+ // CHECK NOTES: 13:1: note: type defined here
+ } catch (...) {
+ }
+ throw bad_inheritance();
+ // CHECK NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'bad_inheritance' is not derived from 'std::exception'
+ // CHECK NOTES: 11:1: note: type defined here
+ throw no_good_inheritance();
+ // CHECK NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'no_good_inheritance' is not derived from 'std::exception'
+ // CHECK NOTES: 12:1: note: type defined here
+ throw really_creative();
+ // CHECK NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'really_creative' is not derived from 'std::exception'
+ // CHECK NOTES: 13:1: note: type defined here
+#endif
+}
+
+void allowed_throws() {
+ try {
+ throw std::exception(); // Ok
+ } catch (std::exception &e) { // Ok
+ }
+ throw std::exception();
+
+ try {
+ throw derived_exception(); // Ok
+ } catch (derived_exception &e) { // Ok
+ }
+ throw derived_exception(); // Ok
+
+ try {
+ throw deep_hierarchy(); // Ok, multiple levels of inheritance
+ } catch (deep_hierarchy &e) { // Ok
+ }
+ throw deep_hierarchy(); // Ok
+
+ try {
+ throw terrible_idea(); // Ok, but multiple inheritance isn't clean
+ } catch (std::exception &e) { // Can be caught as std::exception, even with multiple inheritance
+ }
+ throw terrible_idea(); // Ok, but multiple inheritance
+}
+
+void test_lambdas() {
+ auto BadLambda = []() { throw int(42); };
+ // CHECK-NOTES: [[@LINE-1]]:33: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+ auto GoodLambda = []() { throw derived_exception(); };
+}
+
+// Templated function that throws exception based on template type
+template <typename T>
+void ThrowException() { throw T(); }
+// CHECK-NOTES: [[@LINE-1]]:31: warning: throwing an exception whose type 'bad_generic_exception<int>' is not derived from 'std::exception'
+// CHECK-NOTES: [[@LINE-2]]:31: note: type 'bad_generic_exception<int>' is a template instantiation of 'T'
+// CHECK-NOTES: [[@LINE+25]]:1: note: type defined here
+
+// CHECK-NOTES: [[@LINE-5]]:31: warning: throwing an exception whose type 'bad_generic_exception<std::exception>' is not derived from 'std::exception'
+// CHECK-NOTES: [[@LINE-6]]:31: note: type 'bad_generic_exception<std::exception>' is a template instantiation of 'T'
+// CHECK-NOTES: [[@LINE+21]]:1: note: type defined here
+
+// CHECK-NOTES: [[@LINE-9]]:31: warning: throwing an exception whose type 'exotic_exception<non_derived_exception>' is not derived from 'std::exception'
+// CHECK-NOTES: [[@LINE-10]]:31: note: type 'exotic_exception<non_derived_exception>' is a template instantiation of 'T'
+// CHECK-NOTES: [[@LINE+20]]:1: note: type defined here
+
+// CHECK-NOTES: [[@LINE-13]]:31: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+// CHECK-NOTES: [[@LINE-14]]:31: note: type 'int' is a template instantiation of 'T'
+
+// CHECK-NOTES: [[@LINE-16]]:31: warning: throwing an exception whose type 'non_derived_exception' is not derived from 'std::exception'
+// CHECK-NOTES: [[@LINE-17]]:31: note: type 'non_derived_exception' is a template instantiation of 'T'
+// CHECK-NOTES: 10:1: note: type defined here
+
+#define THROW_EXCEPTION(CLASS) ThrowException<CLASS>()
+#define THROW_BAD_EXCEPTION throw int(42);
+#define THROW_GOOD_EXCEPTION throw std::exception();
+#define THROW_DERIVED_EXCEPTION throw deep_hierarchy();
+
+template <typename T>
+class generic_exception : std::exception {};
+
+template <typename T>
+class bad_generic_exception {};
+
+template <typename T>
+class exotic_exception : public T {};
+
+void generic_exceptions() {
+ THROW_EXCEPTION(int);
+ THROW_EXCEPTION(non_derived_exception);
+ THROW_EXCEPTION(std::exception); // Ok
+ THROW_EXCEPTION(derived_exception); // Ok
+ THROW_EXCEPTION(deep_hierarchy); // Ok
+
+ THROW_BAD_EXCEPTION;
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+ // CHECK-NOTES: [[@LINE-22]]:35: note: expanded from macro 'THROW_BAD_EXCEPTION'
+ THROW_GOOD_EXCEPTION;
+ THROW_DERIVED_EXCEPTION;
+
+ throw generic_exception<int>(); // Ok,
+ THROW_EXCEPTION(generic_exception<float>); // Ok
+
+ throw bad_generic_exception<int>();
+ // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'bad_generic_exception<int>' is not derived from 'std::exception'
+ // CHECK-NOTES: [[@LINE-24]]:1: note: type defined here
+ throw bad_generic_exception<std::exception>();
+ // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'bad_generic_exception<std::exception>' is not derived from 'std::exception'
+ // CHECK-NOTES: [[@LINE-27]]:1: note: type defined here
+ THROW_EXCEPTION(bad_generic_exception<int>);
+ THROW_EXCEPTION(bad_generic_exception<std::exception>);
+
+ throw exotic_exception<non_derived_exception>();
+ // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'exotic_exception<non_derived_exception>' is not derived from 'std::exception'
+ // CHECK-NOTES: [[@LINE-30]]:1: note: type defined here
+ THROW_EXCEPTION(exotic_exception<non_derived_exception>);
+
+ throw exotic_exception<derived_exception>(); // Ok
+ THROW_EXCEPTION(exotic_exception<derived_exception>); // Ok
+}
+
+// Test for typedefed exception types
+typedef int TypedefedBad;
+typedef derived_exception TypedefedGood;
+using UsingBad = int;
+using UsingGood = deep_hierarchy;
+
+void typedefed() {
+ throw TypedefedBad();
+ // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'TypedefedBad' (aka 'int') is not derived from 'std::exception'
+ // CHECK-NOTES: [[@LINE-8]]:1: note: type defined here
+ throw TypedefedGood(); // Ok
+
+ throw UsingBad();
+ // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'UsingBad' (aka 'int') is not derived from 'std::exception'
+ // CHECK-NOTES: [[@LINE-11]]:1: note: type defined here
+ throw UsingGood(); // Ok
+}
+
+// Fix PR37913
+struct invalid_argument_maker {
+ ::std::invalid_argument operator()() const;
+};
+struct int_maker {
+ int operator()() const;
+};
+
+template <typename T>
+void templated_thrower() {
+ throw T{}();
+ // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+}
+template <typename T>
+void templated_thrower2() {
+ T ExceptionFactory; // This test found a <dependant-type> which did not happend with 'throw T{}()'
+ throw ExceptionFactory();
+ // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+}
+
+void exception_created_with_function() {
+ templated_thrower<invalid_argument_maker>();
+ templated_thrower<int_maker>();
+
+ templated_thrower2<invalid_argument_maker>();
+ templated_thrower2<int_maker>();
+
+ throw invalid_argument_maker{}();
+ throw int_maker{}();
+ // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+}
+
+struct invalid_argument_factory {
+ ::std::invalid_argument make_exception() const;
+};
+
+struct int_factory {
+ int make_exception() const;
+};
+
+template <typename T>
+void templated_factory() {
+ T f;
+ throw f.make_exception();
+ // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+}
+template <typename T>
+void templated_factory2() {
+ throw T().make_exception();
+ // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+}
+
+void exception_from_factory() {
+ templated_factory<invalid_argument_factory>();
+ templated_factory<int_factory>();
+
+ templated_factory2<invalid_argument_factory>();
+ templated_factory2<int_factory>();
+
+ throw invalid_argument_factory().make_exception();
+ throw int_factory().make_exception();
+ // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+
+ invalid_argument_factory inv_f;
+ throw inv_f.make_exception();
+
+ int_factory int_f;
+ throw int_f.make_exception();
+ // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+}
+
+template <typename T>
+struct ThrowClassTemplateParam {
+ ThrowClassTemplateParam() { throw T(); }
+ // CHECK-NOTES: [[@LINE-1]]:37: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+ // CHECK-NOTES: [[@LINE-2]]:37: note: type 'int' is a template instantiation of 'T'
+};
+
+template <int V>
+struct ThrowValueTemplate {
+ ThrowValueTemplate() { throw V; }
+ // CHECK-NOTES: [[@LINE-1]]:32: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+};
+
+void class_templates() {
+ ThrowClassTemplateParam<int> IntThrow;
+ ThrowClassTemplateParam<std::invalid_argument> ArgThrow;
+
+ ThrowValueTemplate<42> ValueThrow;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-multiway-paths-covered-else.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-multiway-paths-covered-else.cpp
new file mode 100644
index 0000000..34820b5
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-multiway-paths-covered-else.cpp
@@ -0,0 +1,57 @@
+// RUN: %check_clang_tidy %s hicpp-multiway-paths-covered %t \
+// RUN: -config='{CheckOptions: \
+// RUN: [{key: hicpp-multiway-paths-covered.WarnOnMissingElse, value: 1}]}'\
+// RUN: --
+
+enum OS { Mac,
+ Windows,
+ Linux };
+
+void problematic_if(int i, enum OS os) {
+ if (i > 0) {
+ return;
+ } else if (i < 0) {
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: potentially uncovered codepath; add an ending else statement
+ return;
+ }
+
+ // Could be considered as false positive because all paths are covered logically.
+ // I still think this is valid since the possibility of a final 'everything else'
+ // codepath is expected from if-else if.
+ if (i > 0) {
+ return;
+ } else if (i <= 0) {
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: potentially uncovered codepath; add an ending else statement
+ return;
+ }
+
+ // Test if nesting of if-else chains does get caught as well.
+ if (os == Mac) {
+ return;
+ } else if (os == Linux) {
+ // These checks are kind of degenerated, but the check will not try to solve
+ // if logically all paths are covered, which is more the area of the static analyzer.
+ if (true) {
+ return;
+ } else if (false) {
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: potentially uncovered codepath; add an ending else statement
+ return;
+ }
+ return;
+ } else {
+ /* unreachable */
+ if (true) // check if the parent would match here as well
+ return;
+ // No warning for simple if statements, since it is common to just test one condition
+ // and ignore the opposite.
+ }
+
+ // Ok, because all paths are covered
+ if (i > 0) {
+ return;
+ } else if (i < 0) {
+ return;
+ } else {
+ /* error, maybe precondition failed */
+ }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-multiway-paths-covered.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-multiway-paths-covered.cpp
new file mode 100644
index 0000000..15a3407
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-multiway-paths-covered.cpp
@@ -0,0 +1,468 @@
+// RUN: %check_clang_tidy %s hicpp-multiway-paths-covered %t
+
+enum OS { Mac,
+ Windows,
+ Linux };
+
+struct Bitfields {
+ unsigned UInt : 3;
+ int SInt : 1;
+};
+
+int return_integer() { return 42; }
+
+void bad_switch(int i) {
+ switch (i) {
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: switch with only one case; use an if statement
+ case 0:
+ break;
+ }
+ // No default in this switch
+ switch (i) {
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: potential uncovered code path; add a default label
+ case 0:
+ break;
+ case 1:
+ break;
+ case 2:
+ break;
+ }
+
+ // degenerate, maybe even warning
+ switch (i) {
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: switch statement without labels has no effect
+ }
+
+ switch (int j = return_integer()) {
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: potential uncovered code path; add a default label
+ case 0:
+ case 1:
+ case 2:
+ break;
+ }
+
+ // Degenerated, only default case.
+ switch (i) {
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: degenerated switch with default label only
+ default:
+ break;
+ }
+
+ // Degenerated, only one case label and default case -> Better as if-stmt.
+ switch (i) {
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: switch could be better written as an if/else statement
+ case 0:
+ break;
+ default:
+ break;
+ }
+
+ unsigned long long BigNumber = 0;
+ switch (BigNumber) {
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: potential uncovered code path; add a default label
+ case 0:
+ case 1:
+ break;
+ }
+
+ const int &IntRef = i;
+ switch (IntRef) {
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: potential uncovered code path; add a default label
+ case 0:
+ case 1:
+ break;
+ }
+
+ char C = 'A';
+ switch (C) {
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: potential uncovered code path; add a default label
+ case 'A':
+ break;
+ case 'B':
+ break;
+ }
+
+ Bitfields Bf;
+ // UInt has 3 bits size.
+ switch (Bf.UInt) {
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: potential uncovered code path; add a default label
+ case 0:
+ case 1:
+ break;
+ }
+ // All paths explicitly covered.
+ switch (Bf.UInt) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ break;
+ }
+ // SInt has 1 bit size, so this is somewhat degenerated.
+ switch (Bf.SInt) {
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: switch with only one case; use an if statement
+ case 0:
+ break;
+ }
+ // All paths explicitly covered.
+ switch (Bf.SInt) {
+ case 0:
+ case 1:
+ break;
+ }
+
+ bool Flag = false;
+ switch (Flag) {
+ // CHECK-MESSAGES:[[@LINE-1]]:3: warning: switch with only one case; use an if statement
+ case true:
+ break;
+ }
+
+ switch (Flag) {
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: degenerated switch with default label only
+ default:
+ break;
+ }
+
+ // This `switch` will create a frontend warning from '-Wswitch-bool' but is
+ // ok for this check.
+ switch (Flag) {
+ case true:
+ break;
+ case false:
+ break;
+ }
+}
+
+void unproblematic_switch(unsigned char c) {
+ //
+ switch (c) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ case 17:
+ case 18:
+ case 19:
+ case 20:
+ case 21:
+ case 22:
+ case 23:
+ case 24:
+ case 25:
+ case 26:
+ case 27:
+ case 28:
+ case 29:
+ case 30:
+ case 31:
+ case 32:
+ case 33:
+ case 34:
+ case 35:
+ case 36:
+ case 37:
+ case 38:
+ case 39:
+ case 40:
+ case 41:
+ case 42:
+ case 43:
+ case 44:
+ case 45:
+ case 46:
+ case 47:
+ case 48:
+ case 49:
+ case 50:
+ case 51:
+ case 52:
+ case 53:
+ case 54:
+ case 55:
+ case 56:
+ case 57:
+ case 58:
+ case 59:
+ case 60:
+ case 61:
+ case 62:
+ case 63:
+ case 64:
+ case 65:
+ case 66:
+ case 67:
+ case 68:
+ case 69:
+ case 70:
+ case 71:
+ case 72:
+ case 73:
+ case 74:
+ case 75:
+ case 76:
+ case 77:
+ case 78:
+ case 79:
+ case 80:
+ case 81:
+ case 82:
+ case 83:
+ case 84:
+ case 85:
+ case 86:
+ case 87:
+ case 88:
+ case 89:
+ case 90:
+ case 91:
+ case 92:
+ case 93:
+ case 94:
+ case 95:
+ case 96:
+ case 97:
+ case 98:
+ case 99:
+ case 100:
+ case 101:
+ case 102:
+ case 103:
+ case 104:
+ case 105:
+ case 106:
+ case 107:
+ case 108:
+ case 109:
+ case 110:
+ case 111:
+ case 112:
+ case 113:
+ case 114:
+ case 115:
+ case 116:
+ case 117:
+ case 118:
+ case 119:
+ case 120:
+ case 121:
+ case 122:
+ case 123:
+ case 124:
+ case 125:
+ case 126:
+ case 127:
+ case 128:
+ case 129:
+ case 130:
+ case 131:
+ case 132:
+ case 133:
+ case 134:
+ case 135:
+ case 136:
+ case 137:
+ case 138:
+ case 139:
+ case 140:
+ case 141:
+ case 142:
+ case 143:
+ case 144:
+ case 145:
+ case 146:
+ case 147:
+ case 148:
+ case 149:
+ case 150:
+ case 151:
+ case 152:
+ case 153:
+ case 154:
+ case 155:
+ case 156:
+ case 157:
+ case 158:
+ case 159:
+ case 160:
+ case 161:
+ case 162:
+ case 163:
+ case 164:
+ case 165:
+ case 166:
+ case 167:
+ case 168:
+ case 169:
+ case 170:
+ case 171:
+ case 172:
+ case 173:
+ case 174:
+ case 175:
+ case 176:
+ case 177:
+ case 178:
+ case 179:
+ case 180:
+ case 181:
+ case 182:
+ case 183:
+ case 184:
+ case 185:
+ case 186:
+ case 187:
+ case 188:
+ case 189:
+ case 190:
+ case 191:
+ case 192:
+ case 193:
+ case 194:
+ case 195:
+ case 196:
+ case 197:
+ case 198:
+ case 199:
+ case 200:
+ case 201:
+ case 202:
+ case 203:
+ case 204:
+ case 205:
+ case 206:
+ case 207:
+ case 208:
+ case 209:
+ case 210:
+ case 211:
+ case 212:
+ case 213:
+ case 214:
+ case 215:
+ case 216:
+ case 217:
+ case 218:
+ case 219:
+ case 220:
+ case 221:
+ case 222:
+ case 223:
+ case 224:
+ case 225:
+ case 226:
+ case 227:
+ case 228:
+ case 229:
+ case 230:
+ case 231:
+ case 232:
+ case 233:
+ case 234:
+ case 235:
+ case 236:
+ case 237:
+ case 238:
+ case 239:
+ case 240:
+ case 241:
+ case 242:
+ case 243:
+ case 244:
+ case 245:
+ case 246:
+ case 247:
+ case 248:
+ case 249:
+ case 250:
+ case 251:
+ case 252:
+ case 253:
+ case 254:
+ case 255:
+ break;
+ }
+
+ // Some paths are covered by the switch and a default case is present.
+ switch (c) {
+ case 1:
+ case 2:
+ case 3:
+ default:
+ break;
+ }
+}
+
+OS return_enumerator() {
+ return Linux;
+}
+
+// Enumpaths are already covered by a warning, this is just to ensure, that there is
+// no interference or false positives.
+// -Wswitch warns about uncovered enum paths and each here described case is already
+// covered.
+void switch_enums(OS os) {
+ switch (os) {
+ case Linux:
+ break;
+ }
+
+ switch (OS another_os = return_enumerator()) {
+ case Linux:
+ break;
+ }
+
+ switch (os) {
+ }
+}
+
+/// All of these cases will not emit a warning per default, but with explicit activation.
+/// Covered in extra test file.
+void problematic_if(int i, enum OS os) {
+ if (i > 0) {
+ return;
+ } else if (i < 0) {
+ return;
+ }
+
+ if (os == Mac) {
+ return;
+ } else if (os == Linux) {
+ if (true) {
+ return;
+ } else if (false) {
+ return;
+ }
+ return;
+ } else {
+ /* unreachable */
+ if (true) // check if the parent would match here as well
+ return;
+ }
+
+ // Ok, because all paths are covered
+ if (i > 0) {
+ return;
+ } else if (i < 0) {
+ return;
+ } else {
+ /* error, maybe precondition failed */
+ }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-no-assembler-msvc.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-no-assembler-msvc.cpp
new file mode 100644
index 0000000..d29a9e9
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-no-assembler-msvc.cpp
@@ -0,0 +1,11 @@
+// REQUIRES: system-windows
+// FIXME: Re-enable test on windows (PR36855)
+// UNSUPPORTED: system-windows
+// RUN: %check_clang_tidy %s hicpp-no-assembler %t
+
+void f() {
+ _asm {
+ mov al, 2;
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: do not use inline assembler in safety-critical code [hicpp-no-assembler]
+ }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-no-assembler.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-no-assembler.cpp
new file mode 100644
index 0000000..d08ea74
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-no-assembler.cpp
@@ -0,0 +1,12 @@
+// RUN: %check_clang_tidy %s hicpp-no-assembler %t
+
+__asm__(".symver foo, bar@v");
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not use inline assembler in safety-critical code [hicpp-no-assembler]
+
+static int s asm("spam");
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not use inline assembler in safety-critical code [hicpp-no-assembler]
+
+void f() {
+ __asm("mov al, 2");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use inline assembler in safety-critical code [hicpp-no-assembler]
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-signed-bitwise-bug34747.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-signed-bitwise-bug34747.cpp
new file mode 100644
index 0000000..217df71
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-signed-bitwise-bug34747.cpp
@@ -0,0 +1,29 @@
+// RUN: %check_clang_tidy %s hicpp-signed-bitwise %t --
+
+// Note: this test expects no diagnostics, but FileCheck cannot handle that,
+// hence the use of | count 0.
+
+template <typename C>
+struct OutputStream {
+ OutputStream &operator<<(C);
+};
+
+template <typename C>
+struct foo {
+ typedef OutputStream<C> stream_type;
+ foo(stream_type &o) {
+ o << 'x'; // warning occured here, fixed now
+ }
+};
+
+void bar(OutputStream<signed char> &o) {
+ foo<signed char> f(o);
+}
+
+void silence_lit() {
+ int SValue = 42;
+ int SResult;
+
+ SResult = SValue & 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-signed-bitwise-standard-types.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-signed-bitwise-standard-types.cpp
new file mode 100644
index 0000000..c85fe20
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-signed-bitwise-standard-types.cpp
@@ -0,0 +1,197 @@
+// RUN: clang-tidy %s -checks='-*,hicpp-signed-bitwise' -- -std=c++11
+
+#include "hicpp-signed-bitwise-standard-types.h"
+
+void pure_bitmask_types() {
+ // std::locale::category
+ int SResult = 0;
+ std::locale::category C = std::locale::category::ctype;
+
+ SResult = std::locale::category::none | std::locale::category::collate;
+ SResult|= std::locale::category::collate;
+ SResult = std::locale::category::ctype & std::locale::category::monetary;
+ SResult&= std::locale::category::monetary;
+ SResult = std::locale::category::numeric ^ std::locale::category::time;
+ SResult^= std::locale::category::time;
+ SResult = std::locale::category::messages | std::locale::category::all;
+
+ SResult = std::locale::category::all & C;
+ SResult&= std::locale::category::all;
+ SResult = std::locale::category::all | C;
+ SResult|= std::locale::category::all;
+ SResult = std::locale::category::all ^ C;
+ SResult^= std::locale::category::all;
+
+ // std::ctype_base::mask
+ std::ctype_base::mask M = std::ctype_base::mask::punct;
+
+ SResult = std::ctype_base::mask::space | std::ctype_base::mask::print;
+ SResult = std::ctype_base::mask::cntrl & std::ctype_base::mask::upper;
+ SResult = std::ctype_base::mask::lower ^ std::ctype_base::mask::alpha;
+ SResult|= std::ctype_base::mask::digit | std::ctype_base::mask::punct;
+ SResult&= std::ctype_base::mask::xdigit & std::ctype_base::mask::alnum;
+ SResult^= std::ctype_base::mask::alnum ^ std::ctype_base::mask::graph;
+
+ SResult&= std::ctype_base::mask::space & M;
+ SResult|= std::ctype_base::mask::space | M;
+ SResult^= std::ctype_base::mask::space ^ M;
+
+ // std::ios_base::fmtflags
+ std::ios_base::fmtflags F = std::ios_base::fmtflags::floatfield;
+
+ SResult = std::ios_base::fmtflags::dec | std::ios_base::fmtflags::oct;
+ SResult = std::ios_base::fmtflags::hex & std::ios_base::fmtflags::basefield;
+ SResult = std::ios_base::fmtflags::left ^ std::ios_base::fmtflags::right;
+ SResult|= std::ios_base::fmtflags::internal | std::ios_base::fmtflags::adjustfield;
+ SResult&= std::ios_base::fmtflags::scientific & std::ios_base::fmtflags::fixed;
+ SResult^= std::ios_base::fmtflags::floatfield ^ std::ios_base::fmtflags::boolalpha;
+ SResult = std::ios_base::fmtflags::showbase | std::ios_base::fmtflags::showpoint;
+ SResult = std::ios_base::fmtflags::showpos & std::ios_base::fmtflags::skipws;
+ SResult = std::ios_base::fmtflags::unitbuf ^ std::ios_base::fmtflags::uppercase;
+
+ SResult|= std::ios_base::fmtflags::unitbuf | F;
+ SResult&= std::ios_base::fmtflags::unitbuf & F;
+ SResult^= std::ios_base::fmtflags::unitbuf ^ F;
+
+ // std::ios_base::iostate
+ std::ios_base::iostate S = std::ios_base::iostate::goodbit;
+
+ SResult^= std::ios_base::iostate::goodbit | std::ios_base::iostate::badbit;
+ SResult|= std::ios_base::iostate::failbit & std::ios_base::iostate::eofbit;
+ SResult&= std::ios_base::iostate::failbit ^ std::ios_base::iostate::eofbit;
+
+ SResult = std::ios_base::iostate::goodbit | S;
+ SResult = std::ios_base::iostate::goodbit & S;
+ SResult = std::ios_base::iostate::goodbit ^ S;
+
+ // std::ios_base::openmode
+ std::ios_base::openmode B = std::ios_base::openmode::binary;
+
+ SResult = std::ios_base::openmode::app | std::ios_base::openmode::binary;
+ SResult = std::ios_base::openmode::in & std::ios_base::openmode::out;
+ SResult = std::ios_base::openmode::trunc ^ std::ios_base::openmode::ate;
+
+ SResult&= std::ios_base::openmode::trunc | B;
+ SResult^= std::ios_base::openmode::trunc & B;
+ SResult|= std::ios_base::openmode::trunc ^ B;
+}
+
+void still_forbidden() {
+ // std::locale::category
+ unsigned int UResult = 0u;
+ int SResult = 0;
+
+ SResult = std::ctype_base::mask::print ^ 8u;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ SResult = std::ctype_base::mask::cntrl | 8;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ SResult = std::ctype_base::mask::upper & 8;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ SResult = std::ctype_base::mask::lower ^ -8;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+
+ // Staying within the allowed standard types is ok for bitwise assignment
+ // operations.
+ std::ctype_base::mask var = std::ctype_base::mask::print;
+ SResult<<= std::ctype_base::mask::upper;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ SResult>>= std::ctype_base::mask::upper;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ SResult &= std::ctype_base::mask::upper;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ SResult |= std::ctype_base::mask::upper;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ SResult ^= std::ctype_base::mask::upper;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+
+ UResult = std::locale::category::collate << 1u;
+ UResult = std::locale::category::ctype << 1;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ UResult = std::locale::category::monetary >> 1u;
+ UResult = std::locale::category::numeric >> 1;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+
+ UResult = ~std::locale::category::messages;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
+ SResult = ~std::locale::category::all;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
+
+ // std::ctype_base::mask
+ UResult = std::ctype_base::mask::space | 8;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ UResult = std::ctype_base::mask::print & 8u;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ UResult = std::ctype_base::mask::cntrl ^ -8;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+
+ UResult = std::ctype_base::mask::upper << 1;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ UResult = std::ctype_base::mask::lower << 1u;
+ UResult = std::ctype_base::mask::alpha >> 1u;
+ UResult = std::ctype_base::mask::digit >> 1u;
+
+ UResult = ~std::ctype_base::mask::punct;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
+ SResult = ~std::ctype_base::mask::xdigit;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
+
+ // std::ios_base::fmtflags
+ UResult = std::ios_base::fmtflags::dec | 1;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ UResult = std::ios_base::fmtflags::oct & 1u;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ UResult = std::ios_base::fmtflags::hex ^ -1;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+
+ UResult = std::ios_base::fmtflags::basefield >> 1;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ UResult = std::ios_base::fmtflags::left >> 1u;
+ UResult = std::ios_base::fmtflags::right << 1;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ UResult = std::ios_base::fmtflags::internal << 1u;
+
+ UResult = ~std::ios_base::fmtflags::adjustfield;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
+ SResult = ~std::ios_base::fmtflags::scientific;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
+
+ // std::ios_base::iostate
+ UResult = std::ios_base::iostate::goodbit | 8;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ UResult = std::ios_base::iostate::badbit & 8u;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ UResult = std::ios_base::iostate::failbit ^ -8;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+
+ UResult = std::ios_base::iostate::eofbit << 1;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ UResult = std::ios_base::iostate::goodbit << 1u;
+ UResult = std::ios_base::iostate::badbit >> 1;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ UResult = std::ios_base::iostate::failbit >> 1u;
+
+ UResult = ~std::ios_base::iostate::eofbit;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
+ SResult = ~std::ios_base::iostate::goodbit;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
+
+ // std::ios_base::openmode
+ UResult = std::ios_base::app | 8;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ UResult = std::ios_base::binary & 8u;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ UResult = std::ios_base::in ^ -8;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+
+ UResult = std::ios_base::out >> 1;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ UResult = std::ios_base::trunc >> 1u;
+ UResult = std::ios_base::ate << 1;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ UResult = std::ios_base::ate << 1u;
+
+ UResult = ~std::ios_base::openmode::app;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
+ SResult = ~std::ios_base::openmode::binary;
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-signed-bitwise-standard-types.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-signed-bitwise-standard-types.h
new file mode 100644
index 0000000..e66fd09
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-signed-bitwise-standard-types.h
@@ -0,0 +1,81 @@
+#pragma clang system_header
+
+// Implement standard types that are known to be defined as unsigned in some
+// implementations like MSVC.
+namespace std {
+namespace locale {
+enum category : int {
+ none = 0u,
+ collate = 1u << 1u,
+ ctype = 1u << 2u,
+ monetary = 1u << 3u,
+ numeric = 1u << 4u,
+ time = 1u << 5u,
+ messages = 1u << 6u,
+ all = none | collate | ctype | monetary | numeric | time | messages
+ // CHECK MESSAGES: [[@LINE-1]]:9: warning: use of a signed integer operand with a binary bitwise operator
+};
+} // namespace locale
+
+namespace ctype_base {
+enum mask : int {
+ space,
+ print,
+ cntrl,
+ upper,
+ lower,
+ alpha,
+ digit,
+ punct,
+ xdigit,
+ /* blank, // C++11 */
+ alnum = alpha | digit,
+ // CHECK MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
+ graph = alnum | punct
+ // CHECK MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
+};
+} // namespace ctype_base
+
+namespace ios_base {
+enum fmtflags : int {
+ dec = 0u,
+ oct = 1u << 2u,
+ hex = 1u << 3u,
+ basefield = dec | oct | hex | 0u,
+ // CHECK MESSAGES: [[@LINE-1]]:15: warning: use of a signed integer operand with a binary bitwise operator
+ left = 1u << 4u,
+ right = 1u << 5u,
+ internal = 1u << 6u,
+ adjustfield = left | right | internal,
+ // CHECK MESSAGES: [[@LINE-1]]:17: warning: use of a signed integer operand with a binary bitwise operator
+ scientific = 1u << 7u,
+ fixed = 1u << 8u,
+ floatfield = scientific | fixed | (scientific | fixed) | 0u,
+ // CHECK MESSAGES: [[@LINE-1]]:16: warning: use of a signed integer operand with a binary bitwise operator
+ // CHECK MESSAGES: [[@LINE-2]]:38: warning: use of a signed integer operand with a binary bitwise operator
+ boolalpha = 1u << 9u,
+ showbase = 1u << 10u,
+ showpoint = 1u << 11u,
+ showpos = 1u << 12u,
+ skipws = 1u << 13u,
+ unitbuf = 1u << 14u,
+ uppercase = 1u << 15u
+};
+
+enum iostate : int {
+ goodbit = 0u,
+ badbit = 1u << 1u,
+ failbit = 1u << 2u,
+ eofbit = 1u << 3u
+};
+
+enum openmode : int {
+ app = 0u,
+ binary = 0u << 1u,
+ in = 0u << 2u,
+ out = 0u << 3u,
+ trunc = 0u << 4u,
+ ate = 0u << 5u
+};
+} // namespace ios_base
+} // namespace std
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-signed-bitwise.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-signed-bitwise.cpp
new file mode 100644
index 0000000..97a24b6
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/hicpp-signed-bitwise.cpp
@@ -0,0 +1,240 @@
+// RUN: %check_clang_tidy %s hicpp-signed-bitwise %t -- -- -std=c++11 --target=x86_64-linux
+
+// These could cause false positives and should not be considered.
+struct StreamClass {
+};
+StreamClass &operator<<(StreamClass &os, unsigned int i) {
+ return os;
+}
+StreamClass &operator<<(StreamClass &os, int i) {
+ return os;
+}
+StreamClass &operator>>(StreamClass &os, unsigned int i) {
+ return os;
+}
+StreamClass &operator>>(StreamClass &os, int i) {
+ return os;
+}
+struct AnotherStream {
+ AnotherStream &operator<<(unsigned char c) { return *this; }
+ AnotherStream &operator<<(signed char c) { return *this; }
+
+ AnotherStream &operator>>(unsigned char c) { return *this; }
+ AnotherStream &operator>>(signed char c) { return *this; }
+};
+
+void binary_bitwise() {
+ int SValue = 42;
+ int SResult;
+
+ unsigned int UValue = 42;
+ unsigned int UResult;
+
+ SResult = SValue & 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ SResult = SValue & -1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ SResult = SValue & SValue;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+
+ UResult = SValue & 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ UResult = SValue & -1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ UResult&= 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
+
+ UResult = UValue & 1u; // Ok
+ UResult = UValue & UValue; // Ok
+ UResult&= 2u; // Ok
+
+ unsigned char UByte1 = 0u;
+ unsigned char UByte2 = 16u;
+ signed char SByte1 = 0;
+ signed char SByte2 = 16;
+
+ UByte1 = UByte1 & UByte2; // Ok
+ UByte1 = SByte1 & UByte2;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
+ UByte1 = SByte1 & SByte2;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
+ SByte1 = SByte1 & SByte2;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
+
+ // More complex expressions.
+ UResult = UValue & (SByte1 + (SByte1 | SByte2));
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+ // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: use of a signed integer operand with a binary bitwise operator
+
+ // The rest is to demonstrate functionality but all operators are matched equally.
+ // Therefore functionality is the same for all binary operations.
+ UByte1 = UByte1 | UByte2; // Ok
+ UByte1 = UByte1 | SByte2;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
+ UByte1|= SByte2;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
+ UByte1|= UByte2; // Ok
+
+ UByte1 = UByte1 ^ UByte2; // Ok
+ UByte1 = UByte1 ^ SByte2;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
+ UByte1^= SByte2;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
+ UByte1^= UByte2; // Ok
+
+ UByte1 = UByte1 >> UByte2; // Ok
+ UByte1 = UByte1 >> SByte2;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
+ UByte1>>= SByte2;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
+ UByte1>>= UByte2; // Ok
+
+ UByte1 = UByte1 << UByte2; // Ok
+ UByte1 = UByte1 << SByte2;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
+ UByte1<<= SByte2;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
+ UByte1<<= UByte2; // Ok
+
+ int SignedInt1 = 1 << 12;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator
+ int SignedInt2 = 1u << 12;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator
+}
+
+void f1(unsigned char c) {}
+void f2(signed char c) {}
+void f3(int c) {}
+
+void unary_bitwise() {
+ unsigned char UByte1 = 0u;
+ signed char SByte1 = 0;
+
+ UByte1 = ~UByte1; // Ok
+ SByte1 = ~UByte1;
+ SByte1 = ~SByte1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a unary bitwise operator
+ UByte1 = ~SByte1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a unary bitwise operator
+
+ unsigned int UInt = 0u;
+ int SInt = 0;
+
+ f1(~UByte1); // Ok
+ f1(~SByte1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
+ f1(~UInt);
+ f1(~SInt);
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
+ f2(~UByte1);
+ f2(~SByte1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
+ f2(~UInt);
+ f2(~SInt);
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
+ f3(~UByte1); // Ok
+ f3(~SByte1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
+}
+
+/// HICPP uses these examples to demonstrate the rule.
+void standard_examples() {
+ int i = 3;
+ unsigned int k = 0u;
+
+ int r = i << -1; // Emits -Wshift-count-negative from clang
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
+ r = i << 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
+
+ r = -1 >> -1; // Emits -Wshift-count-negative from clang
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
+ r = -1 >> 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
+
+ r = -1 >> i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
+ r = -1 >> -i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
+
+ r = ~0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a unary bitwise operator
+ r = ~0u; // Ok
+ k = ~k; // Ok
+
+ unsigned int u = (-1) & 2u;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator
+ u = (-1) | 1u;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
+ u = (-1) ^ 1u;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
+}
+
+void streams_should_work() {
+ StreamClass s;
+ s << 1u; // Ok
+ s << 1; // Ok
+ s >> 1; // Ok
+ s >> 1u; // Ok
+
+ AnotherStream as;
+ unsigned char uc = 1u;
+ signed char sc = 1;
+ as << uc; // Ok
+ as << sc; // Ok
+ as >> uc; // Ok
+ as >> sc; // Ok
+}
+
+enum OldEnum {
+ ValueOne,
+ ValueTwo,
+};
+
+enum OldSigned : int {
+ IntOne,
+ IntTwo,
+};
+
+void classicEnums() {
+ OldEnum e1 = ValueOne, e2 = ValueTwo;
+ int e3; // Using the enum type, results in an error.
+ e3 = ValueOne | ValueTwo; // Ok
+ e3 = ValueOne & ValueTwo; // Ok
+ e3 = ValueOne ^ ValueTwo; // Ok
+ e3 = e1 | e2; // Ok
+ e3 = e1 & e2; // Ok
+ e3 = e1 ^ e2; // Ok
+
+ OldSigned s1 = IntOne, s2 = IntTwo;
+ int s3;
+ s3 = IntOne | IntTwo; // Signed
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
+ s3|= IntTwo; // Signed
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
+ s3 = IntOne & IntTwo; // Signed
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
+ s3&= IntTwo; // Signed
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
+ s3 = IntOne ^ IntTwo; // Signed
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
+ s3^= IntTwo; // Signed
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
+ s3 = s1 | s2; // Signed
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
+ s3 = s1 & s2; // Signed
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
+ s3 = s1 ^ s2; // Signed
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
+}
+
+enum EnumConstruction {
+ one = 1,
+ two = 2,
+ test1 = 1 << 12,
+ // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
+ test2 = one << two,
+ // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
+ test3 = 1u << 12,
+ // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/line-filter.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/line-filter.cpp
new file mode 100644
index 0000000..ad980cf
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/line-filter.cpp
@@ -0,0 +1,27 @@
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -line-filter='[{"name":"line-filter.cpp","lines":[[18,18],[22,22]]},{"name":"header1.h","lines":[[1,2]]},{"name":"header2.h"},{"name":"header3.h"}]' -header-filter='header[12]\.h$' %s -- -I %S/Inputs/line-filter 2>&1 | FileCheck %s
+
+#include "header1.h"
+// CHECK-NOT: header1.h:{{.*}} warning
+// CHECK: header1.h:1:12: warning: single-argument constructors must be marked explicit
+// CHECK: header1.h:2:12: warning: single-argument constructors {{.*}}
+// CHECK-NOT: header1.h:{{.*}} warning
+
+#include "header2.h"
+// CHECK: header2.h:1:12: warning: single-argument constructors {{.*}}
+// CHECK: header2.h:2:12: warning: single-argument constructors {{.*}}
+// CHECK: header2.h:3:12: warning: single-argument constructors {{.*}}
+// CHECK-NOT: header2.h:{{.*}} warning
+
+#include "header3.h"
+// CHECK-NOT: header3.h:{{.*}} warning
+
+class A { A(int); };
+// CHECK: :[[@LINE-1]]:11: warning: single-argument constructors {{.*}}
+class B { B(int); };
+// CHECK-NOT: :[[@LINE-1]]:{{.*}} warning
+class C { C(int); };
+// CHECK: :[[@LINE-1]]:11: warning: single-argument constructors {{.*}}
+
+// CHECK-NOT: warning:
+
+// CHECK: Suppressed 3 warnings (1 in non-user code, 2 due to line filter)
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/list-checks.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/list-checks.cpp
new file mode 100644
index 0000000..674c118
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/list-checks.cpp
@@ -0,0 +1,4 @@
+// RUN: mkdir -p %T/clang-tidy/list-checks/
+// RUN: echo '{Checks: "-*,google-*"}' > %T/clang-tidy/.clang-tidy
+// RUN: cd %T/clang-tidy/list-checks
+// RUN: clang-tidy -list-checks | grep "^ *google-"
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/llvm-include-order.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/llvm-include-order.cpp
new file mode 100644
index 0000000..7272353
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/llvm-include-order.cpp
@@ -0,0 +1,42 @@
+// RUN: %check_clang_tidy %s llvm-include-order %t -- -- -isystem %S/Inputs/Headers
+
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: #includes are not sorted properly
+#include "j.h"
+#include "gtest/foo.h"
+#include "i.h"
+#include <s.h>
+#include "llvm/a.h"
+#include "clang/b.h"
+#include "clang-c/c.h" // hi
+#include "llvm-c/d.h" // -c
+
+// CHECK-FIXES: #include "j.h"
+// CHECK-FIXES-NEXT: #include "i.h"
+// CHECK-FIXES-NEXT: #include "clang-c/c.h" // hi
+// CHECK-FIXES-NEXT: #include "clang/b.h"
+// CHECK-FIXES-NEXT: #include "llvm-c/d.h" // -c
+// CHECK-FIXES-NEXT: #include "llvm/a.h"
+// CHECK-FIXES-NEXT: #include "gtest/foo.h"
+// CHECK-FIXES-NEXT: #include <s.h>
+
+#include "b.h"
+#ifdef FOO
+#include "a.h"
+#endif
+
+// CHECK-FIXES: #include "b.h"
+// CHECK-FIXES-NEXT: #ifdef FOO
+// CHECK-FIXES-NEXT: #include "a.h"
+// CHECK-FIXES-NEXT: #endif
+
+// CHECK-MESSAGES: [[@LINE+1]]:1: warning: #includes are not sorted properly
+#include "b.h"
+#include "a.h"
+
+// CHECK-FIXES: #include "a.h"
+// CHECK-FIXES-NEXT: #include "b.h"
+
+// CHECK-MESSAGES-NOT: [[@LINE+1]]:1: warning: #includes are not sorted properly
+#include "cross-file-c.h"
+// This line number should correspond to the position of the #include in cross-file-c.h
+#include "cross-file-a.h"
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/llvm-twine-local.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/llvm-twine-local.cpp
new file mode 100644
index 0000000..06eb761
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/llvm-twine-local.cpp
@@ -0,0 +1,64 @@
+// RUN: %check_clang_tidy %s llvm-twine-local %t
+
+namespace llvm {
+class Twine {
+public:
+ Twine(const char *);
+ Twine(int);
+ Twine();
+ Twine &operator+(const Twine &);
+};
+}
+
+using namespace llvm;
+
+void foo(const Twine &x);
+
+static Twine Moo = Twine("bark") + "bah";
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: static std::string Moo = (Twine("bark") + "bah").str();
+
+int main() {
+ const Twine t = Twine("a") + "b" + Twine(42);
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t = (Twine("a") + "b" + Twine(42)).str();
+ foo(Twine("a") + "b");
+
+ Twine Prefix = false ? "__INT_FAST" : "__UINT_FAST";
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: const char * Prefix = false ? "__INT_FAST" : "__UINT_FAST";
+
+ const Twine t2 = Twine();
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t2 = (Twine()).str();
+ foo(Twine() + "b");
+
+ const Twine t3 = Twine(42);
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t3 = (Twine(42)).str();
+
+ const Twine t4 = Twine(42) + "b";
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t4 = (Twine(42) + "b").str();
+
+ const Twine t5 = Twine() + "b";
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t5 = (Twine() + "b").str();
+
+ const Twine t6 = true ? Twine() : Twine(42);
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t6 = (true ? Twine() : Twine(42)).str();
+
+ const Twine t7 = false ? Twine() : Twine("b");
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t7 = (false ? Twine() : Twine("b")).str();
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/macros.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/macros.cpp
new file mode 100644
index 0000000..fa4f32a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/macros.cpp
@@ -0,0 +1,7 @@
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' %s -- | FileCheck %s
+
+#define Q(name) class name { name(int i); }
+
+Q(A);
+// CHECK: :[[@LINE-1]]:3: warning: single-argument constructors must be marked explicit
+// CHECK: :3:30: note: expanded from macro 'Q'
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-definitions-in-headers-1z.hpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-definitions-in-headers-1z.hpp
new file mode 100644
index 0000000..79fb7bc
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-definitions-in-headers-1z.hpp
@@ -0,0 +1,10 @@
+// RUN: %check_clang_tidy %s misc-definitions-in-headers %t -- -- -std=c++1z
+
+class CE {
+ constexpr static int i = 5; // OK: inline variable definition.
+};
+
+inline int i = 5; // OK: inline variable definition.
+
+int b = 1;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: variable 'b' defined in a header file; variable definitions in header files can lead to ODR violations [misc-definitions-in-headers]
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-definitions-in-headers.hpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-definitions-in-headers.hpp
new file mode 100644
index 0000000..5e83e68
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-definitions-in-headers.hpp
@@ -0,0 +1,181 @@
+// RUN: %check_clang_tidy %s misc-definitions-in-headers %t
+
+int f() {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f' defined in a header file; function definitions in header files can lead to ODR violations [misc-definitions-in-headers]
+// CHECK-FIXES: inline int f() {
+ return 1;
+}
+
+class CA {
+ void f1() {} // OK: inline class member function definition.
+ void f2();
+ template<typename T>
+ T f3() {
+ T a = 1;
+ return a;
+ }
+ template<typename T>
+ struct CAA {
+ struct CAB {
+ void f4();
+ };
+ };
+};
+
+void CA::f2() { }
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: function 'f2' defined in a header file;
+// CHECK-FIXES: inline void CA::f2() {
+
+template <>
+int CA::f3() {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: full function template specialization 'f3<int>' defined in a header file;
+// CHECK-FIXES: inline int CA::f3() {
+ int a = 1;
+ return a;
+}
+
+template <typename T>
+void CA::CAA<T>::CAB::f4() {
+// OK: member function definition of a nested template class in a class.
+}
+
+template <typename T>
+struct CB {
+ void f1();
+ struct CCA {
+ void f2(T a);
+ };
+ struct CCB; // OK: forward declaration.
+ static int a; // OK: class static data member declaration.
+};
+
+template <typename T>
+void CB<T>::f1() { // OK: Member function definition of a class template.
+}
+
+template <typename T>
+void CB<T>::CCA::f2(T a) {
+// OK: member function definition of a nested class in a class template.
+}
+
+template <typename T>
+struct CB<T>::CCB {
+ void f3();
+};
+
+template <typename T>
+void CB<T>::CCB::f3() {
+// OK: member function definition of a nested class in a class template.
+}
+
+template <typename T>
+int CB<T>::a = 2; // OK: static data member definition of a class template.
+
+template class CB<int>; // OK: explicitly instantiated static data member of a class template.
+inline int callCB() {
+ CB<double> cb; // OK: implicitly instantiated static data member of a class template.
+ return cb.a;
+}
+
+template <typename T>
+T tf() { // OK: template function definition.
+ T a;
+ return a;
+}
+
+
+namespace NA {
+ int f() { return 1; }
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: function 'f' defined in a header file;
+// CHECK-FIXES: inline int f() { return 1; }
+}
+
+template <typename T>
+T f3() {
+ T a = 1;
+ return a;
+}
+
+template <>
+int f3() {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: full function template specialization 'f3<int>' defined in a header file;
+// CHECK-FIXES: inline int f3() {
+ int a = 1;
+ return a;
+}
+
+int f5(); // OK: function declaration.
+inline int f6() { return 1; } // OK: inline function definition.
+namespace {
+ int f7() { return 1; }
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: function 'f7' defined in a header file;
+}
+
+int f8() = delete; // OK: the function being marked delete is not callable.
+
+template <typename T>
+int f9(T t) { return 1; }
+
+inline void callF9() { f9(1); } // OK: implicitly instantiated function.
+template int f9(double); // OK: explicitly instantiated function.
+
+int a = 1;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: variable 'a' defined in a header file; variable definitions in header files can lead to ODR violations [misc-definitions-in-headers]
+CA a1;
+// CHECK-MESSAGES: :[[@LINE-1]]:4: warning: variable 'a1' defined in a header file;
+
+namespace NB {
+ int b = 1;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: variable 'b' defined in a header file;
+ const int c = 1; // OK: internal linkage variable definition.
+}
+
+class CC {
+ static int d; // OK: class static data member declaration.
+};
+
+int CC::d = 1;
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: variable 'd' defined in a header file;
+
+const char* ca = "foo";
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: variable 'ca' defined in a header file;
+
+namespace {
+ int e = 2;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: variable 'e' defined in a header file;
+}
+
+const char* const g = "foo"; // OK: internal linkage variable definition.
+static int h = 1; // OK: internal linkage variable definition.
+const int i = 1; // OK: internal linkage variable definition.
+extern int j; // OK: internal linkage variable definition.
+
+template <typename T, typename U>
+struct CD {
+ int f();
+};
+
+template <typename T>
+struct CD<T, int> {
+ int f();
+};
+
+template <>
+struct CD<int, int> {
+ int f();
+};
+
+int CD<int, int>::f() {
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: function 'f' defined in a header file;
+// CHECK-FIXES: inline int CD<int, int>::f() {
+ return 0;
+}
+
+template <typename T>
+int CD<T, int>::f() { // OK: partial template specialization.
+ return 0;
+}
+
+constexpr int k = 1; // OK: constexpr variable has internal linkage.
+
+constexpr int f10() { return 0; } // OK: constexpr function definition.
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-misplaced-const-cxx17.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-misplaced-const-cxx17.cpp
new file mode 100644
index 0000000..7816a09
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-misplaced-const-cxx17.cpp
@@ -0,0 +1,15 @@
+// RUN: %check_clang_tidy -expect-clang-tidy-error %s misc-misplaced-const %t -- -- -std=c++17
+
+// This test previously would cause a failed assertion because the structured
+// binding declaration had no valid type associated with it. This ensures the
+// expected clang diagnostic is generated instead.
+// CHECK-MESSAGES: :[[@LINE+1]]:6: error: decomposition declaration '[x]' requires an initializer [clang-diagnostic-error]
+auto [x];
+
+struct S { int a; };
+S f();
+
+int main() {
+ auto [x] = f();
+}
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-misplaced-const.c b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-misplaced-const.c
new file mode 100644
index 0000000..cccf3a4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-misplaced-const.c
@@ -0,0 +1,45 @@
+// RUN: %check_clang_tidy %s misc-misplaced-const %t
+
+typedef int plain_i;
+typedef int *ip;
+typedef const int *cip;
+
+typedef void (*func_ptr)(void);
+
+void func(void) {
+ // ok
+ const int *i0 = 0;
+ const plain_i *i1 = 0;
+ const cip i2 = 0; // const applies to both pointer and pointee.
+
+ // Not ok
+ const ip i3 = 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: 'i3' declared with a const-qualified typedef type; results in the type being 'int *const' instead of 'const int *'
+
+ ip const i4 = 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: 'i4' declared with a const-qualified
+
+ const volatile ip i5 = 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'i5' declared with a const-qualified typedef type; results in the type being 'int *const volatile' instead of 'const int *volatile'
+}
+
+void func2(const plain_i *i1,
+ const cip i2,
+ const ip i3,
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'i3' declared with a const-qualified
+ const int *i4) {
+}
+
+struct S {
+ const int *i0;
+ const plain_i *i1;
+ const cip i2;
+ const ip i3;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: 'i3' declared with a const-qualified
+};
+
+// Function pointers should not be diagnosed because a function
+// pointer type can never be const.
+void func3(const func_ptr fp) {
+ const func_ptr fp2 = fp;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-misplaced-const.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-misplaced-const.cpp
new file mode 100644
index 0000000..d7ea893
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-misplaced-const.cpp
@@ -0,0 +1,44 @@
+// RUN: %check_clang_tidy %s misc-misplaced-const %t
+
+typedef int plain_i;
+typedef int *ip;
+typedef const int *cip;
+
+void func() {
+ if (const int *i = 0)
+ ;
+ if (const plain_i *i = 0)
+ ;
+ if (const cip i = 0)
+ ;
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:16: warning: 'i' declared with a const-qualified typedef type; results in the type being 'int *const' instead of 'const int *'
+ if (const ip i = 0)
+ ;
+}
+
+template <typename Ty>
+struct S {
+ const Ty *i;
+ const Ty &i2;
+};
+
+template struct S<int>;
+template struct S<ip>; // ok
+template struct S<cip>;
+
+template <typename Ty>
+struct U {
+ const Ty *i;
+ const Ty &i2;
+};
+
+template struct U<int *>; // ok
+
+struct T {
+ typedef void (T::*PMF)();
+
+ void f() {
+ const PMF val = &T::f; // ok
+ }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-new-delete-overloads-sized-dealloc.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-new-delete-overloads-sized-dealloc.cpp
new file mode 100644
index 0000000..2ba60e4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-new-delete-overloads-sized-dealloc.cpp
@@ -0,0 +1,20 @@
+// RUN: %check_clang_tidy %s misc-new-delete-overloads %t -- -- -std=c++14 -fsized-deallocation
+
+typedef decltype(sizeof(int)) size_t;
+
+struct S {
+ // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: declaration of 'operator delete' has no matching declaration of 'operator new' at the same scope [misc-new-delete-overloads]
+ void operator delete(void *ptr, size_t) noexcept; // not a placement delete
+};
+
+struct T {
+ // Because we have enabled sized deallocations explicitly, this new/delete
+ // pair matches.
+ void *operator new(size_t size) noexcept;
+ void operator delete(void *ptr, size_t) noexcept; // ok because sized deallocation is enabled
+};
+
+// While we're here, check that global operator delete with no operator new
+// is also matched.
+// CHECK-MESSAGES: :[[@LINE+1]]:6: warning: declaration of 'operator delete' has no matching declaration of 'operator new' at the same scope
+void operator delete(void *ptr) noexcept;
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-new-delete-overloads.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-new-delete-overloads.cpp
new file mode 100644
index 0000000..3e60537
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-new-delete-overloads.cpp
@@ -0,0 +1,81 @@
+// RUN: %check_clang_tidy %s misc-new-delete-overloads %t -- -- -std=c++14
+
+typedef decltype(sizeof(int)) size_t;
+
+struct S {
+ // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope [misc-new-delete-overloads]
+ void *operator new(size_t size) noexcept;
+ // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new[]' has no matching declaration of 'operator delete[]' at the same scope
+ void *operator new[](size_t size) noexcept;
+};
+
+// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope
+void *operator new(size_t size) noexcept(false);
+
+struct T {
+ // Sized deallocations are not enabled by default, and so this new/delete pair
+ // does not match. However, we expect only one warning, for the new, because
+ // the operator delete is a placement delete and we do not warn on mismatching
+ // placement operations.
+ // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope
+ void *operator new(size_t size) noexcept;
+ void operator delete(void *ptr, size_t) noexcept; // ok only if sized deallocation is enabled
+};
+
+struct U {
+ void *operator new(size_t size) noexcept;
+ void operator delete(void *ptr) noexcept;
+
+ void *operator new[](size_t) noexcept;
+ void operator delete[](void *) noexcept;
+};
+
+struct Z {
+ // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: declaration of 'operator delete' has no matching declaration of 'operator new' at the same scope
+ void operator delete(void *ptr) noexcept;
+ // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: declaration of 'operator delete[]' has no matching declaration of 'operator new[]' at the same scope
+ void operator delete[](void *ptr) noexcept;
+};
+
+struct A {
+ void *operator new(size_t size, Z) noexcept; // ok, placement new
+};
+
+struct B {
+ void operator delete(void *ptr, A) noexcept; // ok, placement delete
+};
+
+// It is okay to have a class with an inaccessible free store operator.
+struct C {
+ void *operator new(size_t, A) noexcept; // ok, placement new
+private:
+ void operator delete(void *) noexcept;
+};
+
+// It is also okay to have a class with a delete free store operator.
+struct D {
+ void *operator new(size_t, A) noexcept; // ok, placement new
+ void operator delete(void *) noexcept = delete;
+};
+
+struct E : U {
+ void *operator new(size_t) noexcept; // okay, we inherit operator delete from U
+};
+
+struct F : S {
+ // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope
+ void *operator new(size_t) noexcept;
+};
+
+class G {
+ void operator delete(void *) noexcept;
+};
+
+struct H : G {
+ // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope
+ void *operator new(size_t) noexcept; // base class operator is inaccessible
+};
+
+template <typename Base> struct Derived : Base {
+ void operator delete(void *);
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-non-copyable-objects.c b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-non-copyable-objects.c
new file mode 100644
index 0000000..ac6198e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-non-copyable-objects.c
@@ -0,0 +1,43 @@
+// RUN: %check_clang_tidy %s misc-non-copyable-objects %t
+
+typedef struct FILE {} FILE;
+typedef struct pthread_cond_t {} pthread_cond_t;
+typedef int pthread_mutex_t;
+
+// CHECK-MESSAGES: :[[@LINE+1]]:13: warning: 'f' declared as type 'FILE', which is unsafe to copy; did you mean 'FILE *'? [misc-non-copyable-objects]
+void g(FILE f);
+// CHECK-MESSAGES: :[[@LINE+1]]:24: warning: 'm' declared as type 'pthread_mutex_t', which is unsafe to copy; did you mean 'pthread_mutex_t *'?
+void h(pthread_mutex_t m);
+// CHECK-MESSAGES: :[[@LINE+1]]:23: warning: 'c' declared as type 'pthread_cond_t', which is unsafe to copy; did you mean 'pthread_cond_t *'?
+void i(pthread_cond_t c);
+
+struct S {
+ pthread_cond_t c; // ok
+ // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: 'f' declared as type 'FILE', which is unsafe to copy; did you mean 'FILE *'?
+ FILE f;
+};
+
+void func(FILE *f) {
+ // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: 'f1' declared as type 'FILE', which is unsafe to copy; did you mean 'FILE *'?
+ FILE f1; // match
+ // CHECK-MESSAGES: :[[@LINE+2]]:8: warning: 'f2' declared as type 'FILE', which is unsafe to copy; did you mean 'FILE *'?
+ // CHECK-MESSAGES: :[[@LINE+1]]:13: warning: expression has opaque data structure type 'FILE'; type should only be used as a pointer and not dereferenced
+ FILE f2 = *f;
+ // CHECK-MESSAGES: :[[@LINE+1]]:15: warning: 'f3' declared as type 'FILE', which is unsafe to copy; did you mean 'FILE *'?
+ struct FILE f3;
+ // CHECK-MESSAGES: :[[@LINE+1]]:16: warning: expression has opaque data structure type 'FILE'; type should only be used as a pointer and not dereferenced
+ (void)sizeof(*f);
+ (void)sizeof(FILE);
+ // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: expression has opaque data structure type 'FILE'; type should only be used as a pointer and not dereferenced
+ g(*f);
+
+ pthread_mutex_t m; // ok
+ h(m); // ok
+
+ pthread_cond_t c; // ok
+ i(c); // ok
+
+ pthread_mutex_t *m1 = &m; // ok
+ // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: expression has opaque data structure type 'pthread_mutex_t'; type should only be used as a pointer and not dereferenced
+ h(*m1);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-non-copyable-objects.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-non-copyable-objects.cpp
new file mode 100644
index 0000000..3d716f4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-non-copyable-objects.cpp
@@ -0,0 +1,26 @@
+// RUN: %check_clang_tidy %s misc-non-copyable-objects %t
+
+namespace std {
+typedef struct FILE {} FILE;
+}
+using namespace std;
+
+// CHECK-MESSAGES: :[[@LINE+1]]:18: warning: 'f' declared as type 'FILE', which is unsafe to copy; did you mean 'FILE *'? [misc-non-copyable-objects]
+void g(std::FILE f);
+
+struct S {
+ // CHECK-MESSAGES: :[[@LINE+1]]:10: warning: 'f' declared as type 'FILE', which is unsafe to copy; did you mean 'FILE *'?
+ ::FILE f;
+};
+
+void func(FILE *f) {
+ // CHECK-MESSAGES: :[[@LINE+1]]:13: warning: 'f1' declared as type 'FILE', which is unsafe to copy; did you mean 'FILE *'?
+ std::FILE f1; // match
+ // CHECK-MESSAGES: :[[@LINE+2]]:10: warning: 'f2' declared as type 'FILE', which is unsafe to copy; did you mean 'FILE *'?
+ // CHECK-MESSAGES: :[[@LINE+1]]:15: warning: expression has opaque data structure type 'FILE'; type should only be used as a pointer and not dereferenced
+ ::FILE f2 = *f; // match, match
+ // CHECK-MESSAGES: :[[@LINE+1]]:15: warning: 'f3' declared as type 'FILE', which is unsafe to copy; did you mean 'FILE *'?
+ struct FILE f3; // match
+ // CHECK-MESSAGES: :[[@LINE+1]]:16: warning: expression has opaque data structure type 'FILE'; type should only be used as a pointer and not dereferenced
+ (void)sizeof(*f); // match
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp
new file mode 100644
index 0000000..2a93ff6
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp
@@ -0,0 +1,397 @@
+// RUN: %check_clang_tidy -check-suffixes=PUBLIC,NONPRIVATE,PROTECTED %s misc-non-private-member-variables-in-classes %t
+// RUN: %check_clang_tidy -check-suffixes=PUBLIC,NONPRIVATE,PROTECTED %s misc-non-private-member-variables-in-classes %t -- -config='{CheckOptions: [{key: misc-non-private-member-variables-in-classes.IgnorePublicMemberVariables, value: 0}, {key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic, value: 0}]}' --
+// RUN: %check_clang_tidy -check-suffixes=PUBLIC,PROTECTED %s misc-non-private-member-variables-in-classes %t -- -config='{CheckOptions: [{key: misc-non-private-member-variables-in-classes.IgnorePublicMemberVariables, value: 0}, {key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic, value: 1}]}' --
+// RUN: %check_clang_tidy -check-suffixes=PUBLIC,PROTECTED %s cppcoreguidelines-non-private-member-variables-in-classes %t -- --
+// RUN: %check_clang_tidy -check-suffixes=PROTECTED %s misc-non-private-member-variables-in-classes %t -- -config='{CheckOptions: [{key: misc-non-private-member-variables-in-classes.IgnorePublicMemberVariables, value: 1}, {key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic, value: 0}]}' --
+// RUN: %check_clang_tidy -check-suffixes=PROTECTED %s misc-non-private-member-variables-in-classes %t -- -config='{CheckOptions: [{key: misc-non-private-member-variables-in-classes.IgnorePublicMemberVariables, value: 1}, {key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic, value: 1}]}' --
+
+//----------------------------------------------------------------------------//
+
+// Only data, do not warn
+
+struct S0 {
+ int S0_v0;
+
+public:
+ int S0_v1;
+
+protected:
+ int S0_v2;
+
+private:
+ int S0_v3;
+};
+
+class S1 {
+ int S1_v0;
+
+public:
+ int S1_v1;
+
+protected:
+ int S1_v2;
+
+private:
+ int S1_v3;
+};
+
+// Only data and implicit or static methods, do not warn
+
+class C {
+public:
+ C() {}
+ ~C() {}
+};
+
+struct S1Implicit {
+ C S1Implicit_v0;
+};
+
+struct S1ImplicitAndStatic {
+ C S1Implicit_v0;
+ static void s() {}
+};
+
+//----------------------------------------------------------------------------//
+
+// All functions are static, do not warn.
+
+struct S2 {
+ static void S2_m0();
+ int S2_v0;
+
+public:
+ static void S2_m1();
+ int S2_v1;
+
+protected:
+ static void S2_m3();
+ int S2_v2;
+
+private:
+ static void S2_m4();
+ int S2_v3;
+};
+
+class S3 {
+ static void S3_m0();
+ int S3_v0;
+
+public:
+ static void S3_m1();
+ int S3_v1;
+
+protected:
+ static void S3_m3();
+ int S3_v2;
+
+private:
+ static void S3_m4();
+ int S3_v3;
+};
+
+//============================================================================//
+
+// union != struct/class. do not diagnose.
+
+union U0 {
+ void U0_m0();
+ int U0_v0;
+
+public:
+ void U0_m1();
+ int U0_v1;
+
+protected:
+ void U0_m2();
+ int U0_v2;
+
+private:
+ void U0_m3();
+ int U0_v3;
+};
+
+//============================================================================//
+
+// Has non-static method with default visibility.
+
+struct S4 {
+ void S4_m0();
+
+ int S4_v0;
+ // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S4_v0' has public visibility
+public:
+ int S4_v1;
+ // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S4_v1' has public visibility
+protected:
+ int S4_v2;
+ // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S4_v2' has protected visibility
+private:
+ int S4_v3;
+};
+
+class S5 {
+ void S5_m0();
+
+ int S5_v0;
+
+public:
+ int S5_v1;
+ // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S5_v1' has public visibility
+protected:
+ int S5_v2;
+ // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S5_v2' has protected visibility
+private:
+ int S5_v3;
+};
+
+//----------------------------------------------------------------------------//
+
+// Has non-static method with public visibility.
+
+struct S6 {
+ int S6_v0;
+ // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S6_v0' has public visibility
+public:
+ void S6_m0();
+ int S6_v1;
+ // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S6_v1' has public visibility
+protected:
+ int S6_v2;
+ // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S6_v2' has protected visibility
+private:
+ int S6_v3;
+};
+
+class S7 {
+ int S7_v0;
+
+public:
+ void S7_m0();
+ int S7_v1;
+ // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S7_v1' has public visibility
+protected:
+ int S7_v2;
+ // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S7_v2' has protected visibility
+private:
+ int S7_v3;
+};
+
+//----------------------------------------------------------------------------//
+
+// Has non-static method with protected visibility.
+
+struct S8 {
+ int S8_v0;
+ // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S8_v0' has public visibility
+public:
+ int S8_v1;
+ // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S8_v1' has public visibility
+protected:
+ void S8_m0();
+ int S8_v2;
+ // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S8_v2' has protected visibility
+private:
+ int S8_v3;
+};
+
+class S9 {
+ int S9_v0;
+
+public:
+ int S9_v1;
+ // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S9_v1' has public visibility
+protected:
+ void S9_m0();
+ int S9_v2;
+ // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S9_v2' has protected visibility
+private:
+ int S9_v3;
+};
+
+//----------------------------------------------------------------------------//
+
+// Has non-static method with private visibility.
+
+struct S10 {
+ int S10_v0;
+ // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S10_v0' has public visibility
+public:
+ int S10_v1;
+ // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S10_v1' has public visibility
+protected:
+ int S10_v2;
+ // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S10_v2' has protected visibility
+private:
+ void S10_m0();
+ int S10_v3;
+};
+
+class S11 {
+ int S11_v0;
+
+public:
+ int S11_v1;
+ // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S11_v1' has public visibility
+protected:
+ int S11_v2;
+ // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S11_v2' has protected visibility
+private:
+ void S11_m0();
+ int S11_v3;
+};
+
+//============================================================================//
+
+// Static variables are ignored.
+// Has non-static methods and static variables.
+
+struct S12 {
+ void S12_m0();
+ static int S12_v0;
+
+public:
+ void S12_m1();
+ static int S12_v1;
+
+protected:
+ void S12_m2();
+ static int S12_v2;
+
+private:
+ void S12_m3();
+ static int S12_v3;
+};
+
+class S13 {
+ void S13_m0();
+ static int S13_v0;
+
+public:
+ void S13_m1();
+ static int S13_v1;
+
+protected:
+ void S13_m2();
+ static int S13_v2;
+
+private:
+ void S13_m3();
+ static int S13_v3;
+};
+
+struct S14 {
+ void S14_m0();
+ int S14_v0;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S14_v0' has public visibility
+
+public:
+ void S14_m1();
+ int S14_v1;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S14_v1' has public visibility
+
+protected:
+ void S14_m2();
+
+private:
+ void S14_m3();
+};
+
+class S15 {
+ void S15_m0();
+
+public:
+ void S15_m1();
+ int S15_v1;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S15_v1' has public visibility
+
+protected:
+ void S15_m2();
+
+private:
+ void S15_m3();
+};
+
+//----------------------------------------------------------------------------//
+
+template <typename T>
+struct S97 {
+ void method();
+ T S97_v0;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:5: warning: member variable 'S97_v0' has public visibility
+};
+
+template struct S97<char *>;
+
+template <>
+struct S97<double> {
+ void method();
+ double S97d_v0;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:10: warning: member variable 'S97d_v0' has public visibility
+};
+
+//----------------------------------------------------------------------------//
+
+#define FIELD(x) int x;
+
+// Do diagnose fields originating from macros.
+struct S98 {
+ void method();
+ FIELD(S98_v0);
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:9: warning: member variable 'S98_v0' has public visibility
+};
+
+//----------------------------------------------------------------------------//
+
+// Don't look in descendant classes.
+class S99 {
+ void method();
+
+ struct S99_0 {
+ int S99_S0_v0;
+ };
+
+public:
+ struct S99_1 {
+ int S99_S0_v0;
+ };
+
+protected:
+ struct S99_2 {
+ int S99_S0_v0;
+ };
+
+private:
+ struct S99_3 {
+ int S99_S0_v0;
+ };
+};
+
+//----------------------------------------------------------------------------//
+
+// Only diagnose once, don't let the inheritance fool you.
+struct S100 {
+ int S100_v0;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S100_v0' has public visibility
+ void m0();
+};
+struct S101_default_inheritance : S100 {
+ int S101_v0;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S101_v0' has public visibility
+ void m1();
+};
+struct S102_public_inheritance : public S100 {
+ int S102_v0;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S102_v0' has public visibility
+ void m1();
+};
+struct S103_protected_inheritance : protected S100 {
+ int S103_v0;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S103_v0' has public visibility
+ void m1();
+};
+struct S104_private_inheritance : private S100 {
+ int S104_v0;
+ // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S104_v0' has public visibility
+ void m1();
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-redundant-expression.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-redundant-expression.cpp
new file mode 100644
index 0000000..3454318
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-redundant-expression.cpp
@@ -0,0 +1,727 @@
+// RUN: %check_clang_tidy %s misc-redundant-expression %t -- -- -std=c++11
+
+typedef __INT64_TYPE__ I64;
+
+struct Point {
+ int x;
+ int y;
+ int a[5];
+} P;
+
+extern Point P1;
+extern Point P2;
+
+extern int foo(int x);
+extern int bar(int x);
+extern int bat(int x, int y);
+
+int TestSimpleEquivalent(int X, int Y) {
+ if (X - X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent [misc-redundant-expression]
+ if (X / X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+ if (X % X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+
+ if (X & X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+ if (X | X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+ if (X ^ X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+
+ if (X < X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+ if (X <= X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+ if (X > X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+ if (X >= X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+
+ if (X && X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+ if (X || X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+
+ if (X != (((X)))) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+
+ if (X + 1 == X + 1) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
+ if (X + 1 != X + 1) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
+ if (X + 1 <= X + 1) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
+ if (X + 1 >= X + 1) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
+
+ if ((X != 1 || Y != 1) && (X != 1 || Y != 1)) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: both sides of operator are equivalent
+ if (P.a[X - P.x] != P.a[X - P.x]) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: both sides of operator are equivalent
+
+ if ((int)X < (int)X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent
+ if (int(X) < int(X)) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent
+
+ if ( + "dummy" == + "dummy") return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both sides of operator are equivalent
+ if (L"abc" == L"abc") return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent
+
+ if (foo(0) - 2 < foo(0) - 2) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both sides of operator are equivalent
+ if (foo(bar(0)) < (foo(bar((0))))) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both sides of operator are equivalent
+
+ if (P1.x < P2.x && P1.x < P2.x) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both sides of operator are equivalent
+ if (P2.a[P1.x + 2] < P2.x && P2.a[(P1.x) + (2)] < (P2.x)) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: both sides of operator are equivalent
+
+ return 0;
+}
+
+int Valid(int X, int Y) {
+ if (X != Y) return 1;
+ if (X == Y + 0) return 1;
+ if (P.x == P.y) return 1;
+ if (P.a[P.x] < P.a[P.y]) return 1;
+ if (P.a[0] < P.a[1]) return 1;
+
+ if (P.a[0] < P.a[0ULL]) return 1;
+ if (0 < 0ULL) return 1;
+ if ((int)0 < (int)0ULL) return 1;
+
+ if (++X != ++X) return 1;
+ if (P.a[X]++ != P.a[X]++) return 1;
+ if (P.a[X++] != P.a[X++]) return 1;
+
+ if ("abc" == "ABC") return 1;
+ if (foo(bar(0)) < (foo(bat(0, 1)))) return 1;
+ return 0;
+}
+
+#define COND_OP_MACRO 9
+#define COND_OP_OTHER_MACRO 9
+int TestConditional(int x, int y) {
+ int k = 0;
+ k += (y < 0) ? x : x;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 'true' and 'false' expressions are equivalent
+ k += (y < 0) ? x + 1 : x + 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'true' and 'false' expressions are equivalent
+ k += (y < 0) ? COND_OP_MACRO : COND_OP_MACRO;
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: 'true' and 'false' expressions are equivalent
+
+ // Do not match for conditional operators with a macro and a const.
+ k += (y < 0) ? COND_OP_MACRO : 9;
+ // Do not match for conditional operators with expressions from different macros.
+ k += (y < 0) ? COND_OP_MACRO : COND_OP_OTHER_MACRO;
+ return k;
+}
+#undef COND_OP_MACRO
+#undef COND_OP_OTHER_MACRO
+
+// Overloaded operators that compare two instances of a struct.
+struct MyStruct {
+ int x;
+ bool operator==(const MyStruct& rhs) const {return this->x == rhs.x; } // not modifing
+ bool operator>=(const MyStruct& rhs) const { return this->x >= rhs.x; } // not modifing
+ bool operator<=(MyStruct& rhs) const { return this->x <= rhs.x; }
+ bool operator&&(const MyStruct& rhs){ this->x++; return this->x && rhs.x; }
+} Q;
+
+bool operator!=(const MyStruct& lhs, const MyStruct& rhs) { return lhs.x == rhs.x; } // not modifing
+bool operator<(const MyStruct& lhs, const MyStruct& rhs) { return lhs.x < rhs.x; } // not modifing
+bool operator>(const MyStruct& lhs, MyStruct& rhs) { rhs.x--; return lhs.x > rhs.x; }
+bool operator||(MyStruct& lhs, const MyStruct& rhs) { lhs.x++; return lhs.x || rhs.x; }
+
+bool TestOverloadedOperator(MyStruct& S) {
+ if (S == Q) return false;
+
+ if (S <= S) return false;
+ if (S && S) return false;
+ if (S > S) return false;
+ if (S || S) return false;
+
+ if (S == S) return true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of overloaded operator are equivalent
+ if (S < S) return true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of overloaded operator are equivalent
+ if (S != S) return true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of overloaded operator are equivalent
+ if (S >= S) return true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of overloaded operator are equivalent
+
+ return true;
+}
+
+#define LT(x, y) (void)((x) < (y))
+#define COND(x, y, z) ((x)?(y):(z))
+#define EQUALS(x, y) (x) == (y)
+
+int TestMacro(int X, int Y) {
+ LT(0, 0);
+ LT(1, 0);
+ LT(X, X);
+ LT(X+1, X + 1);
+ COND(X < Y, X, X);
+ EQUALS(Q, Q);
+ return 0;
+}
+
+int TestFalsePositive(int* A, int X, float F) {
+ // Produced by bison.
+ X = A[(2) - (2)];
+ X = A['a' - 'a'];
+
+ // Testing NaN.
+ if (F != F && F == F) return 1;
+ return 0;
+}
+
+int TestBannedMacros() {
+#define EAGAIN 3
+#define NOT_EAGAIN 3
+ if (EAGAIN == 0 | EAGAIN == 0) return 0;
+ if (NOT_EAGAIN == 0 | NOT_EAGAIN == 0) return 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: both sides of operator are equivalent
+ return 0;
+}
+
+struct MyClass {
+static const int Value = 42;
+};
+template <typename T, typename U>
+void TemplateCheck() {
+ static_assert(T::Value == U::Value, "should be identical");
+ static_assert(T::Value == T::Value, "should be identical");
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: both sides of operator are equivalent
+}
+void TestTemplate() { TemplateCheck<MyClass, MyClass>(); }
+
+int TestArithmetic(int X, int Y) {
+ if (X + 1 == X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
+ if (X + 1 != X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+ if (X - 1 == X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
+ if (X - 1 != X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+
+ if (X + 1LL == X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
+ if (X + 1ULL == X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always false
+
+ if (X == X + 1) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always false
+ if (X != X + 1) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always true
+ if (X == X - 1) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always false
+ if (X != X - 1) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always true
+
+ if (X != X - 1U) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always true
+ if (X != X - 1LL) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always true
+
+ if ((X+X) != (X+X) - 1) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+
+ if (X + 1 == X + 2) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
+ if (X + 1 != X + 2) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+
+ if (X - 1 == X - 2) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
+ if (X - 1 != X - 2) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+
+ if (X + 1 == X - -1) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+ if (X + 1 != X - -1) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
+ if (X + 1 == X - -2) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
+ if (X + 1 != X - -2) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+
+ if (X + 1 == X - (~0)) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+ if (X + 1 == X - (~0U)) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+
+ if (X + 1 == X - (~0ULL)) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+
+ // Should not match.
+ if (X + 0.5 == X) return 1;
+ if (X + 1 == Y) return 1;
+ if (X + 1 == Y + 1) return 1;
+ if (X + 1 == Y + 2) return 1;
+
+ return 0;
+}
+
+int TestBitwise(int X, int Y) {
+
+ if ((X & 0xFF) == 0xF00) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
+ if ((X & 0xFF) != 0xF00) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true
+ if ((X | 0xFF) == 0xF00) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
+ if ((X | 0xFF) != 0xF00) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true
+
+ if ((X | 0xFFULL) != 0xF00) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: logical expression is always true
+ if ((X | 0xFF) != 0xF00ULL) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true
+
+ if ((0xFF & X) == 0xF00) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
+ if ((0xFF & X) != 0xF00) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true
+ if ((0xFF & X) == 0xF00) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
+ if ((0xFF & X) != 0xF00) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true
+
+ if ((0xFFLL & X) == 0xF00) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: logical expression is always false
+ if ((0xFF & X) == 0xF00ULL) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
+
+ return 0;
+}
+
+// Overloaded operators that compare an instance of a struct and an integer
+// constant.
+struct S {
+ S() { x = 1; }
+ int x;
+ // Overloaded comparison operators without any possible side effect.
+ bool operator==(const int &i) const { return x == i; } // not modifying
+ bool operator!=(int i) const { return x != i; } // not modifying
+ bool operator>(const int &i) const { return x > i; } // not modifying
+ bool operator<(int i) const { return x < i; } // not modifying
+};
+
+bool operator<=(const S &s, int i) { return s.x <= i; } // not modifying
+bool operator>=(const S &s, const int &i) { return s.x >= i; } // not modifying
+
+struct S2 {
+ S2() { x = 1; }
+ int x;
+ // Overloaded comparison operators that are able to modify their params.
+ bool operator==(const int &i) {
+ this->x++;
+ return x == i;
+ }
+ bool operator!=(int i) { return x != i; }
+ bool operator>(const int &i) { return x > i; }
+ bool operator<(int i) {
+ this->x--;
+ return x < i;
+ }
+};
+
+bool operator>=(S2 &s, const int &i) { return s.x >= i; }
+bool operator<=(S2 &s, int i) {
+ s.x++;
+ return s.x <= i;
+}
+
+int TestLogical(int X, int Y){
+#define CONFIG 0
+ if (CONFIG && X) return 1;
+#undef CONFIG
+#define CONFIG 1
+ if (CONFIG || X) return 1;
+#undef CONFIG
+
+ if (X == 10 && X != 10) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
+ if (X == 10 && (X != 10)) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
+ if (X == 10 && !(X == 10)) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
+ if (!(X != 10) && !(X == 10)) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
+
+ if (X == 10ULL && X != 10ULL) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
+ if (!(X != 10U) && !(X == 10)) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: logical expression is always false
+ if (!(X != 10LL) && !(X == 10)) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: logical expression is always false
+ if (!(X != 10ULL) && !(X == 10)) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: logical expression is always false
+
+ if (X == 0 && X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
+ if (X != 0 && !X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
+ if (X && !X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always false
+
+ if (X && !!X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: equivalent expression on both sides of logical operator
+ if (X != 0 && X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator
+ if (X != 0 && !!X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator
+ if (X == 0 && !X) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator
+
+ // Should not match.
+ if (X == 10 && Y == 10) return 1;
+ if (X != 10 && X != 12) return 1;
+ if (X == 10 || X == 12) return 1;
+ if (!X && !Y) return 1;
+ if (!X && Y) return 1;
+ if (!X && Y == 0) return 1;
+ if (X == 10 && Y != 10) return 1;
+
+ // Test for overloaded operators with constant params.
+ S s1;
+ if (s1 == 1 && s1 == 1) return true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: equivalent expression on both sides of logical operator
+ if (s1 == 1 || s1 != 1) return true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true
+ if (s1 > 1 && s1 < 1) return true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
+ if (s1 >= 1 || s1 <= 1) return true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true
+
+ // Test for overloaded operators that may modify their params.
+ S2 s2;
+ if (s2 == 1 || s2 != 1) return true;
+ if (s2 == 1 || s2 == 1) return true;
+ if (s2 > 1 && s2 < 1) return true;
+ if (s2 >= 1 || s2 <= 1) return true;
+}
+
+int TestRelational(int X, int Y) {
+ if (X == 10 && X > 10) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
+ if (X == 10 && X < 10) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
+ if (X < 10 && X > 10) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
+ if (X <= 10 && X > 10) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
+ if (X < 10 && X >= 10) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
+ if (X < 10 && X == 10) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
+
+ if (X > 5 && X <= 5) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
+ if (X > -5 && X <= -5) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
+
+ if (X < 10 || X >= 10) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always true
+ if (X <= 10 || X > 10) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true
+ if (X <= 10 || X >= 11) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true
+ if (X != 7 || X != 14) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always true
+ if (X == 7 || X != 5) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+ if (X != 7 || X == 7) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always true
+
+ if (X < 7 && X < 6) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+ if (X < 7 && X < 7) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
+ if (X < 7 && X < 8) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant
+
+ if (X < 7 && X <= 5) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+ if (X < 7 && X <= 6) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: equivalent expression on both sides of logical operator
+ if (X < 7 && X <= 7) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant
+ if (X < 7 && X <= 8) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant
+
+ if (X <= 7 && X < 6) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+ if (X <= 7 && X < 7) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+ if (X <= 7 && X < 8) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator
+
+ if (X >= 7 && X > 6) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator
+ if (X >= 7 && X > 7) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+ if (X >= 7 && X > 8) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+
+ if (X <= 7 && X <= 5) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+ if (X <= 7 && X <= 6) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+ if (X <= 7 && X <= 7) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent
+ if (X <= 7 && X <= 8) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: expression is redundant
+
+ if (X == 11 && X > 10) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: expression is redundant
+ if (X == 11 && X < 12) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: expression is redundant
+ if (X > 10 && X == 11) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+ if (X < 12 && X == 11) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+
+ if (X != 11 && X == 42) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+ if (X != 11 && X > 11) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+ if (X != 11 && X < 11) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+ if (X != 11 && X < 8) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+ if (X != 11 && X > 14) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+
+ if (X < 7 || X < 6) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant
+ if (X < 7 || X < 7) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
+ if (X < 7 || X < 8) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+
+ if (X > 7 || X > 6) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+ if (X > 7 || X > 7) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
+ if (X > 7 || X > 8) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant
+
+ // Should not match.
+ if (X < 10 || X > 12) return 1;
+ if (X > 10 && X < 12) return 1;
+ if (X < 10 || X >= 12) return 1;
+ if (X > 10 && X <= 12) return 1;
+ if (X <= 10 || X > 12) return 1;
+ if (X >= 10 && X < 12) return 1;
+ if (X <= 10 || X >= 12) return 1;
+ if (X >= 10 && X <= 12) return 1;
+ if (X >= 10 && X <= 11) return 1;
+ if (X >= 10 && X < 11) return 1;
+ if (X > 10 && X <= 11) return 1;
+ if (X > 10 && X != 11) return 1;
+ if (X >= 10 && X <= 10) return 1;
+ if (X <= 10 && X >= 10) return 1;
+ if (X < 0 || X > 0) return 1;
+}
+
+int TestRelationalMacros(int X){
+#define SOME_MACRO 3
+#define SOME_MACRO_SAME_VALUE 3
+#define SOME_OTHER_MACRO 9
+ // Do not match for redundant relational macro expressions that can be
+ // considered intentional, and for some particular values, non redundant.
+
+ // Test cases for expressions with the same macro on both sides.
+ if (X < SOME_MACRO && X > SOME_MACRO) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always false
+ if (X < SOME_MACRO && X == SOME_MACRO) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always false
+ if (X < SOME_MACRO || X >= SOME_MACRO) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always true
+ if (X <= SOME_MACRO || X > SOME_MACRO) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: logical expression is always true
+ if (X != SOME_MACRO && X > SOME_MACRO) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+ if (X != SOME_MACRO && X < SOME_MACRO) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+
+ // Test cases for two different macros.
+ if (X < SOME_MACRO && X > SOME_OTHER_MACRO) return 1;
+ if (X != SOME_MACRO && X >= SOME_OTHER_MACRO) return 1;
+ if (X != SOME_MACRO && X != SOME_OTHER_MACRO) return 1;
+ if (X == SOME_MACRO || X == SOME_MACRO_SAME_VALUE) return 1;
+ if (X == SOME_MACRO || X <= SOME_MACRO_SAME_VALUE) return 1;
+ if (X == SOME_MACRO || X > SOME_MACRO_SAME_VALUE) return 1;
+ if (X < SOME_MACRO && X <= SOME_OTHER_MACRO) return 1;
+ if (X == SOME_MACRO && X > SOME_OTHER_MACRO) return 1;
+ if (X == SOME_MACRO && X != SOME_OTHER_MACRO) return 1;
+ if (X == SOME_MACRO && X != SOME_MACRO_SAME_VALUE) return 1;
+ if (X == SOME_MACRO_SAME_VALUE && X == SOME_MACRO ) return 1;
+
+ // Test cases for a macro and a const.
+ if (X < SOME_MACRO && X > 9) return 1;
+ if (X != SOME_MACRO && X >= 9) return 1;
+ if (X != SOME_MACRO && X != 9) return 1;
+ if (X == SOME_MACRO || X == 3) return 1;
+ if (X == SOME_MACRO || X <= 3) return 1;
+ if (X < SOME_MACRO && X <= 9) return 1;
+ if (X == SOME_MACRO && X != 9) return 1;
+ if (X == SOME_MACRO && X == 9) return 1;
+
+#undef SOME_OTHER_MACRO
+#undef SOME_MACRO_SAME_VALUE
+#undef SOME_MACRO
+ return 0;
+}
+
+int TestValidExpression(int X) {
+ if (X - 1 == 1 - X) return 1;
+ if (2 * X == X) return 1;
+ if ((X << 1) == X) return 1;
+
+ return 0;
+}
+
+enum Color { Red, Yellow, Green };
+int TestRelationalWithEnum(enum Color C) {
+ if (C == Red && C == Yellow) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always false
+ if (C == Red && C != Red) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always false
+ if (C != Red || C != Yellow) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always true
+
+ // Should not match.
+ if (C == Red || C == Yellow) return 1;
+ if (C != Red && C != Yellow) return 1;
+
+ return 0;
+}
+
+template<class T>
+int TestRelationalTemplated(int X) {
+ // This test causes a corner case with |isIntegerConstantExpr| where the type
+ // is dependent. There is an assert failing when evaluating
+ // sizeof(<incomplet-type>).
+ if (sizeof(T) == 4 || sizeof(T) == 8) return 1;
+
+ if (X + 0 == -X) return 1;
+ if (X + 0 < X) return 1;
+
+ return 0;
+}
+
+int TestWithSignedUnsigned(int X) {
+ if (X + 1 == X + 1ULL) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+
+ if ((X & 0xFFU) == 0xF00) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: logical expression is always false
+
+ if ((X & 0xFF) == 0xF00U) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
+
+ if ((X & 0xFFU) == 0xF00U) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: logical expression is always false
+
+ return 0;
+}
+
+int TestWithLong(int X, I64 Y) {
+ if (X + 0ULL == -X) return 1;
+ if (Y + 0 == -Y) return 1;
+ if (Y <= 10 && X >= 10LL) return 1;
+ if (Y <= 10 && X >= 10ULL) return 1;
+ if (X <= 10 || X > 12LL) return 1;
+ if (X <= 10 || X > 12ULL) return 1;
+ if (Y <= 10 || Y > 12) return 1;
+
+ return 0;
+}
+
+int TestWithMinMaxInt(int X) {
+ if (X <= X + 0xFFFFFFFFU) return 1;
+ if (X <= X + 0x7FFFFFFF) return 1;
+ if (X <= X + 0x80000000) return 1;
+
+ if (X <= 0xFFFFFFFFU && X > 0) return 1;
+ if (X <= 0xFFFFFFFFU && X > 0U) return 1;
+
+ if (X + 0x80000000 == X - 0x80000000) return 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always true
+
+ if (X > 0x7FFFFFFF || X < ((-0x7FFFFFFF)-1)) return 1;
+ if (X <= 0x7FFFFFFF && X >= ((-0x7FFFFFFF)-1)) return 1;
+
+ return 0;
+}
+
+#define FLAG1 1
+#define FLAG2 2
+#define FLAG3 4
+#define FLAGS (FLAG1 | FLAG2 | FLAG3)
+#define NOTFLAGS !(FLAG1 | FLAG2 | FLAG3)
+int operatorConfusion(int X, int Y, long Z)
+{
+ // Ineffective & expressions.
+ Y = (Y << 8) & 0xff;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and operation
+ Y = (Y << 12) & 0xfff;
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and
+ Y = (Y << 12) & 0xff;
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and
+ Y = (Y << 8) & 0x77;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and
+ Y = (Y << 5) & 0x11;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and
+
+ // Tests for unmatched types
+ Z = (Z << 8) & 0xff;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and operation
+ Y = (Y << 12) & 0xfffL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and
+ Z = (Y << 12) & 0xffLL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and
+ Y = (Z << 8L) & 0x77L;
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and
+
+ Y = (Y << 8) & 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and
+
+ Y = (Y << 8) & -1;
+
+ // Effective expressions. Do not check.
+ Y = (Y << 4) & 0x15;
+ Y = (Y << 3) & 0x250;
+ Y = (Y << 9) & 0xF33;
+
+ int K = !(1 | 2 | 4);
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: ineffective logical negation operator used; did you mean '~'?
+ // CHECK-FIXES: {{^}} int K = ~(1 | 2 | 4);{{$}}
+ K = !(FLAG1 & FLAG2 & FLAG3);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: ineffective logical negation operator
+ // CHECK-FIXES: {{^}} K = ~(FLAG1 & FLAG2 & FLAG3);{{$}}
+ K = !(3 | 4);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: ineffective logical negation operator
+ // CHECK-FIXES: {{^}} K = ~(3 | 4);{{$}}
+ int NotFlags = !FLAGS;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: ineffective logical negation operator
+ // CHECK-FIXES: {{^}} int NotFlags = ~FLAGS;{{$}}
+ NotFlags = NOTFLAGS;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: ineffective logical negation operator
+ return !(1 | 2 | 4);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: ineffective logical negation operator
+ // CHECK-FIXES: {{^}} return ~(1 | 2 | 4);{{$}}
+}
+#undef FLAG1
+#undef FLAG2
+#undef FLAG3
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-static-assert.c b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-static-assert.c
new file mode 100644
index 0000000..e3e8304
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-static-assert.c
@@ -0,0 +1,27 @@
+// RUN: %check_clang_tidy %s misc-static-assert %t -- -- -std=c11
+// RUN: clang-tidy %s -checks=-*,misc-static-assert -- -std=c99 | count 0
+
+void abort() {}
+#ifdef NDEBUG
+#define assert(x) 1
+#else
+#define assert(x) \
+ if (!(x)) \
+ abort()
+#endif
+
+void f(void) {
+ int x = 1;
+ assert(x == 0);
+ // CHECK-FIXES: {{^ }}assert(x == 0);
+
+ #define static_assert(x, msg) _Static_assert(x, msg)
+ assert(11 == 5 + 6);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() that could be
+ // CHECK-FIXES: {{^ }}static_assert(11 == 5 + 6, "");
+ #undef static_assert
+
+ assert(10 == 5 + 5);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() that could be
+ // CHECK-FIXES: {{^ }}static_assert(10 == 5 + 5, "");
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-static-assert.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-static-assert.cpp
new file mode 100644
index 0000000..85ae053
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-static-assert.cpp
@@ -0,0 +1,143 @@
+// RUN: %check_clang_tidy %s misc-static-assert %t
+
+void abort() {}
+#ifdef NDEBUG
+#define assert(x) 1
+#else
+#define assert(x) \
+ if (!(x)) \
+ abort()
+#endif
+
+void print(...);
+
+#define ZERO_MACRO 0
+
+#define False false
+#define FALSE 0
+
+#define my_macro() assert(0 == 1)
+// CHECK-FIXES: #define my_macro() assert(0 == 1)
+
+constexpr bool myfunc(int a, int b) { return a * b == 0; }
+
+typedef __SIZE_TYPE__ size_t;
+extern "C" size_t strlen(const char *s);
+
+class A {
+public:
+ bool method() { return true; }
+};
+
+class B {
+public:
+ constexpr bool method() { return true; }
+};
+
+template <class T> void doSomething(T t) {
+ assert(myfunc(1, 2));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() that could be replaced by static_assert() [misc-static-assert]
+ // CHECK-FIXES: {{^ }}static_assert(myfunc(1, 2), "");
+
+ assert(t.method());
+ // CHECK-FIXES: {{^ }}assert(t.method());
+
+ assert(sizeof(T) == 123);
+}
+
+int main() {
+ my_macro();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() that could be
+ // CHECK-FIXES: {{^ }}my_macro();
+
+ assert(myfunc(1, 2) && (3 == 4));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() that could be
+ // CHECK-FIXES: {{^ }}static_assert(myfunc(1, 2) && (3 == 4), "");
+
+ int x = 1;
+ assert(x == 0);
+ // CHECK-FIXES: {{^ }}assert(x == 0);
+
+ A a;
+ B b;
+
+ doSomething<A>(a);
+ doSomething<B>(b);
+
+ assert(false);
+ // CHECK-FIXES: {{^ }}assert(false);
+
+ assert(False);
+ // CHECK-FIXES: {{^ }}assert(False);
+ assert(FALSE);
+ // CHECK-FIXES: {{^ }}assert(FALSE);
+
+ assert(ZERO_MACRO);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() that could be
+ // CHECK-FIXES: {{^ }}static_assert(ZERO_MACRO, "");
+
+ assert(!"Don't report me!");
+ // CHECK-FIXES: {{^ }}assert(!"Don't report me!");
+
+ assert(0 && "Don't report me!");
+ // CHECK-FIXES: {{^ }}assert(0 && "Don't report me!");
+
+ assert(false && "Don't report me!");
+ // CHECK-FIXES: {{^ }}assert(false && "Don't report me!");
+
+#define NULL ((void*)0)
+ assert(NULL && "Don't report me!");
+ // CHECK-FIXES: {{^ }}assert(NULL && "Don't report me!");
+
+ assert(NULL == "Don't report me!");
+ // CHECK-FIXES: {{^ }}assert(NULL == "Don't report me!");
+
+ assert("Don't report me!" == NULL);
+ // CHECK-FIXES: {{^ }}assert("Don't report me!" == NULL);
+
+ assert(0 == "Don't report me!");
+ // CHECK-FIXES: {{^ }}assert(0 == "Don't report me!");
+
+#define NULL ((unsigned int)0)
+ assert(NULL && "Report me!");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() that could be
+ // CHECK-FIXES: {{^ }}static_assert(NULL , "Report me!");
+
+#define NULL __null
+ assert(__null == "Don't report me!");
+ // CHECK-FIXES: {{^ }}assert(__null == "Don't report me!");
+ assert(NULL == "Don't report me!");
+ // CHECK-FIXES: {{^ }}assert(NULL == "Don't report me!");
+#undef NULL
+
+ assert(ZERO_MACRO && "Report me!");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() that could be
+ // CHECK-FIXES: {{^ }}static_assert(ZERO_MACRO , "Report me!");
+
+ assert(0);
+
+#define false false
+ assert(false);
+
+#define false 0
+ assert(false);
+#undef false
+
+ assert(10==5 && "Report me!");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() that could be
+ // CHECK-FIXES: {{^ }}static_assert(10==5 , "Report me!");
+
+ assert(strlen("12345") == 5);
+ // CHECK-FIXES: {{^ }}assert(strlen("12345") == 5);
+
+#define assert(e) (__builtin_expect(!(e), 0) ? print (#e, __FILE__, __LINE__) : (void)0)
+ assert(false);
+ // CHECK-FIXES: {{^ }}assert(false);
+
+ assert(10 == 5 + 5);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() that could be
+ // CHECK-FIXES: {{^ }}static_assert(10 == 5 + 5, "");
+#undef assert
+
+ return 0;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-throw-by-value-catch-by-reference.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-throw-by-value-catch-by-reference.cpp
new file mode 100644
index 0000000..120b07e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-throw-by-value-catch-by-reference.cpp
@@ -0,0 +1,156 @@
+// RUN: %check_clang_tidy %s misc-throw-by-value-catch-by-reference %t -- -- -std=c++11 -fcxx-exceptions
+
+
+class logic_error {
+public:
+ logic_error(const char *message) {}
+};
+
+typedef logic_error *logic_ptr;
+typedef logic_ptr logic_double_typedef;
+
+int lastException;
+
+template <class T> struct remove_reference { typedef T type; };
+template <class T> struct remove_reference<T &> { typedef T type; };
+template <class T> struct remove_reference<T &&> { typedef T type; };
+
+template <typename T> typename remove_reference<T>::type &&move(T &&arg) {
+ return static_cast<typename remove_reference<T>::type &&>(arg);
+}
+
+logic_error CreateException() { return logic_error("created"); }
+
+void testThrowFunc() {
+ throw new logic_error("by pointer");
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: throw expression throws a pointer; it should throw a non-pointer value instead [misc-throw-by-value-catch-by-reference]
+ logic_ptr tmp = new logic_error("by pointer");
+ throw tmp;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: throw expression should throw anonymous temporary values instead [misc-throw-by-value-catch-by-reference]
+ // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: throw expression throws a pointer; it should throw a non-pointer value instead [misc-throw-by-value-catch-by-reference]
+ throw logic_error("by value");
+ auto *literal = "test";
+ throw logic_error(literal);
+ throw "test string literal";
+ throw L"throw wide string literal";
+ const char *characters = 0;
+ throw characters;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: throw expression should throw anonymous temporary values instead [misc-throw-by-value-catch-by-reference]
+ // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: throw expression throws a pointer; it should throw a non-pointer value instead [misc-throw-by-value-catch-by-reference]
+ logic_error lvalue("lvalue");
+ throw lvalue;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: throw expression should throw anonymous temporary values instead [misc-throw-by-value-catch-by-reference]
+
+ throw move(lvalue);
+ int &ex = lastException;
+ throw ex;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: throw expression should throw anonymous temporary values instead [misc-throw-by-value-catch-by-reference]
+ throw CreateException();
+}
+
+void throwReferenceFunc(logic_error &ref) { throw ref; }
+
+void catchByPointer() {
+ try {
+ testThrowFunc();
+ } catch (logic_error *e) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: catch handler catches a pointer value; should throw a non-pointer value and catch by reference instead [misc-throw-by-value-catch-by-reference]
+ }
+}
+
+void catchByValue() {
+ try {
+ testThrowFunc();
+ } catch (logic_error e) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: catch handler catches by value; should catch by reference instead [misc-throw-by-value-catch-by-reference]
+ }
+}
+
+void catchByReference() {
+ try {
+ testThrowFunc();
+ } catch (logic_error &e) {
+ }
+}
+
+void catchByConstReference() {
+ try {
+ testThrowFunc();
+ } catch (const logic_error &e) {
+ }
+}
+
+void catchTypedef() {
+ try {
+ testThrowFunc();
+ } catch (logic_ptr) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: catch handler catches a pointer value; should throw a non-pointer value and catch by reference instead [misc-throw-by-value-catch-by-reference]
+ }
+}
+
+void catchAll() {
+ try {
+ testThrowFunc();
+ } catch (...) {
+ }
+}
+
+void catchLiteral() {
+ try {
+ testThrowFunc();
+ } catch (const char *) {
+ } catch (const wchar_t *) {
+ // disabled for now until it is clear
+ // how to enable them in the test
+ //} catch (const char16_t*) {
+ //} catch (const char32_t*) {
+ }
+}
+
+// catching fundamentals should not warn
+void catchFundamental() {
+ try {
+ testThrowFunc();
+ } catch (int) {
+ } catch (double) {
+ } catch (unsigned long) {
+ }
+}
+
+struct TrivialType {
+ double x;
+ double y;
+};
+
+void catchTrivial() {
+ try {
+ testThrowFunc();
+ } catch (TrivialType) {
+ }
+}
+
+typedef logic_error &fine;
+void additionalTests() {
+ try {
+ } catch (int i) { // ok
+ throw i; // ok
+ } catch (fine e) { // ok
+ throw e; // ok
+ } catch (logic_error *e) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: catch handler catches a pointer value; should throw a non-pointer value and catch by reference instead [misc-throw-by-value-catch-by-reference]
+ throw e; // ok, despite throwing a pointer
+ } catch (...) { // ok
+ throw; // ok
+ }
+}
+
+struct S {};
+
+S &returnByReference();
+S returnByValue();
+
+void f() {
+ throw returnByReference(); // Should diagnose
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: throw expression should throw anonymous temporary values instead [misc-throw-by-value-catch-by-reference]
+ throw returnByValue(); // Should not diagnose
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unconventional-assign-operator-cxx17.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unconventional-assign-operator-cxx17.cpp
new file mode 100644
index 0000000..ba1a685
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unconventional-assign-operator-cxx17.cpp
@@ -0,0 +1,12 @@
+// RUN: %check_clang_tidy %s misc-unconventional-assign-operator %t -- -- -std=c++17 -fno-delayed-template-parsing
+
+struct BadModifier {
+ BadModifier& operator=(const BadModifier&) const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should not be marked 'const'
+};
+
+struct PR35468 {
+ template<typename T> auto &operator=(const T &) {
+ return *this;
+ }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unconventional-assign-operator.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unconventional-assign-operator.cpp
new file mode 100644
index 0000000..4bd9cb2
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unconventional-assign-operator.cpp
@@ -0,0 +1,111 @@
+// RUN: %check_clang_tidy %s misc-unconventional-assign-operator %t -- -- -std=c++11 -isystem %S/Inputs/Headers -fno-delayed-template-parsing
+
+namespace std {
+template <typename T>
+struct remove_reference { typedef T type; };
+template <typename T>
+struct remove_reference<T &> { typedef T type; };
+template <typename T>
+struct remove_reference<T &&> { typedef T type; };
+template <typename T>
+typename remove_reference<T>::type &&move(T &&t);
+}
+
+
+struct Good {
+ Good& operator=(const Good&);
+ Good& operator=(Good&&);
+
+ // Assign from other types is fine too.
+ Good& operator=(int);
+};
+
+struct AlsoGood {
+ // By value is also fine.
+ AlsoGood& operator=(AlsoGood);
+};
+
+struct BadReturnType {
+ void operator=(const BadReturnType&);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'BadReturnType&' [misc-unconventional-assign-operator]
+ const BadReturnType& operator=(BadReturnType&&);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
+ void operator=(int);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
+};
+
+struct BadReturnType2 {
+ BadReturnType2&& operator=(const BadReturnType2&);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
+ int operator=(BadReturnType2&&);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
+};
+
+struct BadArgument {
+ BadArgument& operator=(BadArgument&);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should take 'BadArgument const&', 'BadArgument&&' or 'BadArgument'
+ BadArgument& operator=(const BadArgument&&);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should take 'BadAr
+};
+
+struct BadModifier {
+ BadModifier& operator=(const BadModifier&) const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should not be marked 'const'
+};
+
+struct Deleted {
+ // We don't check the return value of deleted operators.
+ void operator=(const Deleted&) = delete;
+ void operator=(Deleted&&) = delete;
+};
+
+class Private {
+ // We don't check the return value of private operators.
+ // Pre-C++11 way of disabling assignment.
+ void operator=(const Private &);
+};
+
+struct Virtual {
+ virtual Virtual& operator=(const Virtual &);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should not be marked 'virtual'
+};
+
+class BadReturnStatement {
+ int n;
+
+public:
+ BadReturnStatement& operator=(BadReturnStatement&& rhs) {
+ n = std::move(rhs.n);
+ return rhs;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: operator=() should always return '*this'
+ }
+
+ // Do not check if return type is different from '&BadReturnStatement'
+ int operator=(int i) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
+ n = i;
+ return n;
+ }
+};
+
+namespace pr31531 {
+enum E { e };
+// This declaration makes the 'return *this' below have an unresolved operator
+// in the class template, but not in an instantiation.
+E operator*(E, E);
+
+template <typename>
+struct UnresolvedOperator {
+ UnresolvedOperator &operator=(const UnresolvedOperator &) { return *this; }
+};
+
+UnresolvedOperator<int> UnresolvedOperatorInt;
+
+template <typename>
+struct Template {
+ Template &operator=(const Template &) { return this; }
+ // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: operator=() should always return '*this'
+};
+
+Template<int> TemplateInt;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-uniqueptr-reset-release.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-uniqueptr-reset-release.cpp
new file mode 100644
index 0000000..1bd6e6f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-uniqueptr-reset-release.cpp
@@ -0,0 +1,69 @@
+// RUN: %check_clang_tidy %s misc-uniqueptr-reset-release %t
+
+namespace std {
+
+template <typename T>
+struct default_delete {};
+
+template <typename T, class Deleter = std::default_delete<T>>
+struct unique_ptr {
+ unique_ptr();
+ explicit unique_ptr(T *);
+ template <typename U, typename E>
+ unique_ptr(unique_ptr<U, E> &&);
+ void reset(T *);
+ T *release();
+};
+} // namespace std
+
+struct Foo {};
+struct Bar : Foo {};
+
+std::unique_ptr<Foo> Create();
+std::unique_ptr<Foo> &Look();
+std::unique_ptr<Foo> *Get();
+
+using FooFunc = void (*)(Foo *);
+using BarFunc = void (*)(Bar *);
+
+void f() {
+ std::unique_ptr<Foo> a, b;
+ std::unique_ptr<Bar> c;
+ std::unique_ptr<Foo> *x = &a;
+ std::unique_ptr<Foo> *y = &b;
+
+ a.reset(b.release());
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer ptr1 = std::move(ptr2) over ptr1.reset(ptr2.release()) [misc-uniqueptr-reset-release]
+ // CHECK-FIXES: a = std::move(b);
+ a.reset(c.release());
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer ptr1 = std::move(ptr2)
+ // CHECK-FIXES: a = std::move(c);
+ a.reset(Create().release());
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer ptr = ReturnUnique() over ptr.reset(ReturnUnique().release()) [misc-uniqueptr-reset-release]
+ // CHECK-FIXES: a = Create();
+ x->reset(y->release());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: prefer ptr1 = std::move(ptr2)
+ // CHECK-FIXES: *x = std::move(*y);
+ Look().reset(Look().release());
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer ptr1 = std::move(ptr2)
+ // CHECK-FIXES: Look() = std::move(Look());
+ Get()->reset(Get()->release());
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer ptr1 = std::move(ptr2)
+ // CHECK-FIXES: *Get() = std::move(*Get());
+
+ std::unique_ptr<Bar, FooFunc> func_a, func_b;
+ func_a.reset(func_b.release());
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer ptr1 = std::move(ptr2)
+ // CHECK-FIXES: func_a = std::move(func_b);
+}
+
+void negatives() {
+ std::unique_ptr<Foo> src;
+ struct OtherDeleter {};
+ std::unique_ptr<Foo, OtherDeleter> dest;
+ dest.reset(src.release());
+
+ std::unique_ptr<Bar, FooFunc> func_a;
+ std::unique_ptr<Bar, BarFunc> func_b;
+ func_a.reset(func_b.release());
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unused-alias-decls.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unused-alias-decls.cpp
new file mode 100644
index 0000000..6d63df4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unused-alias-decls.cpp
@@ -0,0 +1,12 @@
+// RUN: %check_clang_tidy %s misc-unused-alias-decls %t
+
+namespace my_namespace {
+class C {};
+}
+
+namespace unused_alias = ::my_namespace; // eol-comments aren't removed (yet)
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: namespace alias decl 'unused_alias' is unused
+// CHECK-FIXES: {{^}}// eol-comments aren't removed (yet)
+
+namespace used_alias = ::my_namespace;
+void f() { used_alias::C c; }
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unused-parameters-strict.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unused-parameters-strict.cpp
new file mode 100644
index 0000000..a334b45
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unused-parameters-strict.cpp
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s misc-unused-parameters %t -- \
+// RUN: -config="{CheckOptions: [{key: StrictMode, value: 1}]}" --
+
+// Warn on empty function bodies in StrictMode.
+namespace strict_mode {
+void f(int foo) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'foo' is unused [misc-unused-parameters]
+// CHECK-FIXES: {{^}}void f(int /*foo*/) {}{{$}}
+class E {
+ int i;
+
+public:
+ E(int j) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'j' is unused
+// CHECK-FIXES: {{^}} E(int /*j*/) {}{{$}}
+};
+class F {
+ int i;
+
+public:
+ F(int j) : i() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'j' is unused
+// CHECK-FIXES: {{^}} F(int /*j*/) : i() {}{{$}}
+};
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unused-parameters.c b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unused-parameters.c
new file mode 100644
index 0000000..d824a80
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unused-parameters.c
@@ -0,0 +1,17 @@
+// RUN: %check_clang_tidy %s misc-unused-parameters %t -- -- -xc
+
+// Basic removal
+// =============
+void a(int i) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'i' is unused [misc-unused-parameters]
+// CHECK-FIXES: {{^}}void a(int /*i*/) {;}{{$}}
+
+static void b(); // In C, forward declarations can leave out parameters.
+static void b(int i) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: parameter 'i' is unused [misc-unused-parameters]
+// CHECK-FIXES: {{^}}static void b() {;}{{$}}
+
+// Unchanged cases
+// ===============
+void h(i, c, d) int i; char *c, *d; {} // Don't mess with K&R style
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unused-parameters.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unused-parameters.cpp
new file mode 100644
index 0000000..ec1ee2d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unused-parameters.cpp
@@ -0,0 +1,277 @@
+// RUN: echo "static void staticFunctionHeader(int i) {;}" > %T/header.h
+// RUN: echo "static void staticFunctionHeader(int /*i*/) {;}" > %T/header-fixed.h
+// RUN: %check_clang_tidy %s misc-unused-parameters %t -- -header-filter='.*' -- -std=c++11 -fno-delayed-template-parsing
+// RUN: diff %T/header.h %T/header-fixed.h
+
+#include "header.h"
+// CHECK-MESSAGES: header.h:1:38: warning
+
+// Basic removal
+// =============
+void a(int i) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'i' is unused [misc-unused-parameters]
+// CHECK-FIXES: {{^}}void a(int /*i*/) {;}{{$}}
+
+void b(int i = 1) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'i' is unused [misc-unused-parameters]
+// CHECK-FIXES: {{^}}void b(int /*i*/ = 1) {;}{{$}}
+
+void c(int *i) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: parameter 'i' is unused [misc-unused-parameters]
+// CHECK-FIXES: {{^}}void c(int * /*i*/) {;}{{$}}
+
+void d(int i[]) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'i' is unused [misc-unused-parameters]
+// CHECK-FIXES: {{^}}void d(int /*i*/[]) {;}{{$}}
+
+void e(int i[1]) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'i' is unused [misc-unused-parameters]
+// CHECK-FIXES: {{^}}void e(int /*i*/[1]) {;}{{$}}
+
+void f(void (*fn)()) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: parameter 'fn' is unused [misc-unused-parameters]
+// CHECK-FIXES: {{^}}void f(void (* /*fn*/)()) {;}{{$}}
+
+// Unchanged cases
+// ===============
+void f(int i); // Don't remove stuff in declarations
+void g(int i = 1);
+void h(int i[]);
+void s(int i[1]);
+void u(void (*fn)());
+void w(int i) { (void)i; } // Don't remove used parameters
+
+bool useLambda(int (*fn)(int));
+static bool static_var = useLambda([] (int a) { return a; });
+
+// Remove parameters of local functions
+// ====================================
+static void staticFunctionA(int i);
+// CHECK-FIXES: {{^}}static void staticFunctionA();
+static void staticFunctionA(int i) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning
+// CHECK-FIXES: {{^}}static void staticFunctionA()
+
+static void staticFunctionB(int i, int j) { (void)i; }
+// CHECK-MESSAGES: :[[@LINE-1]]:40: warning
+// CHECK-FIXES: {{^}}static void staticFunctionB(int i)
+
+static void staticFunctionC(int i, int j) { (void)j; }
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning
+// CHECK-FIXES: {{^}}static void staticFunctionC(int j)
+
+static void staticFunctionD(int i, int j, int k) { (void)i; (void)k; }
+// CHECK-MESSAGES: :[[@LINE-1]]:40: warning
+// CHECK-FIXES: {{^}}static void staticFunctionD(int i, int k)
+
+static void staticFunctionE(int i = 4) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning
+// CHECK-FIXES: {{^}}static void staticFunctionE()
+
+static void staticFunctionF(int i = 4);
+// CHECK-FIXES: {{^}}static void staticFunctionF();
+static void staticFunctionF(int i) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning
+// CHECK-FIXES: {{^}}static void staticFunctionF()
+
+static void staticFunctionG(int i[]);
+// CHECK-FIXES: {{^}}static void staticFunctionG();
+static void staticFunctionG(int i[]) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning
+// CHECK-FIXES: {{^}}static void staticFunctionG()
+
+static void staticFunctionH(void (*fn)());
+// CHECK-FIXES: {{^}}static void staticFunctionH();
+static void staticFunctionH(void (*fn)()) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:36: warning
+// CHECK-FIXES: {{^}}static void staticFunctionH()
+
+static void someCallSites() {
+ staticFunctionA(1);
+// CHECK-FIXES: staticFunctionA();
+ staticFunctionB(1, 2);
+// CHECK-FIXES: staticFunctionB(1);
+ staticFunctionC(1, 2);
+// CHECK-FIXES: staticFunctionC(2);
+ staticFunctionD(1, 2, 3);
+// CHECK-FIXES: staticFunctionD(1, 3);
+ staticFunctionE(1);
+// CHECK-FIXES: staticFunctionE();
+ staticFunctionF(1);
+// CHECK-FIXES: staticFunctionF();
+ staticFunctionF();
+// CHECK-FIXES: staticFunctionF();
+ int t[] = {1};
+ staticFunctionG(t);
+// CHECK-FIXES: staticFunctionG();
+ void func();
+ staticFunctionH(&func);
+// CHECK-FIXES: staticFunctionH();
+}
+
+/*
+ * FIXME: This fails because the removals overlap and ClangTidy doesn't apply
+ * them.
+ * static void bothVarsUnused(int a, int b) {;}
+ */
+
+// Regression test for long variable names and expressions
+// =======================================================
+static int variableWithLongName1(int LongName1, int LongName2) {
+// CHECK-MESSAGES: :[[@LINE-1]]:53: warning: parameter 'LongName2' is unused
+// CHECK-FIXES: {{^}}static int variableWithLongName1(int LongName1) {
+ return LongName1;
+}
+static int variableWithLongName2(int LongName1, int LongName2) {
+// CHECK-MESSAGES: :[[@LINE-1]]:38: warning: parameter 'LongName1' is unused
+// CHECK-FIXES: {{^}}static int variableWithLongName2(int LongName2) {
+ return LongName2;
+}
+static void someLongNameCallSites() {
+ int LongName1 = 7, LongName2 = 17;
+ variableWithLongName1(LongName1, LongName2);
+// CHECK-FIXES: variableWithLongName1(LongName1);
+ variableWithLongName2(LongName1, LongName2);
+// CHECK-FIXES: variableWithLongName2(LongName2);
+}
+
+class SomeClass {
+ static void f(int i) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning
+// CHECK-FIXES: static void f(int /*i*/) {;}
+ static void g(int i = 1) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning
+// CHECK-FIXES: static void g(int /*i*/ = 1) {;}
+ static void h(int i[]) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning
+// CHECK-FIXES: static void h(int /*i*/[]) {;}
+ static void s(void (*fn)()) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning
+// CHECK-FIXES: static void s(void (* /*fn*/)()) {;}
+};
+
+namespace {
+class C {
+public:
+ void f(int i);
+// CHECK-FIXES: void f();
+ void g(int i) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning
+// CHECK-FIXES: void g() {;}
+ void h(int i) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning
+// CHECK-FIXES: void h(int /*i*/) {;}
+ void s(int i = 1) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning
+// CHECK-FIXES: void s(int /*i*/ = 1) {;}
+ void u(int i[]) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning
+// CHECK-FIXES: void u(int /*i*/[]) {;}
+ void w(void (*fn)()) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning
+// CHECK-FIXES: void w(void (* /*fn*/)()) {;}
+};
+
+void C::f(int i) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning
+// CHECK-FIXES: void C::f() {;}
+
+template <typename T>
+void useFunction(T t);
+
+void someMoreCallSites() {
+ C c;
+ c.f(1);
+// CHECK-FIXES: c.f();
+ c.g(1);
+// CHECK-FIXES: c.g();
+
+ useFunction(&C::h);
+ useFunction(&C::s);
+ useFunction(&C::u);
+ useFunction(&C::w);
+}
+
+class Base {
+ virtual void f(int i);
+};
+
+class Derived : public Base {
+ void f(int i) override {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning
+// CHECK-FIXES: void f(int /*i*/) override {;}
+};
+
+} // end namespace
+
+template <typename T> void someFunctionTemplate(T b, T e) { (void)b; (void)e; }
+
+template <typename T> void someFunctionTemplateOneUnusedParam(T b, T e) { (void)e; }
+// CHECK-MESSAGES: :[[@LINE-1]]:65: warning
+// CHECK-FIXES: {{^}}template <typename T> void someFunctionTemplateOneUnusedParam(T /*b*/, T e) { (void)e; }
+
+template <typename T> void someFunctionTemplateAllUnusedParams(T b, T e) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:66: warning
+// CHECK-MESSAGES: :[[@LINE-2]]:71: warning
+// CHECK-FIXES: {{^}}template <typename T> void someFunctionTemplateAllUnusedParams(T /*b*/, T /*e*/) {;}
+
+static void dontGetConfusedByParametersInFunctionTypes() { void (*F)(int i); }
+
+template <typename T> class Function {};
+static Function<void(int, int i)> dontGetConfusedByFunctionReturnTypes() {
+ return Function<void(int, int)>();
+}
+
+namespace PR38055 {
+namespace {
+struct a {
+ void b(int c) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: parameter 'c' is unused
+// CHECK-FIXES: {{^}} void b() {;}{{$}}
+};
+template <class>
+class d {
+ a e;
+ void f() { e.b(); }
+};
+} // namespace
+} // namespace PR38055
+
+namespace strict_mode_off {
+// Do not warn on empty function bodies.
+void f1(int foo1) {}
+void f2(int foo2) {
+ // "empty" in the AST sense, not in textual sense.
+}
+void f3(int foo3) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: parameter 'foo3' is unused
+// CHECK-FIXES: {{^}}void f3(int /*foo3*/) {;}{{$}}
+
+class E {
+ int i;
+
+public:
+ E(int j) {}
+};
+class F {
+ int i;
+
+public:
+ // Constructor initializer counts as a non-empty body.
+ F(int j) : i() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'j' is unused
+// CHECK-FIXES: {{^}} F(int /*j*/) : i() {}{{$}}
+};
+
+class A {
+public:
+ A();
+ A(int);
+};
+class B : public A {
+public:
+ B(int i) : A() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is unused
+// CHECK-FIXES: {{^}} B(int /*i*/) : A() {}{{$}}
+};
+} // namespace strict_mode_off
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unused-using-decls-errors.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unused-using-decls-errors.cpp
new file mode 100644
index 0000000..1c26a69
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unused-using-decls-errors.cpp
@@ -0,0 +1,12 @@
+// RUN: %check_clang_tidy -expect-clang-tidy-error %s misc-unused-using-decls %t
+
+namespace n {
+class C;
+}
+
+using n::C;
+
+void f() {
+ for (C *p : unknown()) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: error: use of undeclared identifier 'unknown' [clang-diagnostic-error]
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unused-using-decls.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unused-using-decls.cpp
new file mode 100644
index 0000000..65ef0da
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-unused-using-decls.cpp
@@ -0,0 +1,203 @@
+// RUN: %check_clang_tidy %s misc-unused-using-decls %t -- -- -fno-delayed-template-parsing -isystem %S/Inputs/
+
+
+// ----- Definitions -----
+template <typename T> class vector {};
+namespace n {
+class A;
+class B;
+class C;
+class D;
+class D { public: static int i; };
+template <typename T> class E {};
+template <typename T> class F {};
+class G { public: static void func() {} };
+class H { public: static int i; };
+class I {
+ public:
+ static int ii;
+};
+template <typename T> class J {};
+class G;
+class H;
+
+template <typename T> class K {};
+template <template <typename> class S>
+class L {};
+
+template <typename T> class M {};
+class N {};
+
+template <int T> class P {};
+const int Constant = 0;
+
+class Base {
+ public:
+ void f();
+};
+
+D UsedInstance;
+D UnusedInstance;
+
+int UsedFunc() { return 1; }
+int UnusedFunc() { return 1; }
+template <typename T> int UsedTemplateFunc() { return 1; }
+template <typename T> int UnusedTemplateFunc() { return 1; }
+template <typename T> int UsedInTemplateFunc() { return 1; }
+void OverloadFunc(int);
+void OverloadFunc(double);
+int FuncUsedByUsingDeclInMacro() { return 1; }
+
+class ostream {
+public:
+ ostream &operator<<(ostream &(*PF)(ostream &));
+};
+extern ostream cout;
+ostream &endl(ostream &os);
+
+enum Color1 { Green };
+
+enum Color2 { Red };
+
+enum Color3 { Yellow };
+
+enum Color4 { Blue };
+
+} // namespace n
+
+#include "unused-using-decls.h"
+namespace ns {
+template <typename T>
+class AA {
+ T t;
+};
+template <typename T>
+T ff() { T t; return t; }
+} // namespace ns
+
+// ----- Using declarations -----
+// eol-comments aren't removed (yet)
+using n::A; // A
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'A' is unused
+// CHECK-FIXES: {{^}}// A
+using n::B;
+using n::C;
+using n::D;
+using n::E; // E
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'E' is unused
+// CHECK-FIXES: {{^}}// E
+using n::F;
+using n::G;
+using n::H;
+using n::I;
+int I::ii = 1;
+class Derived : public n::Base {
+ public:
+ using Base::f;
+};
+using n::UsedInstance;
+using n::UsedFunc;
+using n::UsedTemplateFunc;
+using n::UnusedInstance; // UnusedInstance
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'UnusedInstance' is unused
+// CHECK-FIXES: {{^}}// UnusedInstance
+using n::UnusedFunc; // UnusedFunc
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'UnusedFunc' is unused
+// CHECK-FIXES: {{^}}// UnusedFunc
+using n::cout;
+using n::endl;
+
+using n::UsedInTemplateFunc;
+using n::J;
+template <typename T> void Callee() {
+ J<T> j;
+ UsedInTemplateFunc<T>();
+}
+
+using n::OverloadFunc; // OverloadFunc
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'OverloadFunc' is unused
+// CHECK-FIXES: {{^}}// OverloadFunc
+
+#define DEFINE_INT(name) \
+ namespace INT { \
+ static const int _##name = 1; \
+ } \
+ using INT::_##name
+DEFINE_INT(test);
+#undef DEFIND_INT
+
+#define USING_FUNC \
+ using n::FuncUsedByUsingDeclInMacro;
+USING_FUNC
+#undef USING_FUNC
+
+namespace N1 {
+// n::G is used in namespace N2.
+// Currently, the check doesn't support multiple scopes. All the relevant
+// using-decls will be marked as used once we see an usage even the usage is in
+// other scope.
+using n::G;
+}
+
+namespace N2 {
+using n::G;
+void f(G g);
+}
+
+void IgnoreFunctionScope() {
+// Using-decls defined in function scope will be ignored.
+using n::H;
+}
+
+using n::Color1;
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'Color1' is unused
+using n::Green;
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'Green' is unused
+using n::Color2;
+using n::Color3;
+using n::Blue;
+
+using ns::AA;
+using ns::ff;
+
+using n::K;
+
+using n::N;
+
+// FIXME: Currently non-type template arguments are not supported.
+using n::Constant;
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'Constant' is unused
+
+// ----- Usages -----
+void f(B b);
+void g() {
+ vector<C> data;
+ D::i = 1;
+ F<int> f;
+ void (*func)() = &G::func;
+ int *i = &H::i;
+ UsedInstance.i;
+ UsedFunc();
+ UsedTemplateFunc<int>();
+ cout << endl;
+ Color2 color2;
+ int t1 = Color3::Yellow;
+ int t2 = Blue;
+
+ MyClass a;
+ int t3 = 0;
+ a.func1<AA>(&t3);
+ a.func2<int, ff>(t3);
+
+ n::L<K> l;
+}
+
+template<class T>
+void h(n::M<T>* t) {}
+// n::N is used the explicit template instantiation.
+template void h(n::M<N>* t);
+
+// Test on Non-type template arguments.
+template <int T>
+void i(n::P<T>* t) {}
+template void i(n::P<Constant>* t);
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-avoid-bind.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-avoid-bind.cpp
new file mode 100644
index 0000000..1c78b9e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-avoid-bind.cpp
@@ -0,0 +1,79 @@
+// RUN: %check_clang_tidy %s modernize-avoid-bind %t -- -- -std=c++14
+
+namespace std {
+inline namespace impl {
+template <class Fp, class... Arguments>
+class bind_rt {};
+
+template <class Fp, class... Arguments>
+bind_rt<Fp, Arguments...> bind(Fp &&, Arguments &&...);
+}
+}
+
+int add(int x, int y) { return x + y; }
+
+void f() {
+ auto clj = std::bind(add, 2, 2);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind [modernize-avoid-bind]
+ // CHECK-FIXES: auto clj = [] { return add(2, 2); };
+}
+
+void g() {
+ int x = 2;
+ int y = 2;
+ auto clj = std::bind(add, x, y);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
+ // CHECK-FIXES: auto clj = [=] { return add(x, y); };
+}
+
+struct placeholder {};
+placeholder _1;
+placeholder _2;
+
+void h() {
+ int x = 2;
+ auto clj = std::bind(add, x, _1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
+ // CHECK-FIXES: auto clj = [=](auto && arg1) { return add(x, arg1); };
+}
+
+struct A;
+struct B;
+bool ABTest(const A &, const B &);
+
+void i() {
+ auto BATest = std::bind(ABTest, _2, _1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: prefer a lambda to std::bind
+ // CHECK-FIXES: auto BATest = [](auto && arg1, auto && arg2) { return ABTest(arg2, arg1); };
+}
+
+void j() {
+ auto clj = std::bind(add, 2, 2, 2);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
+ // No fix is applied for argument mismatches.
+ // CHECK-FIXES: auto clj = std::bind(add, 2, 2, 2);
+}
+
+void k() {
+ auto clj = std::bind(add, _1, _1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
+ // No fix is applied for reused placeholders.
+ // CHECK-FIXES: auto clj = std::bind(add, _1, _1);
+}
+
+void m() {
+ auto clj = std::bind(add, 1, add(2, 5));
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
+ // No fix is applied for nested calls.
+ // CHECK-FIXES: auto clj = std::bind(add, 1, add(2, 5));
+}
+
+namespace C {
+ int add(int x, int y){ return x + y; }
+}
+
+void n() {
+ auto clj = std::bind(C::add, 1, 1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
+ // CHECK-FIXES: auto clj = [] { return C::add(1, 1); };
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-avoid-c-arrays-ignores-main.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-avoid-c-arrays-ignores-main.cpp
new file mode 100644
index 0000000..6549422
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-avoid-c-arrays-ignores-main.cpp
@@ -0,0 +1,18 @@
+// RUN: %check_clang_tidy %s modernize-avoid-c-arrays %t
+
+int not_main(int argc, char *argv[]) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not declare C-style arrays, use std::array<> instead
+ int f4[] = {1, 2};
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+}
+
+int main(int argc, char *argv[]) {
+ int f5[] = {1, 2};
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+
+ auto not_main = [](int argc, char *argv[]) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: do not declare C-style arrays, use std::array<> instead
+ int f6[] = {1, 2};
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not declare C-style arrays, use std::array<> instead
+ };
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-avoid-c-arrays-ignores-three-arg-main.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-avoid-c-arrays-ignores-three-arg-main.cpp
new file mode 100644
index 0000000..22a4016
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-avoid-c-arrays-ignores-three-arg-main.cpp
@@ -0,0 +1,20 @@
+// RUN: %check_clang_tidy %s modernize-avoid-c-arrays %t
+
+int not_main(int argc, char *argv[], char *argw[]) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not declare C-style arrays, use std::array<> instead
+ // CHECK-MESSAGES: :[[@LINE-2]]:38: warning: do not declare C-style arrays, use std::array<> instead
+ int f4[] = {1, 2};
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+}
+
+int main(int argc, char *argv[], char *argw[]) {
+ int f5[] = {1, 2};
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+
+ auto not_main = [](int argc, char *argv[], char *argw[]) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: do not declare C-style arrays, use std::array<> instead
+ // CHECK-MESSAGES: :[[@LINE-2]]:46: warning: do not declare C-style arrays, use std::array<> instead
+ int f6[] = {1, 2};
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not declare C-style arrays, use std::array<> instead
+ };
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-avoid-c-arrays.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-avoid-c-arrays.cpp
new file mode 100644
index 0000000..dd30780
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-avoid-c-arrays.cpp
@@ -0,0 +1,88 @@
+// RUN: %check_clang_tidy %s modernize-avoid-c-arrays %t
+
+int a[] = {1, 2};
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead
+
+int b[1];
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead
+
+void foo() {
+ int c[b[0]];
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C VLA arrays, use std::vector<> instead
+
+ using d = decltype(c);
+ d e;
+ // Semi-FIXME: we do not diagnose these last two lines separately,
+ // because we point at typeLoc.getBeginLoc(), which is the decl before that
+ // (int c[b[0]];), which is already diagnosed.
+}
+
+template <typename T, int Size>
+class array {
+ T d[Size];
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+
+ int e[1];
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+};
+
+array<int[4], 2> d;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not declare C-style arrays, use std::array<> instead
+
+using k = int[4];
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not declare C-style arrays, use std::array<> instead
+
+array<k, 2> dk;
+
+template <typename T>
+class unique_ptr {
+ T *d;
+
+ int e[1];
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+};
+
+unique_ptr<int[]> d2;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not declare C-style arrays, use std::array<> instead
+
+using k2 = int[];
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not declare C-style arrays, use std::array<> instead
+
+unique_ptr<k2> dk2;
+
+// Some header
+extern "C" {
+
+int f[] = {1, 2};
+
+int j[1];
+
+inline void bar() {
+ {
+ int j[j[0]];
+ }
+}
+
+extern "C++" {
+int f3[] = {1, 2};
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead
+
+int j3[1];
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead
+
+struct Foo {
+ int f3[3] = {1, 2};
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+
+ int j3[1];
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+};
+}
+
+struct Bar {
+
+ int f[3] = {1, 2};
+
+ int j[1];
+};
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-concat-nested-namespaces.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-concat-nested-namespaces.cpp
new file mode 100644
index 0000000..22a92f6
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-concat-nested-namespaces.cpp
@@ -0,0 +1,161 @@
+// RUN: %check_clang_tidy %s modernize-concat-nested-namespaces %t -- -- -std=c++17
+
+namespace n1 {}
+
+namespace n2 {
+namespace n3 {
+void t();
+}
+namespace n4 {
+void t();
+}
+} // namespace n2
+
+namespace n5 {
+inline namespace n6 {
+void t();
+}
+} // namespace n5
+
+namespace n7 {
+void t();
+
+namespace n8 {
+void t();
+}
+} // namespace n7
+
+namespace n9 {
+namespace n10 {
+// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
+// CHECK-FIXES: namespace n9::n10
+void t();
+} // namespace n10
+} // namespace n9
+// CHECK-FIXES: }
+
+namespace n11 {
+namespace n12 {
+// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
+// CHECK-FIXES: namespace n11::n12
+namespace n13 {
+void t();
+}
+namespace n14 {
+void t();
+}
+} // namespace n12
+} // namespace n11
+// CHECK-FIXES: }
+
+namespace n15 {
+namespace n16 {
+void t();
+}
+
+inline namespace n17 {
+void t();
+}
+
+namespace n18 {
+namespace n19 {
+namespace n20 {
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
+// CHECK-FIXES: namespace n18::n19::n20
+void t();
+} // namespace n20
+} // namespace n19
+} // namespace n18
+// CHECK-FIXES: }
+
+namespace n21 {
+void t();
+}
+} // namespace n15
+
+namespace n22 {
+namespace {
+void t();
+}
+} // namespace n22
+
+namespace n23 {
+namespace {
+namespace n24 {
+namespace n25 {
+// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
+// CHECK-FIXES: namespace n24::n25
+void t();
+} // namespace n25
+} // namespace n24
+// CHECK-FIXES: }
+} // namespace
+} // namespace n23
+
+namespace n26::n27 {
+namespace n28 {
+namespace n29::n30 {
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
+// CHECK-FIXES: namespace n26::n27::n28::n29::n30
+void t() {}
+} // namespace n29::n30
+} // namespace n28
+} // namespace n26::n27
+// CHECK-FIXES: }
+
+namespace n31 {
+namespace n32 {}
+// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
+} // namespace n31
+// CHECK-FIXES-EMPTY
+
+namespace n33 {
+namespace n34 {
+namespace n35 {}
+// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
+} // namespace n34
+// CHECK-FIXES-EMPTY
+namespace n36 {
+void t();
+}
+} // namespace n33
+
+namespace n37::n38 {
+void t();
+}
+
+#define IEXIST
+namespace n39 {
+namespace n40 {
+// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
+// CHECK-FIXES: namespace n39::n40
+#ifdef IEXIST
+void t() {}
+#endif
+} // namespace n40
+} // namespace n39
+// CHECK-FIXES: }
+
+namespace n41 {
+namespace n42 {
+// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
+// CHECK-FIXES: namespace n41::n42
+#ifdef IDONTEXIST
+void t() {}
+#endif
+} // namespace n42
+} // namespace n41
+// CHECK-FIXES: }
+
+int main() {
+ n26::n27::n28::n29::n30::t();
+#ifdef IEXIST
+ n39::n40::t();
+#endif
+
+#ifdef IDONTEXIST
+ n41::n42::t();
+#endif
+
+ return 0;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-deprecated-headers-cxx03.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-deprecated-headers-cxx03.cpp
new file mode 100644
index 0000000..c604ba4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-deprecated-headers-cxx03.cpp
@@ -0,0 +1,148 @@
+// RUN: %check_clang_tidy %s modernize-deprecated-headers %t -- -extra-arg-before=-isystem%S/Inputs/modernize-deprecated-headers -- -std=c++03 -v
+
+#include <assert.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'assert.h'; consider using 'cassert' instead [modernize-deprecated-headers]
+// CHECK-FIXES: {{^}}#include <cassert>{{$}}
+#include <complex.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'complex.h'; consider using 'complex' instead
+// CHECK-FIXES: {{^}}#include <complex>{{$}}
+#include <ctype.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'ctype.h'; consider using 'cctype' instead
+// CHECK-FIXES: {{^}}#include <cctype>{{$}}
+#include <errno.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'errno.h'; consider using 'cerrno' instead
+// CHECK-FIXES: {{^}}#include <cerrno>{{$}}
+#include <float.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'float.h'; consider using 'cfloat' instead
+// CHECK-FIXES: {{^}}#include <cfloat>{{$}}
+#include <limits.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'limits.h'; consider using 'climits' instead
+// CHECK-FIXES: {{^}}#include <climits>{{$}}
+#include <locale.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'locale.h'; consider using 'clocale' instead
+// CHECK-FIXES: {{^}}#include <clocale>{{$}}
+#include <math.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'math.h'; consider using 'cmath' instead
+// CHECK-FIXES: {{^}}#include <cmath>{{$}}
+#include <setjmp.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'setjmp.h'; consider using 'csetjmp' instead
+// CHECK-FIXES: {{^}}#include <csetjmp>{{$}}
+#include <signal.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'signal.h'; consider using 'csignal' instead
+// CHECK-FIXES: {{^}}#include <csignal>{{$}}
+#include <stdarg.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdarg.h'; consider using 'cstdarg' instead
+// CHECK-FIXES: {{^}}#include <cstdarg>{{$}}
+#include <stddef.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stddef.h'; consider using 'cstddef' instead
+// CHECK-FIXES: {{^}}#include <cstddef>{{$}}
+#include <stdio.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdio.h'; consider using 'cstdio' instead
+// CHECK-FIXES: {{^}}#include <cstdio>{{$}}
+#include <stdlib.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdlib.h'; consider using 'cstdlib' instead
+// CHECK-FIXES: {{^}}#include <cstdlib>{{$}}
+#include <string.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'string.h'; consider using 'cstring' instead
+// CHECK-FIXES: {{^}}#include <cstring>{{$}}
+#include <time.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'time.h'; consider using 'ctime' instead
+// CHECK-FIXES: {{^}}#include <ctime>{{$}}
+#include <wchar.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'wchar.h'; consider using 'cwchar' instead
+// CHECK-FIXES: {{^}}#include <cwchar>{{$}}
+#include <wctype.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'wctype.h'; consider using 'cwctype' instead
+// CHECK-FIXES: {{^}}#include <cwctype>{{$}}
+
+// Headers that have no effect in C++; remove them
+#include <stdalign.h> // <stdalign.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdalign.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// <stdalign.h>{{$}}
+#include <stdbool.h> // <stdbool.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdbool.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// <stdbool.h>{{$}}
+#include <iso646.h> // <iso646.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'iso646.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// <iso646.h>{{$}}
+
+// Headers deprecated since C++11: expect no diagnostics.
+#include <fenv.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <tgmath.h>
+#include <uchar.h>
+
+
+#include "assert.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'assert.h'; consider using 'cassert' instead
+// CHECK-FIXES: {{^}}#include <cassert>{{$}}
+#include "complex.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'complex.h'; consider using 'complex' instead
+// CHECK-FIXES: {{^}}#include <complex>{{$}}
+#include "ctype.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'ctype.h'; consider using 'cctype' instead
+// CHECK-FIXES: {{^}}#include <cctype>{{$}}
+#include "errno.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'errno.h'; consider using 'cerrno' instead
+// CHECK-FIXES: {{^}}#include <cerrno>{{$}}
+#include "float.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'float.h'; consider using 'cfloat' instead
+// CHECK-FIXES: {{^}}#include <cfloat>{{$}}
+#include "limits.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'limits.h'; consider using 'climits' instead
+// CHECK-FIXES: {{^}}#include <climits>{{$}}
+#include "locale.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'locale.h'; consider using 'clocale' instead
+// CHECK-FIXES: {{^}}#include <clocale>{{$}}
+#include "math.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'math.h'; consider using 'cmath' instead
+// CHECK-FIXES: {{^}}#include <cmath>{{$}}
+#include "setjmp.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'setjmp.h'; consider using 'csetjmp' instead
+// CHECK-FIXES: {{^}}#include <csetjmp>{{$}}
+#include "signal.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'signal.h'; consider using 'csignal' instead
+// CHECK-FIXES: {{^}}#include <csignal>{{$}}
+#include "stdarg.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdarg.h'; consider using 'cstdarg' instead
+// CHECK-FIXES: {{^}}#include <cstdarg>{{$}}
+#include "stddef.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stddef.h'; consider using 'cstddef' instead
+// CHECK-FIXES: {{^}}#include <cstddef>{{$}}
+#include "stdio.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdio.h'; consider using 'cstdio' instead
+// CHECK-FIXES: {{^}}#include <cstdio>{{$}}
+#include "stdlib.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdlib.h'; consider using 'cstdlib' instead
+// CHECK-FIXES: {{^}}#include <cstdlib>{{$}}
+#include "string.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'string.h'; consider using 'cstring' instead
+// CHECK-FIXES: {{^}}#include <cstring>{{$}}
+#include "time.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'time.h'; consider using 'ctime' instead
+// CHECK-FIXES: {{^}}#include <ctime>{{$}}
+#include "wchar.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'wchar.h'; consider using 'cwchar' instead
+// CHECK-FIXES: {{^}}#include <cwchar>{{$}}
+#include "wctype.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'wctype.h'; consider using 'cwctype' instead
+// CHECK-FIXES: {{^}}#include <cwctype>
+
+// Headers that have no effect in C++; remove them
+#include "stdalign.h" // "stdalign.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdalign.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// "stdalign.h"{{$}}
+#include "stdbool.h" // "stdbool.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdbool.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// "stdbool.h"{{$}}
+#include "iso646.h" // "iso646.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'iso646.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// "iso646.h"{{$}}
+
+// Headers deprecated since C++11; expect no diagnostics
+#include "fenv.h"
+#include "inttypes.h"
+#include "stdint.h"
+#include "tgmath.h"
+#include "uchar.h"
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-deprecated-headers-cxx11.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-deprecated-headers-cxx11.cpp
new file mode 100644
index 0000000..366f045
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-deprecated-headers-cxx11.cpp
@@ -0,0 +1,163 @@
+// RUN: %check_clang_tidy %s modernize-deprecated-headers %t -- -extra-arg-before=-isystem%S/Inputs/modernize-deprecated-headers -- -std=c++11 -v
+
+#include <assert.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'assert.h'; consider using 'cassert' instead [modernize-deprecated-headers]
+// CHECK-FIXES: {{^}}#include <cassert>{{$}}
+#include <complex.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'complex.h'; consider using 'complex' instead
+// CHECK-FIXES: {{^}}#include <complex>{{$}}
+#include <ctype.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'ctype.h'; consider using 'cctype' instead
+// CHECK-FIXES: {{^}}#include <cctype>{{$}}
+#include <errno.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'errno.h'; consider using 'cerrno' instead
+// CHECK-FIXES: {{^}}#include <cerrno>{{$}}
+#include <fenv.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'fenv.h'; consider using 'cfenv' instead
+// CHECK-FIXES: {{^}}#include <cfenv>{{$}}
+#include <float.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'float.h'; consider using 'cfloat' instead
+// CHECK-FIXES: {{^}}#include <cfloat>{{$}}
+#include <inttypes.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'inttypes.h'; consider using 'cinttypes' instead
+// CHECK-FIXES: {{^}}#include <cinttypes>{{$}}
+#include <limits.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'limits.h'; consider using 'climits' instead
+// CHECK-FIXES: {{^}}#include <climits>{{$}}
+#include <locale.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'locale.h'; consider using 'clocale' instead
+// CHECK-FIXES: {{^}}#include <clocale>{{$}}
+#include <math.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'math.h'; consider using 'cmath' instead
+// CHECK-FIXES: {{^}}#include <cmath>{{$}}
+#include <setjmp.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'setjmp.h'; consider using 'csetjmp' instead
+// CHECK-FIXES: {{^}}#include <csetjmp>{{$}}
+#include <signal.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'signal.h'; consider using 'csignal' instead
+// CHECK-FIXES: {{^}}#include <csignal>{{$}}
+#include <stdarg.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdarg.h'; consider using 'cstdarg' instead
+// CHECK-FIXES: {{^}}#include <cstdarg>{{$}}
+#include <stddef.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stddef.h'; consider using 'cstddef' instead
+// CHECK-FIXES: {{^}}#include <cstddef>{{$}}
+#include <stdint.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdint.h'; consider using 'cstdint' instead
+// CHECK-FIXES: {{^}}#include <cstdint>{{$}}
+#include <stdio.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdio.h'; consider using 'cstdio' instead
+// CHECK-FIXES: {{^}}#include <cstdio>{{$}}
+#include <stdlib.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdlib.h'; consider using 'cstdlib' instead
+// CHECK-FIXES: {{^}}#include <cstdlib>{{$}}
+#include <string.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'string.h'; consider using 'cstring' instead
+// CHECK-FIXES: {{^}}#include <cstring>{{$}}
+#include <tgmath.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'tgmath.h'; consider using 'ctgmath' instead
+// CHECK-FIXES: {{^}}#include <ctgmath>{{$}}
+#include <time.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'time.h'; consider using 'ctime' instead
+// CHECK-FIXES: {{^}}#include <ctime>{{$}}
+#include <uchar.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'uchar.h'; consider using 'cuchar' instead
+// CHECK-FIXES: {{^}}#include <cuchar>{{$}}
+#include <wchar.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'wchar.h'; consider using 'cwchar' instead
+// CHECK-FIXES: {{^}}#include <cwchar>{{$}}
+#include <wctype.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'wctype.h'; consider using 'cwctype' instead
+// CHECK-FIXES: {{^}}#include <cwctype>
+
+// Headers that have no effect in C++; remove them
+#include <stdalign.h> // <stdalign.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdalign.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// <stdalign.h>{{$}}
+#include <stdbool.h> // <stdbool.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdbool.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// <stdbool.h>{{$}}
+#include <iso646.h> // <iso646.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'iso646.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// <iso646.h>{{$}}
+
+#include "assert.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'assert.h'; consider using 'cassert' instead
+// CHECK-FIXES: {{^}}#include <cassert>{{$}}
+#include "complex.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'complex.h'; consider using 'complex' instead
+// CHECK-FIXES: {{^}}#include <complex>{{$}}
+#include "ctype.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'ctype.h'; consider using 'cctype' instead
+// CHECK-FIXES: {{^}}#include <cctype>{{$}}
+#include "errno.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'errno.h'; consider using 'cerrno' instead
+// CHECK-FIXES: {{^}}#include <cerrno>{{$}}
+#include "fenv.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'fenv.h'; consider using 'cfenv' instead
+// CHECK-FIXES: {{^}}#include <cfenv>{{$}}
+#include "float.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'float.h'; consider using 'cfloat' instead
+// CHECK-FIXES: {{^}}#include <cfloat>{{$}}
+#include "inttypes.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'inttypes.h'; consider using 'cinttypes' instead
+// CHECK-FIXES: {{^}}#include <cinttypes>{{$}}
+#include "limits.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'limits.h'; consider using 'climits' instead
+// CHECK-FIXES: {{^}}#include <climits>{{$}}
+#include "locale.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'locale.h'; consider using 'clocale' instead
+// CHECK-FIXES: {{^}}#include <clocale>{{$}}
+#include "math.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'math.h'; consider using 'cmath' instead
+// CHECK-FIXES: {{^}}#include <cmath>{{$}}
+#include "setjmp.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'setjmp.h'; consider using 'csetjmp' instead
+// CHECK-FIXES: {{^}}#include <csetjmp>{{$}}
+#include "signal.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'signal.h'; consider using 'csignal' instead
+// CHECK-FIXES: {{^}}#include <csignal>{{$}}
+#include "stdarg.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdarg.h'; consider using 'cstdarg' instead
+// CHECK-FIXES: {{^}}#include <cstdarg>{{$}}
+#include "stddef.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stddef.h'; consider using 'cstddef' instead
+// CHECK-FIXES: {{^}}#include <cstddef>{{$}}
+#include "stdint.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdint.h'; consider using 'cstdint' instead
+// CHECK-FIXES: {{^}}#include <cstdint>{{$}}
+#include "stdio.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdio.h'; consider using 'cstdio' instead
+// CHECK-FIXES: {{^}}#include <cstdio>{{$}}
+#include "stdlib.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdlib.h'; consider using 'cstdlib' instead
+// CHECK-FIXES: {{^}}#include <cstdlib>{{$}}
+#include "string.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'string.h'; consider using 'cstring' instead
+// CHECK-FIXES: {{^}}#include <cstring>{{$}}
+#include "tgmath.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'tgmath.h'; consider using 'ctgmath' instead
+// CHECK-FIXES: {{^}}#include <ctgmath>{{$}}
+#include "time.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'time.h'; consider using 'ctime' instead
+// CHECK-FIXES: {{^}}#include <ctime>{{$}}
+#include "uchar.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'uchar.h'; consider using 'cuchar' instead
+// CHECK-FIXES: {{^}}#include <cuchar>{{$}}
+#include "wchar.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'wchar.h'; consider using 'cwchar' instead
+// CHECK-FIXES: {{^}}#include <cwchar>{{$}}
+#include "wctype.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'wctype.h'; consider using 'cwctype' instead
+// CHECK-FIXES: {{^}}#include <cwctype>
+
+// Headers that have no effect in C++; remove them
+#include "stdalign.h" // "stdalign.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdalign.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// "stdalign.h"{{$}}
+#include "stdbool.h" // "stdbool.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdbool.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// "stdbool.h"{{$}}
+#include "iso646.h" // "iso646.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'iso646.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// "iso646.h"{{$}}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-deprecated-ios-base-aliases.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-deprecated-ios-base-aliases.cpp
new file mode 100644
index 0000000..680cb9e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-deprecated-ios-base-aliases.cpp
@@ -0,0 +1,239 @@
+// RUN: %check_clang_tidy %s modernize-deprecated-ios-base-aliases %t
+
+namespace std {
+class ios_base {
+public:
+ typedef int io_state;
+ typedef int open_mode;
+ typedef int seek_dir;
+
+ typedef int streampos;
+ typedef int streamoff;
+};
+
+template <class CharT>
+class basic_ios : public ios_base {
+};
+} // namespace std
+
+// Test function return values (declaration)
+std::ios_base::io_state f_5();
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'std::ios_base::io_state' is deprecated; use 'std::ios_base::iostate' instead [modernize-deprecated-ios-base-aliases]
+// CHECK-FIXES: std::ios_base::iostate f_5();
+
+// Test function parameters.
+void f_6(std::ios_base::open_mode);
+// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: 'std::ios_base::open_mode' is deprecated
+// CHECK-FIXES: void f_6(std::ios_base::openmode);
+void f_7(const std::ios_base::seek_dir &);
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'std::ios_base::seek_dir' is deprecated
+// CHECK-FIXES: void f_7(const std::ios_base::seekdir &);
+
+// Test on record type fields.
+struct A {
+ std::ios_base::io_state field;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: std::ios_base::iostate field;
+
+ typedef std::ios_base::io_state int_ptr_type;
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: typedef std::ios_base::iostate int_ptr_type;
+};
+
+struct B : public std::ios_base {
+ io_state a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: iostate a;
+};
+
+struct C : public std::basic_ios<char> {
+ io_state a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: iostate a;
+};
+
+void f_1() {
+ std::ios_base::io_state a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: std::ios_base::iostate a;
+
+ // Check that spaces aren't modified unnecessarily.
+ std :: ios_base :: io_state b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: std :: ios_base :: iostate b;
+
+ // Test construction from a temporary.
+ std::ios_base::io_state c = std::ios_base::io_state{};
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-MESSAGES: :[[@LINE-2]]:46: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: std::ios_base::iostate c = std::ios_base::iostate{};
+
+ typedef std::ios_base::io_state alias1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: typedef std::ios_base::iostate alias1;
+ alias1 d(a);
+
+ using alias2 = std::ios_base::io_state;
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: using alias2 = std::ios_base::iostate;
+ alias2 e;
+
+ // Test pointers.
+ std::ios_base::io_state *f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: std::ios_base::iostate *f;
+
+ // Test 'static' declarations.
+ static std::ios_base::io_state g;
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: static std::ios_base::iostate g;
+
+ // Test with cv-qualifiers.
+ const std::ios_base::io_state h(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: const std::ios_base::iostate h(0);
+ volatile std::ios_base::io_state i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: volatile std::ios_base::iostate i;
+ const volatile std::ios_base::io_state j(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: const volatile std::ios_base::iostate j(0);
+
+ // Test auto and initializer-list.
+ auto k = std::ios_base::io_state{};
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: auto k = std::ios_base::iostate{};
+
+ std::ios_base::io_state l{std::ios_base::io_state()};
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-MESSAGES: :[[@LINE-2]]:44: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: std::ios_base::iostate l{std::ios_base::iostate()};
+
+ // Test temporaries.
+ std::ios_base::io_state();
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: std::ios_base::iostate();
+
+ // Test inherited type usage
+ std::basic_ios<char>::io_state m;
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: std::basic_ios<char>::iostate m;
+
+ std::ios_base::streampos n;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'std::ios_base::streampos' is deprecated [modernize-deprecated-ios-base-aliases]
+
+ std::ios_base::streamoff o;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'std::ios_base::streamoff' is deprecated [modernize-deprecated-ios-base-aliases]
+}
+
+// Test without the nested name specifiers.
+void f_2() {
+ using namespace std;
+
+ ios_base::io_state a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: ios_base::iostate a;
+}
+
+// Test messing-up with macros.
+void f_4() {
+#define MACRO_1 std::ios_base::io_state
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: 'std::ios_base::io_state' is deprecated
+ MACRO_1 a;
+
+#define MACRO_2 io_state
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 'std::ios_base::io_state' is deprecated
+ std::ios_base::MACRO_2 b;
+
+#define MACRO_3 std::ios_base
+ MACRO_3::io_state c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: 'std::ios_base::io_state' is deprecated
+
+#define MACRO_4(type) type::io_state
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: 'std::ios_base::io_state' is deprecated
+ MACRO_4(std::ios_base) d;
+
+#undef MACRO_1
+#undef MACRO_2
+#undef MACRO_3
+#undef MACRO_4
+}
+
+// Test function return values (definition).
+std::ios_base::io_state f_5()
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'std::ios_base::io_state' is deprecated
+// CHECK-FIXES: std::ios_base::iostate f_5()
+{
+ // Test constructor.
+ return std::ios_base::io_state(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: return std::ios_base::iostate(0);
+}
+
+// Test that other aliases with same name aren't replaced
+struct my_ios_base {
+ typedef int io_state;
+};
+
+namespace ns_1 {
+struct my_ios_base2 {
+ typedef int io_state;
+};
+} // namespace ns_1
+
+void f_8() {
+ my_ios_base::io_state a;
+
+ ns_1::my_ios_base2::io_state b;
+}
+
+// Test templates
+template <typename X>
+void f_9() {
+ typename std::basic_ios<X>::io_state p;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'std::ios_base::io_state' is deprecated
+ typename std::ios_base::io_state q;
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: typename std::ios_base::iostate q;
+}
+
+template <typename T>
+void f_10(T arg) {
+ T x(arg);
+}
+
+template <typename T>
+void f_11() {
+ typename T::io_state x{};
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 'std::ios_base::io_state' is deprecated
+}
+
+template <typename T>
+struct D : std::ios_base {
+ io_state a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: iostate a;
+
+ typename std::basic_ios<T>::io_state b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'std::ios_base::io_state' is deprecated
+};
+
+template <typename T>
+struct E {
+ T t;
+};
+
+void f_12() {
+ f_9<char>();
+
+ f_10<std::ios_base::io_state>(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: f_10<std::ios_base::iostate>(0);
+
+ f_11<std::ios_base>();
+ D<char> d;
+
+ E<std::ios_base::io_state> e;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 'std::ios_base::io_state' is deprecated
+ // CHECK-FIXES: E<std::ios_base::iostate> e;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-assert-failure.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-assert-failure.cpp
new file mode 100644
index 0000000..fab51da
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-assert-failure.cpp
@@ -0,0 +1,18 @@
+// RUN: not clang-tidy %s -checks=-*,modernize-loop-convert --
+
+// Note: this test expects no assert failure happened in clang-tidy.
+
+class LinguisticItem {
+ LinguisticItem *x0;
+ class x1 {
+ bool operator!= ( const x1 &;
+ operator* ( ;
+ LinguisticItem * &operator-> ( ;
+ operator++ (
+ } begin() const;
+ x1 end() const {
+ LinguisticStream x2;
+ for (x1 x3 = x2.begin x3 != x2.end; ++x3)
+ x3->x0
+ }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-basic.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-basic.cpp
new file mode 100644
index 0000000..def7c4b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-basic.cpp
@@ -0,0 +1,793 @@
+// RUN: %check_clang_tidy %s modernize-loop-convert %t -- -- -std=c++11 -I %S/Inputs/modernize-loop-convert
+
+#include "structures.h"
+
+namespace Array {
+
+const int N = 6;
+const int NMinusOne = N - 1;
+int Arr[N] = {1, 2, 3, 4, 5, 6};
+const int ConstArr[N] = {1, 2, 3, 4, 5, 6};
+int (*PArr)[N] = &Arr;
+
+void f() {
+ int Sum = 0;
+
+ for (int I = 0; I < N; ++I) {
+ Sum += Arr[I];
+ int K;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead [modernize-loop-convert]
+ // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES-NEXT: Sum += I;
+ // CHECK-FIXES-NEXT: int K;
+
+ for (int I = 0; I < N; ++I) {
+ printf("Fibonacci number is %d\n", Arr[I]);
+ Sum += Arr[I] + 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+ // CHECK-FIXES-NEXT: Sum += I + 2;
+
+ for (int I = 0; I < N; ++I) {
+ int X = Arr[I];
+ int Y = Arr[I] + 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES-NEXT: int X = I;
+ // CHECK-FIXES-NEXT: int Y = I + 2;
+
+ for (int I = 0; I < N; ++I) {
+ int X = N;
+ X = Arr[I];
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES-NEXT: int X = N;
+ // CHECK-FIXES-NEXT: X = I;
+
+ for (int I = 0; I < N; ++I) {
+ Arr[I] += 1;
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & I : Arr)
+ // CHECK-FIXES-NEXT: I += 1;
+
+ for (int I = 0; I < N; ++I) {
+ int X = Arr[I] + 2;
+ Arr[I]++;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & I : Arr)
+ // CHECK-FIXES-NEXT: int X = I + 2;
+ // CHECK-FIXES-NEXT: I++;
+
+ for (int I = 0; I < N; ++I) {
+ Arr[I] = 4 + Arr[I];
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & I : Arr)
+ // CHECK-FIXES-NEXT: I = 4 + I;
+
+ for (int I = 0; I < NMinusOne + 1; ++I) {
+ Sum += Arr[I];
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES-NEXT: Sum += I;
+
+ for (int I = 0; I < N; ++I) {
+ printf("Fibonacci number %d has address %p\n", Arr[I], &Arr[I]);
+ Sum += Arr[I] + 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & I : Arr)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I);
+ // CHECK-FIXES-NEXT: Sum += I + 2;
+
+ Val Teas[N];
+ for (int I = 0; I < N; ++I) {
+ Teas[I].g();
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & Tea : Teas)
+ // CHECK-FIXES-NEXT: Tea.g();
+}
+
+const int *constArray() {
+ for (int I = 0; I < N; ++I) {
+ printf("2 * %d = %d\n", ConstArr[I], ConstArr[I] + ConstArr[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : ConstArr)
+ // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I, I + I);
+
+ const NonTriviallyCopyable NonCopy[N]{};
+ for (int I = 0; I < N; ++I) {
+ printf("2 * %d = %d\n", NonCopy[I].X, NonCopy[I].X + NonCopy[I].X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (const auto & I : NonCopy)
+ // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I.X, I.X + I.X);
+
+ const TriviallyCopyableButBig Big[N]{};
+ for (int I = 0; I < N; ++I) {
+ printf("2 * %d = %d\n", Big[I].X, Big[I].X + Big[I].X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (const auto & I : Big)
+ // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I.X, I.X + I.X);
+
+ bool Something = false;
+ for (int I = 0; I < N; ++I) {
+ if (Something)
+ return &ConstArr[I];
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (const int & I : ConstArr)
+ // CHECK-FIXES-NEXT: if (Something)
+ // CHECK-FIXES-NEXT: return &I;
+}
+
+struct HasArr {
+ int Arr[N];
+ Val ValArr[N];
+ void implicitThis() {
+ for (int I = 0; I < N; ++I) {
+ printf("%d", Arr[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES-NEXT: printf("%d", I);
+
+ for (int I = 0; I < N; ++I) {
+ printf("%d", ValArr[I].X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : ValArr)
+ // CHECK-FIXES-NEXT: printf("%d", I.X);
+ }
+
+ void explicitThis() {
+ for (int I = 0; I < N; ++I) {
+ printf("%d", this->Arr[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : this->Arr)
+ // CHECK-FIXES-NEXT: printf("%d", I);
+
+ for (int I = 0; I < N; ++I) {
+ printf("%d", this->ValArr[I].X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : this->ValArr)
+ // CHECK-FIXES-NEXT: printf("%d", I.X);
+ }
+};
+
+struct HasIndirectArr {
+ HasArr HA;
+ void implicitThis() {
+ for (int I = 0; I < N; ++I) {
+ printf("%d", HA.Arr[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : HA.Arr)
+ // CHECK-FIXES-NEXT: printf("%d", I);
+
+ for (int I = 0; I < N; ++I) {
+ printf("%d", HA.ValArr[I].X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : HA.ValArr)
+ // CHECK-FIXES-NEXT: printf("%d", I.X);
+ }
+
+ void explicitThis() {
+ for (int I = 0; I < N; ++I) {
+ printf("%d", this->HA.Arr[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : this->HA.Arr)
+ // CHECK-FIXES-NEXT: printf("%d", I);
+
+ for (int I = 0; I < N; ++I) {
+ printf("%d", this->HA.ValArr[I].X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : this->HA.ValArr)
+ // CHECK-FIXES-NEXT: printf("%d", I.X);
+ }
+};
+
+// Loops whose bounds are value-dependent should not be converted.
+template <int N>
+void dependentExprBound() {
+ for (int I = 0; I < N; ++I)
+ Arr[I] = 0;
+}
+template void dependentExprBound<20>();
+
+void memberFunctionPointer() {
+ Val V;
+ void (Val::*mfpArr[N])(void) = {&Val::g};
+ for (int I = 0; I < N; ++I)
+ (V.*mfpArr[I])();
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : mfpArr)
+ // CHECK-FIXES-NEXT: (V.*I)();
+
+ struct Foo {
+ int (Val::*f)();
+ } Foo[N];
+
+ for (int I = 0; I < N; ++I)
+ int R = (V.*(Foo[I].f))();
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : Foo)
+ // CHECK-FIXES-NEXT: int R = (V.*(I.f))();
+
+}
+
+} // namespace Array
+
+namespace Iterator {
+
+void f() {
+ /// begin()/end() - based for loops here:
+ T Tt;
+ for (T::iterator It = Tt.begin(), E = Tt.end(); It != E; ++It) {
+ printf("I found %d\n", *It);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & It : Tt)
+ // CHECK-FIXES-NEXT: printf("I found %d\n", It);
+
+ T *Pt;
+ for (T::iterator It = Pt->begin(), E = Pt->end(); It != E; ++It) {
+ printf("I found %d\n", *It);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & It : *Pt)
+ // CHECK-FIXES-NEXT: printf("I found %d\n", It);
+
+ S Ss;
+ for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
+ printf("s has value %d\n", (*It).X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+ S *Ps;
+ for (S::iterator It = Ps->begin(), E = Ps->end(); It != E; ++It) {
+ printf("s has value %d\n", (*It).X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & P : *Ps)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);
+
+ for (S::const_iterator It = Ss.cbegin(), E = Ss.cend(); It != E; ++It) {
+ printf("s has value %d\n", (*It).X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto It : Ss)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+ for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
+ printf("s has value %d\n", It->X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+ for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
+ It->X = 3;
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES-NEXT: It.X = 3;
+
+ for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
+ (*It).X = 3;
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES-NEXT: It.X = 3;
+
+ for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
+ It->nonConstFun(4, 5);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES-NEXT: It.nonConstFun(4, 5);
+
+ U Uu;
+ for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) {
+ printf("s has value %d\n", It->X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & It : Uu)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+ for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) {
+ printf("s has value %d\n", (*It).X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & It : Uu)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+ for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) {
+ Val* a = It.operator->();
+ }
+
+ U::iterator A;
+ for (U::iterator I = Uu.begin(), E = Uu.end(); I != E; ++I)
+ int K = A->X + I->X;
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : Uu)
+ // CHECK-FIXES-NEXT: int K = A->X + I.X;
+
+ dependent<int> V;
+ for (dependent<int>::iterator It = V.begin(), E = V.end();
+ It != E; ++It) {
+ printf("Fibonacci number is %d\n", *It);
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & It : V)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
+
+ for (dependent<int>::iterator It(V.begin()), E = V.end();
+ It != E; ++It) {
+ printf("Fibonacci number is %d\n", *It);
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & It : V)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
+
+ doublyDependent<int, int> Intmap;
+ for (doublyDependent<int, int>::iterator It = Intmap.begin(), E = Intmap.end();
+ It != E; ++It) {
+ printf("Intmap[%d] = %d", It->first, It->second);
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & It : Intmap)
+ // CHECK-FIXES: printf("Intmap[%d] = %d", It.first, It.second);
+
+ // PtrSet's iterator dereferences by value so auto & can't be used.
+ {
+ PtrSet<int *> Val_int_ptrs;
+ for (PtrSet<int *>::iterator I = Val_int_ptrs.begin(),
+ E = Val_int_ptrs.end();
+ I != E; ++I) {
+ (void) *I;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto Val_int_ptr : Val_int_ptrs)
+ }
+
+ // This container uses an iterator where the derefence type is a typedef of
+ // a reference type. Make sure non-const auto & is still used. A failure here
+ // means canonical types aren't being tested.
+ {
+ TypedefDerefContainer<int> Int_ptrs;
+ for (TypedefDerefContainer<int>::iterator I = Int_ptrs.begin(),
+ E = Int_ptrs.end();
+ I != E; ++I) {
+ (void) *I;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & Int_ptr : Int_ptrs)
+ }
+
+ {
+ // Iterators returning an rvalue reference should disqualify the loop from
+ // transformation.
+ RValueDerefContainer<int> Container;
+ for (RValueDerefContainer<int>::iterator I = Container.begin(),
+ E = Container.end();
+ I != E; ++I) {
+ (void) *I;
+ }
+ }
+
+ dependent<Val *> Dpp;
+ for (dependent<Val *>::iterator I = Dpp.begin(), E = Dpp.end(); I != E; ++I) {
+ printf("%d\n", (**I).X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : Dpp)
+ // CHECK-FIXES-NEXT: printf("%d\n", (*I).X);
+
+ for (dependent<Val *>::iterator I = Dpp.begin(), E = Dpp.end(); I != E; ++I) {
+ printf("%d\n", (*I)->X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : Dpp)
+ // CHECK-FIXES-NEXT: printf("%d\n", I->X);
+}
+
+// Tests to verify the proper use of auto where the init variable type and the
+// initializer type differ or are mostly the same except for const qualifiers.
+void different_type() {
+ // Ss.begin() returns a type 'iterator' which is just a non-const pointer and
+ // differs from const_iterator only on the const qualification.
+ S Ss;
+ for (S::const_iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
+ printf("s has value %d\n", (*It).X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto It : Ss)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+ S *Ps;
+ for (S::const_iterator It = Ps->begin(), E = Ps->end(); It != E; ++It) {
+ printf("s has value %d\n", (*It).X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto P : *Ps)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);
+
+ // V.begin() returns a user-defined type 'iterator' which, since it's
+ // different from const_iterator, disqualifies these loops from
+ // transformation.
+ dependent<int> V;
+ for (dependent<int>::const_iterator It = V.begin(), E = V.end();
+ It != E; ++It) {
+ printf("Fibonacci number is %d\n", *It);
+ }
+
+ for (dependent<int>::const_iterator It(V.begin()), E = V.end();
+ It != E; ++It) {
+ printf("Fibonacci number is %d\n", *It);
+ }
+}
+
+// Tests to ensure that an implicit 'this' is picked up as the container.
+// If member calls are made to 'this' within the loop, the transform becomes
+// risky as these calls may affect state that affects the loop.
+class C {
+public:
+ typedef MutableVal *iterator;
+ typedef const MutableVal *const_iterator;
+
+ iterator begin();
+ iterator end();
+ const_iterator begin() const;
+ const_iterator end() const;
+
+ void doSomething();
+ void doSomething() const;
+
+ void doLoop() {
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ (void) *I;
+ // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : *this)
+
+ for (iterator I = C::begin(), E = C::end(); I != E; ++I)
+ (void) *I;
+ // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : *this)
+
+ for (iterator I = begin(), E = end(); I != E; ++I) {
+ (void) *I;
+ doSomething();
+ }
+
+ for (iterator I = begin(); I != end(); ++I)
+ (void) *I;
+ // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : *this)
+
+ for (iterator I = begin(); I != end(); ++I) {
+ (void) *I;
+ doSomething();
+ }
+ }
+
+ void doLoop() const {
+ for (const_iterator I = begin(), E = end(); I != E; ++I)
+ (void) *I;
+ // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto I : *this)
+
+ for (const_iterator I = C::begin(), E = C::end(); I != E; ++I)
+ (void) *I;
+ // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto I : *this)
+
+ for (const_iterator I = begin(), E = end(); I != E; ++I) {
+ (void) *I;
+ doSomething();
+ }
+ }
+};
+
+class C2 {
+public:
+ typedef MutableVal *iterator;
+
+ iterator begin() const;
+ iterator end() const;
+
+ void doLoop() {
+ // The implicit 'this' will have an Implicit cast to const C2* wrapped
+ // around it. Make sure the replacement still happens.
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ (void) *I;
+ // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : *this)
+ }
+};
+
+} // namespace Iterator
+
+namespace PseudoArray {
+
+const int N = 6;
+dependent<int> V;
+dependent<int> *Pv;
+const dependent<NonTriviallyCopyable> Constv;
+const dependent<NonTriviallyCopyable> *Pconstv;
+
+transparent<dependent<int>> Cv;
+
+void f() {
+ int Sum = 0;
+ for (int I = 0, E = V.size(); I < E; ++I) {
+ printf("Fibonacci number is %d\n", V[I]);
+ Sum += V[I] + 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : V)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+ // CHECK-FIXES-NEXT: Sum += I + 2;
+
+ for (int I = 0, E = V.size(); I < E; ++I) {
+ printf("Fibonacci number is %d\n", V.at(I));
+ Sum += V.at(I) + 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : V)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+ // CHECK-FIXES-NEXT: Sum += I + 2;
+
+ for (int I = 0, E = Pv->size(); I < E; ++I) {
+ printf("Fibonacci number is %d\n", Pv->at(I));
+ Sum += Pv->at(I) + 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : *Pv)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+ // CHECK-FIXES-NEXT: Sum += I + 2;
+
+ // This test will fail if size() isn't called repeatedly, since it
+ // returns unsigned int, and 0 is deduced to be signed int.
+ // FIXME: Insert the necessary explicit conversion, or write out the types
+ // explicitly.
+ for (int I = 0; I < Pv->size(); ++I) {
+ printf("Fibonacci number is %d\n", (*Pv).at(I));
+ Sum += (*Pv)[I] + 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : *Pv)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+ // CHECK-FIXES-NEXT: Sum += I + 2;
+
+ for (int I = 0; I < Cv->size(); ++I) {
+ printf("Fibonacci number is %d\n", Cv->at(I));
+ Sum += Cv->at(I) + 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : *Cv)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+ // CHECK-FIXES-NEXT: Sum += I + 2;
+}
+
+// Ensure that 'const auto &' is used with containers of non-trivial types.
+void constness() {
+ int Sum = 0;
+ for (int I = 0, E = Constv.size(); I < E; ++I) {
+ printf("Fibonacci number is %d\n", Constv[I].X);
+ Sum += Constv[I].X + 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (const auto & I : Constv)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X);
+ // CHECK-FIXES-NEXT: Sum += I.X + 2;
+
+ for (int I = 0, E = Constv.size(); I < E; ++I) {
+ printf("Fibonacci number is %d\n", Constv.at(I).X);
+ Sum += Constv.at(I).X + 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (const auto & I : Constv)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X);
+ // CHECK-FIXES-NEXT: Sum += I.X + 2;
+
+ for (int I = 0, E = Pconstv->size(); I < E; ++I) {
+ printf("Fibonacci number is %d\n", Pconstv->at(I).X);
+ Sum += Pconstv->at(I).X + 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (const auto & I : *Pconstv)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X);
+ // CHECK-FIXES-NEXT: Sum += I.X + 2;
+
+ // This test will fail if size() isn't called repeatedly, since it
+ // returns unsigned int, and 0 is deduced to be signed int.
+ // FIXME: Insert the necessary explicit conversion, or write out the types
+ // explicitly.
+ for (int I = 0; I < Pconstv->size(); ++I) {
+ printf("Fibonacci number is %d\n", (*Pconstv).at(I).X);
+ Sum += (*Pconstv)[I].X + 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (const auto & I : *Pconstv)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X);
+ // CHECK-FIXES-NEXT: Sum += I.X + 2;
+}
+
+void constRef(const dependent<int>& ConstVRef) {
+ int sum = 0;
+ // FIXME: This does not work with size_t (probably due to the implementation
+ // of dependent); make dependent work exactly like a std container type.
+ for (int I = 0; I < ConstVRef.size(); ++I) {
+ sum += ConstVRef[I];
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : ConstVRef)
+ // CHECK-FIXES-NEXT: sum += I;
+
+ for (auto I = ConstVRef.begin(), E = ConstVRef.end(); I != E; ++I) {
+ sum += *I;
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : ConstVRef)
+ // CHECK-FIXES-NEXT: sum += I;
+}
+
+// Check for loops that don't mention containers.
+void noContainer() {
+ for (auto I = 0; I < V.size(); ++I) {
+ }
+
+ for (auto I = 0; I < V.size(); ++I)
+ ;
+}
+
+struct NoBeginEnd {
+ unsigned size() const;
+ unsigned& operator[](int);
+ const unsigned& operator[](int) const;
+};
+
+struct NoConstBeginEnd {
+ NoConstBeginEnd();
+ unsigned size() const;
+ unsigned* begin();
+ unsigned* end();
+ unsigned& operator[](int);
+ const unsigned& operator[](int) const;
+};
+
+struct ConstBeginEnd {
+ ConstBeginEnd();
+ unsigned size() const;
+ unsigned* begin() const;
+ unsigned* end() const;
+ unsigned& operator[](int);
+ const unsigned& operator[](int) const;
+};
+
+// Shouldn't transform pseudo-array uses if the container doesn't provide
+// begin() and end() of the right const-ness.
+void NoBeginEndTest() {
+ NoBeginEnd NBE;
+ for (unsigned I = 0, E = NBE.size(); I < E; ++I)
+ printf("%d\n", NBE[I]);
+
+ const NoConstBeginEnd Const_NCBE;
+ for (unsigned I = 0, E = Const_NCBE.size(); I < E; ++I)
+ printf("%d\n", Const_NCBE[I]);
+
+ ConstBeginEnd CBE;
+ for (unsigned I = 0, E = CBE.size(); I < E; ++I)
+ printf("%d\n", CBE[I]);
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (unsigned int I : CBE)
+ // CHECK-FIXES-NEXT: printf("%d\n", I);
+
+ const ConstBeginEnd Const_CBE;
+ for (unsigned I = 0, E = Const_CBE.size(); I < E; ++I)
+ printf("%d\n", Const_CBE[I]);
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (unsigned int I : Const_CBE)
+ // CHECK-FIXES-NEXT: printf("%d\n", I);
+}
+
+struct DerefByValue {
+ DerefByValue();
+ struct iter { unsigned operator*(); };
+ unsigned size() const;
+ iter begin();
+ iter end();
+ unsigned operator[](int);
+};
+
+void derefByValueTest() {
+ DerefByValue DBV;
+ for (unsigned I = 0, E = DBV.size(); I < E; ++I) {
+ printf("%d\n", DBV[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (unsigned int I : DBV)
+ // CHECK-FIXES-NEXT: printf("%d\n", I);
+
+ for (unsigned I = 0, E = DBV.size(); I < E; ++I) {
+ auto f = [DBV, I]() {};
+ printf("%d\n", DBV[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (unsigned int I : DBV)
+ // CHECK-FIXES-NEXT: auto f = [DBV, &I]() {};
+ // CHECK-FIXES-NEXT: printf("%d\n", I);
+}
+
+void fundamentalTypesTest() {
+ const int N = 10;
+ bool Bools[N];
+ for (int i = 0; i < N; ++i)
+ printf("%d", Bools[i]);
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (bool Bool : Bools)
+
+ int Ints[N];
+ unsigned short int Shorts[N];
+ for (int i = 0; i < N; ++i)
+ printf("%d", Shorts[i]);
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (unsigned short Short : Shorts)
+
+ signed long Longs[N];
+ for (int i = 0; i < N; ++i)
+ printf("%d", Longs[i]);
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (long Long : Longs)
+
+ long long int LongLongs[N];
+ for (int i = 0; i < N; ++i)
+ printf("%d", LongLongs[i]);
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (long long LongLong : LongLongs)
+
+ char Chars[N];
+ for (int i = 0; i < N; ++i)
+ printf("%d", Chars[i]);
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (char Char : Chars)
+
+ wchar_t WChars[N];
+ for (int i = 0; i < N; ++i)
+ printf("%d", WChars[i]);
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (wchar_t WChar : WChars)
+
+ float Floats[N];
+ for (int i = 0; i < N; ++i)
+ printf("%d", Floats[i]);
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (float Float : Floats)
+
+ double Doubles[N];
+ for (int i = 0; i < N; ++i)
+ printf("%d", Doubles[i]);
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (double Double : Doubles)
+}
+
+} // namespace PseudoArray
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-camelback.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-camelback.cpp
new file mode 100644
index 0000000..50044de
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-camelback.cpp
@@ -0,0 +1,33 @@
+// RUN: %check_clang_tidy %s modernize-loop-convert %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-loop-convert.NamingStyle, value: 'camelBack'}]}" \
+// RUN: -- -std=c++11 -I %S/Inputs/modernize-loop-convert
+
+#include "structures.h"
+
+const int n = 10;
+int arr[n];
+int nums[n];
+
+void naming() {
+ for (int i = 0; i < n; ++i) {
+ printf("%d\n", arr[i]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
+ // CHECK-FIXES: for (int i : arr)
+ // CHECK-FIXES-NEXT: printf("%d\n", i);
+
+ for (int i = 0; i < n; ++i) {
+ printf("%d\n", nums[i]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int num : nums)
+ // CHECK-FIXES-NEXT: printf("%d\n", num);
+
+ int num = 0;
+ for (int i = 0; i < n; ++i) {
+ printf("%d\n", nums[i] + num);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int i : nums)
+ // CHECK-FIXES-NEXT: printf("%d\n", i + num);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-const.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-const.cpp
new file mode 100644
index 0000000..806b6c1
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-const.cpp
@@ -0,0 +1,360 @@
+// RUN: %check_clang_tidy %s modernize-loop-convert %t -- -- -std=c++11
+
+struct Str {
+ Str() = default;
+ Str(const Str &) = default;
+ void constMember(int) const;
+ void nonConstMember(int);
+ bool operator<(const Str &str) const; // const operator.
+ Str &operator=(const Str &str) = default; // non const operator.
+};
+
+// This class is non-trivially copyable because the copy-constructor and copy
+// assignment take non-const references.
+struct ModifiesRightSide {
+ ModifiesRightSide() = default;
+ ModifiesRightSide(ModifiesRightSide &) = default;
+ bool operator<(ModifiesRightSide &) const;
+ ModifiesRightSide &operator=(ModifiesRightSide &) = default;
+};
+
+template <typename T>
+void copyArg(T);
+
+template <typename T>
+void nonConstRefArg(T &);
+
+// If we define this as a template, the type is deduced to "T&",
+// and "const (T&) &" is the same as "T& &", and this collapses to "T&".
+void constRefArg(const Str &);
+void constRefArg(const ModifiesRightSide &);
+void constRefArg(const int &);
+
+void foo();
+
+const int N = 10;
+Str Array[N], OtherStr;
+ModifiesRightSide Right[N], OtherRight;
+int Ints[N], OtherInt;
+
+void memberFunctionsAndOperators() {
+ // Calling const member functions or operator is a const usage.
+ for (int I = 0; I < N; ++I) {
+ Array[I].constMember(0);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
+ // CHECK-FIXES: for (auto I : Array)
+ // CHECK-FIXES-NEXT: I.constMember(0);
+
+ for (int I = 0; I < N; ++I) {
+ if (Array[I] < OtherStr)
+ foo();
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (auto I : Array)
+ // CHECK-FIXES-NEXT: if (I < OtherStr)
+ for (int I = 0; I < N; ++I) {
+ if (Right[I] < OtherRight)
+ foo();
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (const auto & I : Right)
+ // CHECK-FIXES-NEXT: if (I < OtherRight)
+
+ // Calling non-const member functions is not.
+ for (int I = 0; I < N; ++I) {
+ Array[I].nonConstMember(0);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (auto & I : Array)
+ // CHECK-FIXES-NEXT: I.nonConstMember(0);
+
+ for (int I = 0; I < N; ++I) {
+ Array[I] = OtherStr;
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (auto & I : Array)
+ // CHECK-FIXES-NEXT: I = OtherStr;
+
+ for (int I = 0; I < N; ++I) {
+ Right[I] = OtherRight;
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (auto & I : Right)
+ // CHECK-FIXES-NEXT: I = OtherRight;
+}
+
+void usedAsParameterToFunctionOrOperator() {
+ // Copying is OK, as long as the copy constructor takes a const-reference.
+ for (int I = 0; I < N; ++I) {
+ copyArg(Array[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (auto I : Array)
+ // CHECK-FIXES-NEXT: copyArg(I);
+
+ for (int I = 0; I < N; ++I) {
+ copyArg(Right[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (auto & I : Right)
+ // CHECK-FIXES-NEXT: copyArg(I);
+
+ // Using as a const reference argument is allowed.
+ for (int I = 0; I < N; ++I) {
+ constRefArg(Array[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (auto I : Array)
+ // CHECK-FIXES-NEXT: constRefArg(I);
+
+ for (int I = 0; I < N; ++I) {
+ if (OtherStr < Array[I])
+ foo();
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (auto I : Array)
+ // CHECK-FIXES-NEXT: if (OtherStr < I)
+
+ for (int I = 0; I < N; ++I) {
+ constRefArg(Right[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (const auto & I : Right)
+ // CHECK-FIXES-NEXT: constRefArg(I);
+
+ // Using as a non-const reference is not.
+ for (int I = 0; I < N; ++I) {
+ nonConstRefArg(Array[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (auto & I : Array)
+ // CHECK-FIXES-NEXT: nonConstRefArg(I);
+ for (int I = 0; I < N; ++I) {
+ nonConstRefArg(Right[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (auto & I : Right)
+ // CHECK-FIXES-NEXT: nonConstRefArg(I);
+ for (int I = 0; I < N; ++I) {
+ if (OtherRight < Right[I])
+ foo();
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (auto & I : Right)
+ // CHECK-FIXES-NEXT: if (OtherRight < I)
+}
+
+void primitiveTypes() {
+ // As argument to a function.
+ for (int I = 0; I < N; ++I) {
+ copyArg(Ints[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES-NEXT: copyArg(Int);
+ for (int I = 0; I < N; ++I) {
+ constRefArg(Ints[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES-NEXT: constRefArg(Int);
+ for (int I = 0; I < N; ++I) {
+ nonConstRefArg(Ints[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (int & Int : Ints)
+ // CHECK-FIXES-NEXT: nonConstRefArg(Int);
+
+ // Builtin operators.
+ // Comparisons.
+ for (int I = 0; I < N; ++I) {
+ if (Ints[I] < N)
+ foo();
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES-NEXT: if (Int < N)
+
+ for (int I = 0; I < N; ++I) {
+ if (N == Ints[I])
+ foo();
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES-NEXT: if (N == Int)
+
+ // Assignment.
+ for (int I = 0; I < N; ++I) {
+ Ints[I] = OtherInt;
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (int & Int : Ints)
+ // CHECK-FIXES-NEXT: Int = OtherInt;
+
+ for (int I = 0; I < N; ++I) {
+ OtherInt = Ints[I];
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES-NEXT: OtherInt = Int;
+
+ for (int I = 0; I < N; ++I) {
+ OtherInt = Ints[I] = OtherInt;
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (int & Int : Ints)
+ // CHECK-FIXES-NEXT: OtherInt = Int = OtherInt;
+
+ // Arithmetic operations.
+ for (int I = 0; I < N; ++I) {
+ OtherInt += Ints[I];
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES-NEXT: OtherInt += Int;
+
+ for (int I = 0; I < N; ++I) {
+ Ints[I] += Ints[I];
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (int & Int : Ints)
+ // CHECK-FIXES-NEXT: Int += Int;
+
+ for (int I = 0; I < N; ++I) {
+ int Res = 5 * (Ints[I] + 1) - Ints[I];
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES-NEXT: int Res = 5 * (Int + 1) - Int;
+}
+
+void takingReferences() {
+ // We do it twice to prevent the check from thinking that they are aliases.
+
+ // Class type.
+ for (int I = 0; I < N; ++I) {
+ Str &J = Array[I];
+ Str &K = Array[I];
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (auto & I : Array)
+ // CHECK-FIXES-NEXT: Str &J = I;
+ // CHECK-FIXES-NEXT: Str &K = I;
+ for (int I = 0; I < N; ++I) {
+ const Str &J = Array[I];
+ const Str &K = Array[I];
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (auto I : Array)
+ // CHECK-FIXES-NEXT: const Str &J = I;
+ // CHECK-FIXES-NEXT: const Str &K = I;
+
+ // Primitive type.
+ for (int I = 0; I < N; ++I) {
+ int &J = Ints[I];
+ int &K = Ints[I];
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (int & Int : Ints)
+ // CHECK-FIXES-NEXT: int &J = Int;
+ // CHECK-FIXES-NEXT: int &K = Int;
+ for (int I = 0; I < N; ++I) {
+ const int &J = Ints[I];
+ const int &K = Ints[I];
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES-NEXT: const int &J = Int;
+ // CHECK-FIXES-NEXT: const int &K = Int;
+
+ // Aliases.
+ for (int I = 0; I < N; ++I) {
+ const Str &J = Array[I];
+ (void)J;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (auto J : Array)
+ for (int I = 0; I < N; ++I) {
+ Str &J = Array[I];
+ (void)J;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (auto & J : Array)
+
+ for (int I = 0; I < N; ++I) {
+ const int &J = Ints[I];
+ (void)J;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (int J : Ints)
+
+ for (int I = 0; I < N; ++I) {
+ int &J = Ints[I];
+ (void)J;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (int & J : Ints)
+}
+
+template <class T>
+struct vector {
+ unsigned size() const;
+ const T &operator[](int) const;
+ T &operator[](int);
+ T *begin();
+ T *end();
+ const T *begin() const;
+ const T *end() const;
+};
+
+// If the elements are already constant, we won't do any ImplicitCast to const.
+void testContainerOfConstIents() {
+ const int Ints[N]{};
+ for (int I = 0; I < N; ++I) {
+ OtherInt -= Ints[I];
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (int Int : Ints)
+
+ vector<const Str> Strs;
+ for (int I = 0; I < Strs.size(); ++I) {
+ Strs[I].constMember(0);
+ constRefArg(Strs[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+ // CHECK-FIXES: for (auto Str : Strs)
+}
+
+// When we are inside a const-qualified member functions, all the data members
+// are implicitly set as const. As before, there won't be any ImplicitCast to
+// const in their usages.
+class TestInsideConstFunction {
+ const static int N = 10;
+ int Ints[N];
+ Str Array[N];
+ vector<int> V;
+
+ void foo() const {
+ for (int I = 0; I < N; ++I) {
+ if (Ints[I])
+ copyArg(Ints[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop
+ // CHECK-FIXES: for (int Int : Ints)
+
+ for (int I = 0; I < N; ++I) {
+ Array[I].constMember(0);
+ constRefArg(Array[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop
+ // CHECK-FIXES: for (auto I : Array)
+
+ for (int I = 0; I < V.size(); ++I) {
+ if (V[I])
+ copyArg(V[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop
+ // CHECK-FIXES: for (int I : V)
+ }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-extra.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-extra.cpp
new file mode 100644
index 0000000..b46ff25
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-extra.cpp
@@ -0,0 +1,1074 @@
+// RUN: %check_clang_tidy %s modernize-loop-convert %t -- -- -std=c++11 -I %S/Inputs/modernize-loop-convert
+
+#include "structures.h"
+
+namespace Dependency {
+
+void f() {
+ const int N = 6;
+ const int M = 8;
+ int Arr[N][M];
+
+ for (int I = 0; I < N; ++I) {
+ int A = 0;
+ int B = Arr[I][A];
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : Arr)
+ // CHECK-FIXES-NEXT: int A = 0;
+ // CHECK-FIXES-NEXT: int B = I[A];
+
+ for (int J = 0; J < M; ++J) {
+ int A = 0;
+ int B = Arr[A][J];
+ }
+}
+
+} // namespace Dependency
+
+namespace NamingAlias {
+
+const int N = 10;
+
+Val Arr[N];
+dependent<Val> V;
+dependent<Val> *Pv;
+Val &func(Val &);
+void sideEffect(int);
+
+void aliasing() {
+ // If the loop container is only used for a declaration of a temporary
+ // variable to hold each element, we can name the new variable for the
+ // converted range-based loop as the temporary variable's name.
+
+ // In the following case, "T" is used as a temporary variable to hold each
+ // element, and thus we consider the name "T" aliased to the loop.
+ // The extra blank braces are left as a placeholder for after the variable
+ // declaration is deleted.
+ for (int I = 0; I < N; ++I) {
+ Val &T = Arr[I];
+ {}
+ int Y = T.X;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & T : Arr)
+ // CHECK-FIXES-NOT: Val &{{[a-z_]+}} =
+ // CHECK-FIXES-NEXT: {}
+ // CHECK-FIXES-NEXT: int Y = T.X;
+
+ // The container was not only used to initialize a temporary loop variable for
+ // the container's elements, so we do not alias the new loop variable.
+ for (int I = 0; I < N; ++I) {
+ Val &T = Arr[I];
+ int Y = T.X;
+ int Z = Arr[I].X + T.X;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : Arr)
+ // CHECK-FIXES-NEXT: Val &T = I;
+ // CHECK-FIXES-NEXT: int Y = T.X;
+ // CHECK-FIXES-NEXT: int Z = I.X + T.X;
+
+ for (int I = 0; I < N; ++I) {
+ Val T = Arr[I];
+ int Y = T.X;
+ int Z = Arr[I].X + T.X;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : Arr)
+ // CHECK-FIXES-NEXT: Val T = I;
+ // CHECK-FIXES-NEXT: int Y = T.X;
+ // CHECK-FIXES-NEXT: int Z = I.X + T.X;
+
+ // The same for pseudo-arrays like std::vector<T> (or here dependent<Val>)
+ // which provide a subscript operator[].
+ for (int I = 0; I < V.size(); ++I) {
+ Val &T = V[I];
+ {}
+ int Y = T.X;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & T : V)
+ // CHECK-FIXES-NEXT: {}
+ // CHECK-FIXES-NEXT: int Y = T.X;
+
+ // The same with a call to at()
+ for (int I = 0; I < Pv->size(); ++I) {
+ Val &T = Pv->at(I);
+ {}
+ int Y = T.X;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & T : *Pv)
+ // CHECK-FIXES-NEXT: {}
+ // CHECK-FIXES-NEXT: int Y = T.X;
+
+ for (int I = 0; I < N; ++I) {
+ Val &T = func(Arr[I]);
+ int Y = T.X;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : Arr)
+ // CHECK-FIXES-NEXT: Val &T = func(I);
+ // CHECK-FIXES-NEXT: int Y = T.X;
+
+ int IntArr[N];
+ for (unsigned I = 0; I < N; ++I) {
+ if (int Alias = IntArr[I]) {
+ sideEffect(Alias);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int Alias : IntArr)
+ // CHECK-FIXES-NEXT: if (Alias)
+
+ for (unsigned I = 0; I < N; ++I) {
+ while (int Alias = IntArr[I]) {
+ sideEffect(Alias);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int Alias : IntArr)
+ // CHECK-FIXES-NEXT: while (Alias)
+
+ for (unsigned I = 0; I < N; ++I) {
+ switch (int Alias = IntArr[I]) {
+ default:
+ sideEffect(Alias);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int Alias : IntArr)
+ // CHECK-FIXES-NEXT: switch (Alias)
+
+ for (unsigned I = 0; I < N; ++I) {
+ for (int Alias = IntArr[I]; Alias < N; ++Alias) {
+ sideEffect(Alias);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int Alias : IntArr)
+ // CHECK-FIXES-NEXT: for (; Alias < N; ++Alias)
+
+ for (unsigned I = 0; I < N; ++I) {
+ for (unsigned J = 0; int Alias = IntArr[I]; ++J) {
+ sideEffect(Alias);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int Alias : IntArr)
+ // CHECK-FIXES-NEXT: for (unsigned J = 0; Alias; ++J)
+
+ struct IntRef { IntRef(); IntRef(const int& i); operator int*(); };
+ for (int I = 0; I < N; ++I) {
+ IntRef Int(IntArr[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : IntArr)
+ // CHECK-FIXES-NEXT: IntRef Int(I);
+
+ int *PtrArr[N];
+ for (unsigned I = 0; I < N; ++I) {
+ const int* const P = PtrArr[I];
+ printf("%d\n", *P);
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto P : PtrArr)
+ // CHECK-FIXES-NEXT: printf("%d\n", *P);
+
+ IntRef Refs[N];
+ for (unsigned I = 0; I < N; ++I) {
+ int *P = Refs[I];
+ printf("%d\n", *P);
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & Ref : Refs)
+ // CHECK-FIXES-NEXT: int *P = Ref;
+ // CHECK-FIXES-NEXT: printf("%d\n", *P);
+
+ // Ensure that removing the alias doesn't leave empty lines behind.
+ for (int I = 0; I < N; ++I) {
+ auto &X = IntArr[I];
+ X = 0;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & X : IntArr) {
+ // CHECK-FIXES-NEXT: {{^ X = 0;$}}
+ // CHECK-FIXES-NEXT: {{^ }$}}
+}
+
+void refs_and_vals() {
+ // The following tests check that the transform correctly preserves the
+ // reference or value qualifiers of the aliased variable. That is, if the
+ // variable was declared as a value, the loop variable will be declared as a
+ // value and vice versa for references.
+
+ S Ss;
+ const S S_const = Ss;
+
+ for (S::const_iterator It = S_const.begin(); It != S_const.end(); ++It) {
+ MutableVal Alias = *It;
+ {}
+ Alias.X = 0;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto Alias : S_const)
+ // CHECK-FIXES-NOT: MutableVal {{[a-z_]+}} =
+ // CHECK-FIXES-NEXT: {}
+ // CHECK-FIXES-NEXT: Alias.X = 0;
+
+ for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
+ MutableVal Alias = *It;
+ {}
+ Alias.X = 0;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto Alias : Ss)
+ // CHECK-FIXES-NOT: MutableVal {{[a-z_]+}} =
+ // CHECK-FIXES-NEXT: {}
+ // CHECK-FIXES-NEXT: Alias.X = 0;
+
+ for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
+ MutableVal &Alias = *It;
+ {}
+ Alias.X = 0;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & Alias : Ss)
+ // CHECK-FIXES-NOT: MutableVal &{{[a-z_]+}} =
+ // CHECK-FIXES-NEXT: {}
+ // CHECK-FIXES-NEXT: Alias.X = 0;
+
+ dependent<int> Dep, Other;
+ for (dependent<int>::iterator It = Dep.begin(), E = Dep.end(); It != E; ++It) {
+ printf("%d\n", *It);
+ const int& Idx = Other[0];
+ unsigned Othersize = Other.size();
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & It : Dep)
+ // CHECK-FIXES-NEXT: printf("%d\n", It);
+ // CHECK-FIXES-NEXT: const int& Idx = Other[0];
+ // CHECK-FIXES-NEXT: unsigned Othersize = Other.size();
+
+ for (int i = 0; i < Other.size(); ++i) {
+ Other.at(i);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & i : Other)
+ // CHECK-FIXES: i;
+
+ for (int I = 0, E = Dep.size(); I != E; ++I) {
+ int Idx = Other.at(I);
+ Other.at(I, I); // Should not trigger assert failure.
+ }
+}
+
+struct MemberNaming {
+ const static int N = 10;
+ int Ints[N], Ints_[N];
+ dependent<int> DInts;
+ void loops() {
+ for (int I = 0; I < N; ++I) {
+ printf("%d\n", Ints[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES-NEXT: printf("%d\n", Int);
+
+ for (int I = 0; I < N; ++I) {
+ printf("%d\n", Ints_[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int Int : Ints_)
+ // CHECK-FIXES-NEXT: printf("%d\n", Int);
+
+ for (int I = 0; I < DInts.size(); ++I) {
+ printf("%d\n", DInts[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int DInt : DInts)
+ // CHECK-FIXES-NEXT: printf("%d\n", DInt);
+ }
+
+ void outOfLine();
+};
+void MemberNaming::outOfLine() {
+ for (int I = 0; I < N; ++I) {
+ printf("%d\n", Ints[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES-NEXT: printf("%d\n", Int);
+
+ for (int I = 0; I < N; ++I) {
+ printf("%d\n", Ints_[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int Int : Ints_)
+ // CHECK-FIXES-NEXT: printf("%d\n", Int);
+}
+
+} // namespace NamingAlias
+
+namespace NamingConlict {
+
+#define MAX(a, b) (a > b) ? a : b
+#define DEF 5
+
+const int N = 10;
+int Nums[N];
+int Sum = 0;
+
+namespace ns {
+struct St {
+ int X;
+};
+}
+
+void sameNames() {
+ int Num = 0;
+ for (int I = 0; I < N; ++I) {
+ printf("Fibonacci number is %d\n", Nums[I]);
+ Sum += Nums[I] + 2 + Num;
+ (void)Nums[I];
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & I : Nums)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+ // CHECK-FIXES-NEXT: Sum += I + 2 + Num;
+ // CHECK-FIXES-NEXT: (void)I;
+
+ int Elem = 0;
+ for (int I = 0; I < N; ++I) {
+ printf("Fibonacci number is %d\n", Nums[I]);
+ Sum += Nums[I] + 2 + Num + Elem;
+ (void)Nums[I];
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & I : Nums)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+ // CHECK-FIXES-NEXT: Sum += I + 2 + Num + Elem;
+ // CHECK-FIXES-NEXT: (void)I;
+}
+
+void oldIndexConflict() {
+ for (int Num = 0; Num < N; ++Num) {
+ printf("Num: %d\n", Nums[Num]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int Num : Nums)
+ // CHECK-FIXES-NEXT: printf("Num: %d\n", Num);
+
+ S Things;
+ for (S::iterator Thing = Things.begin(), End = Things.end(); Thing != End; ++Thing) {
+ printf("Thing: %d %d\n", Thing->X, (*Thing).X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & Thing : Things)
+ // CHECK-FIXES-NEXT: printf("Thing: %d %d\n", Thing.X, Thing.X);
+}
+
+void macroConflict() {
+ S MAXs;
+ for (S::iterator It = MAXs.begin(), E = MAXs.end(); It != E; ++It) {
+ printf("s has value %d\n", (*It).X);
+ printf("Max of 3 and 5: %d\n", MAX(3, 5));
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & It : MAXs)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+ // CHECK-FIXES-NEXT: printf("Max of 3 and 5: %d\n", MAX(3, 5));
+
+ for (S::const_iterator It = MAXs.begin(), E = MAXs.end(); It != E; ++It) {
+ printf("s has value %d\n", (*It).X);
+ printf("Max of 3 and 5: %d\n", MAX(3, 5));
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto It : MAXs)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+ // CHECK-FIXES-NEXT: printf("Max of 3 and 5: %d\n", MAX(3, 5));
+
+ T DEFs;
+ for (T::iterator It = DEFs.begin(), E = DEFs.end(); It != E; ++It) {
+ if (*It == DEF) {
+ printf("I found %d\n", *It);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & It : DEFs)
+ // CHECK-FIXES-NEXT: if (It == DEF)
+ // CHECK-FIXES-NEXT: printf("I found %d\n", It);
+}
+
+void keywordConflict() {
+ T ints;
+ for (T::iterator It = ints.begin(), E = ints.end(); It != E; ++It) {
+ *It = 5;
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & It : ints)
+ // CHECK-FIXES-NEXT: It = 5;
+
+ U __FUNCTION__s;
+ for (U::iterator It = __FUNCTION__s.begin(), E = __FUNCTION__s.end();
+ It != E; ++It) {
+ int __FUNCTION__s_It = (*It).X + 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & It : __FUNCTION__s)
+ // CHECK-FIXES-NEXT: int __FUNCTION__s_It = It.X + 2;
+}
+
+void typeConflict() {
+ T Vals;
+ // Using the name "Val", although it is the name of an existing struct, is
+ // safe in this loop since it will only exist within this scope.
+ for (T::iterator It = Vals.begin(), E = Vals.end(); It != E; ++It)
+ (void) *It;
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & Val : Vals)
+
+ // We cannot use the name "Val" in this loop since there is a reference to
+ // it in the body of the loop.
+ for (T::iterator It = Vals.begin(), E = Vals.end(); It != E; ++It) {
+ *It = sizeof(Val);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & It : Vals)
+ // CHECK-FIXES-NEXT: It = sizeof(Val);
+
+ typedef struct Val TD;
+ U TDs;
+ // Naming the variable "TD" within this loop is safe because the typedef
+ // was never used within the loop.
+ for (U::iterator It = TDs.begin(), E = TDs.end(); It != E; ++It)
+ (void) *It;
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & TD : TDs)
+
+ // "TD" cannot be used in this loop since the typedef is being used.
+ for (U::iterator It = TDs.begin(), E = TDs.end(); It != E; ++It) {
+ TD V;
+ V.X = 5;
+ (void) *It;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & It : TDs)
+ // CHECK-FIXES-NEXT: TD V;
+ // CHECK-FIXES-NEXT: V.X = 5;
+
+ using ns::St;
+ T Sts;
+ for (T::iterator It = Sts.begin(), E = Sts.end(); It != E; ++It) {
+ *It = sizeof(St);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & It : Sts)
+ // CHECK-FIXES-NEXT: It = sizeof(St);
+}
+
+} // namespace NamingConflict
+
+namespace FreeBeginEnd {
+
+// FIXME: Loop Convert should detect free begin()/end() functions.
+
+struct MyArray {
+ unsigned size();
+};
+
+template <typename T>
+struct MyContainer {
+};
+
+int *begin(const MyArray &Arr);
+int *end(const MyArray &Arr);
+
+template <typename T>
+T *begin(const MyContainer<T> &C);
+template <typename T>
+T *end(const MyContainer<T> &C);
+
+// The Loop Convert Transform doesn't detect free functions begin()/end() and
+// so fails to transform these cases which it should.
+void f() {
+ MyArray Arr;
+ for (unsigned I = 0, E = Arr.size(); I < E; ++I) {
+ }
+
+ MyContainer<int> C;
+ for (int *I = begin(C), *E = end(C); I != E; ++I) {
+ }
+}
+
+} // namespace FreeBeginEnd
+
+namespace Nesting {
+
+void g(S::iterator It);
+void const_g(S::const_iterator It);
+class Foo {
+ public:
+ void g(S::iterator It);
+ void const_g(S::const_iterator It);
+};
+
+void f() {
+ const int N = 10;
+ const int M = 15;
+ Val Arr[N];
+ for (int I = 0; I < N; ++I) {
+ for (int J = 0; J < N; ++J) {
+ int K = Arr[I].X + Arr[J].X;
+ // The repeat is there to allow FileCheck to make sure the two variable
+ // names aren't the same.
+ int L = Arr[I].X + Arr[J].X;
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-8]]:3: warning: use range-based for loop instead
+ // CHECK-MESSAGES: :[[@LINE-8]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : Arr)
+ // CHECK-FIXES-NEXT: for (auto & J : Arr)
+ // CHECK-FIXES-NEXT: int K = I.X + J.X;
+ // CHECK-FIXES-NOT: int L = I.X + I.X;
+
+ // The inner loop is also convertible, but doesn't need to be converted
+ // immediately. FIXME: update this test when that changes.
+ Val Nest[N][M];
+ for (int I = 0; I < N; ++I) {
+ for (int J = 0; J < M; ++J) {
+ printf("Got item %d", Nest[I][J].X);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : Nest)
+ // CHECK-FIXES-NEXT: for (int J = 0; J < M; ++J)
+ // CHECK-FIXES-NEXT: printf("Got item %d", I[J].X);
+
+ // Note that the order of M and N are switched for this test.
+ for (int J = 0; J < M; ++J) {
+ for (int I = 0; I < N; ++I) {
+ printf("Got item %d", Nest[I][J].X);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES-NOT: for (auto & {{[a-zA-Z_]+}} : Nest[I])
+ // CHECK-FIXES: for (int J = 0; J < M; ++J)
+ // CHECK-FIXES-NEXT: for (auto & I : Nest)
+ // CHECK-FIXES-NEXT: printf("Got item %d", I[J].X);
+
+ // The inner loop is also convertible.
+ Nested<T> NestT;
+ for (Nested<T>::iterator I = NestT.begin(), E = NestT.end(); I != E; ++I) {
+ for (T::iterator TI = (*I).begin(), TE = (*I).end(); TI != TE; ++TI) {
+ printf("%d", *TI);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : NestT)
+ // CHECK-FIXES-NEXT: for (T::iterator TI = I.begin(), TE = I.end(); TI != TE; ++TI)
+ // CHECK-FIXES-NEXT: printf("%d", *TI);
+
+ // The inner loop is also convertible.
+ Nested<S> NestS;
+ for (Nested<S>::const_iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
+ for (S::const_iterator SI = (*I).begin(), SE = (*I).end(); SI != SE; ++SI) {
+ printf("%d", *SI);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto I : NestS)
+ // CHECK-FIXES-NEXT: for (S::const_iterator SI = I.begin(), SE = I.end(); SI != SE; ++SI)
+ // CHECK-FIXES-NEXT: printf("%d", *SI);
+
+ for (Nested<S>::const_iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
+ const S &Ss = *I;
+ for (S::const_iterator SI = Ss.begin(), SE = Ss.end(); SI != SE; ++SI) {
+ printf("%d", *SI);
+ const_g(SI);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto Ss : NestS)
+
+ for (Nested<S>::iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
+ S &Ss = *I;
+ for (S::iterator SI = Ss.begin(), SE = Ss.end(); SI != SE; ++SI) {
+ printf("%d", *SI);
+ g(SI);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & Ss : NestS)
+
+ Foo foo;
+ for (Nested<S>::const_iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
+ const S &Ss = *I;
+ for (S::const_iterator SI = Ss.begin(), SE = Ss.end(); SI != SE; ++SI) {
+ printf("%d", *SI);
+ foo.const_g(SI);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto Ss : NestS)
+
+ for (Nested<S>::iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
+ S &Ss = *I;
+ for (S::iterator SI = Ss.begin(), SE = Ss.end(); SI != SE; ++SI) {
+ printf("%d", *SI);
+ foo.g(SI);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & Ss : NestS)
+
+}
+
+} // namespace Nesting
+
+namespace SingleIterator {
+
+void complexContainer() {
+ X Exes[5];
+ int Index = 0;
+
+ for (S::iterator I = Exes[Index].getS().begin(), E = Exes[Index].getS().end(); I != E; ++I) {
+ MutableVal K = *I;
+ MutableVal J = *I;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : Exes[Index].getS())
+ // CHECK-FIXES-NEXT: MutableVal K = I;
+ // CHECK-FIXES-NEXT: MutableVal J = I;
+}
+
+void f() {
+ /// begin()/end() - based for loops here:
+ T Tt;
+ for (T::iterator It = Tt.begin(); It != Tt.end(); ++It) {
+ printf("I found %d\n", *It);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & It : Tt)
+ // CHECK-FIXES-NEXT: printf("I found %d\n", It);
+
+ T *Pt;
+ for (T::iterator It = Pt->begin(); It != Pt->end(); ++It) {
+ printf("I found %d\n", *It);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & It : *Pt)
+ // CHECK-FIXES-NEXT: printf("I found %d\n", It);
+
+ S Ss;
+ for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
+ printf("s has value %d\n", (*It).X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+ S *Ps;
+ for (S::iterator It = Ps->begin(); It != Ps->end(); ++It) {
+ printf("s has value %d\n", (*It).X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & P : *Ps)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);
+
+ for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
+ printf("s has value %d\n", It->X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+ for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
+ It->X = 3;
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES-NEXT: It.X = 3;
+
+ for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
+ (*It).X = 3;
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES-NEXT: It.X = 3;
+
+ for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
+ It->nonConstFun(4, 5);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES-NEXT: It.nonConstFun(4, 5);
+
+ U Uu;
+ for (U::iterator It = Uu.begin(); It != Uu.end(); ++It) {
+ printf("s has value %d\n", It->X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & It : Uu)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+ for (U::iterator It = Uu.begin(); It != Uu.end(); ++It) {
+ printf("s has value %d\n", (*It).X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & It : Uu)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+ U::iterator A;
+ for (U::iterator I = Uu.begin(); I != Uu.end(); ++I)
+ int K = A->X + I->X;
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & I : Uu)
+ // CHECK-FIXES-NEXT: int K = A->X + I.X;
+
+ dependent<int> V;
+ for (dependent<int>::iterator It = V.begin();
+ It != V.end(); ++It) {
+ printf("Fibonacci number is %d\n", *It);
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & It : V)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
+
+ for (dependent<int>::iterator It(V.begin());
+ It != V.end(); ++It) {
+ printf("Fibonacci number is %d\n", *It);
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & It : V)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
+
+ doublyDependent<int, int> intmap;
+ for (doublyDependent<int, int>::iterator It = intmap.begin();
+ It != intmap.end(); ++It) {
+ printf("intmap[%d] = %d", It->first, It->second);
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & It : intmap)
+ // CHECK-FIXES-NEXT: printf("intmap[%d] = %d", It.first, It.second);
+}
+
+void different_type() {
+ // Tests to verify the proper use of auto where the init variable type and the
+ // initializer type differ or are mostly the same except for const qualifiers.
+
+ // Ss.begin() returns a type 'iterator' which is just a non-const pointer and
+ // differs from const_iterator only on the const qualification.
+ S Ss;
+ for (S::const_iterator It = Ss.begin(); It != Ss.end(); ++It) {
+ printf("s has value %d\n", (*It).X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto It : Ss)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+ S *Ps;
+ for (S::const_iterator It = Ps->begin(); It != Ps->end(); ++It) {
+ printf("s has value %d\n", (*It).X);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto P : *Ps)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);
+
+ // V.begin() returns a user-defined type 'iterator' which, since it's
+ // different from const_iterator, disqualifies these loops from
+ // transformation.
+ dependent<int> V;
+ for (dependent<int>::const_iterator It = V.begin(); It != V.end(); ++It) {
+ printf("Fibonacci number is %d\n", *It);
+ }
+
+ for (dependent<int>::const_iterator It(V.begin()); It != V.end(); ++It) {
+ printf("Fibonacci number is %d\n", *It);
+ }
+}
+
+} // namespace SingleIterator
+
+
+namespace Macros {
+
+#define TWO_PARAM(x, y) if (x == y) {}
+#define THREE_PARAM(x, y, z) if (x == y) {z;}
+
+const int N = 10;
+int Arr[N];
+
+void messing_with_macros() {
+ for (int I = 0; I < N; ++I) {
+ printf("Value: %d\n", Arr[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES-NEXT: printf("Value: %d\n", I);
+
+ for (int I = 0; I < N; ++I) {
+ printf("Value: %d\n", CONT Arr[I]);
+ }
+
+ // Multiple macro arguments.
+ for (int I = 0; I < N; ++I) {
+ TWO_PARAM(Arr[I], Arr[I]);
+ THREE_PARAM(Arr[I], Arr[I], Arr[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & I : Arr)
+ // CHECK-FIXES-NEXT: TWO_PARAM(I, I);
+ // CHECK-FIXES-NEXT: THREE_PARAM(I, I, I);
+}
+
+} // namespace Macros
+
+namespace Templates {
+
+template <class Container>
+void set_union(Container &container) {
+ for (typename Container::const_iterator SI = container.begin(),
+ SE = container.end(); SI != SE; ++SI) {
+ (void) *SI;
+ }
+
+ S Ss;
+ for (S::iterator SI = Ss.begin(), SE = Ss.end(); SI != SE; ++SI)
+ (void) *SI;
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & SI : Ss)
+}
+
+void template_instantiation() {
+ S Ss;
+ set_union(Ss);
+}
+
+} // namespace Templates
+
+namespace Lambdas {
+
+void capturesIndex() {
+ const int N = 10;
+ int Arr[N];
+ // FIXME: the next four loops could be convertible, if the capture list is
+ // also changed.
+
+ for (int I = 0; I < N; ++I)
+ auto F1 = [Arr, I]() { int R1 = Arr[I] + 1; };
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES-NEXT: auto F1 = [Arr, &I]() { int R1 = I + 1; };
+
+ for (int I = 0; I < N; ++I)
+ auto F2 = [Arr, &I]() { int R2 = Arr[I] + 3; };
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES-NEXT: auto F2 = [Arr, &I]() { int R2 = I + 3; };
+
+ // FIXME: alias don't work if the index is captured.
+ // Alias declared inside lambda (by value).
+ for (int I = 0; I < N; ++I)
+ auto F3 = [&Arr, I]() { int R3 = Arr[I]; };
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES-NEXT: auto F3 = [&Arr, &I]() { int R3 = I; };
+
+
+ for (int I = 0; I < N; ++I)
+ auto F4 = [&Arr, &I]() { int R4 = Arr[I]; };
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES-NEXT: auto F4 = [&Arr, &I]() { int R4 = I; };
+
+ // Alias declared inside lambda (by reference).
+ for (int I = 0; I < N; ++I)
+ auto F5 = [&Arr, I]() { int &R5 = Arr[I]; };
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & I : Arr)
+ // CHECK-FIXES-NEXT: auto F5 = [&Arr, &I]() { int &R5 = I; };
+
+
+ for (int I = 0; I < N; ++I)
+ auto F6 = [&Arr, &I]() { int &R6 = Arr[I]; };
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & I : Arr)
+ // CHECK-FIXES-NEXT: auto F6 = [&Arr, &I]() { int &R6 = I; };
+
+ for (int I = 0; I < N; ++I) {
+ auto F = [Arr, I](int k) {
+ printf("%d\n", Arr[I] + k);
+ };
+ F(Arr[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES-NEXT: auto F = [Arr, &I](int k)
+ // CHECK-FIXES-NEXT: printf("%d\n", I + k);
+ // CHECK-FIXES: F(I);
+}
+
+void implicitCapture() {
+ const int N = 10;
+ int Arr[N];
+ // Index is used, not convertible.
+ for (int I = 0; I < N; ++I) {
+ auto G1 = [&]() {
+ int R = Arr[I];
+ int J = I;
+ };
+ }
+
+ for (int I = 0; I < N; ++I) {
+ auto G2 = [=]() {
+ int R = Arr[I];
+ int J = I;
+ };
+ }
+
+ // Convertible.
+ for (int I = 0; I < N; ++I) {
+ auto G3 = [&]() {
+ int R3 = Arr[I];
+ int J3 = Arr[I] + R3;
+ };
+ }
+ // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES-NEXT: auto G3 = [&]()
+ // CHECK-FIXES-NEXT: int R3 = I;
+ // CHECK-FIXES-NEXT: int J3 = I + R3;
+
+ for (int I = 0; I < N; ++I) {
+ auto G4 = [=]() {
+ int R4 = Arr[I] + 5;
+ };
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES-NEXT: auto G4 = [=]()
+ // CHECK-FIXES-NEXT: int R4 = I + 5;
+
+ // Alias by value.
+ for (int I = 0; I < N; ++I) {
+ auto G5 = [&]() {
+ int R5 = Arr[I];
+ int J5 = 8 + R5;
+ };
+ }
+ // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int R5 : Arr)
+ // CHECK-FIXES-NEXT: auto G5 = [&]()
+ // CHECK-FIXES-NEXT: int J5 = 8 + R5;
+
+ // Alias by reference.
+ for (int I = 0; I < N; ++I) {
+ auto G6 = [&]() {
+ int &R6 = Arr[I];
+ int J6 = -1 + R6;
+ };
+ }
+ // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & R6 : Arr)
+ // CHECK-FIXES-NEXT: auto G6 = [&]()
+ // CHECK-FIXES-NEXT: int J6 = -1 + R6;
+}
+
+void iterators() {
+ dependent<int> Dep;
+
+ for (dependent<int>::iterator I = Dep.begin(), E = Dep.end(); I != E; ++I)
+ auto H1 = [&I]() { int R = *I; };
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & I : Dep)
+ // CHECK-FIXES-NEXT: auto H1 = [&I]() { int R = I; };
+
+ for (dependent<int>::iterator I = Dep.begin(), E = Dep.end(); I != E; ++I)
+ auto H2 = [&]() { int R = *I + 2; };
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & I : Dep)
+ // CHECK-FIXES-NEXT: auto H2 = [&]() { int R = I + 2; };
+
+ // FIXME: It doesn't work with const iterators.
+ for (dependent<int>::const_iterator I = Dep.begin(), E = Dep.end();
+ I != E; ++I)
+ auto H3 = [I]() { int R = *I; };
+
+ for (dependent<int>::const_iterator I = Dep.begin(), E = Dep.end();
+ I != E; ++I)
+ auto H4 = [&]() { int R = *I + 1; };
+
+ for (dependent<int>::const_iterator I = Dep.begin(), E = Dep.end();
+ I != E; ++I)
+ auto H5 = [=]() { int R = *I; };
+}
+
+void captureByValue() {
+ // When the index is captured by value, we should replace this by a capture
+ // by reference. This avoids extra copies.
+ // FIXME: this could change semantics on array or pseudoarray loops if the
+ // container is captured by copy.
+ const int N = 10;
+ int Arr[N];
+ dependent<int> Dep;
+
+ for (int I = 0; I < N; ++I) {
+ auto C1 = [&Arr, I]() { if (Arr[I] == 1); };
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES-NEXT: auto C1 = [&Arr, &I]() { if (I == 1); };
+
+ for (unsigned I = 0; I < Dep.size(); ++I) {
+ auto C2 = [&Dep, I]() { if (Dep[I] == 2); };
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : Dep)
+ // CHECK-FIXES-NEXT: auto C2 = [&Dep, &I]() { if (I == 2); };
+}
+
+} // namespace Lambdas
+
+namespace InitLists {
+
+struct D { int Ii; };
+struct E { D Dd; };
+int g(int B);
+
+void f() {
+ const unsigned N = 3;
+ int Array[N];
+
+ // Subtrees of InitListExpr are visited twice. Test that we do not do repeated
+ // replacements.
+ for (unsigned I = 0; I < N; ++I) {
+ int A{ Array[I] };
+ int B{ g(Array[I]) };
+ int C{ g( { Array[I] } ) };
+ D Dd{ { g( { Array[I] } ) } };
+ E Ee{ { { g( { Array[I] } ) } } };
+ }
+ // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : Array)
+ // CHECK-FIXES-NEXT: int A{ I };
+ // CHECK-FIXES-NEXT: int B{ g(I) };
+ // CHECK-FIXES-NEXT: int C{ g( { I } ) };
+ // CHECK-FIXES-NEXT: D Dd{ { g( { I } ) } };
+ // CHECK-FIXES-NEXT: E Ee{ { { g( { I } ) } } };
+}
+
+} // namespace InitLists
+
+void bug28341() {
+ char v[5];
+ for(int i = 0; i < 5; ++i) {
+ unsigned char value = v[i];
+ if (value > 127)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for(unsigned char value : v)
+ // CHECK-FIXES-NEXT: if (value > 127)
+ }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-lowercase.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-lowercase.cpp
new file mode 100644
index 0000000..c7bb221
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-lowercase.cpp
@@ -0,0 +1,41 @@
+// RUN: %check_clang_tidy %s modernize-loop-convert %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-loop-convert.NamingStyle, value: 'lower_case'}]}" \
+// RUN: -- -std=c++11 -I %S/Inputs/modernize-loop-convert
+
+#include "structures.h"
+
+const int n = 10;
+int arr[n];
+int nums[n];
+int nums_[n];
+
+void naming() {
+ for (int i = 0; i < n; ++i) {
+ printf("%d\n", arr[i]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
+ // CHECK-FIXES: for (int i : arr)
+ // CHECK-FIXES-NEXT: printf("%d\n", i);
+
+ for (int i = 0; i < n; ++i) {
+ printf("%d\n", nums[i]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int num : nums)
+ // CHECK-FIXES-NEXT: printf("%d\n", num);
+
+ for (int i = 0; i < n; ++i) {
+ printf("%d\n", nums_[i]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int num : nums_)
+ // CHECK-FIXES-NEXT: printf("%d\n", num);
+
+ int num = 0;
+ for (int i = 0; i < n; ++i) {
+ printf("%d\n", nums[i] + num);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int i : nums)
+ // CHECK-FIXES-NEXT: printf("%d\n", i + num);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-negative.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-negative.cpp
new file mode 100644
index 0000000..c038437
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-negative.cpp
@@ -0,0 +1,485 @@
+// RUN: %check_clang_tidy %s modernize-loop-convert %t -- -- -std=c++11 -I %S/Inputs/modernize-loop-convert
+
+#include "structures.h"
+
+// CHECK-FIXES-NOT: for ({{.*[^:]:[^:].*}})
+// CHECK-MESSAGES-NOT: modernize-loop-convert
+
+namespace Negative {
+
+const int N = 6;
+int Arr[N] = {1, 2, 3, 4, 5, 6};
+int (*pArr)[N] = &Arr;
+int Sum = 0;
+
+// Checks for the Index start and end:
+void IndexStartAndEnd() {
+ for (int I = 0; I < N + 1; ++I)
+ Sum += Arr[I];
+
+ for (int I = 0; I < N - 1; ++I)
+ Sum += Arr[I];
+
+ for (int I = 1; I < N; ++I)
+ Sum += Arr[I];
+
+ for (int I = 1; I < N; ++I)
+ Sum += Arr[I];
+
+ for (int I = 0;; ++I)
+ Sum += (*pArr)[I];
+}
+
+// Checks for invalid increment steps:
+void increment() {
+ for (int I = 0; I < N; --I)
+ Sum += Arr[I];
+
+ for (int I = 0; I < N; I)
+ Sum += Arr[I];
+
+ for (int I = 0; I < N;)
+ Sum += Arr[I];
+
+ for (int I = 0; I < N; I += 2)
+ Sum++;
+}
+
+// Checks to make sure that the Index isn't used outside of the array:
+void IndexUse() {
+ for (int I = 0; I < N; ++I)
+ Arr[I] += 1 + I;
+}
+
+// Check for loops that don't mention arrays
+void noArray() {
+ for (int I = 0; I < N; ++I)
+ Sum += I;
+
+ for (int I = 0; I < N; ++I) {
+ }
+
+ for (int I = 0; I < N; ++I)
+ ;
+}
+
+// Checks for incorrect loop variables.
+void mixedVariables() {
+ int BadIndex;
+ for (int I = 0; BadIndex < N; ++I)
+ Sum += Arr[I];
+
+ for (int I = 0; I < N; ++BadIndex)
+ Sum += Arr[I];
+
+ for (int I = 0; BadIndex < N; ++BadIndex)
+ Sum += Arr[I];
+
+ for (int I = 0; BadIndex < N; ++BadIndex)
+ Sum += Arr[BadIndex];
+}
+
+// Checks for multiple arrays Indexed.
+void multipleArrays() {
+ int BadArr[N];
+
+ for (int I = 0; I < N; ++I)
+ Sum += Arr[I] + BadArr[I];
+
+ for (int I = 0; I < N; ++I) {
+ int K = BadArr[I];
+ Sum += Arr[I] + K;
+ }
+}
+
+}
+
+namespace NegativeIterator {
+
+S Ss;
+T Tt;
+U Tu;
+
+struct BadBeginEnd : T {
+ iterator notBegin();
+ iterator notEnd();
+};
+
+void notBeginOrEnd() {
+ BadBeginEnd Bad;
+ for (T::iterator I = Bad.notBegin(), E = Bad.end(); I != E; ++I)
+ int K = *I;
+
+ for (T::iterator I = Bad.begin(), E = Bad.notEnd(); I != E; ++I)
+ int K = *I;
+}
+
+void badLoopShapes() {
+ for (T::iterator I = Tt.begin(), E = Tt.end(), F = E; I != E; ++I)
+ int K = *I;
+
+ for (T::iterator I = Tt.begin(), E = Tt.end(); I != E;)
+ int K = *I;
+
+ for (T::iterator I = Tt.begin(), E = Tt.end();; ++I)
+ int K = *I;
+
+ T::iterator OutsideI;
+ T::iterator OutsideE;
+
+ for (; OutsideI != OutsideE; ++OutsideI)
+ int K = *OutsideI;
+}
+
+void iteratorArrayMix() {
+ int Lower;
+ const int N = 6;
+ for (T::iterator I = Tt.begin(), E = Tt.end(); Lower < N; ++I)
+ int K = *I;
+
+ for (T::iterator I = Tt.begin(), E = Tt.end(); Lower < N; ++Lower)
+ int K = *I;
+}
+
+struct ExtraConstructor : T::iterator {
+ ExtraConstructor(T::iterator, int);
+ explicit ExtraConstructor(T::iterator);
+};
+
+void badConstructor() {
+ for (T::iterator I = ExtraConstructor(Tt.begin(), 0), E = Tt.end();
+ I != E; ++I)
+ int K = *I;
+ for (T::iterator I = ExtraConstructor(Tt.begin()), E = Tt.end(); I != E; ++I)
+ int K = *I;
+}
+
+void foo(S::iterator It) {}
+class Foo {public: void bar(S::iterator It); };
+Foo Fo;
+
+void iteratorUsed() {
+ for (S::iterator I = Ss.begin(), E = Ss.end(); I != E; ++I)
+ foo(I);
+
+ for (S::iterator I = Ss.begin(), E = Ss.end(); I != E; ++I)
+ Fo.bar(I);
+
+ S::iterator Ret;
+ for (S::iterator I = Ss.begin(), E = Ss.end(); I != E; ++I)
+ Ret = I;
+}
+
+void iteratorMemberUsed() {
+ for (T::iterator I = Tt.begin(), E = Tt.end(); I != E; ++I)
+ I.X = *I;
+
+ for (T::iterator I = Tt.begin(), E = Tt.end(); I != E; ++I)
+ int K = I.X + *I;
+
+ for (T::iterator I = Tt.begin(), E = Tt.end(); I != E; ++I)
+ int K = E.X + *I;
+}
+
+void iteratorMethodCalled() {
+ for (T::iterator I = Tt.begin(), E = Tt.end(); I != E; ++I)
+ I.insert(3);
+
+ for (T::iterator I = Tt.begin(), E = Tt.end(); I != E; ++I)
+ if (I != I)
+ int K = 3;
+}
+
+void iteratorOperatorCalled() {
+ for (T::iterator I = Tt.begin(), E = Tt.end(); I != E; ++I)
+ int K = *(++I);
+
+ for (S::iterator I = Ss.begin(), E = Ss.end(); I != E; ++I)
+ MutableVal K = *(++I);
+}
+
+void differentContainers() {
+ T Other;
+ for (T::iterator I = Tt.begin(), E = Other.end(); I != E; ++I)
+ int K = *I;
+
+ for (T::iterator I = Other.begin(), E = Tt.end(); I != E; ++I)
+ int K = *I;
+
+ S OtherS;
+ for (S::iterator I = Ss.begin(), E = OtherS.end(); I != E; ++I)
+ MutableVal K = *I;
+
+ for (S::iterator I = OtherS.begin(), E = Ss.end(); I != E; ++I)
+ MutableVal K = *I;
+}
+
+void wrongIterators() {
+ T::iterator Other;
+ for (T::iterator I = Tt.begin(), E = Tt.end(); I != Other; ++I)
+ int K = *I;
+}
+
+struct EvilArrow : U {
+ // Please, no one ever write code like this.
+ U *operator->();
+};
+
+void differentMemberAccessTypes() {
+ EvilArrow A;
+ for (EvilArrow::iterator I = A.begin(), E = A->end(); I != E; ++I)
+ Val K = *I;
+ for (EvilArrow::iterator I = A->begin(), E = A.end(); I != E; ++I)
+ Val K = *I;
+}
+
+void f(const T::iterator &It, int);
+void f(const T &It, int);
+void g(T &It, int);
+
+void iteratorPassedToFunction() {
+ for (T::iterator I = Tt.begin(), E = Tt.end(); I != E; ++I)
+ f(I, *I);
+}
+
+// FIXME: These tests can be removed if this tool ever does enough analysis to
+// decide that this is a safe transformation. Until then, we don't want it
+// applied.
+void iteratorDefinedOutside() {
+ T::iterator TheEnd = Tt.end();
+ for (T::iterator I = Tt.begin(); I != TheEnd; ++I)
+ int K = *I;
+
+ T::iterator TheBegin = Tt.begin();
+ for (T::iterator E = Tt.end(); TheBegin != E; ++TheBegin)
+ int K = *TheBegin;
+}
+
+} // namespace NegativeIterator
+
+namespace NegativePseudoArray {
+
+const int N = 6;
+dependent<int> V;
+dependent<int> *Pv;
+
+int Sum = 0;
+
+// Checks for the Index start and end:
+void IndexStartAndEnd() {
+ for (int I = 0; I < V.size() + 1; ++I)
+ Sum += V[I];
+
+ for (int I = 0; I < V.size() - 1; ++I)
+ Sum += V[I];
+
+ for (int I = 1; I < V.size(); ++I)
+ Sum += V[I];
+
+ for (int I = 1; I < V.size(); ++I)
+ Sum += V[I];
+
+ for (int I = 0;; ++I)
+ Sum += (*Pv)[I];
+}
+
+// Checks for invalid increment steps:
+void increment() {
+ for (int I = 0; I < V.size(); --I)
+ Sum += V[I];
+
+ for (int I = 0; I < V.size(); I)
+ Sum += V[I];
+
+ for (int I = 0; I < V.size();)
+ Sum += V[I];
+
+ for (int I = 0; I < V.size(); I += 2)
+ Sum++;
+}
+
+// Checks to make sure that the Index isn't used outside of the container:
+void IndexUse() {
+ for (int I = 0; I < V.size(); ++I)
+ V[I] += 1 + I;
+}
+
+// Checks for incorrect loop variables.
+void mixedVariables() {
+ int BadIndex;
+ for (int I = 0; BadIndex < V.size(); ++I)
+ Sum += V[I];
+
+ for (int I = 0; I < V.size(); ++BadIndex)
+ Sum += V[I];
+
+ for (int I = 0; BadIndex < V.size(); ++BadIndex)
+ Sum += V[I];
+
+ for (int I = 0; BadIndex < V.size(); ++BadIndex)
+ Sum += V[BadIndex];
+}
+
+// Checks for an array Indexed in addition to the container.
+void multipleArrays() {
+ int BadArr[N];
+
+ for (int I = 0; I < V.size(); ++I)
+ Sum += V[I] + BadArr[I];
+
+ for (int I = 0; I < V.size(); ++I)
+ Sum += BadArr[I];
+
+ for (int I = 0; I < V.size(); ++I) {
+ int K = BadArr[I];
+ Sum += K + 2;
+ }
+
+ for (int I = 0; I < V.size(); ++I) {
+ int K = BadArr[I];
+ Sum += V[I] + K;
+ }
+}
+
+// Checks for multiple containers being Indexed container.
+void multipleContainers() {
+ dependent<int> BadArr;
+
+ for (int I = 0; I < V.size(); ++I)
+ Sum += V[I] + BadArr[I];
+
+ for (int I = 0; I < V.size(); ++I)
+ Sum += BadArr[I];
+
+ for (int I = 0; I < V.size(); ++I) {
+ int K = BadArr[I];
+ Sum += K + 2;
+ }
+
+ for (int I = 0; I < V.size(); ++I) {
+ int K = BadArr[I];
+ Sum += V[I] + K;
+ }
+}
+
+// Check to make sure that dereferenced pointers-to-containers behave nicely.
+void derefContainer() {
+ // Note the dependent<T>::operator*() returns another dependent<T>.
+ // This test makes sure that we don't allow an arbitrary number of *'s.
+ for (int I = 0; I < Pv->size(); ++I)
+ Sum += (**Pv).at(I);
+
+ for (int I = 0; I < Pv->size(); ++I)
+ Sum += (**Pv)[I];
+}
+
+void wrongEnd() {
+ int Bad;
+ for (int I = 0, E = V.size(); I < Bad; ++I)
+ Sum += V[I];
+}
+
+// Checks to see that non-const member functions are not called on the container
+// object.
+// These could be conceivably allowed with a lower required confidence level.
+void memberFunctionCalled() {
+ for (int I = 0; I < V.size(); ++I) {
+ Sum += V[I];
+ V.foo();
+ }
+
+ for (int I = 0; I < V.size(); ++I) {
+ Sum += V[I];
+ dependent<int>::iterator It = V.begin();
+ }
+}
+
+} // namespace NegativePseudoArray
+
+namespace NegativeMultiEndCall {
+
+S Ss;
+T Tt;
+U Uu;
+
+void f(X);
+void f(S);
+void f(T);
+
+void complexContainer() {
+ X Xx;
+ for (S::iterator I = Xx.Ss.begin(), E = Xx.Ss.end(); I != E; ++I) {
+ f(Xx);
+ MutableVal K = *I;
+ }
+
+ for (T::iterator I = Xx.Tt.begin(), E = Xx.Tt.end(); I != E; ++I) {
+ f(Xx);
+ int K = *I;
+ }
+
+ for (S::iterator I = Xx.Ss.begin(), E = Xx.Ss.end(); I != E; ++I) {
+ f(Xx.Ss);
+ MutableVal K = *I;
+ }
+
+ for (T::iterator I = Xx.Tt.begin(), E = Xx.Tt.end(); I != E; ++I) {
+ f(Xx.Tt);
+ int K = *I;
+ }
+
+ for (S::iterator I = Xx.getS().begin(), E = Xx.getS().end(); I != E; ++I) {
+ f(Xx.getS());
+ MutableVal K = *I;
+ }
+
+ X Exes[5];
+ int Index = 0;
+
+ for (S::iterator I = Exes[Index].getS().begin(),
+ E = Exes[Index].getS().end();
+ I != E; ++I) {
+ Index++;
+ MutableVal K = *I;
+ }
+}
+
+} // namespace NegativeMultiEndCall
+
+namespace NoUsages {
+
+const int N = 6;
+int Arr[N] = {1, 2, 3, 4, 5, 6};
+S Ss;
+dependent<int> V;
+int Count = 0;
+
+void foo();
+
+void f() {
+ for (int I = 0; I < N; ++I) {}
+ for (int I = 0; I < N; ++I)
+ printf("Hello world\n");
+ for (int I = 0; I < N; ++I)
+ ++Count;
+ for (int I = 0; I < N; ++I)
+ foo();
+
+ for (S::iterator I = Ss.begin(), E = Ss.end(); I != E; ++I) {}
+ for (S::iterator I = Ss.begin(), E = Ss.end(); I != E; ++I)
+ printf("Hello world\n");
+ for (S::iterator I = Ss.begin(), E = Ss.end(); I != E; ++I)
+ ++Count;
+ for (S::iterator I = Ss.begin(), E = Ss.end(); I != E; ++I)
+ foo();
+
+ for (int I = 0; I < V.size(); ++I) {}
+ for (int I = 0; I < V.size(); ++I)
+ printf("Hello world\n");
+ for (int I = 0; I < V.size(); ++I)
+ ++Count;
+ for (int I = 0; I < V.size(); ++I)
+ foo();
+}
+
+} // namespace NoUsages
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-uppercase.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-uppercase.cpp
new file mode 100644
index 0000000..4d1d5c2
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert-uppercase.cpp
@@ -0,0 +1,41 @@
+// RUN: %check_clang_tidy %s modernize-loop-convert %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-loop-convert.NamingStyle, value: 'UPPER_CASE'}]}" \
+// RUN: -- -std=c++11 -I %S/Inputs/modernize-loop-convert
+
+#include "structures.h"
+
+const int N = 10;
+int ARR[N];
+int NUMS[N];
+int NUMS_[N];
+
+void naming() {
+ for (int I = 0; I < N; ++I) {
+ printf("%d\n", ARR[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
+ // CHECK-FIXES: for (int I : ARR)
+ // CHECK-FIXES-NEXT: printf("%d\n", I);
+
+ for (int I = 0; I < N; ++I) {
+ printf("%d\n", NUMS[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int NUM : NUMS)
+ // CHECK-FIXES-NEXT: printf("%d\n", NUM);
+
+ for (int I = 0; I < N; ++I) {
+ printf("%d\n", NUMS_[I]);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int NUM : NUMS_)
+ // CHECK-FIXES-NEXT: printf("%d\n", NUM);
+
+ int NUM = 0;
+ for (int I = 0; I < N; ++I) {
+ printf("%d\n", NUMS[I] + NUM);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : NUMS)
+ // CHECK-FIXES-NEXT: printf("%d\n", I + NUM);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert.c b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert.c
new file mode 100644
index 0000000..4c7d956
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-loop-convert.c
@@ -0,0 +1,12 @@
+// RUN: clang-tidy %s -checks=-*,modernize-loop-convert -- -std=c11 | count 0
+
+// Note: this test expects no diagnostics, but FileCheck cannot handle that,
+// hence the use of | count 0.
+
+int arr[6] = {1, 2, 3, 4, 5, 6};
+
+void f(void) {
+ for (int i = 0; i < 6; ++i) {
+ (void)arr[i];
+ }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-shared-header.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-shared-header.cpp
new file mode 100644
index 0000000..21b07ee
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-shared-header.cpp
@@ -0,0 +1,17 @@
+// RUN: %check_clang_tidy %s modernize-make-shared %t -- \
+// RUN: -config="{CheckOptions: \
+// RUN: [{key: modernize-make-shared.MakeSmartPtrFunction, \
+// RUN: value: 'my::MakeShared'}, \
+// RUN: {key: modernize-make-shared.MakeSmartPtrFunctionHeader, \
+// RUN: value: 'make_shared_util.h'} \
+// RUN: ]}" \
+// RUN: -- -std=c++11 -I%S/Inputs/modernize-smart-ptr
+
+#include "shared_ptr.h"
+// CHECK-FIXES: #include "make_shared_util.h"
+
+void f() {
+ std::shared_ptr<int> P1 = std::shared_ptr<int>(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use my::MakeShared instead
+ // CHECK-FIXES: std::shared_ptr<int> P1 = my::MakeShared<int>();
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-shared.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-shared.cpp
new file mode 100644
index 0000000..49012dc
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-shared.cpp
@@ -0,0 +1,298 @@
+// RUN: %check_clang_tidy %s modernize-make-shared %t -- -- -std=c++11 \
+// RUN: -I%S/Inputs/modernize-smart-ptr
+
+#include "shared_ptr.h"
+// CHECK-FIXES: #include <memory>
+
+struct Base {
+ Base();
+ Base(int, int);
+};
+
+struct Derived : public Base {
+ Derived();
+ Derived(int, int);
+};
+
+struct APair {
+ int a, b;
+};
+
+struct DPair {
+ DPair() : a(0), b(0) {}
+ DPair(int x, int y) : a(y), b(x) {}
+ int a, b;
+};
+
+struct Empty {};
+
+template <class T>
+using shared_ptr_ = std::shared_ptr<T>;
+
+void *operator new(__SIZE_TYPE__ Count, void *Ptr);
+
+int g(std::shared_ptr<int> P);
+
+std::shared_ptr<Base> getPointer() {
+ return std::shared_ptr<Base>(new Base);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use std::make_shared instead
+ // CHECK-FIXES: return std::make_shared<Base>();
+}
+
+void basic() {
+ std::shared_ptr<int> P1 = std::shared_ptr<int>(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_shared instead [modernize-make-shared]
+ // CHECK-FIXES: std::shared_ptr<int> P1 = std::make_shared<int>();
+
+ P1.reset(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead [modernize-make-shared]
+ // CHECK-FIXES: P1 = std::make_shared<int>();
+
+ P1 = std::shared_ptr<int>(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead [modernize-make-shared]
+ // CHECK-FIXES: P1 = std::make_shared<int>();
+
+ // Without parenthesis.
+ std::shared_ptr<int> P2 = std::shared_ptr<int>(new int);
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_shared instead [modernize-make-shared]
+ // CHECK-FIXES: std::shared_ptr<int> P2 = std::make_shared<int>();
+
+ P2.reset(new int);
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead [modernize-make-shared]
+ // CHECK-FIXES: P2 = std::make_shared<int>();
+
+ P2 = std::shared_ptr<int>(new int);
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead [modernize-make-shared]
+ // CHECK-FIXES: P2 = std::make_shared<int>();
+
+ // With auto.
+ auto P3 = std::shared_ptr<int>(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_shared instead
+ // CHECK-FIXES: auto P3 = std::make_shared<int>();
+
+ std::shared_ptr<int> P4 = std::shared_ptr<int>((new int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_shared instead [modernize-make-shared]
+ // CHECK-FIXES: std::shared_ptr<int> P4 = std::make_shared<int>();
+
+ P4.reset((((new int()))));
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead [modernize-make-shared]
+ // CHECK-FIXES: P4 = std::make_shared<int>();
+
+ P4 = std::shared_ptr<int>(((new int)));
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead [modernize-make-shared]
+ // CHECK-FIXES: P4 = std::make_shared<int>();
+
+ {
+ // No std.
+ using namespace std;
+ shared_ptr<int> Q = shared_ptr<int>(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use std::make_shared instead
+ // CHECK-FIXES: shared_ptr<int> Q = std::make_shared<int>();
+
+ Q = shared_ptr<int>(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
+ // CHECK-FIXES: Q = std::make_shared<int>();
+ }
+
+ std::shared_ptr<int> R(new int());
+
+ // Create the shared_ptr as a parameter to a function.
+ int T = g(std::shared_ptr<int>(new int()));
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_shared instead
+ // CHECK-FIXES: int T = g(std::make_shared<int>());
+
+ // Only replace if the type in the template is the same as the type returned
+ // by the new operator.
+ auto Pderived = std::shared_ptr<Base>(new Derived());
+
+ // OK to replace for reset and assign
+ Pderived.reset(new Derived());
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use std::make_shared instead
+ // CHECK-FIXES: Pderived = std::make_shared<Derived>();
+
+ Pderived = std::shared_ptr<Derived>(new Derived());
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use std::make_shared instead
+ // CHECK-FIXES: Pderived = std::make_shared<Derived>();
+
+ // FIXME: OK to replace if assigned to shared_ptr<Base>
+ Pderived = std::shared_ptr<Base>(new Derived());
+
+ // FIXME: OK to replace when auto is not used
+ std::shared_ptr<Base> PBase = std::shared_ptr<Base>(new Derived());
+
+ // The pointer is returned by the function, nothing to do.
+ std::shared_ptr<Base> RetPtr = getPointer();
+
+ // This emulates std::move.
+ std::shared_ptr<int> Move = static_cast<std::shared_ptr<int> &&>(P1);
+
+ // Placement arguments should not be removed.
+ int *PInt = new int;
+ std::shared_ptr<int> Placement = std::shared_ptr<int>(new (PInt) int{3});
+ Placement.reset(new (PInt) int{3});
+ Placement = std::shared_ptr<int>(new (PInt) int{3});
+}
+
+// Calling make_smart_ptr from within a member function of a type with a
+// private or protected constructor would be ill-formed.
+class Private {
+private:
+ Private(int z) {}
+
+public:
+ Private() {}
+ void create() {
+ auto callsPublic = std::shared_ptr<Private>(new Private);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_shared instead
+ // CHECK-FIXES: auto callsPublic = std::make_shared<Private>();
+ auto ptr = std::shared_ptr<Private>(new Private(42));
+ ptr.reset(new Private(42));
+ ptr = std::shared_ptr<Private>(new Private(42));
+ }
+
+ virtual ~Private();
+};
+
+class Protected {
+protected:
+ Protected() {}
+
+public:
+ Protected(int, int) {}
+ void create() {
+ auto callsPublic = std::shared_ptr<Protected>(new Protected(1, 2));
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_shared instead
+ // CHECK-FIXES: auto callsPublic = std::make_shared<Protected>(1, 2);
+ auto ptr = std::shared_ptr<Protected>(new Protected);
+ ptr.reset(new Protected);
+ ptr = std::shared_ptr<Protected>(new Protected);
+ }
+};
+
+void initialization(int T, Base b) {
+ // Test different kinds of initialization of the pointee.
+
+ // Direct initialization with parenthesis.
+ std::shared_ptr<DPair> PDir1 = std::shared_ptr<DPair>(new DPair(1, T));
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+ // CHECK-FIXES: std::shared_ptr<DPair> PDir1 = std::make_shared<DPair>(1, T);
+ PDir1.reset(new DPair(1, T));
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
+ // CHECK-FIXES: PDir1 = std::make_shared<DPair>(1, T);
+
+ // Direct initialization with braces.
+ std::shared_ptr<DPair> PDir2 = std::shared_ptr<DPair>(new DPair{2, T});
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+ // CHECK-FIXES: std::shared_ptr<DPair> PDir2 = std::make_shared<DPair>(2, T);
+ PDir2.reset(new DPair{2, T});
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
+ // CHECK-FIXES: PDir2 = std::make_shared<DPair>(2, T);
+
+ // Aggregate initialization.
+ std::shared_ptr<APair> PAggr = std::shared_ptr<APair>(new APair{T, 1});
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+ // CHECK-FIXES: std::shared_ptr<APair> PAggr = std::make_shared<APair>(APair{T, 1});
+ PAggr.reset(new APair{T, 1});
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
+ // CHECK-FIXES: std::make_shared<APair>(APair{T, 1});
+
+ // Test different kinds of initialization of the pointee, when the shared_ptr
+ // is initialized with braces.
+
+ // Direct initialization with parenthesis.
+ std::shared_ptr<DPair> PDir3 = std::shared_ptr<DPair>{new DPair(3, T)};
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+ // CHECK-FIXES: std::shared_ptr<DPair> PDir3 = std::make_shared<DPair>(3, T);
+
+ // Direct initialization with braces.
+ std::shared_ptr<DPair> PDir4 = std::shared_ptr<DPair>{new DPair{4, T}};
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+ // CHECK-FIXES: std::shared_ptr<DPair> PDir4 = std::make_shared<DPair>(4, T);
+
+ // Aggregate initialization.
+ std::shared_ptr<APair> PAggr2 = std::shared_ptr<APair>{new APair{T, 2}};
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_shared instead
+ // CHECK-FIXES: std::shared_ptr<APair> PAggr2 = std::make_shared<APair>(APair{T, 2});
+
+ // Direct initialization with parenthesis, without arguments.
+ std::shared_ptr<DPair> PDir5 = std::shared_ptr<DPair>(new DPair());
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+ // CHECK-FIXES: std::shared_ptr<DPair> PDir5 = std::make_shared<DPair>();
+
+ // Direct initialization with braces, without arguments.
+ std::shared_ptr<DPair> PDir6 = std::shared_ptr<DPair>(new DPair{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+ // CHECK-FIXES: std::shared_ptr<DPair> PDir6 = std::make_shared<DPair>();
+
+ // Aggregate initialization without arguments.
+ std::shared_ptr<Empty> PEmpty = std::shared_ptr<Empty>(new Empty{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_shared instead
+ // CHECK-FIXES: std::shared_ptr<Empty> PEmpty = std::make_shared<Empty>(Empty{});
+}
+
+void aliases() {
+ typedef std::shared_ptr<int> IntPtr;
+ IntPtr Typedef = IntPtr(new int);
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use std::make_shared instead
+ // CHECK-FIXES: IntPtr Typedef = std::make_shared<int>();
+
+ // We use 'bool' instead of '_Bool'.
+ typedef std::shared_ptr<bool> BoolPtr;
+ BoolPtr BoolType = BoolPtr(new bool);
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use std::make_shared instead
+ // CHECK-FIXES: BoolPtr BoolType = std::make_shared<bool>();
+
+ // We use 'Base' instead of 'struct Base'.
+ typedef std::shared_ptr<Base> BasePtr;
+ BasePtr StructType = BasePtr(new Base);
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_shared instead
+// CHECK-FIXES: BasePtr StructType = std::make_shared<Base>();
+
+#define PTR shared_ptr<int>
+ std::shared_ptr<int> Macro = std::PTR(new int);
+// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_shared instead
+// CHECK-FIXES: std::shared_ptr<int> Macro = std::make_shared<int>();
+#undef PTR
+
+ std::shared_ptr<int> Using = shared_ptr_<int>(new int);
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_shared instead
+ // CHECK-FIXES: std::shared_ptr<int> Using = std::make_shared<int>();
+}
+
+void whitespaces() {
+ // clang-format off
+ auto Space = std::shared_ptr <int>(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use std::make_shared instead
+ // CHECK-FIXES: auto Space = std::make_shared<int>();
+
+ auto Spaces = std :: shared_ptr <int>(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use std::make_shared instead
+ // CHECK-FIXES: auto Spaces = std::make_shared<int>();
+ // clang-format on
+}
+
+void nesting() {
+ auto Nest = std::shared_ptr<std::shared_ptr<int>>(new std::shared_ptr<int>(new int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use std::make_shared instead
+ // CHECK-FIXES: auto Nest = std::make_shared<std::shared_ptr<int>>(new int);
+ Nest.reset(new std::shared_ptr<int>(new int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead
+ // CHECK-FIXES: Nest = std::make_shared<std::shared_ptr<int>>(new int);
+ Nest->reset(new int);
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
+ // CHECK-FIXES: *Nest = std::make_shared<int>();
+}
+
+void reset() {
+ std::shared_ptr<int> P;
+ P.reset();
+ P.reset(nullptr);
+ P.reset(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use std::make_shared instead
+ // CHECK-FIXES: P = std::make_shared<int>();
+
+ auto Q = &P;
+ Q->reset(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead
+ // CHECK-FIXES: *Q = std::make_shared<int>();
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-unique-cxx11.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-unique-cxx11.cpp
new file mode 100644
index 0000000..89beb08
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-unique-cxx11.cpp
@@ -0,0 +1,10 @@
+// RUN: %check_clang_tidy %s modernize-make-unique %t -- -- -std=c++11 \
+// RUN: -I%S/Inputs/modernize-smart-ptr
+
+#include "unique_ptr.h"
+// CHECK-FIXES: #include "unique_ptr.h"
+
+void f() {
+ auto my_ptr = std::unique_ptr<int>(new int(1));
+ // CHECK-FIXES: auto my_ptr = std::unique_ptr<int>(new int(1));
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-unique-cxx14.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-unique-cxx14.cpp
new file mode 100644
index 0000000..cd35f75
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-unique-cxx14.cpp
@@ -0,0 +1,11 @@
+// RUN: %check_clang_tidy %s modernize-make-unique %t -- -- -std=c++14 \
+// RUN: -I%S/Inputs/modernize-smart-ptr
+
+#include "unique_ptr.h"
+// CHECK-FIXES: #include <memory>
+
+void f() {
+ auto my_ptr = std::unique_ptr<int>(new int(1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use std::make_unique instead
+ // CHECK-FIXES: auto my_ptr = std::make_unique<int>(1);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-unique-header.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-unique-header.cpp
new file mode 100644
index 0000000..e6c2a61
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-unique-header.cpp
@@ -0,0 +1,17 @@
+// RUN: %check_clang_tidy %s modernize-make-unique %t -- \
+// RUN: -config="{CheckOptions: \
+// RUN: [{key: modernize-make-unique.MakeSmartPtrFunction, \
+// RUN: value: 'my::MakeUnique'}, \
+// RUN: {key: modernize-make-unique.MakeSmartPtrFunctionHeader, \
+// RUN: value: 'make_unique_util.h'} \
+// RUN: ]}" \
+// RUN: -- -std=c++11 -I%S/Inputs/modernize-smart-ptr
+
+#include "unique_ptr.h"
+// CHECK-FIXES: #include "make_unique_util.h"
+
+void f() {
+ std::unique_ptr<int> P1 = std::unique_ptr<int>(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use my::MakeUnique instead
+ // CHECK-FIXES: std::unique_ptr<int> P1 = my::MakeUnique<int>();
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-unique-macros.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-unique-macros.cpp
new file mode 100644
index 0000000..117a45c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-unique-macros.cpp
@@ -0,0 +1,28 @@
+// RUN: %check_clang_tidy %s modernize-make-unique %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-make-unique.IgnoreMacros, value: 0}]}" \
+// RUN: -- -std=c++14 -I%S/Inputs/modernize-smart-ptr
+
+#include "unique_ptr.h"
+
+class Foo {};
+class Bar {};
+#define DEFINE(...) __VA_ARGS__
+// CHECK-FIXES: {{^}}#define DEFINE(...) __VA_ARGS__{{$}}
+template<typename T>
+void g2(std::unique_ptr<Foo> *t) {
+ DEFINE(
+ // CHECK-FIXES: {{^ *}}DEFINE({{$}}
+ auto p = std::unique_ptr<Foo>(new Foo);
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use std::make_unique instead
+ // CHECK-FIXES: {{^ *}}auto p = std::unique_ptr<Foo>(new Foo);{{$}}
+ t->reset(new Foo);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use std::make_unique instead
+ // CHECK-FIXES: {{^ *}}t->reset(new Foo);{{$}}
+ );
+ // CHECK-FIXES: {{^ *}});{{$}}
+}
+void macro() {
+ std::unique_ptr<Foo> *t;
+ g2<Bar>(t);
+}
+#undef DEFINE
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-unique.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-unique.cpp
new file mode 100644
index 0000000..65246da
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-make-unique.cpp
@@ -0,0 +1,621 @@
+// RUN: %check_clang_tidy %s modernize-make-unique %t -- -- -std=c++14 \
+// RUN: -I%S/Inputs/modernize-smart-ptr
+
+#include "unique_ptr.h"
+#include "initializer_list.h"
+// CHECK-FIXES: #include <memory>
+
+struct Base {
+ Base();
+ Base(int, int);
+};
+
+struct Derived : public Base {
+ Derived();
+ Derived(int, int);
+};
+
+struct APair {
+ int a, b;
+};
+
+struct DPair {
+ DPair() : a(0), b(0) {}
+ DPair(int x, int y) : a(y), b(x) {}
+ int a, b;
+};
+
+template<typename T>
+struct MyVector {
+ MyVector(std::initializer_list<T>);
+};
+
+struct Empty {};
+
+struct NoCopyMoveCtor {
+ NoCopyMoveCtor(const NoCopyMoveCtor &) = delete; // implies move ctor is deleted
+};
+
+struct NoCopyMoveCtorVisible {
+private:
+ NoCopyMoveCtorVisible(const NoCopyMoveCtorVisible&) = default;
+ NoCopyMoveCtorVisible(NoCopyMoveCtorVisible&&) = default;
+};
+
+struct OnlyMoveCtor {
+ OnlyMoveCtor() = default;
+ OnlyMoveCtor(OnlyMoveCtor&&) = default;
+ OnlyMoveCtor(const OnlyMoveCtor &) = delete;
+};
+
+struct OnlyCopyCtor {
+ OnlyCopyCtor(const OnlyCopyCtor&) = default;
+ OnlyCopyCtor(OnlyCopyCtor&&) = delete;
+};
+
+struct OnlyCopyCtorVisible {
+ OnlyCopyCtorVisible(const OnlyCopyCtorVisible &) = default;
+
+private:
+ OnlyCopyCtorVisible(OnlyCopyCtorVisible &&) = default;
+};
+
+struct ImplicitDeletedCopyCtor {
+ const OnlyMoveCtor ctor;
+};
+
+struct E {
+ E(std::initializer_list<int>);
+ E();
+};
+
+struct F {
+ F(std::initializer_list<int>);
+ F();
+ int a;
+};
+
+struct G {
+ G(std::initializer_list<int>);
+ G(int);
+};
+
+struct H {
+ H(std::vector<int>);
+ H(std::vector<int> &, double);
+ H(MyVector<int>, int);
+};
+
+struct I {
+ I(G);
+};
+
+struct J {
+ J(E e, int);
+};
+
+namespace {
+class Foo {};
+} // namespace
+
+namespace bar {
+class Bar {};
+} // namespace bar
+
+template <class T>
+using unique_ptr_ = std::unique_ptr<T>;
+
+void *operator new(__SIZE_TYPE__ Count, void *Ptr);
+
+int g(std::unique_ptr<int> P);
+
+std::unique_ptr<Base> getPointer() {
+ return std::unique_ptr<Base>(new Base);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use std::make_unique instead
+ // CHECK-FIXES: return std::make_unique<Base>();
+}
+
+void basic() {
+ std::unique_ptr<int> P1 = std::unique_ptr<int>(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_unique instead [modernize-make-unique]
+ // CHECK-FIXES: std::unique_ptr<int> P1 = std::make_unique<int>();
+
+ P1.reset(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_unique instead [modernize-make-unique]
+ // CHECK-FIXES: P1 = std::make_unique<int>();
+
+ P1 = std::unique_ptr<int>(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_unique instead [modernize-make-unique]
+ // CHECK-FIXES: P1 = std::make_unique<int>();
+
+ // Without parenthesis.
+ std::unique_ptr<int> P2 = std::unique_ptr<int>(new int);
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_unique instead [modernize-make-unique]
+ // CHECK-FIXES: std::unique_ptr<int> P2 = std::make_unique<int>();
+
+ P2.reset(new int);
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_unique instead [modernize-make-unique]
+ // CHECK-FIXES: P2 = std::make_unique<int>();
+
+ P2 = std::unique_ptr<int>(new int);
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_unique instead [modernize-make-unique]
+ // CHECK-FIXES: P2 = std::make_unique<int>();
+
+ // With auto.
+ auto P3 = std::unique_ptr<int>(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_unique instead
+ // CHECK-FIXES: auto P3 = std::make_unique<int>();
+
+ std::unique_ptr<int> P4 = std::unique_ptr<int>((new int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_unique instead [modernize-make-unique]
+ // CHECK-FIXES: std::unique_ptr<int> P4 = std::make_unique<int>();
+ P4.reset((new int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_unique instead [modernize-make-unique]
+ // CHECK-FIXES: P4 = std::make_unique<int>();
+ std::unique_ptr<int> P5 = std::unique_ptr<int>((((new int))));
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_unique instead [modernize-make-unique]
+ // CHECK-FIXES: std::unique_ptr<int> P5 = std::make_unique<int>();
+ P5.reset(((((new int)))));
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_unique instead [modernize-make-unique]
+ // CHECK-FIXES: P5 = std::make_unique<int>();
+
+ {
+ // No std.
+ using namespace std;
+ unique_ptr<int> Q = unique_ptr<int>(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use std::make_unique instead
+ // CHECK-FIXES: unique_ptr<int> Q = std::make_unique<int>();
+
+ Q = unique_ptr<int>(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_unique instead
+ // CHECK-FIXES: Q = std::make_unique<int>();
+ }
+
+ std::unique_ptr<int> R(new int());
+
+ // Create the unique_ptr as a parameter to a function.
+ int T = g(std::unique_ptr<int>(new int()));
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_unique instead
+ // CHECK-FIXES: int T = g(std::make_unique<int>());
+
+ // Only replace if the type in the template is the same as the type returned
+ // by the new operator.
+ auto Pderived = std::unique_ptr<Base>(new Derived());
+
+ // OK to replace for reset and assign
+ Pderived.reset(new Derived());
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use std::make_unique instead
+ // CHECK-FIXES: Pderived = std::make_unique<Derived>();
+
+ Pderived = std::unique_ptr<Derived>(new Derived());
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use std::make_unique instead
+ // CHECK-FIXES: Pderived = std::make_unique<Derived>();
+
+ // FIXME: OK to replace if assigned to unique_ptr<Base>
+ Pderived = std::unique_ptr<Base>(new Derived());
+
+ // FIXME: OK to replace when auto is not used
+ std::unique_ptr<Base> PBase = std::unique_ptr<Base>(new Derived());
+
+ // The pointer is returned by the function, nothing to do.
+ std::unique_ptr<Base> RetPtr = getPointer();
+
+ // This emulates std::move.
+ std::unique_ptr<int> Move = static_cast<std::unique_ptr<int> &&>(P1);
+
+ // Placement arguments should not be removed.
+ int *PInt = new int;
+ std::unique_ptr<int> Placement = std::unique_ptr<int>(new (PInt) int{3});
+ Placement.reset(new (PInt) int{3});
+ Placement = std::unique_ptr<int>(new (PInt) int{3});
+}
+
+// Calling make_smart_ptr from within a member function of a type with a
+// private or protected constructor would be ill-formed.
+class Private {
+private:
+ Private(int z) {}
+
+public:
+ Private() {}
+ void create() {
+ auto callsPublic = std::unique_ptr<Private>(new Private);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_unique instead
+ // CHECK-FIXES: auto callsPublic = std::make_unique<Private>();
+ auto ptr = std::unique_ptr<Private>(new Private(42));
+ ptr.reset(new Private(42));
+ ptr = std::unique_ptr<Private>(new Private(42));
+ }
+
+ virtual ~Private();
+};
+
+class Protected {
+protected:
+ Protected() {}
+
+public:
+ Protected(int, int) {}
+ void create() {
+ auto callsPublic = std::unique_ptr<Protected>(new Protected(1, 2));
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_unique instead
+ // CHECK-FIXES: auto callsPublic = std::make_unique<Protected>(1, 2);
+ auto ptr = std::unique_ptr<Protected>(new Protected);
+ ptr.reset(new Protected);
+ ptr = std::unique_ptr<Protected>(new Protected);
+ }
+};
+
+void initialization(int T, Base b) {
+ // Test different kinds of initialization of the pointee.
+
+ // Direct initialization with parenthesis.
+ std::unique_ptr<DPair> PDir1 = std::unique_ptr<DPair>(new DPair(1, T));
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<DPair> PDir1 = std::make_unique<DPair>(1, T);
+ PDir1.reset(new DPair(1, T));
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_unique instead
+ // CHECK-FIXES: PDir1 = std::make_unique<DPair>(1, T);
+
+ // Direct initialization with braces.
+ std::unique_ptr<DPair> PDir2 = std::unique_ptr<DPair>(new DPair{2, T});
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<DPair> PDir2 = std::make_unique<DPair>(2, T);
+ PDir2.reset(new DPair{2, T});
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_unique instead
+ // CHECK-FIXES: PDir2 = std::make_unique<DPair>(2, T);
+
+ // Aggregate initialization.
+ std::unique_ptr<APair> PAggr = std::unique_ptr<APair>(new APair{T, 1});
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<APair> PAggr = std::make_unique<APair>(APair{T, 1});
+ PAggr.reset(new APair{T, 1});
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_unique instead
+ // CHECK-FIXES: std::make_unique<APair>(APair{T, 1});
+
+ // Test different kinds of initialization of the pointee, when the unique_ptr
+ // is initialized with braces.
+
+ // Direct initialization with parenthesis.
+ std::unique_ptr<DPair> PDir3 = std::unique_ptr<DPair>{new DPair(3, T)};
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<DPair> PDir3 = std::make_unique<DPair>(3, T);
+
+ // Direct initialization with braces.
+ std::unique_ptr<DPair> PDir4 = std::unique_ptr<DPair>{new DPair{4, T}};
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<DPair> PDir4 = std::make_unique<DPair>(4, T);
+
+ // Aggregate initialization.
+ std::unique_ptr<APair> PAggr2 = std::unique_ptr<APair>{new APair{T, 2}};
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<APair> PAggr2 = std::make_unique<APair>(APair{T, 2});
+
+ // Direct initialization with parenthesis, without arguments.
+ std::unique_ptr<DPair> PDir5 = std::unique_ptr<DPair>(new DPair());
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<DPair> PDir5 = std::make_unique<DPair>();
+
+ // Direct initialization with braces, without arguments.
+ std::unique_ptr<DPair> PDir6 = std::unique_ptr<DPair>(new DPair{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<DPair> PDir6 = std::make_unique<DPair>();
+
+ // Aggregate initialization without arguments.
+ std::unique_ptr<Empty> PEmpty = std::unique_ptr<Empty>(new Empty{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<Empty> PEmpty = std::make_unique<Empty>(Empty{});
+
+ // No fixes for classes with deleted copy&move constructors.
+ auto PNoCopyMoveCtor = std::unique_ptr<NoCopyMoveCtor>(new NoCopyMoveCtor{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: use std::make_unique instead
+ // CHECK-FIXES: auto PNoCopyMoveCtor = std::unique_ptr<NoCopyMoveCtor>(new NoCopyMoveCtor{});
+
+ auto PNoCopyMoveCtorVisible = std::unique_ptr<NoCopyMoveCtorVisible>(new NoCopyMoveCtorVisible{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: use std::make_unique instead
+ // CHECK-FIXES: auto PNoCopyMoveCtorVisible = std::unique_ptr<NoCopyMoveCtorVisible>(new NoCopyMoveCtorVisible{});
+
+ auto POnlyMoveCtor = std::unique_ptr<OnlyMoveCtor>(new OnlyMoveCtor{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_unique instead
+ // CHECK-FIXES: auto POnlyMoveCtor = std::unique_ptr<OnlyMoveCtor>(new OnlyMoveCtor{});
+
+ // Fix for classes with classes with move constructor.
+ auto POnlyCopyCtor = std::unique_ptr<OnlyCopyCtor>(new OnlyCopyCtor{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_unique instead
+ // CHECK-FIXES: auto POnlyCopyCtor = std::unique_ptr<OnlyCopyCtor>(new OnlyCopyCtor{});
+
+ // Fix for classes with classes with move constructor.
+ auto POnlyCopyCtorVisible = std::unique_ptr<OnlyCopyCtorVisible>(new OnlyCopyCtorVisible{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use std::make_unique instead
+ // CHECK-FIXES: auto POnlyCopyCtorVisible = std::unique_ptr<OnlyCopyCtorVisible>(new OnlyCopyCtorVisible{});
+
+ auto PImplicitDeletedCopyCtor = std::unique_ptr<ImplicitDeletedCopyCtor>(new ImplicitDeletedCopyCtor{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_unique instead
+ // CHECK-FIXES: auto PImplicitDeletedCopyCtor = std::unique_ptr<ImplicitDeletedCopyCtor>(new ImplicitDeletedCopyCtor{});
+
+ // Initialization with default constructor.
+ std::unique_ptr<E> PE1 = std::unique_ptr<E>(new E{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<E> PE1 = std::make_unique<E>();
+ PE1.reset(new E{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+ // CHECK-FIXES: PE1 = std::make_unique<E>();
+
+ // No warnings for `auto` new expression.
+ PE1.reset(new auto(E()));
+
+ //============================================================================
+ // NOTE: For initlializer-list constructors, the check only gives warnings,
+ // and no fixes are generated.
+ //============================================================================
+
+ // Initialization with the initializer-list constructor.
+ std::unique_ptr<E> PE2 = std::unique_ptr<E>(new E{1, 2});
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<E> PE2 = std::unique_ptr<E>(new E{1, 2});
+ PE2.reset(new E{1, 2});
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+ // CHECK-FIXES: PE2.reset(new E{1, 2});
+
+ // Initialization with default constructor.
+ std::unique_ptr<F> PF1 = std::unique_ptr<F>(new F());
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<F> PF1 = std::make_unique<F>();
+ PF1.reset(new F());
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+ // CHECK-FIXES: PF1 = std::make_unique<F>();
+
+ // Initialization with default constructor.
+ std::unique_ptr<F> PF2 = std::unique_ptr<F>(new F{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<F> PF2 = std::make_unique<F>();
+ PF2.reset(new F());
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+ // CHECK-FIXES: PF2 = std::make_unique<F>();
+
+ // Initialization with the initializer-list constructor.
+ std::unique_ptr<F> PF3 = std::unique_ptr<F>(new F{1});
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<F> PF3 = std::unique_ptr<F>(new F{1});
+ PF3.reset(new F{1});
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+ // CHECK-FIXES: PF3.reset(new F{1});
+
+ // Initialization with the initializer-list constructor.
+ std::unique_ptr<F> PF4 = std::unique_ptr<F>(new F{1, 2});
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<F> PF4 = std::unique_ptr<F>(new F{1, 2});
+
+ // Initialization with the initializer-list constructor.
+ std::unique_ptr<F> PF5 = std::unique_ptr<F>(new F({1, 2}));
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<F> PF5 = std::unique_ptr<F>(new F({1, 2}));
+
+ // Initialization with the initializer-list constructor as the default
+ // constructor is not present.
+ std::unique_ptr<G> PG1 = std::unique_ptr<G>(new G{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<G> PG1 = std::unique_ptr<G>(new G{});
+ PG1.reset(new G{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+ // CHECK-FIXES: PG1.reset(new G{});
+
+ // Initialization with the initializer-list constructor.
+ std::unique_ptr<G> PG2 = std::unique_ptr<G>(new G{1});
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<G> PG2 = std::unique_ptr<G>(new G{1});
+
+ // Initialization with the initializer-list constructor.
+ std::unique_ptr<G> PG3 = std::unique_ptr<G>(new G{1, 2});
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<G> PG3 = std::unique_ptr<G>(new G{1, 2});
+
+ std::unique_ptr<H> PH1 = std::unique_ptr<H>(new H({1, 2, 3}));
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<H> PH1 = std::unique_ptr<H>(new H({1, 2, 3}));
+ PH1.reset(new H({1, 2, 3}));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+ // CHECK-FIXES: PH1.reset(new H({1, 2, 3}));
+
+ std::unique_ptr<H> PH2 = std::unique_ptr<H>(new H({1, 2, 3}, 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<H> PH2 = std::unique_ptr<H>(new H({1, 2, 3}, 1));
+ PH2.reset(new H({1, 2, 3}, 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+ // CHECK-FIXES: PH2.reset(new H({1, 2, 3}, 1));
+
+ std::unique_ptr<H> PH3 = std::unique_ptr<H>(new H({1, 2, 3}, 1.0));
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<H> PH3 = std::unique_ptr<H>(new H({1, 2, 3}, 1.0));
+ PH3.reset(new H({1, 2, 3}, 1.0));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+ // CHECK-FIXES: PH3.reset(new H({1, 2, 3}, 1.0));
+
+ std::unique_ptr<I> PI1 = std::unique_ptr<I>(new I(G({1, 2, 3})));
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<I> PI1 = std::make_unique<I>(G({1, 2, 3}));
+ PI1.reset(new I(G({1, 2, 3})));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+ // CHECK-FIXES: PI1 = std::make_unique<I>(G({1, 2, 3}));
+
+ std::unique_ptr<J> PJ1 = std::unique_ptr<J>(new J({1, 2}, 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<J> PJ1 = std::unique_ptr<J>(new J({1, 2}, 1));
+ PJ1.reset(new J({1, 2}, 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+ // CHECK-FIXES: PJ1.reset(new J({1, 2}, 1));
+
+ std::unique_ptr<J> PJ2 = std::unique_ptr<J>(new J(E{1, 2}, 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<J> PJ2 = std::make_unique<J>(E{1, 2}, 1);
+ PJ2.reset(new J(E{1, 2}, 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+ // CHECK-FIXES: PJ2 = std::make_unique<J>(E{1, 2}, 1);
+
+ std::unique_ptr<J> PJ3 = std::unique_ptr<J>(new J{ {1, 2}, 1 });
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<J> PJ3 = std::unique_ptr<J>(new J{ {1, 2}, 1 });
+ PJ3.reset(new J{ {1, 2}, 1 });
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+ // CHECK-FIXES: PJ3.reset(new J{ {1, 2}, 1 });
+
+ std::unique_ptr<J> PJ4 = std::unique_ptr<J>(new J{E{1, 2}, 1});
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<J> PJ4 = std::make_unique<J>(E{1, 2}, 1);
+ PJ4.reset(new J{E{1, 2}, 1});
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+ // CHECK-FIXES: PJ4 = std::make_unique<J>(E{1, 2}, 1);
+
+ std::unique_ptr<Foo> FF = std::unique_ptr<Foo>(new Foo());
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning:
+ // CHECK-FIXES: std::unique_ptr<Foo> FF = std::make_unique<Foo>();
+ FF.reset(new Foo());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning:
+ // CHECK-FIXES: FF = std::make_unique<Foo>();
+
+ std::unique_ptr<bar::Bar> BB = std::unique_ptr<bar::Bar>(new bar::Bar());
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning:
+ // CHECK-FIXES: std::unique_ptr<bar::Bar> BB = std::make_unique<bar::Bar>();
+ BB.reset(new bar::Bar());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning:
+ // CHECK-FIXES: BB = std::make_unique<bar::Bar>();
+
+ std::unique_ptr<Foo[]> FFs;
+ FFs.reset(new Foo[5]);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning:
+ // CHECK-FIXES: FFs = std::make_unique<Foo[]>(5);
+ FFs.reset(new Foo[5]());
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning:
+ // CHECK-FIXES: FFs = std::make_unique<Foo[]>(5);
+ const int Num = 1;
+ FFs.reset(new Foo[Num]);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning:
+ // CHECK-FIXES: FFs = std::make_unique<Foo[]>(Num);
+ int Num2 = 1;
+ FFs.reset(new Foo[Num2]);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning:
+ // CHECK-FIXES: FFs = std::make_unique<Foo[]>(Num2);
+
+ std::unique_ptr<int[]> FI;
+ FI.reset(new int[5]()); // default initialization.
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning:
+ // CHECK-FIXES: FI = std::make_unique<int[]>(5);
+
+ // The check doesn't give warnings and fixes for cases where the original new
+ // expresion doesn't do any initialization.
+ FI.reset(new int[5]);
+ FI.reset(new int[Num]);
+ FI.reset(new int[Num2]);
+}
+
+void aliases() {
+ typedef std::unique_ptr<int> IntPtr;
+ IntPtr Typedef = IntPtr(new int);
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use std::make_unique instead
+ // CHECK-FIXES: IntPtr Typedef = std::make_unique<int>();
+
+ // We use 'bool' instead of '_Bool'.
+ typedef std::unique_ptr<bool> BoolPtr;
+ BoolPtr BoolType = BoolPtr(new bool);
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use std::make_unique instead
+ // CHECK-FIXES: BoolPtr BoolType = std::make_unique<bool>();
+
+ // We use 'Base' instead of 'struct Base'.
+ typedef std::unique_ptr<Base> BasePtr;
+ BasePtr StructType = BasePtr(new Base);
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_unique instead
+// CHECK-FIXES: BasePtr StructType = std::make_unique<Base>();
+
+#define PTR unique_ptr<int>
+ std::unique_ptr<int> Macro = std::PTR(new int);
+// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_unique instead
+// CHECK-FIXES: std::unique_ptr<int> Macro = std::make_unique<int>();
+#undef PTR
+
+ std::unique_ptr<int> Using = unique_ptr_<int>(new int);
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<int> Using = std::make_unique<int>();
+}
+
+void whitespaces() {
+ // clang-format off
+ auto Space = std::unique_ptr <int>(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use std::make_unique instead
+ // CHECK-FIXES: auto Space = std::make_unique<int>();
+
+ auto Spaces = std :: unique_ptr <int>(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use std::make_unique instead
+ // CHECK-FIXES: auto Spaces = std::make_unique<int>();
+ // clang-format on
+}
+
+void nesting() {
+ auto Nest = std::unique_ptr<std::unique_ptr<int>>(new std::unique_ptr<int>(new int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use std::make_unique instead
+ // CHECK-FIXES: auto Nest = std::make_unique<std::unique_ptr<int>>(new int);
+ Nest.reset(new std::unique_ptr<int>(new int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_unique instead
+ // CHECK-FIXES: Nest = std::make_unique<std::unique_ptr<int>>(new int);
+ Nest->reset(new int);
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_unique instead
+ // CHECK-FIXES: *Nest = std::make_unique<int>();
+}
+
+void reset() {
+ std::unique_ptr<int> P;
+ P.reset();
+ P.reset(nullptr);
+ P.reset(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use std::make_unique instead
+ // CHECK-FIXES: P = std::make_unique<int>();
+
+ auto Q = &P;
+ Q->reset(new int());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_unique instead
+ // CHECK-FIXES: *Q = std::make_unique<int>();
+}
+
+#define DEFINE(...) __VA_ARGS__
+template<typename T>
+void g2(std::unique_ptr<Foo> *t) {
+ DEFINE(auto p = std::unique_ptr<Foo>(new Foo); t->reset(new Foo););
+}
+void macro() {
+ std::unique_ptr<Foo> *t;
+ g2<bar::Bar>(t);
+}
+#undef DEFINE
+
+class UniqueFoo : public std::unique_ptr<Foo> {
+ public:
+ void foo() {
+ reset(new Foo);
+ this->reset(new Foo);
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use std::make_unique instead
+ // CHECK-FIXES: *this = std::make_unique<Foo>();
+ (*this).reset(new Foo);
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_unique instead
+ // CHECK-FIXES: (*this) = std::make_unique<Foo>();
+ }
+};
+
+// Ignore statements inside a template instantiation.
+template<typename T>
+void template_fun(T* t) {
+ std::unique_ptr<T> t2 = std::unique_ptr<T>(new T);
+ t2.reset(new T);
+}
+
+void invoke_template() {
+ Foo* foo;
+ template_fun(foo);
+}
+
+void no_fix_for_invalid_new_loc() {
+ // FIXME: Although the code is valid, the end location of `new struct Base` is
+ // invalid. Correct it once https://bugs.llvm.org/show_bug.cgi?id=35952 is
+ // fixed.
+ auto T = std::unique_ptr<Base>(new struct Base);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use std::make_unique instead
+ // CHECK-FIXES: auto T = std::unique_ptr<Base>(new struct Base);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-pass-by-value-header.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-pass-by-value-header.cpp
new file mode 100644
index 0000000..95ad623
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-pass-by-value-header.cpp
@@ -0,0 +1,8 @@
+// RUN: cp %S/Inputs/modernize-pass-by-value/header.h %T/pass-by-value-header.h
+// RUN: clang-tidy %s -checks='-*,modernize-pass-by-value' -header-filter='.*' -fix -- -std=c++11 -I %T | FileCheck %s -check-prefix=CHECK-MESSAGES -implicit-check-not="{{warning|error}}:"
+// RUN: FileCheck -input-file=%T/pass-by-value-header.h %s -check-prefix=CHECK-FIXES
+
+#include "pass-by-value-header.h"
+// CHECK-MESSAGES: :8:5: warning: pass by value and use std::move [modernize-pass-by-value]
+// CHECK-FIXES: #include <utility>
+// CHECK-FIXES: A(ThreadId tid) : threadid(std::move(tid)) {}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-pass-by-value-macro-header.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-pass-by-value-macro-header.cpp
new file mode 100644
index 0000000..543b7e4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-pass-by-value-macro-header.cpp
@@ -0,0 +1,18 @@
+// RUN: %check_clang_tidy %s modernize-pass-by-value %t -- -- -std=c++11 -isystem %S/Inputs/Headers
+
+// CHECK-FIXES: #include <utility>
+
+#define HEADER <./a.h>
+#include HEADER
+
+struct A {
+ A(const A &) {}
+ A(A &&) {}
+};
+
+struct B {
+ B(const A &a) : a(a) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move [modernize-pass-by-value]
+// CHECK-FIXES: B(A a) : a(std::move(a)) {}
+ A a;
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-pass-by-value-multi-fixes.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-pass-by-value-multi-fixes.cpp
new file mode 100644
index 0000000..7980c30
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-pass-by-value-multi-fixes.cpp
@@ -0,0 +1,12 @@
+// RUN: cat %S/Inputs/modernize-pass-by-value/header-with-fix.h > %T/pass-by-value-header-with-fix.h
+// RUN: sed -e 's#//.*$##' %s > %t.cpp
+// RUN: clang-tidy %t.cpp -checks='-*,modernize-pass-by-value' -header-filter='.*' -fix -- -std=c++11 -I %T | FileCheck %s -check-prefix=CHECK-MESSAGES -implicit-check-not="{{warning|error}}:"
+// RUN: FileCheck -input-file=%t.cpp %s -check-prefix=CHECK-FIXES
+// RUN: FileCheck -input-file=%T/pass-by-value-header-with-fix.h %s -check-prefix=CHECK-HEADER-FIXES
+
+#include "pass-by-value-header-with-fix.h"
+// CHECK-HEADER-FIXES: Foo(S s);
+Foo::Foo(const S &s) : s(s) {}
+// CHECK-MESSAGES: :9:10: warning: pass by value and use std::move [modernize-pass-by-value]
+// CHECK-FIXES: #include <utility>
+// CHECK-FIXES: Foo::Foo(S s) : s(std::move(s)) {}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-pass-by-value.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-pass-by-value.cpp
new file mode 100644
index 0000000..87e22ba
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-pass-by-value.cpp
@@ -0,0 +1,215 @@
+// RUN: %check_clang_tidy %s modernize-pass-by-value %t -- -- -std=c++11 -fno-delayed-template-parsing
+
+namespace {
+// POD types are trivially move constructible.
+struct POD {
+ int a, b, c;
+};
+
+struct Movable {
+ int a, b, c;
+ Movable() = default;
+ Movable(const Movable &) {}
+ Movable(Movable &&) {}
+};
+
+struct NotMovable {
+ NotMovable() = default;
+ NotMovable(const NotMovable &) = default;
+ NotMovable(NotMovable &&) = delete;
+ int a, b, c;
+};
+}
+
+struct A {
+ A(const Movable &M) : M(M) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move [modernize-pass-by-value]
+ // CHECK-FIXES: A(Movable M) : M(std::move(M)) {}
+ Movable M;
+};
+
+// Test that we aren't modifying other things than a parameter.
+Movable GlobalObj;
+struct B {
+ B(const Movable &M) : M(GlobalObj) {}
+ // CHECK-FIXES: B(const Movable &M) : M(GlobalObj) {}
+ Movable M;
+};
+
+// Test that a parameter with more than one reference to it won't be changed.
+struct C {
+ // Tests extra-reference in body.
+ C(const Movable &M) : M(M) { this->i = M.a; }
+ // CHECK-FIXES: C(const Movable &M) : M(M) { this->i = M.a; }
+
+ // Tests extra-reference in init-list.
+ C(const Movable &M, int) : M(M), i(M.a) {}
+ // CHECK-FIXES: C(const Movable &M, int) : M(M), i(M.a) {}
+ Movable M;
+ int i;
+};
+
+// Test that both declaration and definition are updated.
+struct D {
+ D(const Movable &M);
+ // CHECK-FIXES: D(Movable M);
+ Movable M;
+};
+D::D(const Movable &M) : M(M) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: pass by value and use std::move
+// CHECK-FIXES: D::D(Movable M) : M(std::move(M)) {}
+
+// Test with default parameter.
+struct E {
+ E(const Movable &M = Movable()) : M(M) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move
+ // CHECK-FIXES: E(Movable M = Movable()) : M(std::move(M)) {}
+ Movable M;
+};
+
+// Test with object that can't be moved.
+struct F {
+ F(const NotMovable &NM) : NM(NM) {}
+ // CHECK-FIXES: F(const NotMovable &NM) : NM(NM) {}
+ NotMovable NM;
+};
+
+// Test unnamed parameter in declaration.
+struct G {
+ G(const Movable &);
+ // CHECK-FIXES: G(Movable );
+ Movable M;
+};
+G::G(const Movable &M) : M(M) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: pass by value and use std::move
+// CHECK-FIXES: G::G(Movable M) : M(std::move(M)) {}
+
+// Test parameter with and without qualifier.
+namespace ns_H {
+typedef ::Movable HMovable;
+}
+struct H {
+ H(const ns_H::HMovable &M);
+ // CHECK-FIXES: H(ns_H::HMovable M);
+ ns_H::HMovable M;
+};
+using namespace ns_H;
+H::H(const HMovable &M) : M(M) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: pass by value and use std::move
+// CHECK-FIXES: H(HMovable M) : M(std::move(M)) {}
+
+// Try messing up with macros.
+#define MOVABLE_PARAM(Name) const Movable & Name
+// CHECK-FIXES: #define MOVABLE_PARAM(Name) const Movable & Name
+struct I {
+ I(MOVABLE_PARAM(M)) : M(M) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move
+ // CHECK-FIXES: I(MOVABLE_PARAM(M)) : M(M) {}
+ Movable M;
+};
+#undef MOVABLE_PARAM
+
+// Test that templates aren't modified.
+template <typename T> struct J {
+ J(const T &M) : M(M) {}
+ // CHECK-FIXES: J(const T &M) : M(M) {}
+ T M;
+};
+J<Movable> j1(Movable());
+J<NotMovable> j2(NotMovable());
+
+struct K_Movable {
+ K_Movable() = default;
+ K_Movable(const K_Movable &) = default;
+ K_Movable(K_Movable &&o) { dummy = o.dummy; }
+ int dummy;
+};
+
+// Test with movable type with an user defined move constructor.
+struct K {
+ K(const K_Movable &M) : M(M) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move
+ // CHECK-FIXES: K(K_Movable M) : M(std::move(M)) {}
+ K_Movable M;
+};
+
+template <typename T> struct L {
+ L(const Movable &M) : M(M) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move
+ // CHECK-FIXES: L(Movable M) : M(std::move(M)) {}
+ Movable M;
+};
+L<int> l(Movable());
+
+// Test with a non-instantiated template class.
+template <typename T> struct N {
+ N(const Movable &M) : M(M) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move
+ // CHECK-FIXES: N(Movable M) : M(std::move(M)) {}
+
+ Movable M;
+ T A;
+};
+
+// Test with value parameter.
+struct O {
+ O(Movable M) : M(M) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move
+ // CHECK-FIXES: O(Movable M) : M(std::move(M)) {}
+ Movable M;
+};
+
+// Test with a const-value parameter.
+struct P {
+ P(const Movable M) : M(M) {}
+ // CHECK-FIXES: P(const Movable M) : M(M) {}
+ Movable M;
+};
+
+// Test with multiples parameters where some need to be changed and some don't.
+// need to.
+struct Q {
+ Q(const Movable &A, const Movable &B, const Movable &C, double D)
+ : A(A), B(B), C(C), D(D) {}
+ // CHECK-MESSAGES: :[[@LINE-2]]:23: warning: pass by value and use std::move
+ // CHECK-MESSAGES: :[[@LINE-3]]:41: warning: pass by value and use std::move
+ // CHECK-FIXES: Q(const Movable &A, Movable B, Movable C, double D)
+ // CHECK-FIXES: : A(A), B(std::move(B)), C(std::move(C)), D(D) {}
+ const Movable &A;
+ Movable B;
+ Movable C;
+ double D;
+};
+
+// Test that value-parameters with a nested name specifier are left as-is.
+namespace ns_R {
+typedef ::Movable RMovable;
+}
+struct R {
+ R(ns_R::RMovable M) : M(M) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move
+ // CHECK-FIXES: R(ns_R::RMovable M) : M(std::move(M)) {}
+ ns_R::RMovable M;
+};
+
+// Test with rvalue parameter.
+struct S {
+ S(Movable &&M) : M(M) {}
+ // CHECK-FIXES: S(Movable &&M) : M(M) {}
+ Movable M;
+};
+
+template <typename T, int N> struct array { T A[N]; };
+
+// Test that types that are trivially copyable will not use std::move. This will
+// cause problems with performance-move-const-arg, as it will revert it.
+struct T {
+ T(array<int, 10> a) : a_(a) {}
+ // CHECK-FIXES: T(array<int, 10> a) : a_(a) {}
+ array<int, 10> a_;
+};
+
+struct U {
+ U(const POD &M) : M(M) {}
+ POD M;
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-raw-string-literal-delimiter.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-raw-string-literal-delimiter.cpp
new file mode 100644
index 0000000..1dd3e13
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-raw-string-literal-delimiter.cpp
@@ -0,0 +1,9 @@
+// RUN: %check_clang_tidy %s modernize-raw-string-literal %t -- -config='{CheckOptions: [{key: "modernize-raw-string-literal.DelimiterStem", value: "str"}, {key: modernize-raw-string-literal.ReplaceShorterLiterals, value: 1}]}' -- -std=c++11
+
+char const *const ContainsSentinel{"who\\ops)\""};
+// CHECK-MESSAGES: :[[@LINE-1]]:36: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const ContainsSentinel{R"str(who\ops)")str"};{{$}}
+
+//char const *const ContainsDelim{"whoops)\")lit\""};
+// CHECK-XMESSAGES: :[[@LINE-1]]:33: warning: {{.*}} can be written as a raw string literal
+// CHECK-XFIXES: {{^}}char const *const ContainsDelim{R"lit1(whoops)")lit")lit1"};{{$}}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-raw-string-literal-replace-shorter.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-raw-string-literal-replace-shorter.cpp
new file mode 100644
index 0000000..673a8aa
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-raw-string-literal-replace-shorter.cpp
@@ -0,0 +1,13 @@
+// RUN: %check_clang_tidy %s modernize-raw-string-literal %t
+
+// Don't replace these, because the raw literal would be longer.
+char const *const JustAQuote("quote:\'");
+char const *const NeedDelimiter("\":)\"");
+
+char const *const ManyQuotes("quotes:\'\'\'\'");
+// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const ManyQuotes(R"(quotes:'''')");{{$}}
+
+char const *const LongOctal("\042\072\051\042");
+// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const LongOctal(R"lit(":)")lit");{{$}}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-raw-string-literal.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-raw-string-literal.cpp
new file mode 100644
index 0000000..b6d4995
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-raw-string-literal.cpp
@@ -0,0 +1,131 @@
+// RUN: %check_clang_tidy %s modernize-raw-string-literal %t -- -config="{CheckOptions: [{key: modernize-raw-string-literal.ReplaceShorterLiterals, value: 1}]}" -- -std=c++11
+
+char const *const BackSlash("goink\\frob");
+// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: escaped string literal can be written as a raw string literal [modernize-raw-string-literal]
+// CHECK-FIXES: {{^}}char const *const BackSlash(R"(goink\frob)");{{$}}
+
+char const *const PlainLiteral("plain literal");
+
+// Non-printable ASCII characters.
+char const *const Nul("goink\\\000");
+char const *const Soh("goink\\\001");
+char const *const Stx("goink\\\002");
+char const *const Etx("goink\\\003");
+char const *const Enq("goink\\\004");
+char const *const Ack("goink\\\005");
+char const *const Bell("goink\\\afrob");
+char const *const BackSpace("goink\\\bfrob");
+char const *const HorizontalTab("goink\\\tfrob");
+char const *const NewLine("goink\nfrob");
+char const *const VerticalTab("goink\\\vfrob");
+char const *const FormFeed("goink\\\ffrob");
+char const *const CarraigeReturn("goink\\\rfrob");
+char const *const So("goink\\\016");
+char const *const Si("goink\\\017");
+char const *const Dle("goink\\\020");
+char const *const Dc1("goink\\\021");
+char const *const Dc2("goink\\\022");
+char const *const Dc3("goink\\\023");
+char const *const Dc4("goink\\\024");
+char const *const Nak("goink\\\025");
+char const *const Syn("goink\\\026");
+char const *const Etb("goink\\\027");
+char const *const Can("goink\\\030");
+char const *const Em("goink\\\031");
+char const *const Sub("goink\\\032");
+char const *const Esc("goink\\\033");
+char const *const Fs("goink\\\034");
+char const *const Gs("goink\\\035");
+char const *const Rs("goink\\\036");
+char const *const Us("goink\\\037");
+char const *const HexNonPrintable("\\\x03");
+char const *const Delete("\\\177");
+char const *const MultibyteSnowman("\xE2\x98\x83");
+// CHECK-FIXES: {{^}}char const *const MultibyteSnowman("\xE2\x98\x83");{{$}}
+
+char const *const TrailingSpace("A line \\with space. \n");
+char const *const TrailingNewLine("A single \\line.\n");
+char const *const AlreadyRaw(R"(foobie\\bletch)");
+char const *const UTF8Literal(u8"foobie\\bletch");
+char const *const UTF8RawLiteral(u8R"(foobie\\bletch)");
+// TODO: enable these tests once all supported compilers
+// support char16_t and char32_t (VS2013 does not)
+// char16_t const *const UTF16Literal(u"foobie\\bletch");
+// char16_t const *const UTF16RawLiteral(uR"(foobie\\bletch)");
+// char32_t const *const UTF32Literal(U"foobie\\bletch");
+// char32_t const *const UTF32RawLiteral(UR"(foobie\\bletch)");
+wchar_t const *const WideLiteral(L"foobie\\bletch");
+wchar_t const *const WideRawLiteral(LR"(foobie\\bletch)");
+
+char const *const SingleQuote("goink\'frob");
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: {{.*}} can be written as a raw string literal
+// CHECK-XFIXES: {{^}}char const *const SingleQuote(R"(goink'frob)");{{$}}
+
+char const *const DoubleQuote("goink\"frob");
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const DoubleQuote(R"(goink"frob)");{{$}}
+
+char const *const QuestionMark("goink\?frob");
+// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const QuestionMark(R"(goink?frob)");{{$}}
+
+char const *const RegEx("goink\\(one|two\\)\\\\\\?.*\\nfrob");
+// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const RegEx(R"(goink\(one|two\)\\\?.*\nfrob)");{{$}}
+
+char const *const Path("C:\\Program Files\\Vendor\\Application\\Application.exe");
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const Path(R"(C:\Program Files\Vendor\Application\Application.exe)");{{$}}
+
+char const *const ContainsSentinel("who\\ops)\"");
+// CHECK-MESSAGES: :[[@LINE-1]]:36: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const ContainsSentinel(R"lit(who\ops)")lit");{{$}}
+
+char const *const ContainsDelim("whoops)\")lit\"");
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const ContainsDelim(R"lit1(whoops)")lit")lit1");{{$}}
+
+char const *const OctalPrintable("\100\\");
+// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const OctalPrintable(R"(@\)");{{$}}
+
+char const *const HexPrintable("\x40\\");
+// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const HexPrintable(R"(@\)");{{$}}
+
+char const *const prettyFunction(__PRETTY_FUNCTION__);
+char const *const function(__FUNCTION__);
+char const *const func(__func__);
+
+#define TRICK(arg_) #arg_
+char const *const MacroBody = TRICK(foo\\bar);
+
+#define HAT(rabbit_) #rabbit_ "foo\\bar"
+char const *const StringizedMacroArgument = HAT(foo\\bar);
+
+#define SUBST(lit_) lit_
+char const *const MacroArgument = SUBST("foo\\bar");
+// FIXME: We should be able to replace this string literal macro argument
+
+template <typename T>
+void fn(char const *const Arg) {
+ char const *const Str("foo\\bar");
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: {{.*}} can be written as a raw string literal
+ // CHECK-FIXES: {{^}} char const *const Str(R"(foo\bar)");{{$}}
+}
+
+template <>
+void fn<int>(char const *const Arg) {
+ char const *const Str("foo\\bar");
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: {{.*}} can be written as a raw string literal
+ // CHECK-FIXES: {{^}} char const *const Str(R"(foo\bar)");{{$}}
+}
+
+void callFn() {
+ fn<int>("foo\\bar");
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} can be written as a raw string literal
+ // CHECK-FIXES: {{^}} fn<int>(R"(foo\bar)");{{$}}
+ fn<double>("foo\\bar");
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} can be written as a raw string literal
+ // CHECK-FIXES: {{^}} fn<double>(R"(foo\bar)");{{$}}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-redundant-void-arg-delayed.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-redundant-void-arg-delayed.cpp
new file mode 100644
index 0000000..dd88775
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-redundant-void-arg-delayed.cpp
@@ -0,0 +1,28 @@
+// RUN: %check_clang_tidy %s modernize-redundant-void-arg %t -- -- -fdelayed-template-parsing
+
+int foo(void) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: redundant void argument list in function definition [modernize-redundant-void-arg]
+// CHECK-FIXES: {{^}}int foo() {{{$}}
+ return 0;
+}
+
+template <class T>
+struct MyFoo {
+ int foo(void) {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant void argument list in function definition [modernize-redundant-void-arg]
+// CHECK-FIXES: {{^}} int foo() {{{$}}
+ return 0;
+ }
+};
+// Explicit instantiation.
+template class MyFoo<int>;
+
+template <class T>
+struct MyBar {
+ // This declaration isn't instantiated and won't be parsed 'delayed-template-parsing'.
+ int foo(void) {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant void argument list in function definition [modernize-redundant-void-arg]
+// CHECK-FIXES: {{^}} int foo() {{{$}}
+ return 0;
+ }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-redundant-void-arg.c b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-redundant-void-arg.c
new file mode 100644
index 0000000..fdaf375
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-redundant-void-arg.c
@@ -0,0 +1,58 @@
+// RUN: clang-tidy -checks=-*,modernize-redundant-void-arg %s -- -x c | count 0
+
+#define NULL 0
+
+extern int i;
+
+int foo2() {
+ return 0;
+}
+
+int j = 1;
+
+int foo(void) {
+ return 0;
+}
+
+typedef unsigned int my_uint;
+
+typedef void my_void;
+
+// A function taking void and returning a pointer to function taking void
+// and returning int.
+int (*returns_fn_void_int(void))(void);
+
+typedef int (*returns_fn_void_int_t(void))(void);
+
+int (*returns_fn_void_int(void))(void) {
+ return NULL;
+}
+
+// A function taking void and returning a pointer to a function taking void
+// and returning a pointer to a function taking void and returning void.
+void (*(*returns_fn_returns_fn_void_void(void))(void))(void);
+
+typedef void (*(*returns_fn_returns_fn_void_void_t(void))(void))(void);
+
+void (*(*returns_fn_returns_fn_void_void(void))(void))(void) {
+ return NULL;
+}
+
+void bar() {
+ int i;
+ int *pi = NULL;
+ void *pv = (void *) pi;
+ float f;
+ float *fi;
+ double d;
+ double *pd;
+}
+
+void (*f1)(void);
+void (*f2)(void) = NULL;
+void (*f3)(void) = bar;
+void (*fa)();
+void (*fb)() = NULL;
+void (*fc)() = bar;
+
+typedef void (function_ptr)(void);
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-redundant-void-arg.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-redundant-void-arg.cpp
new file mode 100644
index 0000000..44a726b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-redundant-void-arg.cpp
@@ -0,0 +1,551 @@
+// RUN: %check_clang_tidy %s modernize-redundant-void-arg %t
+
+#define NULL 0
+
+int foo();
+
+void bar();
+
+void bar2();
+
+extern "C" void ecfoo(void);
+
+extern "C" void ecfoo(void) {
+}
+
+extern int i;
+
+int j = 1;
+
+int foo(void) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: redundant void argument list in function definition [modernize-redundant-void-arg]
+// CHECK-FIXES: {{^}}int foo() {{{$}}
+ return 0;
+}
+
+typedef unsigned int my_uint;
+
+typedef void my_void;
+
+// A function taking void and returning a pointer to function taking void
+// and returning int.
+int (*returns_fn_void_int(void))(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: {{.*}} in function declaration
+// CHECK-MESSAGES: :[[@LINE-2]]:34: warning: {{.*}} in function declaration
+// CHECK-FIXES: {{^}}int (*returns_fn_void_int())();{{$}}
+
+typedef int (*returns_fn_void_int_t(void))(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: {{.*}} in typedef
+// CHECK-MESSAGES: :[[@LINE-2]]:44: warning: {{.*}} in typedef
+// CHECK-FIXES: {{^}}typedef int (*returns_fn_void_int_t())();{{$}}
+
+// Should work for type aliases as well as typedef.
+using returns_fn_void_int_t2 = int (*(void))(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:39: warning: {{.*}} in type alias
+// CHECK-MESSAGES: :[[@LINE-2]]:46: warning: {{.*}} in type alias
+// CHECK-FIXES: {{^}}using returns_fn_void_int_t2 = int (*())();{{$}}
+
+int (*returns_fn_void_int(void))(void) {
+// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: {{.*}} in function definition
+// CHECK-MESSAGES: :[[@LINE-2]]:34: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^}}int (*returns_fn_void_int())() {{{$}}
+ return nullptr;
+}
+
+// A function taking void and returning a pointer to a function taking void
+// and returning a pointer to a function taking void and returning void.
+void (*(*returns_fn_returns_fn_void_void(void))(void))(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: {{.*}} in function declaration
+// CHECK-MESSAGES: :[[@LINE-2]]:49: warning: {{.*}} in function declaration
+// CHECK-MESSAGES: :[[@LINE-3]]:56: warning: {{.*}} in function declaration
+// CHECK-FIXES: {{^}}void (*(*returns_fn_returns_fn_void_void())())();{{$}}
+
+typedef void (*(*returns_fn_returns_fn_void_void_t(void))(void))(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:52: warning: {{.*}} in typedef
+// CHECK-MESSAGES: :[[@LINE-2]]:59: warning: {{.*}} in typedef
+// CHECK-MESSAGES: :[[@LINE-3]]:66: warning: {{.*}} in typedef
+// CHECK-FIXES: {{^}}typedef void (*(*returns_fn_returns_fn_void_void_t())())();{{$}}
+
+void (*(*returns_fn_returns_fn_void_void(void))(void))(void) {
+// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: {{.*}} in function definition
+// CHECK-MESSAGES: :[[@LINE-2]]:49: warning: {{.*}} in function definition
+// CHECK-MESSAGES: :[[@LINE-3]]:56: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^}}void (*(*returns_fn_returns_fn_void_void())())() {{{$}}
+ return nullptr;
+}
+
+void bar(void) {
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^}}void bar() {{{$}}
+}
+
+void op_fn(int i) {
+}
+
+class gronk {
+public:
+ gronk();
+ ~gronk();
+
+ void foo();
+ void bar();
+ void bar2
+ ();
+ void operation(int i) { }
+
+private:
+ int m_i;
+ int *m_pi;
+ float m_f;
+ float *m_pf;
+ double m_d;
+ double *m_pd;
+
+ void (*f1)(void);
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} in field declaration
+ // CHECK-FIXES: {{^ }}void (*f1)();{{$}}
+
+ void (*op)(int i);
+
+ void (gronk::*p1)(void);
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: {{.*}} in field declaration
+ // CHECK-FIXES: {{^ }}void (gronk::*p1)();{{$}}
+
+ int (gronk::*p_mi);
+
+ void (gronk::*p2)(int);
+
+ void (*(*returns_fn_returns_fn_void_void(void))(void))(void);
+ // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: {{.*}} in function declaration
+ // CHECK-MESSAGES: :[[@LINE-2]]:51: warning: {{.*}} in function declaration
+ // CHECK-MESSAGES: :[[@LINE-3]]:58: warning: {{.*}} in function declaration
+ // CHECK-FIXES: {{^}} void (*(*returns_fn_returns_fn_void_void())())();{{$}}
+
+ void (*(*(gronk::*returns_fn_returns_fn_void_void_mem)(void))(void))(void);
+ // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: {{.*}} in field declaration
+ // CHECK-MESSAGES: :[[@LINE-2]]:65: warning: {{.*}} in field declaration
+ // CHECK-MESSAGES: :[[@LINE-3]]:72: warning: {{.*}} in field declaration
+ // CHECK-FIXES: {{^}} void (*(*(gronk::*returns_fn_returns_fn_void_void_mem)())())();{{$}}
+};
+
+int i;
+int *pi;
+void *pv = (void *) pi;
+float f;
+float *fi;
+double d;
+double *pd;
+
+void (*f1)(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}} in variable declaration
+// CHECK-FIXES: {{^}}void (*f1)();{{$}}
+
+void (*f2)(void) = nullptr;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f2)() = nullptr;{{$}}
+
+void (*f2b)(void)(nullptr);
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f2b)()(nullptr);{{$}}
+
+void (*f2c)(void){nullptr};
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f2c)(){nullptr};{{$}}
+
+void (*f2d)(void) = NULL;
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f2d)() = NULL;{{$}}
+
+void (*f2e)(void)(NULL);
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f2e)()(NULL);{{$}}
+
+void (*f2f)(void){NULL};
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f2f)(){NULL};{{$}}
+
+void (*f3)(void) = bar;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f3)() = bar;{{$}}
+
+void (*o1)(int i);
+void (*o2)(int i) = nullptr;
+void (*o3)(int i)(nullptr);
+void (*o4)(int i){nullptr};
+void (*o5)(int i) = NULL;
+void (*o6)(int i)(NULL);
+void (*o7)(int i){NULL};
+void (*o8)(int i) = op_fn;
+
+void (*fa)();
+
+void (*fb)() = nullptr;
+
+void (*fc)() = bar;
+
+typedef void (function_ptr)(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: {{.*}} in typedef
+// CHECK-FIXES: {{^}}typedef void (function_ptr)();{{$}}
+
+// intentionally not LLVM style to check preservation of whitesapce
+typedef void (function_ptr2)
+ (
+ void
+ );
+// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: {{.*}} in typedef
+// CHECK-FIXES: {{^typedef void \(function_ptr2\)$}}
+// CHECK-FIXES-NEXT: {{^ \($}}
+// CHECK-FIXES-NEXT: {{^ $}}
+// CHECK-FIXES-NEXT: {{^ \);$}}
+
+// intentionally not LLVM style to check preservation of whitesapce
+typedef
+void
+(
+*
+(
+*
+returns_fn_returns_fn_void_void_t2
+(
+void
+)
+)
+(
+void
+)
+)
+(
+void
+)
+;
+// CHECK-MESSAGES: :[[@LINE-11]]:1: warning: {{.*}} in typedef
+// CHECK-MESSAGES: :[[@LINE-8]]:1: warning: {{.*}} in typedef
+// CHECK-MESSAGES: :[[@LINE-5]]:1: warning: {{.*}} in typedef
+// CHECK-FIXES: {{^typedef$}}
+// CHECK-FIXES-NEXT: {{^void$}}
+// CHECK-FIXES-NEXT: {{^\($}}
+// CHECK-FIXES-NEXT: {{^\*$}}
+// CHECK-FIXES-NEXT: {{^\($}}
+// CHECK-FIXES-NEXT: {{^\*$}}
+// CHECK-FIXES-NEXT: {{^returns_fn_returns_fn_void_void_t2$}}
+// CHECK-FIXES-NEXT: {{^\($}}
+// CHECK-FIXES-NOT: {{[^ ]}}
+// CHECK-FIXES: {{^\)$}}
+// CHECK-FIXES-NEXT: {{^\)$}}
+// CHECK-FIXES-NEXT: {{^\($}}
+// CHECK-FIXES-NOT: {{[^ ]}}
+// CHECK-FIXES: {{^\)$}}
+// CHECK-FIXES-NEXT: {{^\)$}}
+// CHECK-FIXES-NEXT: {{^\($}}
+// CHECK-FIXES-NOT: {{[^ ]}}
+// CHECK-FIXES: {{^\)$}}
+// CHECK-FIXES-NEXT: {{^;$}}
+
+
+void (gronk::*p1)(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: {{.*}} in variable declaration
+// CHECK-FIXES: {{^}}void (gronk::*p1)();{{$}}
+
+void (gronk::*p2)(void) = &gronk::foo;
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (gronk::*p2)() = &gronk::foo;{{$}}
+
+typedef void (gronk::*member_function_ptr)(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:44: warning: {{.*}} in typedef
+// CHECK-FIXES: {{^}}typedef void (gronk::*member_function_ptr)();{{$}}
+
+// intentionally not LLVM style to check preservation of whitesapce
+typedef void (gronk::*member_function_ptr2)
+ (
+ void
+ );
+// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: {{.*}} in typedef
+// CHECK-FIXES: {{^typedef void \(gronk::\*member_function_ptr2\)$}}
+// CHECK-FIXES-NEXT: {{^ \($}}
+// CHECK-FIXES-NEXT: {{^ $}}
+// CHECK-FIXES-NEXT: {{^ \);$}}
+
+void gronk::foo() {
+ void (*f1)(void) = &::bar;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} in variable declaration with initializer
+ // CHECK-FIXES: {{^ }}void (*f1)() = &::bar;{{$}}
+
+ void (*f2)(void);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} in variable declaration
+ // CHECK-FIXES: {{^ }}void (*f2)();{{$}}
+
+ // intentionally not LLVM style to check preservation of whitesapce
+ void (*f3)
+ (
+ void
+ );
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: {{.*}} in variable declaration
+ // CHECK-FIXES: {{^ }}void (*f3){{$}}
+ // CHECK-FIXES-NEXT: {{^ \($}}
+ // CHECK-FIXES-NEXT: {{^ $}}
+ // CHECK-FIXES-NEXT: {{^ \);$}}
+}
+
+void gronk::bar(void) {
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^}}void gronk::bar() {{{$}}
+ void (gronk::*p3)(void) = &gronk::foo;
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: {{.*}} in variable declaration with initializer
+ // CHECK-FIXES: {{^ }}void (gronk::*p3)() = &gronk::foo;{{$}}
+
+ void (gronk::*p4)(void);
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: {{.*}} in variable declaration
+ // CHECK-FIXES: {{^ }}void (gronk::*p4)();{{$}}
+
+ // intentionally not LLVM style to check preservation of whitesapce
+ void (gronk::*p5)
+ (
+ void
+ );
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: {{.*}} in variable declaration
+ // CHECK-FIXES: {{^ }}void (gronk::*p5){{$}}
+ // CHECK-FIXES-NEXT: {{^ \($}}
+ // CHECK-FIXES-NExT: {{^ $}}
+ // CHECK-FIXES-NExT: {{^ \);$}}
+}
+
+// intentionally not LLVM style to check preservation of whitesapce
+void gronk::bar2
+ (
+ void
+ )
+// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^void gronk::bar2$}}
+// CHECK-FIXES-NEXT: {{^ \($}}
+// CHECK-FIXES-NEXT: {{^ $}}
+// CHECK-FIXES-NEXT: {{^ \)$}}
+{
+}
+
+gronk::gronk(void)
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^}}gronk::gronk(){{$}}
+ : f1(nullptr),
+ p1(nullptr) {
+}
+
+gronk::~gronk(void) {
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^}}gronk::~gronk() {{{$}}
+}
+
+class nutter {
+public:
+ nutter();
+};
+
+nutter::nutter(void) {
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^}}nutter::nutter() {{{$}}
+ void (*f3)(void) = static_cast<void (*)(void)>(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} in variable declaration with initializer
+ // CHECK-MESSAGES: :[[@LINE-2]]:43: warning: {{.*}} in named cast
+ // CHECK-FIXES: void (*f3)() = static_cast<void (*)()>(0);{{$}}
+
+ void (*f4)(void) = (void (*)(void)) 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} in variable declaration with initializer
+ // CHECK-MESSAGES: :[[@LINE-2]]:32: warning: {{.*}} in cast expression
+ // CHECK-FIXES: void (*f4)() = (void (*)()) 0;{{$}}
+
+ void (*f5)(void) = reinterpret_cast<void (*)(void)>(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} in variable declaration with initializer
+ // CHECK-MESSAGES: :[[@LINE-2]]:48: warning: {{.*}} in named cast
+ // CHECK-FIXES: void (*f5)() = reinterpret_cast<void (*)()>(0);{{$}}
+
+ // intentionally not LLVM style to check preservation of whitesapce
+ void (*f6)(void) = static_cast<void (*)
+ (
+ void
+ )>(0);
+ // CHECK-MESSAGES: :[[@LINE-4]]:14: warning: {{.*}} in variable declaration with initializer
+ // CHECK-MESSAGES: :[[@LINE-3]]:11: warning: {{.*}} in named cast
+ // CHECK-FIXES: {{^ }}void (*f6)() = static_cast<void (*){{$}}
+ // CHECK-FIXES-NEXT: {{^ \($}}
+ // CHECK-FIXES-NEXT: {{^ $}}
+ // CHECK-FIXES-NEXT: {{^ }})>(0);{{$}}
+
+ // intentionally not LLVM style to check preservation of whitesapce
+ void (*f7)(void) = (void (*)
+ (
+ void
+ )) 0;
+ // CHECK-MESSAGES: :[[@LINE-4]]:14: warning: {{.*}} in variable declaration with initializer
+ // CHECK-MESSAGES: :[[@LINE-3]]:11: warning: {{.*}} in cast expression
+ // CHECK-FIXES: {{^ }}void (*f7)() = (void (*){{$}}
+ // CHECK-FIXES-NEXT: {{^ \($}}
+ // CHECK-FIXES-NEXT: {{^ $}}
+ // CHECK-FIXES-NEXT: {{^ \)\) 0;$}}
+
+ // intentionally not LLVM style to check preservation of whitesapce
+ void (*f8)(void) = reinterpret_cast<void (*)
+ (
+ void
+ )>(0);
+ // CHECK-MESSAGES: :[[@LINE-4]]:14: warning: {{.*}} in variable declaration with initializer
+ // CHECK-MESSAGES: :[[@LINE-3]]:11: warning: {{.*}} in named cast
+ // CHECK-FIXES: {{^ }}void (*f8)() = reinterpret_cast<void (*){{$}}
+ // CHECK-FIXES-NEXT: {{^ \($}}
+ // CHECK-FIXES-NEXT: {{^ $}}
+ // CHECK-FIXES-NEXT: {{^ \)>\(0\);$}}
+
+ void (*o1)(int) = static_cast<void (*)(int)>(0);
+ void (*o2)(int) = (void (*)(int)) 0;
+ void (*o3)(int) = reinterpret_cast<void (*)(int)>(0);
+}
+
+class generator {
+public:
+ int operator()(void) { return 1; }
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: {{.*}} in function definition
+ // CHECK-FIXES: {{^ }}int operator()() { return 1; }{{$}}
+};
+
+void test_lambda_functions() {
+ auto lamb_duh = [](void (*fn)(void)) { (*fn)(); };
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: {{.*}} in variable declaration
+ // CHECK-FIXES: {{^ }}auto lamb_duh = [](void (*fn)()) { (*fn)(); };{{$}}
+
+ auto lambda_generator = [](void) { return 1; };
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: {{.*}} in lambda expression
+ // CHECK-FIXES: {{^ }}auto lambda_generator = []() { return 1; };{{$}}
+
+ auto gen2 = []() { return 1; };
+
+ auto gen3 = []{ return 1; };
+
+ auto void_returner = [](void) -> void (*)(void) { return f1; };
+ // CHECK-MESSAGES: [[@LINE-1]]:27: warning: {{.*}} in lambda expression
+ // CHECK-MESSAGES: [[@LINE-2]]:45: warning: {{.*}} in lambda expression
+ // CHECK-FIXES: {{^ }}auto void_returner = []() -> void (*)() { return f1; };{{$}}
+}
+
+#define M(x) x
+
+M(void inmacro(void) {})
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} in function definition
+// CHECK-FIXES: M(void inmacro() {})
+
+#define F(A, B) \
+ struct F_##A##_##B { \
+ F_##A##_##B(void); \
+ }; \
+ F_##A##_##B::F_##A##_##B(void)
+
+F(Foo, Bar) {
+
+}
+
+struct DefinitionWithNoBody {
+ DefinitionWithNoBody(void) = delete;
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: {{.*}} in function definition
+ // CHECK-FIXES: DefinitionWithNoBody() = delete;
+};
+
+
+
+#define BODY {}
+#define LAMBDA1 [](void){}
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg]
+// CHECK-FIXES: LAMBDA1 [](){}
+
+#define LAMBDA2 [](void)BODY
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg]
+// CHECK-FIXES: LAMBDA2 []()BODY
+
+#define LAMBDA3(captures, args, body) captures args body
+#define WRAP(...) __VA_ARGS__
+
+#define LAMBDA4 (void)LAMBDA3([],(void),BODY)
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg]
+// CHECK-FIXES: LAMBDA4 (void)LAMBDA3([],(),BODY)
+
+#define LAMBDA5 []() -> void (*)(void) {return BODY;}
+// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg]
+// CHECK-FIXES: LAMBDA5 []() -> void (*)() {return BODY;}
+void lambda_expression_with_macro_test(){
+ (void)LAMBDA1;
+ (void)LAMBDA2;
+ (void)LAMBDA3([], (void), BODY);
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg]
+ // CHECK-FIXES: (void)LAMBDA3([], (), BODY);
+
+ LAMBDA4;
+ LAMBDA5;
+ WRAP((void)WRAP(WRAP(LAMBDA3(WRAP([]), WRAP((void)), WRAP(BODY)))));
+ // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg]
+ // CHECK-FIXES: WRAP((void)WRAP(WRAP(LAMBDA3(WRAP([]), WRAP(()), WRAP(BODY)))));
+
+ (void)WRAP([](void) {});
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg]
+ // CHECK-FIXES: (void)WRAP([]() {});
+
+ [](void) BODY;
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg]
+ // CHECK-FIXES: []() BODY;
+}
+
+struct S_1 {
+ void g_1(void) const {
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant void argument list in function definition [modernize-redundant-void-arg]
+ // CHECK-FIXES: void g_1() const {
+ int a;
+ (void)a;
+ }
+
+ void g_2() const {
+ int a;
+ (void)a;
+ }
+};
+
+template <typename T0>
+struct S_2 {
+ void g_1(void) const {
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant void argument list in function definition [modernize-redundant-void-arg]
+ // CHECK-FIXES: void g_1() const {
+ int a;
+ (void)a;
+ }
+
+ void g_2() const {
+ int a;
+ (void)a;
+ }
+};
+
+template <typename T0>
+struct S_3 {
+ template <typename T1>
+ void g_1(void) const {
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant void argument list in function definition [modernize-redundant-void-arg]
+ // CHECK-FIXES: void g_1() const {
+ int a;
+ (void)a;
+ }
+ template <typename T2>
+ void g_2() const {
+ int a;
+ (void)a;
+ }
+};
+
+template <typename T1>
+void g_3(void) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: redundant void argument list in function definition [modernize-redundant-void-arg]
+ // CHECK-FIXES: void g_3() {
+ int a;
+ (void)a;
+}
+
+//Template instantiation
+void f_testTemplate() {
+ S_1();
+ S_2<int>();
+ S_3<int>();
+ g_3<int>();
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-replace-auto-ptr.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-replace-auto-ptr.cpp
new file mode 100644
index 0000000..13405b2
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-replace-auto-ptr.cpp
@@ -0,0 +1,304 @@
+// RUN: %check_clang_tidy %s modernize-replace-auto-ptr %t -- -- \
+// RUN: -std=c++11 -I %S/Inputs/modernize-replace-auto-ptr
+
+// CHECK-FIXES: #include <utility>
+
+#include "memory.h"
+
+// Instrumentation for auto_ptr_ref test.
+struct Base {};
+struct Derived : Base {};
+std::auto_ptr<Derived> create_derived_ptr();
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: auto_ptr is deprecated, use unique_ptr instead [modernize-replace-auto-ptr]
+// CHECK-FIXES: std::unique_ptr<Derived> create_derived_ptr();
+
+
+// Test function return values (declaration)
+std::auto_ptr<char> f_5();
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: auto_ptr is deprecated
+// CHECK-FIXES: std::unique_ptr<char> f_5()
+
+
+// Test function parameters.
+void f_6(std::auto_ptr<int>);
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: auto_ptr is deprecated
+// CHECK-FIXES: void f_6(std::unique_ptr<int>);
+void f_7(const std::auto_ptr<int> &);
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: auto_ptr is deprecated
+// CHECK-FIXES: void f_7(const std::unique_ptr<int> &);
+
+
+// Test on record type fields.
+struct A {
+ std::auto_ptr<int> field;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+ // CHECK-FIXES: std::unique_ptr<int> field;
+
+ typedef std::auto_ptr<int> int_ptr_type;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: auto_ptr is deprecated
+ // CHECK-FIXES: typedef std::unique_ptr<int> int_ptr_type;
+};
+
+
+// FIXME: Test template WITH instantiation.
+template <typename T> struct B {
+ typedef typename std::auto_ptr<T> created_type;
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: auto_ptr is deprecated
+ // CHECK-FIXES: typedef typename std::unique_ptr<T> created_type;
+
+ created_type create() { return std::auto_ptr<T>(new T()); }
+ // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: auto_ptr is deprecated
+ // CHECK-FIXES: created_type create() { return std::unique_ptr<T>(new T()); }
+};
+
+
+// Test 'using' in a namespace (declaration)
+namespace ns_1 {
+// Test multiple using declarations.
+ using std::auto_ptr;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: auto_ptr is deprecated
+ // CHECK-FIXES: using std::unique_ptr;
+ using std::auto_ptr;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: auto_ptr is deprecated
+ // CHECK-FIXES: using std::unique_ptr;
+}
+
+
+namespace ns_2 {
+template <typename T> struct auto_ptr {};
+}
+
+void f_1() {
+ std::auto_ptr<int> a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+ // CHECK-FIXES: std::unique_ptr<int> a;
+
+ // Check that spaces aren't modified unnecessarily.
+ std:: auto_ptr <int> b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: auto_ptr is deprecated
+ // CHECK-FIXES: std:: unique_ptr <int> b;
+ std :: auto_ptr < char > c(new char());
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: auto_ptr is deprecated
+ // CHECK-FIXES: std :: unique_ptr < char > c(new char());
+
+ // Test construction from a temporary.
+ std::auto_ptr<char> d = std::auto_ptr<char>();
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+ // CHECK-MESSAGES: :[[@LINE-2]]:32: warning: auto_ptr is deprecated
+ // CHECK-FIXES: std::unique_ptr<char> d = std::unique_ptr<char>();
+
+ typedef std::auto_ptr<int> int_ptr_t;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: auto_ptr is deprecated
+ // CHECK-FIXES: typedef std::unique_ptr<int> int_ptr_t;
+ int_ptr_t e(new int());
+
+ // Test pointers.
+ std::auto_ptr<int> *f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+ // CHECK-FIXES: std::unique_ptr<int> *f;
+
+ // Test 'static' declarations.
+ static std::auto_ptr<int> g;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: auto_ptr is deprecated
+ // CHECK-FIXES: static std::unique_ptr<int> g;
+
+ // Test with cv-qualifiers.
+ const std::auto_ptr<int> h;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: auto_ptr is deprecated
+ // CHECK-FIXES: const std::unique_ptr<int> h;
+ volatile std::auto_ptr<int> i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: auto_ptr is deprecated
+ // CHECK-FIXES: volatile std::unique_ptr<int> i;
+ const volatile std::auto_ptr<int> j;
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: auto_ptr is deprecated
+ // CHECK-FIXES: const volatile std::unique_ptr<int> j;
+
+ // Test auto and initializer-list.
+ auto k = std::auto_ptr<int>{};
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: auto_ptr is deprecated
+ // CHECK-FIXES: auto k = std::unique_ptr<int>{};
+ std::auto_ptr<int> l{std::auto_ptr<int>()};
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+ // CHECK-MESSAGES: :[[@LINE-2]]:29: warning: auto_ptr is deprecated
+ // CHECK-FIXES: std::unique_ptr<int> l{std::unique_ptr<int>()};
+
+ // Test interlocked auto_ptr.
+ std::auto_ptr<std::auto_ptr<int> > m;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+ // CHECK-MESSAGES: :[[@LINE-2]]:22: warning: auto_ptr is deprecated
+ // CHECK-FIXES: std::unique_ptr<std::unique_ptr<int> > m;
+
+ // Test temporaries.
+ std::auto_ptr<char>();
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+ // CHECK-FIXES: std::unique_ptr<char>();
+
+ // Test void-specialization.
+ std::auto_ptr<void> n;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+ // CHECK-FIXES: std::unique_ptr<void> n;
+
+ // Test template WITH instantiation (instantiation).
+ B<double> o;
+ std::auto_ptr<double> p(o.create());
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+ // CHECK-FIXES: std::unique_ptr<double> p(o.create());
+
+ // Test 'using' in a namespace ("definition").
+ ns_1::auto_ptr<int> q;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: auto_ptr is deprecated
+ // CHECK-FIXES: ns_1::unique_ptr<int> q;
+
+ // Test construction with an 'auto_ptr_ref'.
+ std::auto_ptr<Base> r(create_derived_ptr());
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+ // CHECK-FIXES: std::unique_ptr<Base> r(create_derived_ptr());
+}
+
+// Test without the nested name specifiers.
+void f_2() {
+ using namespace std;
+
+ auto_ptr<int> a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: auto_ptr is deprecated
+ // CHECK-FIXES: unique_ptr<int> a;
+}
+
+// Test using declaration.
+void f_3() {
+ using std::auto_ptr;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: auto_ptr is deprecated
+ // CHECK-FIXES: using std::unique_ptr;
+
+ auto_ptr<int> a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: auto_ptr is deprecated
+ // CHECK-FIXES: unique_ptr<int> a;
+}
+
+// Test messing-up with macros.
+void f_4() {
+#define MACRO_1 <char>
+ std::auto_ptr MACRO_1 p(new char());
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+ // CHECK-FIXES: std::unique_ptr MACRO_1 p(new char());
+#define MACRO_2 auto_ptr
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: auto_ptr is deprecated
+ // CHECK-FIXES: #define MACRO_2 unique_ptr
+ std::MACRO_2<int> q;
+#define MACRO_3(Type) std::auto_ptr<Type>
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: auto_ptr is deprecated
+ // CHECK-FIXES: #define MACRO_3(Type) std::unique_ptr<Type>
+ MACRO_3(float)r(new float());
+#define MACRO_4 std::auto_ptr
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: auto_ptr is deprecated
+ // CHECK-FIXES: #define MACRO_4 std::unique_ptr
+ using MACRO_4;
+#undef MACRO_1
+#undef MACRO_2
+#undef MACRO_3
+#undef MACRO_4
+}
+
+// Test function return values (definition).
+std::auto_ptr<char> f_5()
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: auto_ptr is deprecated
+ // CHECK-FIXES: std::unique_ptr<char> f_5()
+{
+ // Test constructor.
+ return std::auto_ptr<char>(new char());
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: auto_ptr is deprecated
+ // CHECK-FIXES: return std::unique_ptr<char>(new char());
+}
+
+// Test that non-std auto_ptr aren't replaced.
+void f_8() {
+ ns_2::auto_ptr<char> a;
+ using namespace ns_2;
+ auto_ptr<int> b;
+}
+
+// Fail to modify when the template is never instantiated.
+//
+// This might not be an issue. If it's never used it doesn't really matter if
+// it's changed or not. If it's a header and one of the source use it, then it
+// will still be changed.
+template <typename X>
+void f() {
+ std::auto_ptr<X> p;
+}
+
+// FIXME: Alias template could be replaced if a matcher existed.
+namespace std {
+template <typename T> using aaaaaaaa = auto_ptr<T>;
+}
+
+// We want to avoid replacing 'aaaaaaaa' by unique_ptr here. It's better to
+// change the type alias directly.
+std::aaaaaaaa<int> d;
+
+
+void takes_ownership_fn(std::auto_ptr<int> x);
+// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: auto_ptr is deprecated
+// CHECK-FIXES: void takes_ownership_fn(std::unique_ptr<int> x);
+
+std::auto_ptr<int> get_by_value();
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: auto_ptr is deprecated
+// CHECK-FIXES: std::unique_ptr<int> get_by_value();
+
+class Wrapper {
+ public:
+ std::auto_ptr<int> &get_wrapped();
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+
+ private:
+ std::auto_ptr<int> wrapped;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+};
+
+void f() {
+ std::auto_ptr<int> a, b, c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+ // CHECK-FIXES: std::unique_ptr<int> a, b, c;
+ Wrapper wrapper_a, wrapper_b;
+
+ a = b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::move to transfer ownership
+ // CHECK-FIXES: a = std::move(b);
+
+ wrapper_a.get_wrapped() = wrapper_b.get_wrapped();
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::move to transfer ownership
+ // CHECK-FIXES: wrapper_a.get_wrapped() = std::move(wrapper_b.get_wrapped());
+
+ // Test that 'std::move()' is inserted when call to the
+ // copy-constructor are made.
+ takes_ownership_fn(c);
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use std::move to transfer ownership
+ // CHECK-FIXES: takes_ownership_fn(std::move(c));
+ takes_ownership_fn(wrapper_a.get_wrapped());
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use std::move to transfer ownership
+ // CHECK-FIXES: takes_ownership_fn(std::move(wrapper_a.get_wrapped()));
+
+ std::auto_ptr<int> d[] = { std::auto_ptr<int>(new int(1)),
+ std::auto_ptr<int>(new int(2)) };
+ // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: auto_ptr is deprecated
+ // CHECK-MESSAGES: :[[@LINE-3]]:35: warning: auto_ptr is deprecated
+ // CHECK-MESSAGES: :[[@LINE-3]]:35: warning: auto_ptr is deprecated
+ // CHECK-FIXES: std::unique_ptr<int> d[] = { std::unique_ptr<int>(new int(1)),
+ // CHECK-FIXES-NEXT: std::unique_ptr<int>(new int(2)) };
+ std::auto_ptr<int> e = d[0];
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+ // CHECK-MESSAGES: :[[@LINE-2]]:26: warning: use std::move to transfer ownership
+ // CHECK: std::unique_ptr<int> e = std::move(d[0]);
+
+ // Test that std::move() is not used when assigning an rvalue
+ std::auto_ptr<int> f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+ // CHECK-FIXES: std::unique_ptr<int> f;
+ f = std::auto_ptr<int>(new int(0));
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: auto_ptr is deprecated
+ // CHECK-NEXT: f = std::unique_ptr<int>(new int(0));
+
+ std::auto_ptr<int> g = get_by_value();
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+ // CHECK-FIXES: std::unique_ptr<int> g = get_by_value();
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-replace-random-shuffle.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-replace-random-shuffle.cpp
new file mode 100644
index 0000000..019471e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-replace-random-shuffle.cpp
@@ -0,0 +1,57 @@
+// RUN: %check_clang_tidy %s modernize-replace-random-shuffle %t -- -- -std=c++11
+
+//CHECK-FIXES: #include <random>
+
+namespace std {
+template <typename T> struct vec_iterator {
+ T *ptr;
+ vec_iterator operator++(int);
+};
+
+template <typename T> struct vector {
+ typedef vec_iterator<T> iterator;
+
+ iterator begin();
+ iterator end();
+};
+
+template <typename FwIt>
+void random_shuffle(FwIt begin, FwIt end);
+
+template <typename FwIt, typename randomFunc>
+void random_shuffle(FwIt begin, FwIt end, randomFunc& randomfunc);
+
+template <typename FwIt>
+void shuffle(FwIt begin, FwIt end);
+} // namespace std
+
+// Random Func
+int myrandom (int i) { return i;}
+
+using namespace std;
+
+int main() {
+ std::vector<int> vec;
+
+ std::random_shuffle(vec.begin(), vec.end());
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'std::random_shuffle' has been removed in C++17; use 'std::shuffle' instead
+ // CHECK-FIXES: std::shuffle(vec.begin(), vec.end(), std::mt19937(std::random_device()()));
+
+ std::shuffle(vec.begin(), vec.end());
+
+ random_shuffle(vec.begin(), vec.end());
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'std::random_shuffle' has been removed in C++17; use 'std::shuffle' instead
+ // CHECK-FIXES: shuffle(vec.begin(), vec.end(), std::mt19937(std::random_device()()));
+
+ std::random_shuffle(vec.begin(), vec.end(), myrandom);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'std::random_shuffle' has been removed in C++17; use 'std::shuffle' and an alternative random mechanism instead
+ // CHECK-FIXES: std::shuffle(vec.begin(), vec.end(), std::mt19937(std::random_device()()));
+
+ random_shuffle(vec.begin(), vec.end(), myrandom);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'std::random_shuffle' has been removed in C++17; use 'std::shuffle' and an alternative random mechanism instead
+ // CHECK-FIXES: shuffle(vec.begin(), vec.end(), std::mt19937(std::random_device()()));
+
+ shuffle(vec.begin(), vec.end());
+
+ return 0;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-return-braced-init-list.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-return-braced-init-list.cpp
new file mode 100644
index 0000000..49a41ae
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-return-braced-init-list.cpp
@@ -0,0 +1,198 @@
+// RUN: %check_clang_tidy %s modernize-return-braced-init-list %t -- -- -std=c++14
+
+namespace std {
+typedef decltype(sizeof(int)) size_t;
+
+// libc++'s implementation
+template <class _E>
+class initializer_list {
+ const _E *__begin_;
+ size_t __size_;
+
+ initializer_list(const _E *__b, size_t __s)
+ : __begin_(__b),
+ __size_(__s) {}
+
+public:
+ typedef _E value_type;
+ typedef const _E &reference;
+ typedef const _E &const_reference;
+ typedef size_t size_type;
+
+ typedef const _E *iterator;
+ typedef const _E *const_iterator;
+
+ initializer_list() : __begin_(nullptr), __size_(0) {}
+
+ size_t size() const { return __size_; }
+ const _E *begin() const { return __begin_; }
+ const _E *end() const { return __begin_ + __size_; }
+};
+
+template <typename T>
+class vector {
+public:
+ vector(T) {}
+ vector(std::initializer_list<T>) {}
+};
+}
+
+class Bar {};
+
+Bar b0;
+
+class Foo {
+public:
+ Foo(Bar) {}
+ explicit Foo(Bar, unsigned int) {}
+ Foo(unsigned int) {}
+};
+
+class Baz {
+public:
+ Foo m() {
+ Bar bm;
+ return Foo(bm);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid repeating the return type from the declaration; use a braced initializer list instead [modernize-return-braced-init-list]
+ // CHECK-FIXES: return {bm};
+ }
+};
+
+class Quux : public Foo {
+public:
+ Quux(Bar bar) : Foo(bar) {}
+ Quux(unsigned, unsigned, unsigned k = 0) : Foo(k) {}
+};
+
+Foo f() {
+ Bar b1;
+ return Foo(b1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
+ // CHECK-FIXES: return {b1};
+}
+
+Foo f2() {
+ Bar b2;
+ return {b2};
+}
+
+auto f3() {
+ Bar b3;
+ return Foo(b3);
+}
+
+#define A(b) Foo(b)
+
+Foo f4() {
+ Bar b4;
+ return A(b4);
+}
+
+Foo f5() {
+ Bar b5;
+ return Quux(b5);
+}
+
+Foo f6() {
+ Bar b6;
+ return Foo(b6, 1);
+}
+
+std::vector<int> f7() {
+ int i7 = 1;
+ return std::vector<int>(i7);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
+}
+
+Bar f8() {
+ return {};
+}
+
+Bar f9() {
+ return Bar();
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
+}
+
+Bar f10() {
+ return Bar{};
+}
+
+Foo f11(Bar b11) {
+ return Foo(b11);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
+ // CHECK-FIXES: return {b11};
+}
+
+Foo f12() {
+ return f11(Bar());
+}
+
+Foo f13() {
+ return Foo(Bar()); // 13
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
+ // CHECK-FIXES: return {Bar()}; // 13
+}
+
+Foo f14() {
+ // FIXME: Type narrowing should not occur!
+ return Foo(-1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
+ // CHECK-FIXES: return {-1};
+}
+
+Foo f15() {
+ return Foo(f10());
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
+ // CHECK-FIXES: return {f10()};
+}
+
+Quux f16() {
+ return Quux(1, 2);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
+ // CHECK-FIXES: return {1, 2};
+}
+
+Quux f17() {
+ return Quux(1, 2, 3);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
+ // CHECK-FIXES: return {1, 2, 3};
+}
+
+template <typename T>
+T f19() {
+ return T();
+}
+
+Bar i1 = f19<Bar>();
+Baz i2 = f19<Baz>();
+
+template <typename T>
+Foo f20(T t) {
+ return Foo(t);
+}
+
+Foo i3 = f20(b0);
+
+template <typename T>
+class BazT {
+public:
+ T m() {
+ Bar b;
+ return T(b);
+ }
+
+ Foo m2(T t) {
+ return Foo(t);
+ }
+};
+
+BazT<Foo> bazFoo;
+Foo i4 = bazFoo.m();
+Foo i5 = bazFoo.m2(b0);
+
+BazT<Quux> bazQuux;
+Foo i6 = bazQuux.m();
+Foo i7 = bazQuux.m2(b0);
+
+auto v1 = []() { return std::vector<int>({1, 2}); }();
+auto v2 = []() -> std::vector<int> { return std::vector<int>({1, 2}); }();
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-shrink-to-fit.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-shrink-to-fit.cpp
new file mode 100644
index 0000000..6993d300
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-shrink-to-fit.cpp
@@ -0,0 +1,87 @@
+// RUN: %check_clang_tidy %s modernize-shrink-to-fit %t
+
+namespace std {
+template <typename T> struct vector { void swap(vector &other); };
+}
+
+void f() {
+ std::vector<int> v;
+
+ std::vector<int>(v).swap(v);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the shrink_to_fit method should be used to reduce the capacity of a shrinkable container [modernize-shrink-to-fit]
+ // CHECK-FIXES: {{^ }}v.shrink_to_fit();{{$}}
+
+ std::vector<int> &vref = v;
+ std::vector<int>(vref).swap(vref);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the shrink_to_fit method should
+ // CHECK-FIXES: {{^ }}vref.shrink_to_fit();{{$}}
+
+ std::vector<int> *vptr = &v;
+ std::vector<int>(*vptr).swap(*vptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the shrink_to_fit method should
+ // CHECK-FIXES: {{^ }}vptr->shrink_to_fit();{{$}}
+}
+
+struct X {
+ std::vector<int> v;
+ void f() {
+ std::vector<int>(v).swap(v);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: the shrink_to_fit method should
+ // CHECK-FIXES: {{^ }}v.shrink_to_fit();{{$}}
+
+ std::vector<int> *vptr = &v;
+ std::vector<int>(*vptr).swap(*vptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: the shrink_to_fit method should
+ // CHECK-FIXES: {{^ }}vptr->shrink_to_fit();{{$}}
+ }
+};
+
+template <typename T> void g() {
+ std::vector<int> v;
+ std::vector<int>(v).swap(v);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the shrink_to_fit method should
+ // CHECK-FIXES: {{^ }}v.shrink_to_fit();{{$}}
+
+ std::vector<T> v2;
+ std::vector<T>(v2).swap(v2);
+ // CHECK-FIXES: {{^ }}std::vector<T>(v2).swap(v2);{{$}}
+}
+
+template <typename T> void g2() {
+ std::vector<int> v;
+ std::vector<int>(v).swap(v);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the shrink_to_fit method should
+ // CHECK-FIXES: {{^ }}v.shrink_to_fit();{{$}}
+
+ T v3;
+ T(v3).swap(v3);
+ // CHECK-FIXES: {{^ }}T(v3).swap(v3);{{$}}
+}
+
+#define COPY_AND_SWAP_INT_VEC(x) std::vector<int>(x).swap(x)
+// CHECK-FIXES: #define COPY_AND_SWAP_INT_VEC(x) std::vector<int>(x).swap(x)
+
+void h() {
+ g<int>();
+ g<double>();
+ g<bool>();
+ g2<std::vector<int>>();
+ std::vector<int> v;
+ COPY_AND_SWAP_INT_VEC(v);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the shrink_to_fit method should
+ // CHECK-FIXES: {{^ }}COPY_AND_SWAP_INT_VEC(v);{{$}}
+}
+
+void PR38315() {
+ typedef std::vector<int> Vector;
+ Vector v;
+ Vector(v).swap(v);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the shrink_to_fit method should
+ // CHECK-FIXES: {{^ }}v.shrink_to_fit();{{$}}
+
+ using Vector2 = std::vector<int>;
+ Vector2 v2;
+ Vector2(v2).swap(v2);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the shrink_to_fit method should
+ // CHECK-FIXES: {{^ }}v2.shrink_to_fit();{{$}}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-unary-static-assert.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-unary-static-assert.cpp
new file mode 100644
index 0000000..fd39d5b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-unary-static-assert.cpp
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s modernize-unary-static-assert %t -- -- -std=c++1z
+
+#define FOO static_assert(sizeof(a) <= 15, "");
+#define MSG ""
+
+void f_textless(int a) {
+ static_assert(sizeof(a) <= 10, "");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use unary 'static_assert' when the string literal is an empty string [modernize-unary-static-assert]
+ // CHECK-FIXES: {{^}} static_assert(sizeof(a) <= 10 );{{$}}
+ static_assert(sizeof(a) <= 12, L"");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use unary 'static_assert' when
+ // CHECK-FIXES: {{^}} static_assert(sizeof(a) <= 12 );{{$}}
+ FOO
+ // CHECK-FIXES: {{^}} FOO{{$}}
+ static_assert(sizeof(a) <= 17, MSG);
+ // CHECK-FIXES: {{^}} static_assert(sizeof(a) <= 17, MSG);{{$}}
+}
+
+void f_with_tex(int a) {
+ static_assert(sizeof(a) <= 10, "Size of variable a is out of range!");
+}
+
+void f_unary(int a) { static_assert(sizeof(a) <= 10); }
+
+void f_incorrect_assert() { static_assert(""); }
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-auto-cast-remove-stars.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-auto-cast-remove-stars.cpp
new file mode 100644
index 0000000..97b87b8
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-auto-cast-remove-stars.cpp
@@ -0,0 +1,233 @@
+// RUN: %check_clang_tidy %s modernize-use-auto %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: '1'} , {key: modernize-use-auto.MinTypeNameLength, value: '0'}]}" \
+// RUN: -- -std=c++11 -frtti
+
+struct A {
+ virtual ~A() {}
+};
+
+struct B : public A {};
+
+struct C {};
+
+void f_static_cast() {
+ long l = 1;
+ int i1 = static_cast<int>(l);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto i1 = static_cast<int>(l);
+
+ const int i2 = static_cast<int>(l);
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: const auto i2 = static_cast<int>(l);
+
+ long long ll = static_cast<long long>(l);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto ll = static_cast<long long>(l);
+ unsigned long long ull = static_cast<unsigned long long>(l);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto ull = static_cast<unsigned long long>(l);
+ unsigned int ui = static_cast<unsigned int>(l);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto ui = static_cast<unsigned int>(l);
+ long double ld = static_cast<long double>(l);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto ld = static_cast<long double>(l);
+
+ A *a = new B();
+ B *b1 = static_cast<B *>(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto b1 = static_cast<B *>(a);
+
+ B *const b2 = static_cast<B *>(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto const b2 = static_cast<B *>(a);
+
+ const B *b3 = static_cast<const B *>(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: const auto b3 = static_cast<const B *>(a);
+
+ B &b4 = static_cast<B &>(*a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto &b4 = static_cast<B &>(*a);
+
+ const B &b5 = static_cast<const B &>(*a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: const auto &b5 = static_cast<const B &>(*a);
+
+ B &b6 = static_cast<B &>(*a), &b7 = static_cast<B &>(*a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto &b6 = static_cast<B &>(*a), &b7 = static_cast<B &>(*a);
+
+ // Don't warn when non-cast involved
+ long double cast = static_cast<long double>(l), noncast = 5;
+
+ // Don't warn when auto is already being used.
+ auto i3 = static_cast<int>(l);
+ auto *b8 = static_cast<B *>(a);
+ auto &b9 = static_cast<B &>(*a);
+}
+
+void f_dynamic_cast() {
+ A *a = new B();
+ B *b1 = dynamic_cast<B *>(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto b1 = dynamic_cast<B *>(a);
+
+ B &b2 = dynamic_cast<B &>(*a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto &b2 = dynamic_cast<B &>(*a);
+}
+
+void f_reinterpret_cast() {
+ auto *a = new A();
+ C *c1 = reinterpret_cast<C *>(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto c1 = reinterpret_cast<C *>(a);
+
+ C &c2 = reinterpret_cast<C &>(*a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto &c2 = reinterpret_cast<C &>(*a);
+}
+
+void f_const_cast() {
+ const A *a1 = new A();
+ A *a2 = const_cast<A *>(a1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto a2 = const_cast<A *>(a1);
+ A &a3 = const_cast<A &>(*a1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto &a3 = const_cast<A &>(*a1);
+}
+
+typedef unsigned char xmlChar;
+#define BAD_CAST (xmlChar *)
+
+#define XMLCHAR_CAST(x) (xmlChar *)(x)
+
+#define CAST_IN_MACRO(x) \
+ do { \
+ xmlChar *s = (xmlChar *)(x); \
+ } while (false);
+// CHECK-FIXES: xmlChar *s = (xmlChar *)(x);
+
+void f_cstyle_cast() {
+ auto *a = new A();
+ C *c1 = (C *)a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto c1 = (C *)a;
+
+ C &c2 = (C &)*a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto &c2 = (C &)*a;
+
+ xmlChar *s = BAD_CAST "xml";
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto s = BAD_CAST "xml";
+ xmlChar *t = XMLCHAR_CAST("xml");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto t = XMLCHAR_CAST("xml");
+ CAST_IN_MACRO("xml");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+}
+
+void f_functional_cast() {
+ long l = 1;
+ int i1 = int(l);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto i1 = int(l);
+
+ B b;
+ A a = A(b);
+}
+
+class StringRef
+{
+public:
+ StringRef(const char *);
+ const char *begin() const;
+ const char *end() const;
+};
+
+template <typename T, typename U>
+T template_value_cast(const U &u);
+
+template <typename T, typename U>
+T *template_pointer_cast(U *u);
+
+template <typename T, typename U>
+T &template_reference_cast(U &u);
+
+template <typename T, typename U>
+const T *template_const_pointer_cast(const U *u);
+
+template <typename T, typename U>
+const T &template_const_reference_cast(const U &u);
+
+template <typename T>
+T template_value_get(StringRef s);
+
+struct S {
+ template <typename T>
+ const T *template_member_get();
+};
+
+template <typename T>
+T max(T t1, T t2);
+
+void f_template_cast()
+{
+ double d = 0;
+ int i1 = template_value_cast<int>(d);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+ // CHECK-FIXES: auto i1 = template_value_cast<int>(d);
+
+ A *a = new B();
+ B *b1 = template_value_cast<B *>(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+ // CHECK-FIXES: auto b1 = template_value_cast<B *>(a);
+ B &b2 = template_value_cast<B &>(*a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+ // CHECK-FIXES: auto &b2 = template_value_cast<B &>(*a);
+ B *b3 = template_pointer_cast<B>(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+ // CHECK-FIXES: auto b3 = template_pointer_cast<B>(a);
+ B &b4 = template_reference_cast<B>(*a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+ // CHECK-FIXES: auto &b4 = template_reference_cast<B>(*a);
+ const B *b5 = template_const_pointer_cast<B>(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a template cast to avoid duplicating the type name
+ // CHECK-FIXES: const auto b5 = template_const_pointer_cast<B>(a);
+ const B &b6 = template_const_reference_cast<B>(*a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a template cast to avoid duplicating the type name
+ // CHECK-FIXES: const auto &b6 = template_const_reference_cast<B>(*a);
+ B *b7 = template_value_get<B *>("foo");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+ // CHECK-FIXES: auto b7 = template_value_get<B *>("foo");
+ B *b8 = template_value_get<B *>("foo"), *b9 = template_value_get<B *>("bar");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+ // CHECK-FIXES: auto b8 = template_value_get<B *>("foo"), b9 = template_value_get<B *>("bar");
+
+ S s;
+ const B *b10 = s.template_member_get<B>();
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a template cast to avoid duplicating the type name
+ // CHECK-FIXES: const auto b10 = s.template_member_get<B>();
+
+ // Don't warn when auto is already being used.
+ auto i2 = template_value_cast<int>(d);
+ auto *i3 = template_value_cast<int *>(d);
+ auto **i4 = template_value_cast<int **>(d);
+ auto &i5 = template_reference_cast<int>(d);
+
+ // Don't warn for implicit template arguments.
+ int i6 = max(i1, i2);
+
+ // Don't warn for mismatched var and initializer types.
+ A *a1 = template_value_cast<B *>(a);
+
+ // Don't warn for mismatched var types.
+ B *b11 = template_value_get<B *>("foo"), b12 = template_value_get<B>("bar");
+
+ // Don't warn for implicit variables.
+ for (auto &c : template_reference_cast<StringRef>(*a)) {
+ }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-auto-cast.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-auto-cast.cpp
new file mode 100644
index 0000000..e07c9cb
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-auto-cast.cpp
@@ -0,0 +1,233 @@
+// RUN: %check_clang_tidy %s modernize-use-auto %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-auto.MinTypeNameLength, value: '0'}]}" \
+// RUN: -- -std=c++11 -I %S/Inputs/modernize-use-auto -frtti
+
+struct A {
+ virtual ~A() {}
+};
+
+struct B : public A {};
+
+struct C {};
+
+void f_static_cast() {
+ long l = 1;
+ int i1 = static_cast<int>(l);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto i1 = static_cast<int>(l);
+
+ const int i2 = static_cast<int>(l);
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: const auto i2 = static_cast<int>(l);
+
+ long long ll = static_cast<long long>(l);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto ll = static_cast<long long>(l);
+ unsigned long long ull = static_cast<unsigned long long>(l);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto ull = static_cast<unsigned long long>(l);
+ unsigned int ui = static_cast<unsigned int>(l);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto ui = static_cast<unsigned int>(l);
+ long double ld = static_cast<long double>(l);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto ld = static_cast<long double>(l);
+
+ A *a = new B();
+ B *b1 = static_cast<B *>(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto *b1 = static_cast<B *>(a);
+
+ B *const b2 = static_cast<B *>(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto *const b2 = static_cast<B *>(a);
+
+ const B *b3 = static_cast<const B *>(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: const auto *b3 = static_cast<const B *>(a);
+
+ B &b4 = static_cast<B &>(*a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto &b4 = static_cast<B &>(*a);
+
+ const B &b5 = static_cast<const B &>(*a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: const auto &b5 = static_cast<const B &>(*a);
+
+ B &b6 = static_cast<B &>(*a), &b7 = static_cast<B &>(*a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto &b6 = static_cast<B &>(*a), &b7 = static_cast<B &>(*a);
+
+ // Don't warn when non-cast involved
+ long double cast = static_cast<long double>(l), noncast = 5;
+
+ // Don't warn when auto is already being used.
+ auto i3 = static_cast<int>(l);
+ auto *b8 = static_cast<B *>(a);
+ auto &b9 = static_cast<B &>(*a);
+}
+
+void f_dynamic_cast() {
+ A *a = new B();
+ B *b1 = dynamic_cast<B *>(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto *b1 = dynamic_cast<B *>(a);
+
+ B &b2 = dynamic_cast<B &>(*a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto &b2 = dynamic_cast<B &>(*a);
+}
+
+void f_reinterpret_cast() {
+ auto *a = new A();
+ C *c1 = reinterpret_cast<C *>(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto *c1 = reinterpret_cast<C *>(a);
+
+ C &c2 = reinterpret_cast<C &>(*a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto &c2 = reinterpret_cast<C &>(*a);
+}
+
+void f_const_cast() {
+ const A *a1 = new A();
+ A *a2 = const_cast<A *>(a1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto *a2 = const_cast<A *>(a1);
+ A &a3 = const_cast<A &>(*a1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto &a3 = const_cast<A &>(*a1);
+}
+
+typedef unsigned char xmlChar;
+#define BAD_CAST (xmlChar *)
+
+#define XMLCHAR_CAST(x) (xmlChar *)(x)
+
+#define CAST_IN_MACRO(x) \
+ do { \
+ xmlChar *s = (xmlChar *)(x); \
+ } while (false);
+// CHECK-FIXES: xmlChar *s = (xmlChar *)(x);
+
+void f_cstyle_cast() {
+ auto *a = new A();
+ C *c1 = (C *)a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto *c1 = (C *)a;
+
+ C &c2 = (C &)*a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto &c2 = (C &)*a;
+
+ xmlChar *s = BAD_CAST "xml";
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto *s = BAD_CAST "xml";
+ xmlChar *t = XMLCHAR_CAST("xml");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto *t = XMLCHAR_CAST("xml");
+ CAST_IN_MACRO("xml");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+}
+
+void f_functional_cast() {
+ long l = 1;
+ int i1 = int(l);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+ // CHECK-FIXES: auto i1 = int(l);
+
+ B b;
+ A a = A(b);
+}
+
+class StringRef
+{
+public:
+ StringRef(const char *);
+ const char *begin() const;
+ const char *end() const;
+};
+
+template <typename T, typename U>
+T template_value_cast(const U &u);
+
+template <typename T, typename U>
+T *template_pointer_cast(U *u);
+
+template <typename T, typename U>
+T &template_reference_cast(U &u);
+
+template <typename T, typename U>
+const T *template_const_pointer_cast(const U *u);
+
+template <typename T, typename U>
+const T &template_const_reference_cast(const U &u);
+
+template <typename T>
+T template_value_get(StringRef s);
+
+struct S {
+ template <typename T>
+ const T *template_member_get();
+};
+
+template <typename T>
+T max(T t1, T t2);
+
+void f_template_cast()
+{
+ double d = 0;
+ int i1 = template_value_cast<int>(d);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+ // CHECK-FIXES: auto i1 = template_value_cast<int>(d);
+
+ A *a = new B();
+ B *b1 = template_value_cast<B *>(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+ // CHECK-FIXES: auto *b1 = template_value_cast<B *>(a);
+ B &b2 = template_value_cast<B &>(*a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+ // CHECK-FIXES: auto &b2 = template_value_cast<B &>(*a);
+ B *b3 = template_pointer_cast<B>(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+ // CHECK-FIXES: auto *b3 = template_pointer_cast<B>(a);
+ B &b4 = template_reference_cast<B>(*a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+ // CHECK-FIXES: auto &b4 = template_reference_cast<B>(*a);
+ const B *b5 = template_const_pointer_cast<B>(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a template cast to avoid duplicating the type name
+ // CHECK-FIXES: const auto *b5 = template_const_pointer_cast<B>(a);
+ const B &b6 = template_const_reference_cast<B>(*a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a template cast to avoid duplicating the type name
+ // CHECK-FIXES: const auto &b6 = template_const_reference_cast<B>(*a);
+ B *b7 = template_value_get<B *>("foo");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+ // CHECK-FIXES: auto *b7 = template_value_get<B *>("foo");
+ B *b8 = template_value_get<B *>("foo"), *b9 = template_value_get<B *>("bar");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+ // CHECK-FIXES: auto *b8 = template_value_get<B *>("foo"), *b9 = template_value_get<B *>("bar");
+
+ S s;
+ const B *b10 = s.template_member_get<B>();
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a template cast to avoid duplicating the type name
+ // CHECK-FIXES: const auto *b10 = s.template_member_get<B>();
+
+ // Don't warn when auto is already being used.
+ auto i2 = template_value_cast<int>(d);
+ auto *i3 = template_value_cast<int *>(d);
+ auto **i4 = template_value_cast<int **>(d);
+ auto &i5 = template_reference_cast<int>(d);
+
+ // Don't warn for implicit template arguments.
+ int i6 = max(i1, i2);
+
+ // Don't warn for mismatched var and initializer types.
+ A *a1 = template_value_cast<B *>(a);
+
+ // Don't warn for mismatched var types.
+ B *b11 = template_value_get<B *>("foo"), b12 = template_value_get<B>("bar");
+
+ // Don't warn for implicit variables.
+ for (auto &c : template_reference_cast<StringRef>(*a)) {
+ }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-auto-iterator.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-auto-iterator.cpp
new file mode 100644
index 0000000..98117fc
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-auto-iterator.cpp
@@ -0,0 +1,320 @@
+// RUN: %check_clang_tidy %s modernize-use-auto %t -- -- \
+// RUN: -std=c++11 -I %S/Inputs/modernize-use-auto
+
+#include "containers.h"
+
+void f_array() {
+ std::array<int, 4> C;
+ std::array<int, 4>::iterator ArrayI1 = C.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators [modernize-use-auto]
+ // CHECK-FIXES: auto ArrayI1 = C.begin();
+
+ std::array<int, 5>::reverse_iterator ArrayI2 = C.rbegin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto ArrayI2 = C.rbegin();
+
+ const std::array<int, 3> D;
+ std::array<int, 3>::const_iterator ArrayI3 = D.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto ArrayI3 = D.begin();
+
+ std::array<int, 5>::const_reverse_iterator ArrayI4 = D.rbegin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto ArrayI4 = D.rbegin();
+}
+
+void f_deque() {
+ std::deque<int> C;
+ std::deque<int>::iterator DequeI1 = C.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto DequeI1 = C.begin();
+
+ std::deque<int>::reverse_iterator DequeI2 = C.rbegin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto DequeI2 = C.rbegin();
+
+ const std::deque<int> D;
+ std::deque<int>::const_iterator DequeI3 = D.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto DequeI3 = D.begin();
+
+ std::deque<int>::const_reverse_iterator DequeI4 = D.rbegin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto DequeI4 = D.rbegin();
+}
+
+void f_forward_list() {
+ std::forward_list<int> C;
+ std::forward_list<int>::iterator FListI1 = C.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto FListI1 = C.begin();
+
+ const std::forward_list<int> D;
+ std::forward_list<int>::const_iterator FListI2 = D.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto FListI2 = D.begin();
+}
+
+void f_list() {
+ std::list<int> C;
+ std::list<int>::iterator ListI1 = C.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto ListI1 = C.begin();
+ std::list<int>::reverse_iterator ListI2 = C.rbegin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto ListI2 = C.rbegin();
+
+ const std::list<int> D;
+ std::list<int>::const_iterator ListI3 = D.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto ListI3 = D.begin();
+ std::list<int>::const_reverse_iterator ListI4 = D.rbegin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto ListI4 = D.rbegin();
+}
+
+void f_vector() {
+ std::vector<int> C;
+ std::vector<int>::iterator VecI1 = C.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto VecI1 = C.begin();
+
+ std::vector<int>::reverse_iterator VecI2 = C.rbegin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto VecI2 = C.rbegin();
+
+ const std::vector<int> D;
+ std::vector<int>::const_iterator VecI3 = D.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto VecI3 = D.begin();
+
+ std::vector<int>::const_reverse_iterator VecI4 = D.rbegin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto VecI4 = D.rbegin();
+}
+
+void f_map() {
+ std::map<int, int> C;
+ std::map<int, int>::iterator MapI1 = C.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto MapI1 = C.begin();
+
+ std::map<int, int>::reverse_iterator MapI2 = C.rbegin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto MapI2 = C.rbegin();
+
+ const std::map<int, int> D;
+ std::map<int, int>::const_iterator MapI3 = D.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto MapI3 = D.begin();
+
+ std::map<int, int>::const_reverse_iterator MapI4 = D.rbegin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto MapI4 = D.rbegin();
+}
+
+void f_multimap() {
+ std::multimap<int, int> C;
+ std::multimap<int, int>::iterator MMapI1 = C.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto MMapI1 = C.begin();
+
+ std::multimap<int, int>::reverse_iterator MMapI2 = C.rbegin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto MMapI2 = C.rbegin();
+
+ const std::multimap<int, int> D;
+ std::multimap<int, int>::const_iterator MMapI3 = D.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto MMapI3 = D.begin();
+
+ std::multimap<int, int>::const_reverse_iterator MMapI4 = D.rbegin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto MMapI4 = D.rbegin();
+}
+
+void f_set() {
+ std::set<int> C;
+ std::set<int>::iterator SetI1 = C.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto SetI1 = C.begin();
+
+ std::set<int>::reverse_iterator SetI2 = C.rbegin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto SetI2 = C.rbegin();
+
+ const std::set<int> D;
+ std::set<int>::const_iterator SetI3 = D.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto SetI3 = D.begin();
+
+ std::set<int>::const_reverse_iterator SetI4 = D.rbegin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto SetI4 = D.rbegin();
+}
+
+void f_multiset() {
+ std::multiset<int> C;
+ std::multiset<int>::iterator MSetI1 = C.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto MSetI1 = C.begin();
+
+ std::multiset<int>::reverse_iterator MSetI2 = C.rbegin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto MSetI2 = C.rbegin();
+
+ const std::multiset<int> D;
+ std::multiset<int>::const_iterator MSetI3 = D.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto MSetI3 = D.begin();
+
+ std::multiset<int>::const_reverse_iterator MSetI4 = D.rbegin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto MSetI4 = D.rbegin();
+}
+
+void f_unordered_map() {
+ std::unordered_map<int, int> C;
+ std::unordered_map<int, int>::iterator UMapI1 = C.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto UMapI1 = C.begin();
+
+ const std::unordered_map<int, int> D;
+ std::unordered_map<int, int>::const_iterator UMapI2 = D.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto UMapI2 = D.begin();
+}
+
+void f_unordered_multimap() {
+ std::unordered_multimap<int, int> C;
+ std::unordered_multimap<int, int>::iterator UMMapI1 = C.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto UMMapI1 = C.begin();
+
+ const std::unordered_multimap<int, int> D;
+ std::unordered_multimap<int, int>::const_iterator UMMapI2 = D.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto UMMapI2 = D.begin();
+}
+
+void f_unordered_set() {
+ std::unordered_set<int> C;
+ std::unordered_set<int>::iterator USetI1 = C.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto USetI1 = C.begin();
+
+ const std::unordered_set<int> D;
+ std::unordered_set<int>::const_iterator USetI2 = D.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto USetI2 = D.begin();
+}
+
+void f_unordered_multiset() {
+ std::unordered_multiset<int> C;
+ std::unordered_multiset<int>::iterator UMSetI1 = C.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto UMSetI1 = C.begin();
+
+ const std::unordered_multiset<int> D;
+ std::unordered_multiset<int>::const_iterator UMSetI2 = D.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto UMSetI2 = D.begin();
+}
+
+typedef std::vector<int>::iterator int_iterator;
+
+std::vector<int> Vec;
+std::unordered_map<int, int> Map;
+
+void sugar() {
+ // Types with more sugar should work. Types with less should not.
+ int_iterator more_sugar = Vec.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto more_sugar = Vec.begin();
+}
+
+void initializer_list() {
+ // Initialization from initializer lists isn't allowed. Using 'auto' would
+ // result in std::initializer_list being deduced for the type.
+ std::unordered_map<int, int>::iterator I{Map.begin()};
+ std::unordered_map<int, int>::iterator I2 = {Map.begin()};
+}
+
+void construction() {
+ // Various forms of construction. Default constructors and constructors with
+ // all-default parameters shouldn't get transformed. Construction from other
+ // types is also not allowed.
+
+ std::unordered_map<int, int>::iterator copy(Map.begin());
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto copy(Map.begin());
+
+ std::unordered_map<int, int>::iterator def;
+ std::unordered_map<int, int>::const_iterator constI;
+
+ // Implicit conversion.
+ std::unordered_map<int, int>::const_iterator constI2 = def;
+ std::unordered_map<int, int>::const_iterator constI3(def);
+
+ // Explicit conversion
+ std::unordered_map<int, int>::const_iterator constI4
+ = std::unordered_map<int, int>::const_iterator(def);
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto constI4
+ // CHECK-FIXES-NEXT: = std::unordered_map<int, int>::const_iterator(def);
+}
+
+void pointer_to_iterator() {
+ int_iterator I = Vec.begin();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto I = Vec.begin();
+
+ // Pointers and references to iterators are not transformed.
+ int_iterator *IPtr = &I;
+ int_iterator &IRef = I;
+}
+
+void loop() {
+ for (std::vector<int>::iterator I = Vec.begin(); I != Vec.end(); ++I) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use auto when declaring iterators
+ // CHECK-FIXES: for (auto I = Vec.begin(); I != Vec.end(); ++I)
+ }
+
+ for (int_iterator I = Vec.begin(), E = Vec.end(); I != E; ++I) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use auto when declaring iterators
+ // CHECK-FIXES: for (auto I = Vec.begin(), E = Vec.end(); I != E; ++I)
+ }
+
+ std::vector<std::vector<int>::iterator> IterVec;
+ for (std::vector<int>::iterator I : IterVec) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use auto when declaring iterators
+ // CHECK-FIXES: for (auto I : IterVec)
+ }
+}
+
+void cv_qualifiers() {
+ // Make sure references and cv qualifiers don't get removed (i.e. replaced
+ // with just 'auto').
+ const auto & I = Vec.begin();
+ auto && I2 = Vec.begin();
+}
+
+void cleanup() {
+ // Passing a string as an argument to introduce a temporary object that will
+ // create an expression with cleanups.
+ std::map<std::string, int> MapFind;
+ std::map<std::string, int>::iterator I = MapFind.find("foo");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto I = MapFind.find("foo");
+}
+
+void declaration_lists() {
+ // Declaration lists that match the declaration type with written no-list
+ // initializer are transformed.
+ std::vector<int>::iterator I = Vec.begin(), E = Vec.end();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+ // CHECK-FIXES: auto I = Vec.begin(), E = Vec.end();
+
+ // Declaration lists with non-initialized variables should not be transformed.
+ std::vector<int>::iterator J = Vec.begin(), K;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-auto-min-type-name-length.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-auto-min-type-name-length.cpp
new file mode 100644
index 0000000..1cd9158
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-auto-min-type-name-length.cpp
@@ -0,0 +1,85 @@
+// RUN: %check_clang_tidy -check-suffix=0-0 %s modernize-use-auto %t -- -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: 0}, {key: modernize-use-auto.MinTypeNameLength, value: 0}]}" -- --std=c++11 -frtti
+// RUN: %check_clang_tidy -check-suffix=0-8 %s modernize-use-auto %t -- -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: 0}, {key: modernize-use-auto.MinTypeNameLength, value: 8}]}" -- --std=c++11 -frtti
+// RUN: %check_clang_tidy -check-suffix=1-0 %s modernize-use-auto %t -- -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: 1}, {key: modernize-use-auto.MinTypeNameLength, value: 0}]}" -- --std=c++11 -frtti
+// RUN: %check_clang_tidy -check-suffix=1-8 %s modernize-use-auto %t -- -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: 1}, {key: modernize-use-auto.MinTypeNameLength, value: 8}]}" -- --std=c++11 -frtti
+
+template <class T> extern T foo();
+template <class T> struct P { explicit P(T t) : t_(t) {} T t_;};
+template <class T> P<T> *foo_ptr();
+template <class T> P<T> &foo_ref();
+
+int bar() {
+ {
+ // Lenth(long) = 4
+ long i = static_cast<long>(foo<long>());
+ // CHECK-FIXES-0-0: auto i = {{.*}}
+ // CHECK-FIXES-0-8: long i = {{.*}}
+ // CHECK-FIXES-1-0: auto i = {{.*}}
+ // CHECK-FIXES-1-8: long i = {{.*}}
+ const long ci = static_cast<long>(foo<const long>());
+ // CHECK-FIXES-0-0: auto ci = {{.*}}
+ // CHECK-FIXES-0-8: long ci = {{.*}}
+ // CHECK-FIXES-1-0: auto ci = {{.*}}
+ // CHECK-FIXES-1-8: long ci = {{.*}}
+ long *pi = static_cast<long *>(foo<long *>());
+ // CHECK-FIXES-0-0: auto *pi = {{.*}}
+ // CHECK-FIXES-0-8: long *pi = {{.*}}
+ // CHECK-FIXES-1-0: auto pi = {{.*}}
+ // CHECK-FIXES-1-8: long *pi = {{.*}}
+
+ // Length(long *) is still 5
+ long * pi2 = static_cast<long *>(foo<long *>());
+ // CHECK-FIXES-0-0: auto * pi2 = {{.*}}
+ // CHECK-FIXES-0-8: long * pi2 = {{.*}}
+ // CHECK-FIXES-1-0: auto pi2 = {{.*}}
+ // CHECK-FIXES-1-8: long * pi2 = {{.*}}
+
+ // Length(long **) = 6
+ long **ppi = static_cast<long **>(foo<long **>());
+ // CHECK-FIXES-0-0: auto **ppi = {{.*}}
+ // CHECK-FIXES-0-8: long **ppi = {{.*}}
+ // CHECK-FIXES-1-0: auto ppi = {{.*}}
+ // CHECK-FIXES-1-8: long **ppi = {{.*}}
+ }
+
+ {
+ // Lenth(long int) = 4 + 1 + 3 = 8
+ // Lenth(long int) is still 8
+ long int i = static_cast<long int>(foo<long int>());
+ // CHECK-FIXES-0-0: auto i = {{.*}}
+ // CHECK-FIXES-0-8: auto i = {{.*}}
+ // CHECK-FIXES-1-0: auto i = {{.*}}
+ // CHECK-FIXES-1-8: auto i = {{.*}}
+
+ long int *pi = static_cast<long int *>(foo<long int *>());
+ // CHECK-FIXES-0-0: auto *pi = {{.*}}
+ // CHECK-FIXES-0-8: auto *pi = {{.*}}
+ // CHECK-FIXES-1-0: auto pi = {{.*}}
+ // CHECK-FIXES-1-8: auto pi = {{.*}}
+ }
+
+ // Templates
+ {
+ // Length(P<long>) = 7
+ P<long>& i = static_cast<P<long>&>(foo_ref<long>());
+ // CHECK-FIXES-0-0: auto& i = {{.*}}
+ // CHECK-FIXES-0-8: P<long>& i = {{.*}}
+ // CHECK-FIXES-1-0: auto & i = {{.*}}
+ // CHECK-FIXES-1-8: P<long>& i = {{.*}}
+
+ // Length(P<long*>) = 8
+ P<long*>& pi = static_cast<P<long*> &>(foo_ref<long*>());
+ // CHECK-FIXES-0-0: auto& pi = {{.*}}
+ // CHECK-FIXES-0-8: auto& pi = {{.*}}
+ // CHECK-FIXES-1-0: auto & pi = {{.*}}
+ // CHECK-FIXES-1-8: auto & pi = {{.*}}
+
+ P<long>* pi2 = static_cast<P<long>*>(foo_ptr<long>());
+ // CHECK-FIXES-0-0: auto* pi2 = {{.*}}
+ // CHECK-FIXES-0-8: P<long>* pi2 = {{.*}}
+ // CHECK-FIXES-1-0: auto pi2 = {{.*}}
+ // CHECK-FIXES-1-8: auto pi2 = {{.*}}
+ }
+
+ return 1;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-auto-new-remove-stars.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-auto-new-remove-stars.cpp
new file mode 100644
index 0000000..00e3c89
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-auto-new-remove-stars.cpp
@@ -0,0 +1,106 @@
+// RUN: %check_clang_tidy %s modernize-use-auto %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: '1'}, {key: modernize-use-auto.MinTypeNameLength, value: '0'}]}" \
+// RUN: -- -std=c++11
+
+class MyType {};
+
+class MyDerivedType : public MyType {};
+
+// FIXME: the replacement sometimes results in two consecutive spaces after
+// the word 'auto' (due to the presence of spaces at both sides of '*').
+void auto_new() {
+ MyType *a_new = new MyType();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+ // CHECK-FIXES: auto a_new = new MyType();
+
+ static MyType *a_static = new MyType();
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use auto when initializing with new
+ // CHECK-FIXES: static auto a_static = new MyType();
+
+ MyType *derived = new MyDerivedType();
+
+ void *vd = new MyType();
+
+ // CV-qualifier tests.
+ //
+ // NOTE : the form "type const" is expected here because of a deficiency in
+ // TypeLoc where CV qualifiers are not considered part of the type location
+ // info. That is, all that is being replaced in each case is "MyType *" and
+ // not "MyType * const".
+ static MyType * const d_static = new MyType();
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use auto when initializing with new
+ // CHECK-FIXES: static auto const d_static = new MyType();
+
+ MyType * const a_const = new MyType();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+ // CHECK-FIXES: auto const a_const = new MyType();
+
+ MyType * volatile vol = new MyType();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+ // CHECK-FIXES: auto volatile vol = new MyType();
+
+ struct SType {} *stype = new SType;
+
+ int (**func)(int, int) = new (int(*[5])(int,int));
+
+ int *array = new int[5];
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+ // CHECK-FIXES: auto array = new int[5];
+
+ MyType *ptr(new MyType);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+ // CHECK-FIXES: auto ptr(new MyType);
+
+ MyType *ptr2{new MyType};
+
+ {
+ // Test for declaration lists.
+ MyType *a = new MyType(), *b = new MyType(), *c = new MyType();
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+ // CHECK-FIXES: auto a = new MyType(), b = new MyType(), c = new MyType();
+
+ // Non-initialized declaration should not be transformed.
+ MyType *d = new MyType(), *e;
+
+ MyType **f = new MyType*(), **g = new MyType*();
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+ // CHECK-FIXES: auto f = new MyType*(), g = new MyType*();
+
+ // Mismatching types in declaration lists should not be transformed.
+ MyType *h = new MyType(), **i = new MyType*();
+
+ // '*' shouldn't be removed in case of mismatching types with multiple
+ // declarations.
+ MyType *j = new MyType(), *k = new MyType(), **l = new MyType*();
+ }
+
+ {
+ // Test for typedefs.
+ typedef int * int_p;
+ // CHECK-FIXES: typedef int * int_p;
+
+ int_p a = new int;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+ // CHECK-FIXES: auto a = new int;
+ int_p *b = new int*;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+ // CHECK-FIXES: auto b = new int*;
+
+ // Test for typedefs in declarations lists.
+ int_p c = new int, d = new int;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+ // CHECK-FIXES: auto c = new int, d = new int;
+
+ // Different types should not be transformed.
+ int_p e = new int, *f = new int_p;
+
+ int_p *g = new int*, *h = new int_p;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+ // CHECK-FIXES: auto g = new int*, h = new int_p;
+ }
+
+ // Don't warn when 'auto' is already being used.
+ auto aut = new MyType();
+ auto *paut = new MyType();
+ const auto *pcaut = new MyType();
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-auto-new.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-auto-new.cpp
new file mode 100644
index 0000000..3c872c9
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-auto-new.cpp
@@ -0,0 +1,110 @@
+// RUN: %check_clang_tidy %s modernize-use-auto %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-auto.MinTypeNameLength, value: '0'}]}" \
+// RUN: -- -std=c++11 -frtti
+
+class MyType {};
+
+class MyDerivedType : public MyType {};
+
+// FIXME: the replacement sometimes results in two consecutive spaces after
+// the word 'auto' (due to the presence of spaces at both sides of '*').
+void auto_new() {
+ MyType *a_new = new MyType();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+ // CHECK-FIXES: auto *a_new = new MyType();
+
+ static MyType *a_static = new MyType();
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use auto when initializing with new
+ // CHECK-FIXES: static auto *a_static = new MyType();
+
+ long long *ll = new long long();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+ // CHECK-FIXES: auto *ll = new long long();
+
+ MyType *derived = new MyDerivedType();
+
+ void *vd = new MyType();
+
+ // CV-qualifier tests.
+ //
+ // NOTE : the form "type const" is expected here because of a deficiency in
+ // TypeLoc where CV qualifiers are not considered part of the type location
+ // info. That is, all that is being replaced in each case is "MyType *" and
+ // not "MyType * const".
+ static MyType * const d_static = new MyType();
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use auto when initializing with new
+ // CHECK-FIXES: static auto * const d_static = new MyType();
+
+ MyType * const a_const = new MyType();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+ // CHECK-FIXES: auto * const a_const = new MyType();
+
+ MyType * volatile vol = new MyType();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+ // CHECK-FIXES: auto * volatile vol = new MyType();
+
+ struct SType {} *stype = new SType;
+
+ int (**func)(int, int) = new (int(*[5])(int,int));
+
+ int *array = new int[5];
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+ // CHECK-FIXES: auto *array = new int[5];
+
+ MyType *ptr(new MyType);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+ // CHECK-FIXES: auto *ptr(new MyType);
+
+ MyType *ptr2{new MyType};
+
+ {
+ // Test for declaration lists.
+ MyType *a = new MyType(), *b = new MyType(), *c = new MyType();
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+ // CHECK-FIXES: auto *a = new MyType(), *b = new MyType(), *c = new MyType();
+
+ // Non-initialized declaration should not be transformed.
+ MyType *d = new MyType(), *e;
+
+ MyType **f = new MyType*(), **g = new MyType*();
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+ // CHECK-FIXES: auto **f = new MyType*(), **g = new MyType*();
+
+ // Mismatching types in declaration lists should not be transformed.
+ MyType *h = new MyType(), **i = new MyType*();
+
+ // '*' shouldn't be removed in case of mismatching types with multiple
+ // declarations.
+ MyType *j = new MyType(), *k = new MyType(), **l = new MyType*();
+ }
+
+ {
+ // Test for typedefs.
+ typedef int * int_p;
+ // CHECK-FIXES: typedef int * int_p;
+
+ int_p a = new int;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+ // CHECK-FIXES: auto a = new int;
+ int_p *b = new int*;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+ // CHECK-FIXES: auto *b = new int*;
+
+ // Test for typedefs in declarations lists.
+ int_p c = new int, d = new int;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+ // CHECK-FIXES: auto c = new int, d = new int;
+
+ // Different types should not be transformed.
+ int_p e = new int, *f = new int_p;
+
+ int_p *g = new int*, *h = new int_p;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+ // CHECK-FIXES: auto *g = new int*, *h = new int_p;
+ }
+
+ // Don't warn when 'auto' is already being used.
+ auto aut = new MyType();
+ auto *paut = new MyType();
+ const auto *pcaut = new MyType();
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-bool-literals-ignore-macros.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-bool-literals-ignore-macros.cpp
new file mode 100644
index 0000000..cf8f72c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-bool-literals-ignore-macros.cpp
@@ -0,0 +1,148 @@
+// RUN: %check_clang_tidy %s modernize-use-bool-literals %t -- \
+// RUN: -config="{CheckOptions: \
+// RUN: [{key: modernize-use-bool-literals.IgnoreMacros, \
+// RUN: value: 1}]}" \
+// RUN: -- -std=c++11
+
+bool IntToTrue = 1;
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: converting integer literal to bool, use bool literal instead [modernize-use-bool-literals]
+// CHECK-FIXES: {{^}}bool IntToTrue = true;{{$}}
+
+bool IntToFalse(0);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: converting integer literal to bool
+// CHECK-FIXES: {{^}}bool IntToFalse(false);{{$}}
+
+bool LongLongToTrue{0x1LL};
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: converting integer literal to bool
+// CHECK-FIXES: {{^}}bool LongLongToTrue{true};{{$}}
+
+bool ExplicitCStyleIntToFalse = (bool)0;
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: converting integer literal to bool
+// CHECK-FIXES: {{^}}bool ExplicitCStyleIntToFalse = false;{{$}}
+
+bool ExplicitFunctionalIntToFalse = bool(0);
+// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: converting integer literal to bool
+// CHECK-FIXES: {{^}}bool ExplicitFunctionalIntToFalse = false;{{$}}
+
+bool ExplicitStaticIntToFalse = static_cast<bool>(0);
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: converting integer literal to bool
+// CHECK-FIXES: {{^}}bool ExplicitStaticIntToFalse = false;{{$}}
+
+#define TRUE_MACRO 1
+// CHECK-FIXES: {{^}}#define TRUE_MACRO 1{{$}}
+
+bool MacroIntToTrue = TRUE_MACRO;
+// CHECK-FIXES: {{^}}bool MacroIntToTrue = TRUE_MACRO;{{$}}
+
+#define FALSE_MACRO bool(0)
+// CHECK-FIXES: {{^}}#define FALSE_MACRO bool(0){{$}}
+
+bool TrueBool = true; // OK
+
+bool FalseBool = bool(FALSE_MACRO);
+// CHECK-FIXES: {{^}}bool FalseBool = bool(FALSE_MACRO);{{$}}
+
+void boolFunction(bool bar) {
+
+}
+
+char Character = 0; // OK
+
+unsigned long long LongInteger = 1; // OK
+
+#define MACRO_DEPENDENT_CAST(x) static_cast<bool>(x)
+// CHECK-FIXES: {{^}}#define MACRO_DEPENDENT_CAST(x) static_cast<bool>(x){{$}}
+
+bool MacroDependentBool = MACRO_DEPENDENT_CAST(0);
+// CHECK-FIXES: {{^}}bool MacroDependentBool = MACRO_DEPENDENT_CAST(0);{{$}}
+
+bool ManyMacrosDependent = MACRO_DEPENDENT_CAST(FALSE_MACRO);
+// CHECK-FIXES: {{^}}bool ManyMacrosDependent = MACRO_DEPENDENT_CAST(FALSE_MACRO);{{$}}
+
+class FooClass {
+ public:
+ FooClass() : JustBool(0) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}FooClass() : JustBool(false) {}{{$}}
+ FooClass(int) : JustBool{0} {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}FooClass(int) : JustBool{false} {}{{$}}
+ private:
+ bool JustBool;
+ bool BoolWithBraces{0};
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}bool BoolWithBraces{false};{{$}}
+ bool BoolFromInt = 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}bool BoolFromInt = false;{{$}}
+ bool SimpleBool = true; // OK
+};
+
+template<typename type>
+void templateFunction(type) {
+ type TemplateType = 0;
+ // CHECK-FIXES: {{^ *}}type TemplateType = 0;{{$}}
+}
+
+template<int c>
+void valueDependentTemplateFunction() {
+ bool Boolean = c;
+ // CHECK-FIXES: {{^ *}}bool Boolean = c;{{$}}
+}
+
+template<typename type>
+void anotherTemplateFunction(type) {
+ bool JustBool = 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}bool JustBool = false;{{$}}
+}
+
+int main() {
+ boolFunction(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}boolFunction(true);{{$}}
+
+ boolFunction(false);
+
+ templateFunction(0);
+
+ templateFunction(false);
+
+ valueDependentTemplateFunction<1>();
+
+ anotherTemplateFunction(1);
+
+ IntToTrue = 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}IntToTrue = true;{{$}}
+}
+
+static int Value = 1;
+
+bool Function1() {
+ bool Result = Value == 1 ? 1 : 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: converting integer literal to bool
+ // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}bool Result = Value == 1 ? true : false;{{$}}
+ return Result;
+}
+
+bool Function2() {
+ return Value == 1 ? 1 : 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: converting integer literal to bool
+ // CHECK-MESSAGES: :[[@LINE-2]]:27: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}return Value == 1 ? true : false;{{$}}
+}
+
+void foo() {
+ bool Result;
+ Result = Value == 1 ? true : 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}Result = Value == 1 ? true : false;{{$}}
+ Result = Value == 1 ? false : bool(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}Result = Value == 1 ? false : false;{{$}}
+ Result = Value == 1 ? (bool)0 : false;
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}Result = Value == 1 ? false : false;{{$}}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-bool-literals.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-bool-literals.cpp
new file mode 100644
index 0000000..f2ab9ce
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-bool-literals.cpp
@@ -0,0 +1,152 @@
+// RUN: %check_clang_tidy %s modernize-use-bool-literals %t -- \
+// RUN: -config="{CheckOptions: \
+// RUN: [{key: modernize-use-bool-literals.IgnoreMacros, \
+// RUN: value: 0}]}" \
+// RUN: -- -std=c++11
+
+bool IntToTrue = 1;
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: converting integer literal to bool, use bool literal instead [modernize-use-bool-literals]
+// CHECK-FIXES: {{^}}bool IntToTrue = true;{{$}}
+
+bool IntToFalse(0);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: converting integer literal to bool
+// CHECK-FIXES: {{^}}bool IntToFalse(false);{{$}}
+
+bool LongLongToTrue{0x1LL};
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: converting integer literal to bool
+// CHECK-FIXES: {{^}}bool LongLongToTrue{true};{{$}}
+
+bool ExplicitCStyleIntToFalse = (bool)0;
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: converting integer literal to bool
+// CHECK-FIXES: {{^}}bool ExplicitCStyleIntToFalse = false;{{$}}
+
+bool ExplicitFunctionalIntToFalse = bool(0);
+// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: converting integer literal to bool
+// CHECK-FIXES: {{^}}bool ExplicitFunctionalIntToFalse = false;{{$}}
+
+bool ExplicitStaticIntToFalse = static_cast<bool>(0);
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: converting integer literal to bool
+// CHECK-FIXES: {{^}}bool ExplicitStaticIntToFalse = false;{{$}}
+
+#define TRUE_MACRO 1
+// CHECK-FIXES: {{^}}#define TRUE_MACRO 1{{$}}
+
+bool MacroIntToTrue = TRUE_MACRO;
+// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: converting integer literal to bool
+// CHECK-FIXES: {{^}}bool MacroIntToTrue = TRUE_MACRO;{{$}}
+
+#define FALSE_MACRO bool(0)
+// CHECK-FIXES: {{^}}#define FALSE_MACRO bool(0){{$}}
+
+bool TrueBool = true; // OK
+
+bool FalseBool = bool(FALSE_MACRO);
+// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: converting integer literal to bool
+// CHECK-FIXES: {{^}}bool FalseBool = bool(FALSE_MACRO);{{$}}
+
+void boolFunction(bool bar) {
+
+}
+
+char Character = 0; // OK
+
+unsigned long long LongInteger = 1; // OK
+
+#define MACRO_DEPENDENT_CAST(x) static_cast<bool>(x)
+// CHECK-FIXES: {{^}}#define MACRO_DEPENDENT_CAST(x) static_cast<bool>(x){{$}}
+
+bool MacroDependentBool = MACRO_DEPENDENT_CAST(0);
+// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: converting integer literal to bool
+// CHECK-FIXES: {{^}}bool MacroDependentBool = MACRO_DEPENDENT_CAST(0);{{$}}
+
+bool ManyMacrosDependent = MACRO_DEPENDENT_CAST(FALSE_MACRO);
+// CHECK-MESSAGES: :[[@LINE-1]]:49: warning: converting integer literal to bool
+// CHECK-FIXES: {{^}}bool ManyMacrosDependent = MACRO_DEPENDENT_CAST(FALSE_MACRO);{{$}}
+
+class FooClass {
+ public:
+ FooClass() : JustBool(0) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}FooClass() : JustBool(false) {}{{$}}
+ FooClass(int) : JustBool{0} {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}FooClass(int) : JustBool{false} {}{{$}}
+ private:
+ bool JustBool;
+ bool BoolWithBraces{0};
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}bool BoolWithBraces{false};{{$}}
+ bool BoolFromInt = 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}bool BoolFromInt = false;{{$}}
+ bool SimpleBool = true; // OK
+};
+
+template<typename type>
+void templateFunction(type) {
+ type TemplateType = 0;
+ // CHECK-FIXES: {{^ *}}type TemplateType = 0;{{$}}
+}
+
+template<int c>
+void valueDependentTemplateFunction() {
+ bool Boolean = c;
+ // CHECK-FIXES: {{^ *}}bool Boolean = c;{{$}}
+}
+
+template<typename type>
+void anotherTemplateFunction(type) {
+ bool JustBool = 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}bool JustBool = false;{{$}}
+}
+
+int main() {
+ boolFunction(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}boolFunction(true);{{$}}
+
+ boolFunction(false);
+
+ templateFunction(0);
+
+ templateFunction(false);
+
+ valueDependentTemplateFunction<1>();
+
+ anotherTemplateFunction(1);
+
+ IntToTrue = 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}IntToTrue = true;{{$}}
+}
+
+static int Value = 1;
+
+bool Function1() {
+ bool Result = Value == 1 ? 1 : 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: converting integer literal to bool
+ // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}bool Result = Value == 1 ? true : false;{{$}}
+ return Result;
+}
+
+bool Function2() {
+ return Value == 1 ? 1 : 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: converting integer literal to bool
+ // CHECK-MESSAGES: :[[@LINE-2]]:27: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}return Value == 1 ? true : false;{{$}}
+}
+
+void foo() {
+ bool Result;
+ Result = Value == 1 ? true : 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}Result = Value == 1 ? true : false;{{$}}
+ Result = Value == 1 ? false : bool(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}Result = Value == 1 ? false : false;{{$}}
+ Result = Value == 1 ? (bool)0 : false;
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: converting integer literal to bool
+ // CHECK-FIXES: {{^ *}}Result = Value == 1 ? false : false;{{$}}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-default-member-init-assignment.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-default-member-init-assignment.cpp
new file mode 100644
index 0000000..fdc0db1
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-default-member-init-assignment.cpp
@@ -0,0 +1,184 @@
+// RUN: %check_clang_tidy %s modernize-use-default-member-init %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-default-member-init.UseAssignment, value: 1}]}" -- -std=c++11
+
+struct S {
+};
+
+struct PositiveValueChar {
+ PositiveValueChar() : c0(), c1()/*, c2(), c3()*/ {}
+ // CHECK-FIXES: PositiveValueChar() {}
+ const char c0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use default member initializer for 'c0' [modernize-use-default-member-init]
+ // CHECK-FIXES: const char c0 = '\0';
+ wchar_t c1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use default member initializer for 'c1'
+ // CHECK-FIXES: wchar_t c1 = L'\0';
+ // FIXME: char16_t c2;
+ // C HECK-MESSAGES: :[[@LINE-1]]:12: warning: use default member initializer for 'c2'
+ // C HECK-FIXES: char16_t c2 = u'\0';
+ // FIXME: char32_t c3;
+ // C HECK-MESSAGES: :[[@LINE-1]]:12: warning: use default member initializer for 'c3'
+ // C HECK-FIXES: char32_t c3 = U'\0';
+};
+
+struct PositiveChar {
+ PositiveChar() : d('a') {}
+ // CHECK-FIXES: PositiveChar() {}
+ char d;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'd'
+ // CHECK-FIXES: char d = 'a';
+};
+
+struct PositiveValueInt {
+ PositiveValueInt() : i() {}
+ // CHECK-FIXES: PositiveValueInt() {}
+ const int i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use default member initializer for 'i'
+ // CHECK-FIXES: const int i = 0;
+};
+
+struct PositiveInt {
+ PositiveInt() : j(1) {}
+ // CHECK-FIXES: PositiveInt() {}
+ int j;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'j'
+ // CHECK-FIXES: int j = 1;
+};
+
+struct PositiveUnaryMinusInt {
+ PositiveUnaryMinusInt() : j(-1) {}
+ // CHECK-FIXES: PositiveUnaryMinusInt() {}
+ int j;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'j'
+ // CHECK-FIXES: int j = -1;
+};
+
+struct PositiveUnaryPlusInt {
+ PositiveUnaryPlusInt() : j(+1) {}
+ // CHECK-FIXES: PositiveUnaryPlusInt() {}
+ int j;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'j'
+ // CHECK-FIXES: int j = +1;
+};
+
+struct PositiveValueComplexInt {
+ PositiveValueComplexInt() : i() {}
+ // CHECK-FIXES: PositiveValueComplexInt() {}
+ _Complex int i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use default member initializer for 'i'
+ // CHECK-FIXES: _Complex int i = 0;
+};
+
+struct PositiveValueFloat {
+ PositiveValueFloat() : f() {}
+ // CHECK-FIXES: PositiveValueFloat() {}
+ float f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use default member initializer for 'f'
+ // CHECK-FIXES: float f = 0.0f;
+};
+
+struct PositiveValueDouble {
+ PositiveValueDouble() : d() {}
+ // CHECK-FIXES: PositiveValueDouble() {}
+ double d;
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use default member initializer for 'd'
+ // CHECK-FIXES: double d = 0.0;
+};
+
+struct PositiveDouble {
+ PositiveDouble() : f(2.5463e43) {}
+ // CHECK-FIXES: PositiveDouble() {}
+ double f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use default member initializer for 'f'
+ // CHECK-FIXES: double f = 2.5463e43;
+};
+
+struct PositiveValueComplexFloat {
+ PositiveValueComplexFloat() : f() {}
+ // CHECK-FIXES: PositiveValueComplexFloat() {}
+ _Complex float f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use default member initializer for 'f'
+ // CHECK-FIXES: _Complex float f = 0.0f;
+};
+
+struct PositiveValueComplexDouble {
+ PositiveValueComplexDouble() : f() {}
+ // CHECK-FIXES: PositiveValueComplexDouble() {}
+ _Complex double f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use default member initializer for 'f'
+ // CHECK-FIXES: _Complex double f = 0.0;
+};
+
+struct PositiveUnaryMinusDouble {
+ PositiveUnaryMinusDouble() : f(-2.5463e43) {}
+ // CHECK-FIXES: PositiveUnaryMinusDouble() {}
+ double f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use default member initializer for 'f'
+ // CHECK-FIXES: double f = -2.5463e43;
+};
+
+struct PositiveUnaryPlusDouble {
+ PositiveUnaryPlusDouble() : f(+2.5463e43) {}
+ // CHECK-FIXES: PositiveUnaryPlusDouble() {}
+ double f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use default member initializer for 'f'
+ // CHECK-FIXES: double f = +2.5463e43;
+};
+
+struct PositiveValueBool {
+ PositiveValueBool() : b() {}
+ // CHECK-FIXES: PositiveValueBool() {}
+ bool b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'b'
+ // CHECK-FIXES: bool b = false;
+};
+
+struct PositiveBool {
+ PositiveBool() : a(true) {}
+ // CHECK-FIXES: PositiveBool() {}
+ bool a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'a'
+ // CHECK-FIXES: bool a = true;
+};
+
+struct PositiveValuePointer {
+ PositiveValuePointer() : p() {}
+ // CHECK-FIXES: PositiveValuePointer() {}
+ int *p;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'p'
+ // CHECK-FIXES: int *p = nullptr;
+};
+
+struct PositiveNullPointer {
+ PositiveNullPointer() : q(nullptr) {}
+ // CHECK-FIXES: PositiveNullPointer() {}
+ int *q;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'q'
+ // CHECK-FIXES: int *q = nullptr;
+};
+
+enum Enum { Foo };
+struct PositiveEnum {
+ PositiveEnum() : e(Foo) {}
+ // CHECK-FIXES: PositiveEnum() {}
+ Enum e;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'e'
+ // CHECK-FIXES: Enum e = Foo;
+};
+
+struct PositiveString {
+ PositiveString() : s("foo") {}
+ // CHECK-FIXES: PositiveString() {}
+ const char *s;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use default member initializer for 's'
+ // CHECK-FIXES: const char *s = "foo";
+};
+
+template <typename T>
+struct NegativeTemplate {
+ NegativeTemplate() : t() {}
+ T t;
+};
+
+NegativeTemplate<int> nti;
+NegativeTemplate<double> ntd;
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-default-member-init-bitfield.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-default-member-init-bitfield.cpp
new file mode 100644
index 0000000..1ff08f9
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-default-member-init-bitfield.cpp
@@ -0,0 +1,10 @@
+// RUN: %check_clang_tidy %s modernize-use-default-member-init %t -- -- -std=c++2a
+
+struct PositiveBitField
+{
+ PositiveBitField() : i(6) {}
+ // CHECK-FIXES: PositiveBitField() {}
+ int i : 5;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'i' [modernize-use-default-member-init]
+ // CHECK-FIXES: int i : 5{6};
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-default-member-init-macros.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-default-member-init-macros.cpp
new file mode 100644
index 0000000..5b366b5
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-default-member-init-macros.cpp
@@ -0,0 +1,18 @@
+// RUN: %check_clang_tidy %s modernize-use-default-member-init %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-default-member-init.IgnoreMacros, value: 0}]}" \
+// RUN: -- -std=c++11
+
+#define MACRO() \
+ struct S { \
+ void *P; \
+ S() : P(nullptr) {} \
+ };
+
+MACRO();
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use default member initializer for 'P'
+
+struct S2 {
+ void *P;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use default member initializer for 'P'
+ S2() : P(nullptr) {}
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-default-member-init.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-default-member-init.cpp
new file mode 100644
index 0000000..0ed65df
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-default-member-init.cpp
@@ -0,0 +1,401 @@
+// RUN: %check_clang_tidy %s modernize-use-default-member-init %t -- -- -std=c++11
+
+struct S {
+};
+
+struct PositiveValueChar {
+ PositiveValueChar() : c0(), c1()/*, c2(), c3()*/ {}
+ // CHECK-FIXES: PositiveValueChar() {}
+ const char c0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use default member initializer for 'c0' [modernize-use-default-member-init]
+ // CHECK-FIXES: const char c0{};
+ wchar_t c1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use default member initializer for 'c1'
+ // CHECK-FIXES: wchar_t c1{};
+ // FIXME: char16_t c2;
+ // C HECK-MESSAGES: :[[@LINE-1]]:12: warning: use default member initializer for 'c2'
+ // C HECK-FIXES: char16_t c2{};
+ // FIXME: char32_t c3;
+ // C HECK-MESSAGES: :[[@LINE-1]]:12: warning: use default member initializer for 'c3'
+ // C HECK-FIXES: char32_t c3{};
+};
+
+struct PositiveChar {
+ PositiveChar() : d('a') {}
+ // CHECK-FIXES: PositiveChar() {}
+ char d;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'd'
+ // CHECK-FIXES: char d{'a'};
+};
+
+struct PositiveValueInt {
+ PositiveValueInt() : i() {}
+ // CHECK-FIXES: PositiveValueInt() {}
+ const int i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use default member initializer for 'i'
+ // CHECK-FIXES: const int i{};
+};
+
+struct PositiveInt {
+ PositiveInt() : j(1) {}
+ // CHECK-FIXES: PositiveInt() {}
+ int j;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'j'
+ // CHECK-FIXES: int j{1};
+};
+
+struct PositiveUnaryMinusInt {
+ PositiveUnaryMinusInt() : j(-1) {}
+ // CHECK-FIXES: PositiveUnaryMinusInt() {}
+ int j;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'j'
+ // CHECK-FIXES: int j{-1};
+};
+
+struct PositiveUnaryPlusInt {
+ PositiveUnaryPlusInt() : j(+1) {}
+ // CHECK-FIXES: PositiveUnaryPlusInt() {}
+ int j;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'j'
+ // CHECK-FIXES: int j{+1};
+};
+
+struct PositiveValueComplexInt {
+ PositiveValueComplexInt() : i() {}
+ // CHECK-FIXES: PositiveValueComplexInt() {}
+ _Complex int i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use default member initializer for 'i'
+ // CHECK-FIXES: _Complex int i{};
+};
+
+struct PositiveValueFloat {
+ PositiveValueFloat() : f() {}
+ // CHECK-FIXES: PositiveValueFloat() {}
+ float f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use default member initializer for 'f'
+ // CHECK-FIXES: float f{};
+};
+
+struct PositiveValueDouble {
+ PositiveValueDouble() : d() {}
+ // CHECK-FIXES: PositiveValueDouble() {}
+ double d;
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use default member initializer for 'd'
+ // CHECK-FIXES: double d{};
+};
+
+struct PositiveDouble {
+ PositiveDouble() : f(2.5463e43) {}
+ // CHECK-FIXES: PositiveDouble() {}
+ double f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use default member initializer for 'f'
+ // CHECK-FIXES: double f{2.5463e43};
+};
+
+struct PositiveValueComplexFloat {
+ PositiveValueComplexFloat() : f() {}
+ // CHECK-FIXES: PositiveValueComplexFloat() {}
+ _Complex float f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use default member initializer for 'f'
+ // CHECK-FIXES: _Complex float f{};
+};
+
+struct PositiveValueComplexDouble {
+ PositiveValueComplexDouble() : f() {}
+ // CHECK-FIXES: PositiveValueComplexDouble() {}
+ _Complex double f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use default member initializer for 'f'
+ // CHECK-FIXES: _Complex double f{};
+};
+
+struct PositiveUnaryMinusDouble {
+ PositiveUnaryMinusDouble() : f(-2.5463e43) {}
+ // CHECK-FIXES: PositiveUnaryMinusDouble() {}
+ double f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use default member initializer for 'f'
+ // CHECK-FIXES: double f{-2.5463e43};
+};
+
+struct PositiveUnaryPlusDouble {
+ PositiveUnaryPlusDouble() : f(+2.5463e43) {}
+ // CHECK-FIXES: PositiveUnaryPlusDouble() {}
+ double f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use default member initializer for 'f'
+ // CHECK-FIXES: double f{+2.5463e43};
+};
+
+struct PositiveValueBool {
+ PositiveValueBool() : b() {}
+ // CHECK-FIXES: PositiveValueBool() {}
+ bool b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'b'
+ // CHECK-FIXES: bool b{};
+};
+
+struct PositiveBool {
+ PositiveBool() : a(true) {}
+ // CHECK-FIXES: PositiveBool() {}
+ bool a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'a'
+ // CHECK-FIXES: bool a{true};
+};
+
+struct PositiveValuePointer {
+ PositiveValuePointer() : p() {}
+ // CHECK-FIXES: PositiveValuePointer() {}
+ int *p;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'p'
+ // CHECK-FIXES: int *p{};
+};
+
+struct PositiveNullPointer {
+ PositiveNullPointer() : q(nullptr) {}
+ // CHECK-FIXES: PositiveNullPointer() {}
+ int *q;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'q'
+ // CHECK-FIXES: int *q{nullptr};
+};
+
+enum Enum { Foo, Bar };
+struct PositiveEnum {
+ PositiveEnum() : e(Foo) {}
+ // CHECK-FIXES: PositiveEnum() {}
+ Enum e;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'e'
+ // CHECK-FIXES: Enum e{Foo};
+};
+
+struct PositiveString {
+ PositiveString() : s("foo") {}
+ // CHECK-FIXES: PositiveString() {}
+ const char *s;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use default member initializer for 's'
+ // CHECK-FIXES: const char *s{"foo"};
+};
+
+struct PositiveStruct {
+ PositiveStruct() : s(7) {}
+ // CHECK-FIXES: PositiveStruct() {}
+ struct {
+ int s;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use default member initializer for 's'
+ // CHECK-FIXES: int s{7};
+ };
+};
+
+template <typename T>
+struct NegativeTemplate {
+ NegativeTemplate() : t() {}
+ T t;
+};
+
+NegativeTemplate<int> nti;
+NegativeTemplate<double> ntd;
+
+struct NegativeDefaultMember {
+ NegativeDefaultMember() {}
+ int i = 2;
+};
+
+struct NegativeClass : S {
+ NegativeClass() : s() {}
+ S s;
+};
+
+struct NegativeBase : S {
+ NegativeBase() : S() {}
+};
+
+struct NegativeDefaultOtherMember{
+ NegativeDefaultOtherMember() : i(3) {}
+ int i = 4;
+};
+
+struct NegativeUnion {
+ NegativeUnion() : d(5.0) {}
+ union {
+ int i;
+ double d;
+ };
+};
+
+struct NegativeBitField
+{
+ NegativeBitField() : i(6) {}
+ int i : 5;
+};
+
+struct NegativeNotDefaultInt
+{
+ NegativeNotDefaultInt(int) : i(7) {}
+ int i;
+};
+
+struct NegativeDefaultArg
+{
+ NegativeDefaultArg(int i = 4) : i(i) {}
+ int i;
+};
+
+struct ExistingChar {
+ ExistingChar(short) : e1(), e2(), e3(), e4() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: member initializer for 'e1' is redundant [modernize-use-default-member-init]
+ // CHECK-MESSAGES: :[[@LINE-2]]:31: warning: member initializer for 'e2' is redundant
+ // CHECK-MESSAGES: :[[@LINE-3]]:37: warning: member initializer for 'e3' is redundant
+ // CHECK-FIXES: ExistingChar(short) : e4() {}
+ ExistingChar(int) : e1(0), e2(0), e3(0), e4(0) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: member initializer for 'e1' is redundant
+ // CHECK-MESSAGES: :[[@LINE-2]]:30: warning: member initializer for 'e2' is redundant
+ // CHECK-MESSAGES: :[[@LINE-3]]:37: warning: member initializer for 'e3' is redundant
+ // CHECK-FIXES: ExistingChar(int) : e4(0) {}
+ ExistingChar(long) : e1('\0'), e2('\0'), e3('\0'), e4('\0') {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: member initializer for 'e1' is redundant
+ // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: member initializer for 'e2' is redundant
+ // CHECK-MESSAGES: :[[@LINE-3]]:44: warning: member initializer for 'e3' is redundant
+ // CHECK-FIXES: ExistingChar(long) : e4('\0') {}
+ ExistingChar(char) : e1('a'), e2('a'), e3('a'), e4('a') {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:51: warning: member initializer for 'e4' is redundant
+ // CHECK-FIXES: ExistingChar(char) : e1('a'), e2('a'), e3('a') {}
+ char e1{};
+ char e2 = 0;
+ char e3 = '\0';
+ char e4 = 'a';
+};
+
+struct ExistingInt {
+ ExistingInt(short) : e1(), e2(), e3(), e4(), e5(), e6() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: member initializer for 'e1' is redundant [modernize-use-default-member-init]
+ // CHECK-MESSAGES: :[[@LINE-2]]:30: warning: member initializer for 'e2' is redundant
+ // CHECK-FIXES: ExistingInt(short) : e3(), e4(), e5(), e6() {}
+ ExistingInt(int) : e1(0), e2(0), e3(0), e4(0), e5(0), e6(0) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: member initializer for 'e1' is redundant
+ // CHECK-MESSAGES: :[[@LINE-2]]:29: warning: member initializer for 'e2' is redundant
+ // CHECK-FIXES: ExistingInt(int) : e3(0), e4(0), e5(0), e6(0) {}
+ ExistingInt(long) : e1(5), e2(5), e3(5), e4(5), e5(5), e6(5) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: member initializer for 'e3' is redundant
+ // CHECK-MESSAGES: :[[@LINE-2]]:44: warning: member initializer for 'e4' is redundant
+ // CHECK-MESSAGES: :[[@LINE-3]]:58: warning: member initializer for 'e6' is redundant
+ // CHECK-FIXES: ExistingInt(long) : e1(5), e2(5), e5(5) {}
+ ExistingInt(char) : e1(-5), e2(-5), e3(-5), e4(-5), e5(-5), e6(-5) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:55: warning: member initializer for 'e5' is redundant
+ // CHECK-FIXES: ExistingInt(char) : e1(-5), e2(-5), e3(-5), e4(-5), e6(-5) {}
+ int e1{};
+ int e2 = 0;
+ int e3 = {5};
+ int e4 = 5;
+ int e5 = -5;
+ int e6 = +5;
+};
+
+struct ExistingDouble {
+ ExistingDouble(short) : e1(), e2(), e3(), e4(), e5() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: member initializer for 'e1' is redundant
+ // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: member initializer for 'e2' is redundant
+ // CHECK-FIXES: ExistingDouble(short) : e3(), e4(), e5() {}
+ ExistingDouble(int) : e1(0.0), e2(0.0), e3(0.0), e4(0.0), e5(0.0) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: member initializer for 'e1' is redundant
+ // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: member initializer for 'e2' is redundant
+ // CHECK-FIXES: ExistingDouble(int) : e3(0.0), e4(0.0), e5(0.0) {}
+ ExistingDouble(long) : e1(5.0), e2(5.0), e3(5.0), e4(5.0), e5(5.0) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: member initializer for 'e3' is redundant
+ // CHECK-MESSAGES: :[[@LINE-2]]:62: warning: member initializer for 'e5' is redundant
+ // CHECK-FIXES: ExistingDouble(long) : e1(5.0), e2(5.0), e4(5.0) {}
+ ExistingDouble(char) : e1(-5.0), e2(-5.0), e3(-5.0), e4(-5.0), e5(-5.0) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:56: warning: member initializer for 'e4' is redundant
+ // CHECK-FIXES: ExistingDouble(char) : e1(-5.0), e2(-5.0), e3(-5.0), e5(-5.0) {}
+ double e1{};
+ double e2 = 0.0;
+ double e3 = 5.0;
+ double e4 = -5.0;
+ double e5 = +5.0;
+};
+
+struct ExistingBool {
+ ExistingBool(short) : e1(), e2(), e3() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: member initializer for 'e1' is redundant
+ // CHECK-MESSAGES: :[[@LINE-2]]:31: warning: member initializer for 'e2' is redundant
+ // CHECK-FIXES: ExistingBool(short) : e3() {}
+ ExistingBool(int) : e1(false), e2(false), e3(false) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: member initializer for 'e1' is redundant
+ // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: member initializer for 'e2' is redundant
+ // CHECK-FIXES: ExistingBool(int) : e3(false) {}
+ ExistingBool(long) : e1(true), e2(true), e3(true) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: member initializer for 'e3' is redundant
+ // CHECK-FIXES: ExistingBool(long) : e1(true), e2(true) {}
+ bool e1{};
+ bool e2 = false;
+ bool e3 = true;
+};
+
+struct ExistingEnum {
+ ExistingEnum(short) : e1(Foo), e2(Foo) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: member initializer for 'e1' is redundant
+ // CHECK-FIXES: ExistingEnum(short) : e2(Foo) {}
+ ExistingEnum(int) : e1(Bar), e2(Bar) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: member initializer for 'e2' is redundant
+ // CHECK-FIXES: ExistingEnum(int) : e1(Bar) {}
+ Enum e1 = Foo;
+ Enum e2{Bar};
+};
+
+struct ExistingPointer {
+ ExistingPointer(short) : e1(), e2(), e3(), e4() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: member initializer for 'e1' is redundant
+ // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: member initializer for 'e2' is redundant
+ // CHECK-MESSAGES: :[[@LINE-3]]:40: warning: member initializer for 'e3' is redundant
+ // CHECK-FIXES: ExistingPointer(short) : e4() {}
+ ExistingPointer(int) : e1(0), e2(0), e3(0), e4(&e1) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: member initializer for 'e1' is redundant
+ // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: member initializer for 'e2' is redundant
+ // CHECK-MESSAGES: :[[@LINE-3]]:40: warning: member initializer for 'e3' is redundant
+ // CHECK-FIXES: ExistingPointer(int) : e4(&e1) {}
+ ExistingPointer(long) : e1(nullptr), e2(nullptr), e3(nullptr), e4(&e2) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: member initializer for 'e1' is redundant
+ // CHECK-MESSAGES: :[[@LINE-2]]:40: warning: member initializer for 'e2' is redundant
+ // CHECK-MESSAGES: :[[@LINE-3]]:53: warning: member initializer for 'e3' is redundant
+ // CHECK-FIXES: ExistingPointer(long) : e4(&e2) {}
+ int *e1{};
+ int *e2 = 0;
+ int *e3 = nullptr;
+ int **e4 = &e1;
+};
+
+struct ExistingString {
+ ExistingString(short) : e1(), e2(), e3(), e4() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: member initializer for 'e1' is redundant [modernize-use-default-member-init]
+ // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: member initializer for 'e2' is redundant
+ // CHECK-FIXES: ExistingString(short) : e3(), e4() {}
+ ExistingString(int) : e1(0), e2(0), e3(0), e4(0) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: member initializer for 'e1' is redundant
+ // CHECK-MESSAGES: :[[@LINE-2]]:32: warning: member initializer for 'e2' is redundant
+ // CHECK-FIXES: ExistingString(int) : e3(0), e4(0) {}
+ ExistingString(long) : e1(nullptr), e2(nullptr), e3(nullptr), e4(nullptr) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: member initializer for 'e1' is redundant
+ // CHECK-MESSAGES: :[[@LINE-2]]:39: warning: member initializer for 'e2' is redundant
+ // CHECK-FIXES: ExistingString(long) : e3(nullptr), e4(nullptr) {}
+ ExistingString(char) : e1("foo"), e2("foo"), e3("foo"), e4("foo") {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: member initializer for 'e3' is redundant
+ // CHECK-FIXES: ExistingString(char) : e1("foo"), e2("foo"), e4("foo") {}
+ const char *e1{};
+ const char *e2 = nullptr;
+ const char *e3 = "foo";
+ const char *e4 = "bar";
+};
+
+template <typename T>
+struct NegativeTemplateExisting {
+ NegativeTemplateExisting(int) : t(0) {}
+ T t{};
+};
+
+NegativeTemplateExisting<int> ntei(0);
+NegativeTemplateExisting<double> nted(0);
+
+// This resulted in a warning by default.
+#define MACRO() \
+ struct MacroS { \
+ void *P; \
+ MacroS() : P(nullptr) {} \
+ };
+
+MACRO();
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-emplace-ignore-implicit-constructors.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-emplace-ignore-implicit-constructors.cpp
new file mode 100644
index 0000000..2f6b37f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-emplace-ignore-implicit-constructors.cpp
@@ -0,0 +1,123 @@
+// RUN: %check_clang_tidy %s modernize-use-emplace %t -- \
+// RUN: -config="{CheckOptions: \
+// RUN: [{key: modernize-use-emplace.IgnoreImplicitConstructors, \
+// RUN: value: 1}] \
+// RUN: }" -- -std=c++11
+
+namespace std {
+template <typename>
+class initializer_list
+{
+public:
+ initializer_list() noexcept {}
+};
+
+template <typename T>
+class vector {
+public:
+ vector() = default;
+ vector(initializer_list<T>) {}
+
+ void push_back(const T &) {}
+ void push_back(T &&) {}
+
+ template <typename... Args>
+ void emplace_back(Args &&... args){};
+ ~vector();
+};
+
+} // namespace std
+
+void testInts() {
+ std::vector<int> v;
+ v.push_back(42);
+ v.push_back(int(42));
+ v.push_back(int{42});
+ v.push_back(42.0);
+ int z;
+ v.push_back(z);
+}
+
+struct Something {
+ Something(int a, int b = 41) {}
+ Something() {}
+ void push_back(Something);
+ int getInt() { return 42; }
+};
+
+struct Convertable {
+ operator Something() { return Something{}; }
+};
+
+struct Zoz {
+ Zoz(Something, int = 42) {}
+};
+
+Zoz getZoz(Something s) { return Zoz(s); }
+
+void test_Something() {
+ std::vector<Something> v;
+
+ v.push_back(Something(1, 2));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back instead of push_back [modernize-use-emplace]
+ // CHECK-FIXES: v.emplace_back(1, 2);
+
+ v.push_back(Something{1, 2});
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(1, 2);
+
+ v.push_back(Something());
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back();
+
+ v.push_back(Something{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back();
+
+ Something Different;
+ v.push_back(Something(Different.getInt(), 42));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(Different.getInt(), 42);
+
+ v.push_back(Different.getInt());
+ v.push_back(42);
+
+ Something temporary(42, 42);
+ temporary.push_back(temporary);
+ v.push_back(temporary);
+
+ v.push_back(Convertable());
+ v.push_back(Convertable{});
+ Convertable s;
+ v.push_back(s);
+}
+
+template <typename ElemType>
+void dependOnElem() {
+ std::vector<ElemType> v;
+ v.push_back(ElemType(42));
+}
+
+template <typename ContainerType>
+void dependOnContainer() {
+ ContainerType v;
+ v.push_back(Something(42));
+}
+
+void callDependent() {
+ dependOnElem<Something>();
+ dependOnContainer<std::vector<Something>>();
+}
+
+void test2() {
+ std::vector<Zoz> v;
+ v.push_back(Zoz(Something(21, 37)));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(Something(21, 37));
+
+ v.push_back(Zoz(Something(21, 37), 42));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(Something(21, 37), 42);
+
+ v.push_back(getZoz(Something(1, 2)));
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-emplace.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-emplace.cpp
new file mode 100644
index 0000000..c03d024
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-emplace.cpp
@@ -0,0 +1,607 @@
+// RUN: %check_clang_tidy %s modernize-use-emplace %t -- \
+// RUN: -config="{CheckOptions: \
+// RUN: [{key: modernize-use-emplace.ContainersWithPushBack, \
+// RUN: value: '::std::vector; ::std::list; ::std::deque; llvm::LikeASmallVector'}, \
+// RUN: {key: modernize-use-emplace.TupleTypes, \
+// RUN: value: '::std::pair; std::tuple; ::test::Single'}, \
+// RUN: {key: modernize-use-emplace.TupleMakeFunctions, \
+// RUN: value: '::std::make_pair; ::std::make_tuple; ::test::MakeSingle'}] \
+// RUN: }" -- -std=c++11
+
+namespace std {
+template <typename>
+class initializer_list
+{
+public:
+ initializer_list() noexcept {}
+};
+
+template <typename T>
+class vector {
+public:
+ vector() = default;
+ vector(initializer_list<T>) {}
+
+ void push_back(const T &) {}
+ void push_back(T &&) {}
+
+ template <typename... Args>
+ void emplace_back(Args &&... args){};
+ ~vector();
+};
+template <typename T>
+class list {
+public:
+ void push_back(const T &) {}
+ void push_back(T &&) {}
+
+ template <typename... Args>
+ void emplace_back(Args &&... args){};
+ ~list();
+};
+
+template <typename T>
+class deque {
+public:
+ void push_back(const T &) {}
+ void push_back(T &&) {}
+
+ template <typename... Args>
+ void emplace_back(Args &&... args){};
+ ~deque();
+};
+
+template <typename T> struct remove_reference { using type = T; };
+template <typename T> struct remove_reference<T &> { using type = T; };
+template <typename T> struct remove_reference<T &&> { using type = T; };
+
+template <typename T1, typename T2> class pair {
+public:
+ pair() = default;
+ pair(const pair &) = default;
+ pair(pair &&) = default;
+
+ pair(const T1 &, const T2 &) {}
+ pair(T1 &&, T2 &&) {}
+
+ template <typename U1, typename U2> pair(const pair<U1, U2> &){};
+ template <typename U1, typename U2> pair(pair<U1, U2> &&){};
+};
+
+template <typename T1, typename T2>
+pair<typename remove_reference<T1>::type, typename remove_reference<T2>::type>
+make_pair(T1 &&, T2 &&) {
+ return {};
+};
+
+template <typename... Ts> class tuple {
+public:
+ tuple() = default;
+ tuple(const tuple &) = default;
+ tuple(tuple &&) = default;
+
+ tuple(const Ts &...) {}
+ tuple(Ts &&...) {}
+
+ template <typename... Us> tuple(const tuple<Us...> &){};
+ template <typename... Us> tuple(tuple<Us...> &&) {}
+
+ template <typename U1, typename U2> tuple(const pair<U1, U2> &) {
+ static_assert(sizeof...(Ts) == 2, "Wrong tuple size");
+ };
+ template <typename U1, typename U2> tuple(pair<U1, U2> &&) {
+ static_assert(sizeof...(Ts) == 2, "Wrong tuple size");
+ };
+};
+
+template <typename... Ts>
+tuple<typename remove_reference<Ts>::type...> make_tuple(Ts &&...) {
+ return {};
+}
+
+template <typename T>
+class unique_ptr {
+public:
+ explicit unique_ptr(T *) {}
+ ~unique_ptr();
+};
+} // namespace std
+
+namespace llvm {
+template <typename T>
+class LikeASmallVector {
+public:
+ void push_back(const T &) {}
+ void push_back(T &&) {}
+
+ template <typename... Args>
+ void emplace_back(Args &&... args){};
+};
+
+} // llvm
+
+void testInts() {
+ std::vector<int> v;
+ v.push_back(42);
+ v.push_back(int(42));
+ v.push_back(int{42});
+ v.push_back(42.0);
+ int z;
+ v.push_back(z);
+}
+
+struct Something {
+ Something(int a, int b = 41) {}
+ Something() {}
+ void push_back(Something);
+ int getInt() { return 42; }
+};
+
+struct Convertable {
+ operator Something() { return Something{}; }
+};
+
+struct Zoz {
+ Zoz(Something, int = 42) {}
+};
+
+Zoz getZoz(Something s) { return Zoz(s); }
+
+void test_Something() {
+ std::vector<Something> v;
+
+ v.push_back(Something(1, 2));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back instead of push_back [modernize-use-emplace]
+ // CHECK-FIXES: v.emplace_back(1, 2);
+
+ v.push_back(Something{1, 2});
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(1, 2);
+
+ v.push_back(Something());
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back();
+
+ v.push_back(Something{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back();
+
+ Something Different;
+ v.push_back(Something(Different.getInt(), 42));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(Different.getInt(), 42);
+
+ v.push_back(Different.getInt());
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(Different.getInt());
+
+ v.push_back(42);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(42);
+
+ Something temporary(42, 42);
+ temporary.push_back(temporary);
+ v.push_back(temporary);
+
+ v.push_back(Convertable());
+ v.push_back(Convertable{});
+ Convertable s;
+ v.push_back(s);
+}
+
+template <typename ElemType>
+void dependOnElem() {
+ std::vector<ElemType> v;
+ v.push_back(ElemType(42));
+}
+
+template <typename ContainerType>
+void dependOnContainer() {
+ ContainerType v;
+ v.push_back(Something(42));
+}
+
+void callDependent() {
+ dependOnElem<Something>();
+ dependOnContainer<std::vector<Something>>();
+}
+
+void test2() {
+ std::vector<Zoz> v;
+ v.push_back(Zoz(Something(21, 37)));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(Something(21, 37));
+
+ v.push_back(Zoz(Something(21, 37), 42));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(Something(21, 37), 42);
+
+ v.push_back(getZoz(Something(1, 2)));
+}
+
+struct GetPair {
+ std::pair<int, long> getPair();
+};
+void testPair() {
+ std::vector<std::pair<int, int>> v;
+ v.push_back(std::pair<int, int>(1, 2));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(1, 2);
+
+ GetPair g;
+ v.push_back(g.getPair());
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(g.getPair());
+
+ std::vector<std::pair<Something, Zoz>> v2;
+ v2.push_back(std::pair<Something, Zoz>(Something(42, 42), Zoz(Something(21, 37))));
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
+ // CHECK-FIXES: v2.emplace_back(Something(42, 42), Zoz(Something(21, 37)));
+}
+
+void testTuple() {
+ std::vector<std::tuple<bool, char, int>> v;
+ v.push_back(std::tuple<bool, char, int>(false, 'x', 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(false, 'x', 1);
+
+ v.push_back(std::tuple<bool, char, int>{false, 'y', 2});
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(false, 'y', 2);
+
+ v.push_back({true, 'z', 3});
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(true, 'z', 3);
+
+ std::vector<std::tuple<int, bool>> x;
+ x.push_back(std::make_pair(1, false));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: x.emplace_back(1, false);
+
+ x.push_back(std::make_pair(2LL, 1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: x.emplace_back(2LL, 1);
+}
+
+struct Base {
+ Base(int, int *, int = 42);
+};
+
+struct Derived : Base {
+ Derived(int *, Something) : Base(42, nullptr) {}
+};
+
+void testDerived() {
+ std::vector<Base> v;
+ v.push_back(Derived(nullptr, Something{}));
+}
+
+void testNewExpr() {
+ std::vector<Derived> v;
+ v.push_back(Derived(new int, Something{}));
+}
+
+void testSpaces() {
+ std::vector<Something> v;
+
+ // clang-format off
+
+ v.push_back(Something(1, //arg1
+ 2 // arg2
+ ) // Something
+ );
+ // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(1, //arg1
+ // CHECK-FIXES: 2 // arg2
+ // CHECK-FIXES: // Something
+ // CHECK-FIXES: );
+
+ v.push_back( Something (1, 2) );
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(1, 2 );
+
+ v.push_back( Something {1, 2} );
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(1, 2 );
+
+ v.push_back( Something {} );
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back( );
+
+ v.push_back(
+ Something(1, 2) );
+ // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(1, 2 );
+
+ std::vector<Base> v2;
+ v2.push_back(
+ Base(42, nullptr));
+ // CHECK-MESSAGES: :[[@LINE-2]]:6: warning: use emplace_back
+ // CHECK-FIXES: v2.emplace_back(42, nullptr);
+
+ // clang-format on
+}
+
+void testPointers() {
+ std::vector<int *> v;
+ v.push_back(new int(5));
+
+ std::vector<std::unique_ptr<int>> v2;
+ v2.push_back(std::unique_ptr<int>(new int(42)));
+ // This call can't be replaced with emplace_back.
+ // If emplacement will fail (not enough memory to add to vector)
+ // we will have leak of int because unique_ptr won't be constructed
+ // (and destructed) as in push_back case.
+
+ auto *ptr = new int;
+ v2.push_back(std::unique_ptr<int>(ptr));
+ // Same here
+}
+
+void testMakePair() {
+ std::vector<std::pair<int, int>> v;
+ v.push_back(std::make_pair(1, 2));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(1, 2);
+
+ v.push_back(std::make_pair(42LL, 13));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(42LL, 13);
+
+ v.push_back(std::make_pair<char, char>(0, 3));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(std::make_pair<char, char>(0, 3));
+ //
+ // Even though the call above could be turned into v.emplace_back(0, 3),
+ // we don't eliminate the make_pair call here, because of the explicit
+ // template parameters provided. make_pair's arguments can be convertible
+ // to its explicitly provided template parameter, but not to the pair's
+ // element type. The examples below illustrate the problem.
+ struct D {
+ D(...) {}
+ operator char() const { return 0; }
+ };
+ v.push_back(std::make_pair<D, int>(Something(), 2));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(std::make_pair<D, int>(Something(), 2));
+
+ struct X {
+ X(std::pair<int, int>) {}
+ };
+ std::vector<X> x;
+ x.push_back(std::make_pair(1, 2));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: x.emplace_back(std::make_pair(1, 2));
+ // make_pair cannot be removed here, as X is not constructible with two ints.
+
+ struct Y {
+ Y(std::pair<int, int>&&) {}
+ };
+ std::vector<Y> y;
+ y.push_back(std::make_pair(2, 3));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: y.emplace_back(std::make_pair(2, 3));
+ // make_pair cannot be removed here, as Y is not constructible with two ints.
+}
+
+void testMakeTuple() {
+ std::vector<std::tuple<int, bool, char>> v;
+ v.push_back(std::make_tuple(1, true, 'v'));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(1, true, 'v');
+
+ v.push_back(std::make_tuple(2ULL, 1, 0));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(2ULL, 1, 0);
+
+ v.push_back(std::make_tuple<long long, int, int>(3LL, 1, 0));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(std::make_tuple<long long, int, int>(3LL, 1, 0));
+ // make_tuple is not removed when there are explicit template
+ // arguments provided.
+}
+
+namespace test {
+template <typename T> struct Single {
+ Single() = default;
+ Single(const Single &) = default;
+ Single(Single &&) = default;
+
+ Single(const T &) {}
+ Single(T &&) {}
+
+ template <typename U> Single(const Single<U> &) {}
+ template <typename U> Single(Single<U> &&) {}
+
+ template <typename U> Single(const std::tuple<U> &) {}
+ template <typename U> Single(std::tuple<U> &&) {}
+};
+
+template <typename T>
+Single<typename std::remove_reference<T>::type> MakeSingle(T &&) {
+ return {};
+}
+} // namespace test
+
+void testOtherTuples() {
+ std::vector<test::Single<int>> v;
+ v.push_back(test::Single<int>(1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(1);
+
+ v.push_back({2});
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(2);
+
+ v.push_back(test::MakeSingle(3));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(3);
+
+ v.push_back(test::MakeSingle<long long>(4));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(test::MakeSingle<long long>(4));
+ // We don't remove make functions with explicit template parameters.
+
+ v.push_back(test::MakeSingle(5LL));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(5LL);
+
+ v.push_back(std::make_tuple(6));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(6);
+
+ v.push_back(std::make_tuple(7LL));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(7LL);
+}
+
+void testOtherContainers() {
+ std::list<Something> l;
+ l.push_back(Something(42, 41));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: l.emplace_back(42, 41);
+
+ std::deque<Something> d;
+ d.push_back(Something(42));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: d.emplace_back(42);
+
+ llvm::LikeASmallVector<Something> ls;
+ ls.push_back(Something(42));
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
+ // CHECK-FIXES: ls.emplace_back(42);
+}
+
+class IntWrapper {
+public:
+ IntWrapper(int x) : value(x) {}
+ IntWrapper operator+(const IntWrapper other) const {
+ return IntWrapper(value + other.value);
+ }
+
+private:
+ int value;
+};
+
+void testMultipleOpsInPushBack() {
+ std::vector<IntWrapper> v;
+ v.push_back(IntWrapper(42) + IntWrapper(27));
+}
+
+// Macro tests.
+#define PUSH_BACK_WHOLE(c, x) c.push_back(x)
+#define PUSH_BACK_NAME push_back
+#define PUSH_BACK_ARG(x) (x)
+#define SOME_OBJ Something(10)
+#define MILLION 3
+#define SOME_WEIRD_PUSH(v) v.push_back(Something(
+#define OPEN (
+#define CLOSE )
+void macroTest() {
+ std::vector<Something> v;
+ Something s;
+
+ PUSH_BACK_WHOLE(v, Something(5, 6));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use emplace_back
+
+ v.PUSH_BACK_NAME(Something(5));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+
+ v.push_back PUSH_BACK_ARG(Something(5, 6));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+
+ v.push_back(SOME_OBJ);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+
+ v.push_back(Something(MILLION));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(MILLION);
+
+ // clang-format off
+ v.push_back( Something OPEN 3 CLOSE );
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // clang-format on
+ PUSH_BACK_WHOLE(s, Something(1));
+}
+
+struct A {
+ int value1, value2;
+};
+
+struct B {
+ B(A) {}
+};
+
+struct C {
+ int value1, value2, value3;
+};
+
+void testAggregation() {
+ // This should not be noticed or fixed; after the correction, the code won't
+ // compile.
+
+ std::vector<A> v;
+ v.push_back(A({1, 2}));
+
+ std::vector<B> vb;
+ vb.push_back(B({10, 42}));
+}
+
+struct Bitfield {
+ unsigned bitfield : 1;
+ unsigned notBitfield;
+};
+
+void testBitfields() {
+ std::vector<Something> v;
+ Bitfield b;
+ v.push_back(Something(42, b.bitfield));
+ v.push_back(Something(b.bitfield));
+
+ v.push_back(Something(42, b.notBitfield));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(42, b.notBitfield);
+ int var;
+ v.push_back(Something(42, var));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(42, var);
+}
+
+class PrivateCtor {
+ PrivateCtor(int z);
+
+public:
+ void doStuff() {
+ std::vector<PrivateCtor> v;
+ // This should not change it because emplace back doesn't have permission.
+ // Check currently doesn't support friend declarations because pretty much
+ // nobody would want to be friend with std::vector :(.
+ v.push_back(PrivateCtor(42));
+ }
+};
+
+struct WithDtor {
+ WithDtor(int) {}
+ ~WithDtor();
+};
+
+void testWithDtor() {
+ std::vector<WithDtor> v;
+
+ v.push_back(WithDtor(42));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+ // CHECK-FIXES: v.emplace_back(42);
+}
+
+void testInitializerList() {
+ std::vector<std::vector<int>> v;
+ v.push_back(std::vector<int>({1}));
+ // Test against the bug reported in PR32896.
+
+ v.push_back({{2}});
+
+ using PairIntVector = std::pair<int, std::vector<int>>;
+ std::vector<PairIntVector> x;
+ x.push_back(PairIntVector(3, {4}));
+ x.push_back({5, {6}});
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-equals-default-copy.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-equals-default-copy.cpp
new file mode 100644
index 0000000..39a864d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-equals-default-copy.cpp
@@ -0,0 +1,507 @@
+// RUN: %check_clang_tidy %s modernize-use-equals-default %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-equals-default.IgnoreMacros, value: 0}]}" \
+// RUN: -- -std=c++11 -fno-delayed-template-parsing -fexceptions
+
+// Out of line definition.
+struct OL {
+ OL(const OL &);
+ OL &operator=(const OL &);
+ int Field;
+};
+OL::OL(const OL &Other) : Field(Other.Field) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default' to define a trivial copy constructor [modernize-use-equals-default]
+// CHECK-FIXES: OL::OL(const OL &Other) = default;
+OL &OL::operator=(const OL &Other) {
+ Field = Other.Field;
+ return *this;
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:9: warning: use '= default' to define a trivial copy-assignment operator [modernize-use-equals-default]
+// CHECK-FIXES: OL &OL::operator=(const OL &Other) = default;
+
+// Inline.
+struct IL {
+ IL(const IL &Other) : Field(Other.Field) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: IL(const IL &Other) = default;
+ IL &operator=(const IL &Other) {
+ Field = Other.Field;
+ return *this;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:7: warning: use '= default'
+ // CHECK-FIXES: IL &operator=(const IL &Other) = default;
+ int Field;
+};
+
+// Wrong type.
+struct WT {
+ WT(const IL &Other) {}
+ WT &operator=(const IL &);
+};
+WT &WT::operator=(const IL &Other) { return *this; }
+
+// Qualifiers.
+struct Qual {
+ Qual(const Qual &Other) : Field(Other.Field), Volatile(Other.Volatile),
+ Mutable(Other.Mutable), Reference(Other.Reference),
+ Const(Other.Const) {}
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use '= default'
+ // CHECK-FIXES: Qual(const Qual &Other)
+ // CHECK-FIXES: = default;
+
+ int Field;
+ volatile char Volatile;
+ mutable bool Mutable;
+ const OL &Reference; // This makes this class non-assignable.
+ const IL Const; // This also makes this class non-assignable.
+ static int Static;
+};
+
+// Wrong init arguments.
+struct WI {
+ WI(const WI &Other) : Field1(Other.Field1), Field2(Other.Field1) {}
+ WI &operator=(const WI &);
+ int Field1, Field2;
+};
+WI &WI::operator=(const WI &Other) {
+ Field1 = Other.Field1;
+ Field2 = Other.Field1;
+ return *this;
+}
+
+// Missing field.
+struct MF {
+ MF(const MF &Other) : Field1(Other.Field1), Field2(Other.Field2) {}
+ MF &operator=(const MF &);
+ int Field1, Field2, Field3;
+};
+MF &MF::operator=(const MF &Other) {
+ Field1 = Other.Field1;
+ Field2 = Other.Field2;
+ return *this;
+}
+
+struct Comments {
+ Comments(const Comments &Other)
+ /* don't delete */ : /* this comment */ Field(Other.Field) {}
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default'
+ // CHECK-FIXES: /* don't delete */ = default;
+ int Field;
+};
+
+struct MoreComments {
+ MoreComments(const MoreComments &Other) /* this comment is OK */
+ : Field(Other.Field) {}
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default'
+ // CHECK-FIXES: MoreComments(const MoreComments &Other) /* this comment is OK */
+ // CHECK-FIXES-NEXT: = default;
+ int Field;
+};
+
+struct ColonInComment {
+ ColonInComment(const ColonInComment &Other) /* : */ : Field(Other.Field) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: ColonInComment(const ColonInComment &Other) /* : */ = default;
+ int Field;
+};
+
+// No members or bases (in particular, no colon).
+struct Empty {
+ Empty(const Empty &Other) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: Empty(const Empty &Other) = default;
+ Empty &operator=(const Empty &);
+};
+Empty &Empty::operator=(const Empty &Other) { return *this; }
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use '= default'
+// CHECK-FIXES: Empty &Empty::operator=(const Empty &Other) = default;
+
+// Bit fields.
+struct BF {
+ BF() = default;
+ BF(const BF &Other) : Field1(Other.Field1), Field2(Other.Field2), Field3(Other.Field3),
+ Field4(Other.Field4) {}
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default'
+ // CHECK-FIXES: BF(const BF &Other) {{$}}
+ // CHECK-FIXES: = default;
+ BF &operator=(const BF &);
+
+ unsigned Field1 : 3;
+ int : 7;
+ char Field2 : 6;
+ int : 0;
+ int Field3 : 24;
+ unsigned char Field4;
+};
+BF &BF::operator=(const BF &Other) {
+ Field1 = Other.Field1;
+ Field2 = Other.Field2;
+ Field3 = Other.Field3;
+ Field4 = Other.Field4;
+ return *this;
+}
+// CHECK-MESSAGES: :[[@LINE-7]]:9: warning: use '= default'
+// CHECK-FIXES: BF &BF::operator=(const BF &Other) = default;
+
+// Base classes.
+struct BC : IL, OL, BF {
+ BC(const BC &Other) : IL(Other), OL(Other), BF(Other) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: BC(const BC &Other) = default;
+ BC &operator=(const BC &Other);
+};
+BC &BC::operator=(const BC &Other) {
+ IL::operator=(Other);
+ OL::operator=(Other);
+ BF::operator=(Other);
+ return *this;
+}
+// CHECK-MESSAGES: :[[@LINE-6]]:9: warning: use '= default'
+// CHECK-FIXES: BC &BC::operator=(const BC &Other) = default;
+
+// Base classes with member.
+struct BCWM : IL, OL {
+ BCWM(const BCWM &Other) : IL(Other), OL(Other), Bf(Other.Bf) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: BCWM(const BCWM &Other) = default;
+ BCWM &operator=(const BCWM &);
+ BF Bf;
+};
+BCWM &BCWM::operator=(const BCWM &Other) {
+ IL::operator=(Other);
+ OL::operator=(Other);
+ Bf = Other.Bf;
+ return *this;
+}
+// CHECK-MESSAGES: :[[@LINE-6]]:13: warning: use '= default'
+// CHECK-FIXES: BCWM &BCWM::operator=(const BCWM &Other) = default;
+
+// Missing base class.
+struct MBC : IL, OL, BF {
+ MBC(const MBC &Other) : IL(Other), OL(Other) {}
+ MBC &operator=(const MBC &);
+};
+MBC &MBC::operator=(const MBC &Other) {
+ IL::operator=(Other);
+ OL::operator=(Other);
+ return *this;
+}
+
+// Base classes, incorrect parameter.
+struct BCIP : BCWM, BF {
+ BCIP(const BCIP &Other) : BCWM(Other), BF(Other.Bf) {}
+ BCIP &operator=(const BCIP &);
+};
+BCIP &BCIP::operator=(const BCIP &Other) {
+ BCWM::operator=(Other);
+ BF::operator=(Other.Bf);
+ return *this;
+}
+
+// Virtual base classes.
+struct VA : virtual OL {};
+struct VB : virtual OL {};
+struct VBC : VA, VB, virtual OL {
+ // OL is the first thing that is going to be initialized, despite the fact
+ // that it is the last in the list of bases, because it is virtual and there
+ // is a virtual OL at the beginning of VA (which is the same).
+ VBC(const VBC &Other) : OL(Other), VA(Other), VB(Other) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: VBC(const VBC &Other) = default;
+ VBC &operator=(const VBC &Other);
+};
+VBC &VBC::operator=(const VBC &Other) {
+ OL::operator=(Other);
+ VA::operator=(Other);
+ VB::operator=(Other);
+ return *this;
+}
+// CHECK-MESSAGES: :[[@LINE-6]]:11: warning: use '= default'
+// CHECK-FIXES: VBC &VBC::operator=(const VBC &Other) = default;
+
+// Indirect base.
+struct IB : VBC {
+ IB(const IB &Other) : OL(Other), VBC(Other) {}
+ IB &operator=(const IB &);
+};
+IB &IB::operator=(const IB &Other) {
+ OL::operator=(Other);
+ VBC::operator=(Other);
+ return *this;
+}
+
+// Class template.
+template <class T>
+struct Template {
+ Template() = default;
+ Template(const Template &Other) : Field(Other.Field) {}
+ Template &operator=(const Template &Other);
+ void foo(const T &t);
+ int Field;
+};
+template <class T>
+Template<T> &Template<T>::operator=(const Template<T> &Other) {
+ Field = Other.Field;
+ return *this;
+}
+Template<int> T1;
+
+// Dependent types.
+template <class T>
+struct DT1 {
+ DT1() = default;
+ DT1(const DT1 &Other) : Field(Other.Field) {}
+ DT1 &operator=(const DT1 &);
+ T Field;
+};
+template <class T>
+DT1<T> &DT1<T>::operator=(const DT1<T> &Other) {
+ Field = Other.Field;
+ return *this;
+}
+DT1<int> Dt1;
+
+template <class T>
+struct DT2 {
+ DT2() = default;
+ DT2(const DT2 &Other) : Field(Other.Field), Dependent(Other.Dependent) {}
+ DT2 &operator=(const DT2 &);
+ T Field;
+ typename T::TT Dependent;
+};
+template <class T>
+DT2<T> &DT2<T>::operator=(const DT2<T> &Other) {
+ Field = Other.Field;
+ Dependent = Other.Dependent;
+ return *this;
+}
+struct T {
+ typedef int TT;
+};
+DT2<T> Dt2;
+
+// Default arguments.
+struct DA {
+ DA(int Int);
+ DA(const DA &Other = DA(0)) : Field1(Other.Field1), Field2(Other.Field2) {}
+ DA &operator=(const DA &);
+ int Field1;
+ char Field2;
+};
+// Overloaded operator= cannot have a default argument.
+DA &DA::operator=(const DA &Other) {
+ Field1 = Other.Field1;
+ Field2 = Other.Field2;
+ return *this;
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:9: warning: use '= default'
+// CHECK-FIXES: DA &DA::operator=(const DA &Other) = default;
+
+struct DA2 {
+ // Can be used as copy-constructor but cannot be explicitly defaulted.
+ DA2(const DA &Other, int Def = 0) {}
+};
+
+// Default initialization.
+struct DI {
+ DI(const DI &Other) : Field1(Other.Field1), Field2(Other.Field2) {}
+ int Field1;
+ int Field2 = 0;
+ int Fiedl3;
+};
+
+// Statement inside body.
+void foo();
+struct SIB {
+ SIB(const SIB &Other) : Field(Other.Field) { foo(); }
+ SIB &operator=(const SIB &);
+ int Field;
+};
+SIB &SIB::operator=(const SIB &Other) {
+ Field = Other.Field;
+ foo();
+ return *this;
+}
+
+// Comment inside body.
+struct CIB {
+ CIB(const CIB &Other) : Field(Other.Field) { /* Don't erase this */
+ }
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default'
+ CIB &operator=(const CIB &);
+ int Field;
+};
+CIB &CIB::operator=(const CIB &Other) {
+ Field = Other.Field;
+ // FIXME: don't erase this comment.
+ return *this;
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:11: warning: use '= default'
+// CHECK-FIXES: CIB &CIB::operator=(const CIB &Other) = default;
+
+// Take non-const reference as argument.
+struct NCRef {
+ NCRef(NCRef &Other) : Field1(Other.Field1), Field2(Other.Field2) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: NCRef(NCRef &Other) = default;
+ NCRef &operator=(NCRef &);
+ int Field1, Field2;
+};
+NCRef &NCRef::operator=(NCRef &Other) {
+ Field1 = Other.Field1;
+ Field2 = Other.Field2;
+ return *this;
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:15: warning: use '= default'
+// CHECK-FIXES: NCRef &NCRef::operator=(NCRef &Other) = default;
+
+// Already defaulted.
+struct IAD {
+ IAD(const IAD &Other) = default;
+ IAD &operator=(const IAD &Other) = default;
+};
+
+struct OAD {
+ OAD(const OAD &Other);
+ OAD &operator=(const OAD &);
+};
+OAD::OAD(const OAD &Other) = default;
+OAD &OAD::operator=(const OAD &Other) = default;
+
+// Deleted.
+struct ID {
+ ID(const ID &Other) = delete;
+ ID &operator=(const ID &Other) = delete;
+};
+
+// Non-reference parameter.
+struct NRef {
+ NRef &operator=(NRef Other);
+ int Field1;
+};
+NRef &NRef::operator=(NRef Other) {
+ Field1 = Other.Field1;
+ return *this;
+}
+
+// RValue reference parameter.
+struct RVR {
+ RVR(RVR &&Other) {}
+ RVR &operator=(RVR &&);
+};
+RVR &RVR::operator=(RVR &&Other) { return *this; }
+
+// Similar function.
+struct SF {
+ SF &foo(const SF &);
+ int Field1;
+};
+SF &SF::foo(const SF &Other) {
+ Field1 = Other.Field1;
+ return *this;
+}
+
+// No return.
+struct NR {
+ NR &operator=(const NR &);
+};
+NR &NR::operator=(const NR &Other) {}
+
+// Return misplaced.
+struct RM {
+ RM &operator=(const RM &);
+ int Field;
+};
+RM &RM::operator=(const RM &Other) {
+ return *this;
+ Field = Other.Field;
+}
+
+// Wrong return value.
+struct WRV {
+ WRV &operator=(WRV &);
+};
+WRV &WRV::operator=(WRV &Other) {
+ return Other;
+}
+
+// Wrong return type.
+struct WRT : IL {
+ IL &operator=(const WRT &);
+};
+IL &WRT::operator=(const WRT &Other) {
+ return *this;
+}
+
+// Try-catch.
+struct ITC {
+ ITC(const ITC &Other)
+ try : Field(Other.Field) {
+ } catch (...) {
+ }
+ ITC &operator=(const ITC &Other) try {
+ Field = Other.Field;
+ } catch (...) {
+ }
+ int Field;
+};
+
+struct OTC {
+ OTC(const OTC &);
+ OTC &operator=(const OTC &);
+ int Field;
+};
+OTC::OTC(const OTC &Other) try : Field(Other.Field) {
+} catch (...) {
+}
+OTC &OTC::operator=(const OTC &Other) try {
+ Field = Other.Field;
+} catch (...) {
+}
+
+// FIXME: the check is not able to detect exception specification.
+// noexcept(true).
+struct NET {
+ // This is the default.
+ //NET(const NET &Other) noexcept {}
+ NET &operator=(const NET &Other) noexcept;
+};
+//NET &NET::operator=(const NET &Other) noexcept { return *this; }
+
+// noexcept(false).
+struct NEF {
+ // This is the default.
+ //NEF(const NEF &Other) noexcept(false) {}
+ NEF &operator=(const NEF &Other) noexcept(false);
+};
+//NEF &NEF::operator=(const NEF &Other) noexcept(false) { return *this; }
+
+#define STRUCT_WITH_COPY_CONSTRUCT(_base, _type) \
+ struct _type { \
+ _type(const _type &v) : value(v.value) {} \
+ _base value; \
+ };
+
+STRUCT_WITH_COPY_CONSTRUCT(unsigned char, Hex8CopyConstruct)
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default' to define a trivial copy constructor
+// CHECK-MESSAGES: :[[@LINE-6]]:44: note:
+
+#define STRUCT_WITH_COPY_ASSIGN(_base, _type) \
+ struct _type { \
+ _type &operator=(const _type &rhs) { \
+ value = rhs.value; \
+ return *this; \
+ } \
+ _base value; \
+ };
+
+STRUCT_WITH_COPY_ASSIGN(unsigned char, Hex8CopyAssign)
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default' to define a trivial copy-assignment operator
+// CHECK-MESSAGES: :[[@LINE-9]]:40: note:
+
+// Use of braces
+struct UOB{
+ UOB(const UOB &Other):j{Other.j}{}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' to define a trivial copy constructor [modernize-use-equals-default]
+ // CHECK-FIXES: UOB(const UOB &Other)= default;
+ int j;
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-equals-default-delayed.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-equals-default-delayed.cpp
new file mode 100644
index 0000000..953d88a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-equals-default-delayed.cpp
@@ -0,0 +1,8 @@
+// RUN: clang-tidy %s -checks=-*,modernize-use-equals-default -- -std=c++11 -fdelayed-template-parsing -fexceptions | count 0
+// Note: this test expects no diagnostics, but FileCheck cannot handle that,
+// hence the use of | count 0.
+
+template <typename Ty>
+struct S {
+ S<Ty>& operator=(const S<Ty>&) { return *this; }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-equals-default-macros.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-equals-default-macros.cpp
new file mode 100644
index 0000000..2277a86
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-equals-default-macros.cpp
@@ -0,0 +1,13 @@
+// RUN: %check_clang_tidy %s modernize-use-equals-default %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-equals-default.IgnoreMacros, value: 0}]}" \
+// RUN: -- -std=c++11
+
+#define STRUCT_WITH_DEFAULT(_base, _type) \
+ struct _type { \
+ _type() {} \
+ _base value; \
+ };
+
+STRUCT_WITH_DEFAULT(unsigned char, InMacro)
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default' to define a trivial default constructor
+// CHECK-MESSAGES: :[[@LINE-6]]:13: note:
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-equals-default.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-equals-default.cpp
new file mode 100644
index 0000000..8fa15ff
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-equals-default.cpp
@@ -0,0 +1,207 @@
+// RUN: %check_clang_tidy %s modernize-use-equals-default %t -- -- -std=c++11 -fno-delayed-template-parsing -fexceptions
+
+// Out of line definition.
+class OL {
+public:
+ OL();
+ ~OL();
+};
+
+OL::OL() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default' to define a trivial default constructor [modernize-use-equals-default]
+// CHECK-FIXES: OL::OL() = default;
+OL::~OL() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default' to define a trivial destructor [modernize-use-equals-default]
+// CHECK-FIXES: OL::~OL() = default;
+
+// Inline definitions.
+class IL {
+public:
+ IL() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: IL() = default;
+ ~IL() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: ~IL() = default;
+};
+
+// Non-empty body.
+void f();
+class NE {
+public:
+ NE() { f(); }
+ ~NE() { f(); }
+};
+
+// Initializer or arguments.
+class IA {
+public:
+ // Constructor with initializer.
+ IA() : Field(5) {}
+ // Constructor with arguments.
+ IA(int Arg1, int Arg2) {}
+ int Field;
+};
+
+// Default member initializer
+class DMI {
+public:
+ DMI() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: DMI() = default;
+ int Field = 5;
+};
+
+// Class member
+class CM {
+public:
+ CM() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: CM() = default;
+ OL o;
+};
+
+// Private constructor/destructor.
+class Priv {
+ Priv() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: Priv() = default;
+ ~Priv() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: ~Priv() = default;
+};
+
+// struct.
+struct ST {
+ ST() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: ST() = default;
+ ~ST() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: ST() = default;
+};
+
+// Deleted constructor/destructor.
+class Del {
+public:
+ Del() = delete;
+ ~Del() = delete;
+};
+
+// Do not remove other keywords.
+class KW {
+public:
+ explicit KW() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use '= default'
+ // CHECK-FIXES: explicit KW() = default;
+ virtual ~KW() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use '= default'
+ // CHECK-FIXES: virtual ~KW() = default;
+};
+
+// Nested class.
+struct N {
+ struct NN {
+ NN() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default'
+ // CHECK-FIXES: NN() = default;
+ ~NN() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default'
+ // CHECK-FIXES: ~NN() = default;
+ };
+ int Int;
+};
+
+// Class template.
+template <class T>
+class Temp {
+public:
+ Temp() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: Temp() = default;
+ ~Temp() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: ~Temp() = default;
+};
+
+// Class template out of line with explicit instantiation.
+template <class T>
+class TempODef {
+public:
+ TempODef();
+ ~TempODef();
+};
+
+template <class T>
+TempODef<T>::TempODef() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use '= default'
+// CHECK-FIXES: TempODef<T>::TempODef() = default;
+template <class T>
+TempODef<T>::~TempODef() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use '= default'
+// CHECK-FIXES: TempODef<T>::~TempODef() = default;
+
+template class TempODef<int>;
+template class TempODef<double>;
+
+// Non user-provided constructor/destructor.
+struct Imp {
+ int Int;
+};
+void g() {
+ Imp *PtrImp = new Imp();
+ PtrImp->~Imp();
+ delete PtrImp;
+}
+
+// Already using default.
+struct IDef {
+ IDef() = default;
+ ~IDef() = default;
+};
+struct ODef {
+ ODef();
+ ~ODef();
+};
+ODef::ODef() = default;
+ODef::~ODef() = default;
+
+// Delegating constructor and overriden destructor.
+struct DC : KW {
+ DC() : KW() {}
+ ~DC() override {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+ // CHECK-FIXES: ~DC() override = default;
+};
+
+struct Comments {
+ Comments() {
+ // Don't erase comments inside the body.
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use '= default'
+ ~Comments() {
+ // Don't erase comments inside the body.
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use '= default'
+};
+
+// Try-catch.
+struct ITC {
+ ITC() try {} catch(...) {}
+ ~ITC() try {} catch(...) {}
+};
+
+struct OTC {
+ OTC();
+ ~OTC();
+};
+OTC::OTC() try {} catch(...) {}
+OTC::~OTC() try {} catch(...) {}
+
+#define STRUCT_WITH_DEFAULT(_base, _type) \
+ struct _type { \
+ _type() {} \
+ _base value; \
+ };
+
+STRUCT_WITH_DEFAULT(unsigned char, InMacro)
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-equals-delete-macros.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-equals-delete-macros.cpp
new file mode 100644
index 0000000..1b5a89c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-equals-delete-macros.cpp
@@ -0,0 +1,10 @@
+// RUN: %check_clang_tidy %s modernize-use-equals-delete %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-equals-delete.IgnoreMacros, value: 0}]}" \
+// RUN: -- -std=c++11
+
+#define MACRO(type) void operator=(type const &)
+class C {
+private:
+ MACRO(C);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-equals-delete.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-equals-delete.cpp
new file mode 100644
index 0000000..988c8e5
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-equals-delete.cpp
@@ -0,0 +1,193 @@
+// RUN: %check_clang_tidy %s modernize-use-equals-delete %t
+
+struct PositivePrivate {
+private:
+ PositivePrivate();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete]
+ // CHECK-FIXES: PositivePrivate() = delete;
+ PositivePrivate(const PositivePrivate &);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete]
+ // CHECK-FIXES: PositivePrivate(const PositivePrivate &) = delete;
+ PositivePrivate &operator=(const PositivePrivate &);
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete]
+ // CHECK-FIXES: PositivePrivate &operator=(const PositivePrivate &) = delete;
+ PositivePrivate(PositivePrivate &&);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete]
+ // CHECK-FIXES: PositivePrivate(PositivePrivate &&) = delete;
+ PositivePrivate &operator=(PositivePrivate &&);
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete]
+ // CHECK-FIXES: PositivePrivate &operator=(PositivePrivate &&) = delete;
+ ~PositivePrivate();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete]
+ // CHECK-FIXES: ~PositivePrivate() = delete;
+};
+
+template<typename T>
+struct PositivePrivateTemplate {
+private:
+ PositivePrivateTemplate();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete]
+ // CHECK-FIXES: PositivePrivateTemplate() = delete;
+ PositivePrivateTemplate(const PositivePrivateTemplate &);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete]
+ // CHECK-FIXES: PositivePrivateTemplate(const PositivePrivateTemplate &) = delete;
+ PositivePrivateTemplate &operator=(const PositivePrivateTemplate &);
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete]
+ // CHECK-FIXES: PositivePrivateTemplate &operator=(const PositivePrivateTemplate &) = delete;
+ PositivePrivateTemplate(PositivePrivateTemplate &&);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete]
+ // CHECK-FIXES: PositivePrivateTemplate(PositivePrivateTemplate &&) = delete;
+ PositivePrivateTemplate &operator=(PositivePrivateTemplate &&);
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete]
+ // CHECK-FIXES: PositivePrivateTemplate &operator=(PositivePrivateTemplate &&) = delete;
+ ~PositivePrivateTemplate();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete]
+ // CHECK-FIXES: ~PositivePrivateTemplate() = delete;
+};
+
+template struct PositivePrivateTemplate<int>;
+template struct PositivePrivateTemplate<char>;
+
+struct NegativePublic {
+ NegativePublic(const NegativePublic &);
+};
+
+struct NegativeProtected {
+protected:
+ NegativeProtected(const NegativeProtected &);
+};
+
+struct PositiveInlineMember {
+ int foo() { return 0; }
+
+private:
+ PositiveInlineMember(const PositiveInlineMember &);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete]
+ // CHECK-FIXES: PositiveInlineMember(const PositiveInlineMember &) = delete;
+};
+
+struct PositiveOutOfLineMember {
+ int foo();
+
+private:
+ PositiveOutOfLineMember(const PositiveOutOfLineMember &);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete]
+ // CHECK-FIXES: PositiveOutOfLineMember(const PositiveOutOfLineMember &) = delete;
+};
+
+int PositiveOutOfLineMember::foo() { return 0; }
+
+struct PositiveAbstractMember {
+ virtual int foo() = 0;
+
+private:
+ PositiveAbstractMember(const PositiveAbstractMember &);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete]
+ // CHECK-FIXES: PositiveAbstractMember(const PositiveAbstractMember &) = delete;
+};
+
+struct NegativeMemberNotImpl {
+ int foo();
+
+private:
+ NegativeMemberNotImpl(const NegativeMemberNotImpl &);
+};
+
+struct NegativeStaticMemberNotImpl {
+ static int foo();
+
+private:
+ NegativeStaticMemberNotImpl(const NegativeStaticMemberNotImpl &);
+};
+
+struct NegativeInline {
+private:
+ NegativeInline(const NegativeInline &) {}
+};
+
+struct NegativeOutOfLine {
+private:
+ NegativeOutOfLine(const NegativeOutOfLine &);
+};
+
+NegativeOutOfLine::NegativeOutOfLine(const NegativeOutOfLine &) {}
+
+struct NegativeConstructNotImpl {
+ NegativeConstructNotImpl();
+
+private:
+ NegativeConstructNotImpl(const NegativeConstructNotImpl &);
+};
+
+struct PositiveDefaultedConstruct {
+ PositiveDefaultedConstruct() = default;
+
+private:
+ PositiveDefaultedConstruct(const PositiveDefaultedConstruct &);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete]
+ // CHECK-FIXES: PositiveDefaultedConstruct(const PositiveDefaultedConstruct &) = delete;
+};
+
+struct PositiveDeletedConstruct {
+ PositiveDeletedConstruct() = delete;
+
+private:
+ PositiveDeletedConstruct(const PositiveDeletedConstruct &);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete]
+ // CHECK-FIXES: PositiveDeletedConstruct(const PositiveDeletedConstruct &) = delete;
+};
+
+struct NegativeDefaulted {
+private:
+ NegativeDefaulted(const NegativeDefaulted &) = default;
+};
+
+struct PrivateDeleted {
+private:
+ PrivateDeleted(const PrivateDeleted &) = delete;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: deleted member function should be public [modernize-use-equals-delete]
+};
+
+struct ProtectedDeleted {
+protected:
+ ProtectedDeleted(const ProtectedDeleted &) = delete;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: deleted member function should be public [modernize-use-equals-delete]
+};
+
+struct PublicDeleted {
+public:
+ PublicDeleted(const PublicDeleted &) = delete;
+};
+
+#define M1 \
+ struct PrivateDeletedMacro { \
+ private: \
+ PrivateDeletedMacro(const PrivateDeletedMacro &) = delete; \
+ }; \
+ struct ProtectedDeletedMacro { \
+ protected: \
+ ProtectedDeletedMacro(const ProtectedDeletedMacro &) = delete; \
+ }
+
+M1;
+
+#define DISALLOW_COPY_AND_ASSIGN(name) \
+ name(const name &) = delete; \
+ void operator=(const name &) = delete
+
+struct PrivateDeletedMacro2 {
+private:
+ DISALLOW_COPY_AND_ASSIGN(PrivateDeletedMacro2);
+};
+
+struct ProtectedDeletedMacro2 {
+protected:
+ DISALLOW_COPY_AND_ASSIGN(ProtectedDeletedMacro2);
+};
+
+// This resulted in a warning by default.
+#define MACRO(type) void operator=(type const &)
+class C {
+private:
+ MACRO(C);
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nodiscard-clang-unused.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nodiscard-clang-unused.cpp
new file mode 100644
index 0000000..0951e61
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nodiscard-clang-unused.cpp
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s modernize-use-nodiscard %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-nodiscard.ReplacementString, value: '[[clang::warn_unused_result]]'}]}" \
+// RUN: -- -std=c++11
+
+class Foo
+{
+public:
+ bool f1() const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f1' should be marked {{\[\[clang::warn_unused_result\]\]}} [modernize-use-nodiscard]
+ // CHECK-FIXES: {{\[\[clang::warn_unused_result\]\]}} bool f1() const;
+
+ bool f2(int) const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f2' should be marked {{\[\[clang::warn_unused_result\]\]}} [modernize-use-nodiscard]
+ // CHECK-FIXES: {{\[\[clang::warn_unused_result\]\]}} bool f2(int) const;
+
+ bool f3(const int &) const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f3' should be marked {{\[\[clang::warn_unused_result\]\]}} [modernize-use-nodiscard]
+ // CHECK-FIXES: {{\[\[clang::warn_unused_result\]\]}} bool f3(const int &) const;
+
+ bool f4(void) const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f4' should be marked {{\[\[clang::warn_unused_result\]\]}} [modernize-use-nodiscard]
+ // CHECK-FIXES: {{\[\[clang::warn_unused_result\]\]}} bool f4(void) const;
+
+};
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nodiscard-cxx11.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nodiscard-cxx11.cpp
new file mode 100644
index 0000000..cbf0cea
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nodiscard-cxx11.cpp
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s modernize-use-nodiscard %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-nodiscard.ReplacementString, value: '__attribute__((warn_unused_result))'}]}" \
+// RUN: -- -std=c++11
+
+class Foo
+{
+public:
+ bool f1() const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f1' should be marked __attribute__((warn_unused_result)) [modernize-use-nodiscard]
+ // CHECK-FIXES: __attribute__((warn_unused_result)) bool f1() const;
+
+ bool f2(int) const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f2' should be marked __attribute__((warn_unused_result)) [modernize-use-nodiscard]
+ // CHECK-FIXES: __attribute__((warn_unused_result)) bool f2(int) const;
+
+ bool f3(const int &) const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f3' should be marked __attribute__((warn_unused_result)) [modernize-use-nodiscard]
+ // CHECK-FIXES: __attribute__((warn_unused_result)) bool f3(const int &) const;
+
+ bool f4(void) const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f4' should be marked __attribute__((warn_unused_result)) [modernize-use-nodiscard]
+ // CHECK-FIXES: __attribute__((warn_unused_result)) bool f4(void) const;
+};
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nodiscard-gcc-unused.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nodiscard-gcc-unused.cpp
new file mode 100644
index 0000000..54b808e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nodiscard-gcc-unused.cpp
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s modernize-use-nodiscard %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-nodiscard.ReplacementString, value: '[[gcc::warn_unused_result]]'}]}" \
+// RUN: -- -std=c++11
+
+class Foo
+{
+public:
+ bool f1() const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f1' should be marked {{\[\[gcc::warn_unused_result\]\]}} [modernize-use-nodiscard]
+ // CHECK-FIXES: {{\[\[gcc::warn_unused_result\]\]}} bool f1() const;
+
+ bool f2(int) const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f2' should be marked {{\[\[gcc::warn_unused_result\]\]}} [modernize-use-nodiscard]
+ // CHECK-FIXES: {{\[\[gcc::warn_unused_result\]\]}} bool f2(int) const;
+
+ bool f3(const int &) const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f3' should be marked {{\[\[gcc::warn_unused_result\]\]}} [modernize-use-nodiscard]
+ // CHECK-FIXES: {{\[\[gcc::warn_unused_result\]\]}} bool f3(const int &) const;
+
+ bool f4(void) const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f4' should be marked {{\[\[gcc::warn_unused_result\]\]}} [modernize-use-nodiscard]
+ // CHECK-FIXES: {{\[\[gcc::warn_unused_result\]\]}} bool f4(void) const;
+
+};
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nodiscard-no-macro-inscope-cxx11.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nodiscard-no-macro-inscope-cxx11.cpp
new file mode 100644
index 0000000..0564a13
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nodiscard-no-macro-inscope-cxx11.cpp
@@ -0,0 +1,13 @@
+// RUN: %check_clang_tidy %s modernize-use-nodiscard %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-nodiscard.ReplacementString, value: 'CUSTOM_NO_DISCARD'}]}" -- -std=c++11
+
+// As if the macro was not defined.
+// #define CUSTOM_NO_DISCARD __attribute_((warn_unused_result))
+
+class Foo
+{
+public:
+ bool f1() const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f1' should be marked CUSTOM_NO_DISCARD [modernize-use-nodiscard]
+};
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nodiscard-no-macro.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nodiscard-no-macro.cpp
new file mode 100644
index 0000000..7898b6e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nodiscard-no-macro.cpp
@@ -0,0 +1,22 @@
+// RUN: %check_clang_tidy %s modernize-use-nodiscard %t -- -- -std=c++17
+
+class Foo
+{
+public:
+ bool f1() const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f1' should be marked {{\[\[nodiscard\]\]}} [modernize-use-nodiscard]
+ // CHECK-FIXES: {{\[\[nodiscard\]\]}} bool f1() const;
+
+ bool f2(int) const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f2' should be marked {{\[\[nodiscard\]\]}} [modernize-use-nodiscard]
+ // CHECK-FIXES: {{\[\[nodiscard\]\]}} bool f2(int) const;
+
+ bool f3(const int &) const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f3' should be marked {{\[\[nodiscard\]\]}} [modernize-use-nodiscard]
+ // CHECK-FIXES: {{\[\[nodiscard\]\]}} bool f3(const int &) const;
+
+ bool f4(void) const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f4' should be marked {{\[\[nodiscard\]\]}} [modernize-use-nodiscard]
+ // CHECK-FIXES: {{\[\[nodiscard\]\]}} bool f4(void) const;
+
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nodiscard.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nodiscard.cpp
new file mode 100644
index 0000000..a571f09
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nodiscard.cpp
@@ -0,0 +1,262 @@
+// RUN: %check_clang_tidy %s modernize-use-nodiscard %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-nodiscard.ReplacementString, value: 'NO_DISCARD'}]}" \
+// RUN: -- -std=c++17
+
+namespace std {
+template <class>
+class function;
+class string {};
+}
+
+namespace boost {
+template <class>
+class function;
+}
+
+#define MUST_USE_RESULT __attribute__((warn_unused_result))
+#define NO_DISCARD [[nodiscard]]
+#define NO_RETURN [[noreturn]]
+
+#define BOOLEAN_FUNC bool f23() const
+
+typedef unsigned my_unsigned;
+typedef unsigned &my_unsigned_reference;
+typedef const unsigned &my_unsigned_const_reference;
+
+class Foo {
+public:
+ using size_type = unsigned;
+
+ bool f1() const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f1' should be marked NO_DISCARD [modernize-use-nodiscard]
+ // CHECK-FIXES: NO_DISCARD bool f1() const;
+
+ bool f2(int) const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f2' should be marked NO_DISCARD [modernize-use-nodiscard]
+ // CHECK-FIXES: NO_DISCARD bool f2(int) const;
+
+ bool f3(const int &) const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f3' should be marked NO_DISCARD [modernize-use-nodiscard]
+ // CHECK-FIXES: NO_DISCARD bool f3(const int &) const;
+
+ bool f4(void) const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f4' should be marked NO_DISCARD [modernize-use-nodiscard]
+ // CHECK-FIXES: NO_DISCARD bool f4(void) const;
+
+ // negative tests
+
+ void f5() const;
+
+ bool f6();
+
+ bool f7(int &);
+
+ bool f8(int &) const;
+
+ bool f9(int *) const;
+
+ bool f10(const int &, int &) const;
+
+ NO_DISCARD bool f12() const;
+
+ MUST_USE_RESULT bool f13() const;
+
+ [[nodiscard]] bool f11() const;
+
+ [[clang::warn_unused_result]] bool f11a() const;
+
+ [[gnu::warn_unused_result]] bool f11b() const;
+
+ bool _f20() const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function '_f20' should be marked NO_DISCARD [modernize-use-nodiscard]
+ // CHECK-FIXES: NO_DISCARD bool _f20() const;
+
+ NO_RETURN bool f21() const;
+
+ ~Foo();
+
+ bool operator+=(int) const;
+
+ // extra keywords (virtual,inline,const) on return type
+
+ virtual bool f14() const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f14' should be marked NO_DISCARD [modernize-use-nodiscard]
+ // CHECK-FIXES: NO_DISCARD virtual bool f14() const;
+
+ const bool f15() const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f15' should be marked NO_DISCARD [modernize-use-nodiscard]
+ // CHECK-FIXES: NO_DISCARD const bool f15() const;
+
+ inline const bool f16() const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f16' should be marked NO_DISCARD [modernize-use-nodiscard]
+ // CHECK-FIXES: NO_DISCARD inline const bool f16() const;
+
+ inline const std::string &f45() const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f45' should be marked NO_DISCARD [modernize-use-nodiscard]
+ // CHECK-FIXES: NO_DISCARD inline const std::string &f45() const;
+
+ inline virtual const bool f17() const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f17' should be marked NO_DISCARD [modernize-use-nodiscard]
+ // CHECK-FIXES: NO_DISCARD inline virtual const bool f17() const;
+
+ // inline with body
+ bool f18() const
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f18' should be marked NO_DISCARD [modernize-use-nodiscard]
+ // CHECK-FIXES: NO_DISCARD bool f18() const
+ {
+ return true;
+ }
+
+ bool f19() const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f19' should be marked NO_DISCARD [modernize-use-nodiscard]
+ // CHECK-FIXES: NO_DISCARD bool f19() const;
+
+ BOOLEAN_FUNC;
+
+ bool f24(size_type) const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f24' should be marked NO_DISCARD [modernize-use-nodiscard]
+ // CHECK-FIXES: NO_DISCARD bool f24(size_type) const;
+
+ bool f28(my_unsigned) const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f28' should be marked NO_DISCARD [modernize-use-nodiscard]
+ // CHECK-FIXES: NO_DISCARD bool f28(my_unsigned) const;
+
+ bool f29(my_unsigned_reference) const;
+
+ bool f30(my_unsigned_const_reference) const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f30' should be marked NO_DISCARD [modernize-use-nodiscard]
+ // CHECK-FIXES: NO_DISCARD bool f30(my_unsigned_const_reference) const;
+
+ template <class F>
+ F f37(F a, F b) const;
+
+ template <class F>
+ bool f38(F a) const;
+
+ bool f39(const std::function<bool()> &predicate) const;
+
+ bool f39a(std::function<bool()> predicate) const;
+
+ bool f39b(const std::function<bool()> predicate) const;
+
+ bool f45(const boost::function<bool()> &predicate) const;
+
+ bool f45a(boost::function<bool()> predicate) const;
+
+ bool f45b(const boost::function<bool()> predicate) const;
+
+ // Do not add ``[[nodiscard]]`` to parameter packs.
+ template <class... Args>
+ bool ParameterPack(Args... args) const;
+
+ template <typename... Targs>
+ bool ParameterPack2(Targs... Fargs) const;
+
+ // Do not add ``[[nodiscard]]`` to variadic functions.
+ bool VariadicFunctionTest(const int &, ...) const;
+
+ // Do not add ``[[nodiscard]]`` to non constant static functions.
+ static bool not_empty();
+
+ // Do not add ``[[nodiscard]]`` to conversion functions.
+ // explicit operator bool() const { return true; }
+};
+
+// Do not add ``[[nodiscard]]`` to Lambda.
+const auto nonConstReferenceType = [] {
+ return true;
+};
+
+auto lambda1 = [](int a, int b) { return a < b; };
+auto lambda1a = [](int a) { return a; };
+auto lambda1b = []() { return true;};
+
+auto get_functor = [](bool check) {
+ return [&](const std::string& sr)->std::string {
+ if(check){
+ return std::string();
+ }
+ return std::string();
+ };
+};
+
+// Do not add ``[[nodiscard]]`` to function definition.
+bool Foo::f19() const {
+ return true;
+}
+
+template <class T>
+class Bar {
+public:
+ using value_type = T;
+ using reference = value_type &;
+ using const_reference = const value_type &;
+
+ // Do not add ``[[nodiscard]]`` to non explicit conversion functions.
+ operator bool() const { return true; }
+
+ bool empty() const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'empty' should be marked NO_DISCARD [modernize-use-nodiscard]
+ // CHECK-FIXES: NO_DISCARD bool empty() const;
+
+ // we cannot assume that the template parameter isn't a pointer
+ bool f25(value_type) const;
+
+ bool f27(reference) const;
+
+ typename T::value_type f35() const;
+
+ T f34() const;
+
+ bool f31(T) const;
+
+ bool f33(T &) const;
+
+ bool f26(const_reference) const;
+
+ bool f32(const T &) const;
+};
+
+template <typename _Tp, int cn>
+class Vec {
+public:
+ Vec(_Tp v0, _Tp v1); //!< 2-element vector constructor
+
+ Vec cross(const Vec &v) const;
+
+ template <typename T2>
+ operator Vec<T2, cn>() const;
+};
+
+template <class T>
+class Bar2 {
+public:
+ typedef T value_type;
+ typedef value_type &reference;
+ typedef const value_type &const_reference;
+
+ // we cannot assume that the template parameter isn't a pointer
+ bool f40(value_type) const;
+
+ bool f41(reference) const;
+
+ value_type f42() const;
+
+ typename T::value_type f43() const;
+
+ bool f44(const_reference) const;
+};
+
+template <class T>
+bool Bar<T>::empty() const {
+ return true;
+}
+
+// don't mark typical ``[[nodiscard]]`` candidates if the class
+// has mutable member variables
+class MutableExample {
+ mutable bool m_isempty;
+
+public:
+ bool empty() const;
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-noexcept-macro.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-noexcept-macro.cpp
new file mode 100644
index 0000000..3948b66
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-noexcept-macro.cpp
@@ -0,0 +1,36 @@
+// RUN: %check_clang_tidy %s modernize-use-noexcept %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-noexcept.ReplacementString, value: 'NOEXCEPT'}]}" \
+// RUN: -- -std=c++11 -fexceptions
+
+// Example definition of NOEXCEPT -- simplified test to see if noexcept is supported.
+#if (__has_feature(cxx_noexcept))
+#define NOEXCEPT noexcept
+#else
+#define NOEXCEPT throw()
+#endif
+
+void bar() throw() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: dynamic exception specification 'throw()' is deprecated; consider using 'NOEXCEPT' instead [modernize-use-noexcept]
+// CHECK-FIXES: void bar() NOEXCEPT {}
+
+// Should not trigger a FixItHint, since macros only support noexcept, and this
+// case throws.
+class A {};
+class B {};
+void foobar() throw(A, B);
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: dynamic exception specification 'throw(A, B)' is deprecated; consider removing it instead [modernize-use-noexcept]
+
+// Should not trigger a replacement.
+void foo() noexcept(true);
+
+struct Z {
+ void operator delete(void *ptr) throw();
+ void operator delete[](void *ptr) throw(int);
+ ~Z() throw(int) {}
+};
+// CHECK-MESSAGES: :[[@LINE-4]]:35: warning: dynamic exception specification 'throw()' is deprecated; consider using 'NOEXCEPT' instead [modernize-use-noexcept]
+// CHECK-MESSAGES: :[[@LINE-4]]:37: warning: dynamic exception specification 'throw(int)' is deprecated; consider removing it instead [modernize-use-noexcept]
+// CHECK-MESSAGES: :[[@LINE-4]]:8: warning: dynamic exception specification 'throw(int)' is deprecated; consider removing it instead [modernize-use-noexcept]
+// CHECK-FIXES: void operator delete(void *ptr) NOEXCEPT;
+// CHECK-FIXES: void operator delete[](void *ptr) throw(int);
+// CHECK-FIXES: ~Z() throw(int) {}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-noexcept-opt.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-noexcept-opt.cpp
new file mode 100644
index 0000000..85a83c8
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-noexcept-opt.cpp
@@ -0,0 +1,88 @@
+// RUN: %check_clang_tidy %s modernize-use-noexcept %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-noexcept.UseNoexceptFalse, value: 0}]}" \
+// RUN: -- -std=c++11 -fexceptions
+
+class A {};
+class B {};
+
+void foo() throw();
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
+// CHECK-FIXES: void foo() noexcept;
+
+void bar() throw(...);
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: dynamic exception specification 'throw(...)' is deprecated; consider removing it instead [modernize-use-noexcept]
+// CHECK-FIXES: void bar() ;
+
+void k() throw(int(int));
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: dynamic exception specification 'throw(int(int))' is deprecated; consider removing it instead [modernize-use-noexcept]
+// CHECK-FIXES: void k() ;
+
+void foobar() throw(A, B)
+{}
+// CHECK-MESSAGES: :[[@LINE-2]]:15: warning: dynamic exception specification 'throw(A, B)' is deprecated; consider removing it instead [modernize-use-noexcept]
+// CHECK-FIXES: void foobar()
+
+void baz(int = (throw A(), 0)) throw(A, B) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: dynamic exception specification 'throw(A, B)' is deprecated; consider removing it instead [modernize-use-noexcept]
+// CHECK-FIXES: void baz(int = (throw A(), 0)) {}
+
+void g(void (*fp)(void) throw());
+// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
+// CHECK-FIXES: void g(void (*fp)(void) noexcept);
+
+void f(void (*fp)(void) throw(int)) throw(char);
+// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: dynamic exception specification 'throw(int)' is deprecated; consider removing it instead [modernize-use-noexcept]
+// CHECK-MESSAGES: :[[@LINE-2]]:37: warning: dynamic exception specification 'throw(char)' is deprecated; consider removing it instead [modernize-use-noexcept]
+// CHECK-FIXES: void f(void (*fp)(void) ) ;
+
+#define THROW throw
+void h(void (*fp)(void) THROW(int)) THROW(char);
+// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: dynamic exception specification 'THROW(int)' is deprecated; consider removing it instead [modernize-use-noexcept]
+// CHECK-MESSAGES: :[[@LINE-2]]:37: warning: dynamic exception specification 'THROW(char)' is deprecated; consider removing it instead [modernize-use-noexcept]
+// CHECK-FIXES: void h(void (*fp)(void) ) ;
+
+void j() throw(int(int) throw(void(void) throw(int)));
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: dynamic exception specification 'throw(int(int) throw(void(void) throw(int)))' is deprecated; consider removing it instead [modernize-use-noexcept]
+// CHECK-FIXES: void j() ;
+
+class Y {
+ Y() throw() = default;
+};
+// CHECK-MESSAGES: :[[@LINE-2]]:7: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
+// CHECK-FIXES: Y() noexcept = default;
+
+struct Z {
+ void operator delete(void *ptr) throw();
+ void operator delete[](void *ptr) throw(int);
+ ~Z() throw(int) {}
+};
+// CHECK-MESSAGES: :[[@LINE-4]]:35: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
+// CHECK-MESSAGES: :[[@LINE-4]]:37: warning: dynamic exception specification 'throw(int)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
+// CHECK-MESSAGES: :[[@LINE-4]]:8: warning: dynamic exception specification 'throw(int)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
+// CHECK-FIXES: void operator delete(void *ptr) noexcept;
+// CHECK-FIXES: void operator delete[](void *ptr) noexcept(false);
+// CHECK-FIXES: ~Z() noexcept(false) {}
+
+struct S {
+ void f() throw();
+};
+void f(void (S::*)() throw());
+// CHECK-MESSAGES: :[[@LINE-3]]:12: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
+// CHECK-MESSAGES: :[[@LINE-2]]:22: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
+// CHECK-FIXES: void f() noexcept;
+// CHECK-FIXES: void f(void (S::*)() noexcept);
+
+typedef void (*fp)(void (*fp2)(int) throw());
+// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
+// CHECK-FIXES: typedef void (*fp)(void (*fp2)(int) noexcept);
+
+// Should not trigger a replacement.
+void titi() noexcept {}
+void toto() noexcept(true) {}
+
+// Should not trigger a replacement.
+void bad()
+#if !__has_feature(cxx_noexcept)
+ throw()
+#endif
+ ;
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-noexcept.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-noexcept.cpp
new file mode 100644
index 0000000..58c764a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-noexcept.cpp
@@ -0,0 +1,104 @@
+// RUN: %check_clang_tidy %s modernize-use-noexcept %t -- \
+// RUN: -- -std=c++11 -fexceptions
+
+class A {};
+class B {};
+
+void foo() throw();
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
+// CHECK-FIXES: void foo() noexcept;
+
+template <typename T>
+void foo() throw();
+void footest() { foo<int>(); foo<double>(); }
+// CHECK-MESSAGES: :[[@LINE-2]]:12: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
+// CHECK-FIXES: void foo() noexcept;
+
+void bar() throw(...);
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: dynamic exception specification 'throw(...)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
+// CHECK-FIXES: void bar() noexcept(false);
+
+void k() throw(int(int));
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: dynamic exception specification 'throw(int(int))' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
+// CHECK-FIXES: void k() noexcept(false);
+
+void foobar() throw(A, B)
+{}
+// CHECK-MESSAGES: :[[@LINE-2]]:15: warning: dynamic exception specification 'throw(A, B)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
+// CHECK-FIXES: void foobar() noexcept(false)
+
+void baz(int = (throw A(), 0)) throw(A, B) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: dynamic exception specification 'throw(A, B)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
+// CHECK-FIXES: void baz(int = (throw A(), 0)) noexcept(false) {}
+
+void g(void (*fp)(void) throw());
+// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
+// CHECK-FIXES: void g(void (*fp)(void) noexcept);
+
+void f(void (*fp)(void) throw(int)) throw(char);
+// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: dynamic exception specification 'throw(int)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
+// CHECK-MESSAGES: :[[@LINE-2]]:37: warning: dynamic exception specification 'throw(char)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
+// CHECK-FIXES: void f(void (*fp)(void) noexcept(false)) noexcept(false);
+
+#define THROW throw
+void h(void (*fp)(void) THROW(int)) THROW(char);
+// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: dynamic exception specification 'THROW(int)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
+// CHECK-MESSAGES: :[[@LINE-2]]:37: warning: dynamic exception specification 'THROW(char)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
+// CHECK-FIXES: void h(void (*fp)(void) noexcept(false)) noexcept(false);
+
+void j() throw(int(int) throw(void(void) throw(int)));
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: dynamic exception specification 'throw(int(int) throw(void(void) throw(int)))' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
+// CHECK-FIXES: void j() noexcept(false);
+
+class Y {
+ Y() throw() = default;
+};
+// CHECK-MESSAGES: :[[@LINE-2]]:7: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
+// CHECK-FIXES: Y() noexcept = default;
+
+struct Z {
+ void operator delete(void *ptr) throw();
+ void operator delete[](void *ptr) throw(int);
+ ~Z() throw(int) {}
+};
+// CHECK-MESSAGES: :[[@LINE-4]]:35: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
+// CHECK-MESSAGES: :[[@LINE-4]]:37: warning: dynamic exception specification 'throw(int)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
+// CHECK-MESSAGES: :[[@LINE-4]]:8: warning: dynamic exception specification 'throw(int)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
+// CHECK-FIXES: void operator delete(void *ptr) noexcept;
+// CHECK-FIXES: void operator delete[](void *ptr) noexcept(false);
+// CHECK-FIXES: ~Z() noexcept(false) {}
+
+struct S {
+ void f() throw();
+};
+void f(void (S::*)() throw());
+// CHECK-MESSAGES: :[[@LINE-3]]:12: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
+// CHECK-MESSAGES: :[[@LINE-2]]:22: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
+// CHECK-FIXES: void f() noexcept;
+// CHECK-FIXES: void f(void (S::*)() noexcept);
+
+template <typename T>
+struct ST {
+ void foo() throw();
+};
+template <typename T>
+void ft(void (ST<T>::*)() throw());
+// CHECK-MESSAGES: :[[@LINE-4]]:14: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
+// CHECK-MESSAGES: :[[@LINE-2]]:27: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
+// CHECK-FIXES: void foo() noexcept;
+// CHECK-FIXES: void ft(void (ST<T>::*)() noexcept);
+
+typedef void (*fp)(void (*fp2)(int) throw());
+// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
+// CHECK-FIXES: typedef void (*fp)(void (*fp2)(int) noexcept);
+
+// Should not trigger a replacement.
+void titi() noexcept {}
+void toto() noexcept(true) {}
+
+// Should not trigger a replacement.
+void bad()
+#if !__has_feature(cxx_noexcept)
+ throw()
+#endif
+ ;
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nullptr-basic.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nullptr-basic.cpp
new file mode 100644
index 0000000..7a953a7
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nullptr-basic.cpp
@@ -0,0 +1,361 @@
+// RUN: %check_clang_tidy %s modernize-use-nullptr %t -- -- \
+// RUN: -std=c++98 -Wno-non-literal-null-conversion
+//
+// Some parts of the test (e.g. assignment of `const int` to `int *`) fail in
+// C++11, so we need to run the test in C++98 mode.
+
+const unsigned int g_null = 0;
+#define NULL 0
+
+void test_assignment() {
+ int *p1 = 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr [modernize-use-nullptr]
+ // CHECK-FIXES: int *p1 = nullptr;
+ p1 = 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use nullptr
+ // CHECK-FIXES: p1 = nullptr;
+
+ int *p2 = NULL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr
+ // CHECK-FIXES: int *p2 = nullptr;
+
+ p2 = p1;
+ // CHECK-FIXES: p2 = p1;
+
+ const int null = 0;
+ int *p3 = null;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr
+ // CHECK-FIXES: int *p3 = nullptr;
+
+ p3 = NULL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use nullptr
+ // CHECK-FIXES: p3 = nullptr;
+
+ int *p4 = p3;
+ // CHECK-FIXES: int *p4 = p3;
+
+ p4 = null;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use nullptr
+ // CHECK-FIXES: p4 = nullptr;
+
+ int i1 = 0;
+
+ int i2 = NULL;
+
+ int i3 = null;
+
+ int *p5, *p6, *p7;
+ p5 = p6 = p7 = NULL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr
+ // CHECK-FIXES: p5 = p6 = p7 = nullptr;
+}
+
+struct Foo {
+ Foo(int *p = NULL) : m_p1(p) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr
+ // CHECK-FIXES: Foo(int *p = nullptr) : m_p1(p) {}
+
+ void bar(int *p = 0) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use nullptr
+ // CHECK-FIXES: void bar(int *p = nullptr) {}
+
+ void baz(int i = 0) {}
+
+ int *m_p1;
+ static int *m_p2;
+};
+
+int *Foo::m_p2 = NULL;
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr
+// CHECK-FIXES: int *Foo::m_p2 = nullptr;
+
+template <typename T>
+struct Bar {
+ Bar(T *p) : m_p(p) {
+ m_p = static_cast<T*>(NULL);
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use nullptr
+ // CHECK-FIXES: m_p = static_cast<T*>(nullptr);
+
+ m_p = static_cast<T*>(reinterpret_cast<int*>((void*)NULL));
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use nullptr
+ // CHECK-FIXES: m_p = static_cast<T*>(nullptr);
+
+ m_p = static_cast<T*>(p ? p : static_cast<void*>(g_null));
+ // CHECK-MESSAGES: :[[@LINE-1]]:54: warning: use nullptr
+ // CHECK-FIXES: m_p = static_cast<T*>(p ? p : static_cast<void*>(nullptr));
+
+ T *p2 = static_cast<T*>(reinterpret_cast<int*>((void*)NULL));
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use nullptr
+ // CHECK-FIXES: T *p2 = static_cast<T*>(nullptr);
+
+ m_p = NULL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use nullptr
+ // CHECK-FIXES: m_p = nullptr;
+
+ int i = static_cast<int>(0.f);
+ T *i2 = static_cast<int>(0.f);
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr
+ // CHECK-FIXES: T *i2 = nullptr;
+ }
+
+ T *m_p;
+};
+
+struct Baz {
+ Baz() : i(0) {}
+ int i;
+};
+
+void test_cxx_cases() {
+ Foo f(g_null);
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
+ // CHECK-FIXES: Foo f(nullptr);
+
+ f.bar(NULL);
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
+ // CHECK-FIXES: f.bar(nullptr);
+
+ f.baz(g_null);
+
+ f.m_p1 = 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr
+ // CHECK-FIXES: f.m_p1 = nullptr;
+
+ Bar<int> b(g_null);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use nullptr
+ // CHECK-FIXES: Bar<int> b(nullptr);
+
+ Baz b2;
+ int Baz::*memptr(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use nullptr
+ // CHECK-FIXES: int Baz::*memptr(nullptr);
+
+ memptr = 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr
+ // CHECK-FIXES: memptr = nullptr;
+}
+
+void test_function_default_param1(void *p = 0);
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use nullptr
+// CHECK-FIXES: void test_function_default_param1(void *p = nullptr);
+
+void test_function_default_param2(void *p = NULL);
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use nullptr
+// CHECK-FIXES: void test_function_default_param2(void *p = nullptr);
+
+void test_function_default_param3(void *p = g_null);
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use nullptr
+// CHECK-FIXES: void test_function_default_param3(void *p = nullptr);
+
+void test_function(int *p) {}
+
+void test_function_no_ptr_param(int i) {}
+
+void test_function_call() {
+ test_function(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use nullptr
+ // CHECK-FIXES: test_function(nullptr);
+
+ test_function(NULL);
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use nullptr
+ // CHECK-FIXES: test_function(nullptr);
+
+ test_function(g_null);
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use nullptr
+ // CHECK-FIXES: test_function(nullptr);
+
+ test_function_no_ptr_param(0);
+}
+
+char *test_function_return1() {
+ return 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
+ // CHECK-FIXES: return nullptr;
+}
+
+void *test_function_return2() {
+ return NULL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
+ // CHECK-FIXES: return nullptr;
+}
+
+long *test_function_return3() {
+ return g_null;
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
+ // CHECK-FIXES: return nullptr;
+}
+
+int test_function_return4() {
+ return 0;
+}
+
+int test_function_return5() {
+ return NULL;
+}
+
+int test_function_return6() {
+ return g_null;
+}
+
+int *test_function_return_cast1() {
+ return(int)0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
+ // CHECK-FIXES: return nullptr;
+}
+
+int *test_function_return_cast2() {
+#define RET return
+ RET(int)0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use nullptr
+ // CHECK-FIXES: RET nullptr;
+#undef RET
+}
+
+// Test parentheses expressions resulting in a nullptr.
+int *test_parentheses_expression1() {
+ return(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
+ // CHECK-FIXES: return(nullptr);
+}
+
+int *test_parentheses_expression2() {
+ return(int(0.f));
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
+ // CHECK-FIXES: return(nullptr);
+}
+
+int *test_nested_parentheses_expression() {
+ return((((0))));
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr
+ // CHECK-FIXES: return((((nullptr))));
+}
+
+void *test_parentheses_explicit_cast() {
+ return(static_cast<void*>(0));
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use nullptr
+ // CHECK-FIXES: return(static_cast<void*>(nullptr));
+}
+
+void *test_parentheses_explicit_cast_sequence1() {
+ return(static_cast<void*>(static_cast<int*>((void*)NULL)));
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use nullptr
+ // CHECK-FIXES: return(static_cast<void*>(nullptr));
+}
+
+void *test_parentheses_explicit_cast_sequence2() {
+ return(static_cast<void*>(reinterpret_cast<int*>((float*)int(0.f))));
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use nullptr
+ // CHECK-FIXES: return(static_cast<void*>(nullptr));
+}
+
+// Test explicit cast expressions resulting in nullptr.
+struct Bam {
+ Bam(int *a) {}
+ Bam(float *a) {}
+ Bam operator=(int *a) { return Bam(a); }
+ Bam operator=(float *a) { return Bam(a); }
+};
+
+void ambiguous_function(int *a) {}
+void ambiguous_function(float *a) {}
+void const_ambiguous_function(const int *p) {}
+void const_ambiguous_function(const float *p) {}
+
+void test_explicit_cast_ambiguous1() {
+ ambiguous_function((int*)0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use nullptr
+ // CHECK-FIXES: ambiguous_function((int*)nullptr);
+}
+
+void test_explicit_cast_ambiguous2() {
+ ambiguous_function((int*)(0));
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use nullptr
+ // CHECK-FIXES: ambiguous_function((int*)nullptr);
+}
+
+void test_explicit_cast_ambiguous3() {
+ ambiguous_function(static_cast<int*>(reinterpret_cast<int*>((float*)0)));
+ // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: use nullptr
+ // CHECK-FIXES: ambiguous_function(static_cast<int*>(nullptr));
+}
+
+Bam test_explicit_cast_ambiguous4() {
+ return(((int*)(0)));
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use nullptr
+ // CHECK-FIXES: return(((int*)nullptr));
+}
+
+void test_explicit_cast_ambiguous5() {
+ // Test for ambiguous overloaded constructors.
+ Bam k((int*)(0));
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use nullptr
+ // CHECK-FIXES: Bam k((int*)nullptr);
+
+ // Test for ambiguous overloaded operators.
+ k = (int*)0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr
+ // CHECK-FIXES: k = (int*)nullptr;
+}
+
+void test_const_pointers_abiguous() {
+ const_ambiguous_function((int*)0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use nullptr
+ // CHECK-FIXES: const_ambiguous_function((int*)nullptr);
+}
+
+// Test where the implicit cast to null is surrounded by another implict cast
+// with possible explict casts in-between.
+void test_const_pointers() {
+ const int *const_p1 = 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr
+ // CHECK-FIXES: const int *const_p1 = nullptr;
+ const int *const_p2 = NULL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr
+ // CHECK-FIXES: const int *const_p2 = nullptr;
+ const int *const_p3 = (int)0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr
+ // CHECK-FIXES: const int *const_p3 = nullptr;
+ const int *const_p4 = (int)0.0f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr
+ // CHECK-FIXES: const int *const_p4 = nullptr;
+ const int *const_p5 = (int*)0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use nullptr
+ // CHECK-FIXES: const int *const_p5 = (int*)nullptr;
+ int *t;
+ const int *const_p6 = static_cast<int*>(t ? t : static_cast<int*>(0));
+ // CHECK-MESSAGES: :[[@LINE-1]]:69: warning: use nullptr
+ // CHECK-FIXES: const int *const_p6 = static_cast<int*>(t ? t : static_cast<int*>(nullptr));
+}
+
+void test_nested_implicit_cast_expr() {
+ int func0(void*, void*);
+ int func1(int, void*, void*);
+
+ (double)func1(0, 0, 0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use nullptr
+ // CHECK-MESSAGES: :[[@LINE-2]]:23: warning: use nullptr
+ // CHECK-FIXES: (double)func1(0, nullptr, nullptr);
+ (double)func1(func0(0, 0), 0, 0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use nullptr
+ // CHECK-MESSAGES: :[[@LINE-2]]:26: warning: use nullptr
+ // CHECK-MESSAGES: :[[@LINE-3]]:30: warning: use nullptr
+ // CHECK-MESSAGES: :[[@LINE-4]]:33: warning: use nullptr
+ // CHECK-FIXES: (double)func1(func0(nullptr, nullptr), nullptr, nullptr);
+}
+
+// FIXME: currently, the check doesn't work as it should with templates.
+template<typename T>
+class A {
+ public:
+ A(T *p = NULL) {}
+
+ void f() {
+ Ptr = NULL;
+ }
+ T *Ptr;
+};
+
+template<typename T>
+T *f2(T *a = NULL) {
+ return a ? a : NULL;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nullptr.c b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nullptr.c
new file mode 100644
index 0000000..c2ccbbd
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nullptr.c
@@ -0,0 +1,10 @@
+// RUN: clang-tidy %s -checks=-*,modernize-use-nullptr -- | count 0
+
+// Note: this test expects no diagnostics, but FileCheck cannot handle that,
+// hence the use of | count 0.
+
+#define NULL 0
+void f(void) {
+ char *str = NULL; // ok
+ (void)str;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nullptr.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nullptr.cpp
new file mode 100644
index 0000000..878c114
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-nullptr.cpp
@@ -0,0 +1,305 @@
+// RUN: %check_clang_tidy %s modernize-use-nullptr %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-nullptr.NullMacros, value: 'MY_NULL,NULL'}]}" \
+// RUN: -- -std=c++11
+
+#define NULL 0
+
+namespace std {
+
+typedef decltype(nullptr) nullptr_t;
+
+} // namespace std
+
+// Just to make sure make_null() could have side effects.
+void external();
+
+std::nullptr_t make_null() {
+ external();
+ return nullptr;
+}
+
+void func() {
+ void *CallTest = make_null();
+
+ int var = 1;
+ void *CommaTest = (var+=2, make_null());
+
+ int *CastTest = static_cast<int*>(make_null());
+}
+
+void dummy(int*) {}
+void side_effect() {}
+
+#define MACRO_EXPANSION_HAS_NULL \
+ void foo() { \
+ dummy(0); \
+ dummy(NULL); \
+ side_effect(); \
+ }
+
+MACRO_EXPANSION_HAS_NULL;
+#undef MACRO_EXPANSION_HAS_NULL
+
+
+void test_macro_expansion1() {
+#define MACRO_EXPANSION_HAS_NULL \
+ dummy(NULL); \
+ side_effect();
+
+ MACRO_EXPANSION_HAS_NULL;
+
+#undef MACRO_EXPANSION_HAS_NULL
+}
+
+// Test macro expansion with cast sequence, PR15572.
+void test_macro_expansion2() {
+#define MACRO_EXPANSION_HAS_NULL \
+ dummy((int*)0); \
+ side_effect();
+
+ MACRO_EXPANSION_HAS_NULL;
+
+#undef MACRO_EXPANSION_HAS_NULL
+}
+
+void test_macro_expansion3() {
+#define MACRO_EXPANSION_HAS_NULL \
+ dummy(NULL); \
+ side_effect();
+
+#define OUTER_MACRO \
+ MACRO_EXPANSION_HAS_NULL; \
+ side_effect();
+
+ OUTER_MACRO;
+
+#undef OUTER_MACRO
+#undef MACRO_EXPANSION_HAS_NULL
+}
+
+void test_macro_expansion4() {
+#define MY_NULL NULL
+ int *p = MY_NULL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr [modernize-use-nullptr]
+ // CHECK-FIXES: int *p = nullptr;
+#undef MY_NULL
+}
+
+#define IS_EQ(x, y) if (x != y) return;
+void test_macro_args() {
+ int i = 0;
+ int *Ptr;
+
+ IS_EQ(static_cast<int*>(0), Ptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use nullptr
+ // CHECK-FIXES: IS_EQ(static_cast<int*>(nullptr), Ptr);
+
+ IS_EQ(0, Ptr); // literal
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
+ // CHECK-FIXES: IS_EQ(nullptr, Ptr);
+
+ IS_EQ(NULL, Ptr); // macro
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
+ // CHECK-FIXES: IS_EQ(nullptr, Ptr);
+
+ // These are ok since the null literal is not spelled within a macro.
+#define myassert(x) if (!(x)) return;
+ myassert(0 == Ptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr
+ // CHECK-FIXES: myassert(nullptr == Ptr);
+
+ myassert(NULL == Ptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr
+ // CHECK-FIXES: myassert(nullptr == Ptr);
+
+ // These are bad as the null literal is buried in a macro.
+#define BLAH(X) myassert(0 == (X));
+#define BLAH2(X) myassert(NULL == (X));
+ BLAH(Ptr);
+ BLAH2(Ptr);
+
+ // Same as above but testing extra macro expansion.
+#define EXPECT_NULL(X) IS_EQ(0, X);
+#define EXPECT_NULL2(X) IS_EQ(NULL, X);
+ EXPECT_NULL(Ptr);
+ EXPECT_NULL2(Ptr);
+
+ // Almost the same as above but now null literal is not in a macro so ok
+ // to transform.
+#define EQUALS_PTR(X) IS_EQ(X, Ptr);
+ EQUALS_PTR(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use nullptr
+ // CHECK-FIXES: EQUALS_PTR(nullptr);
+ EQUALS_PTR(NULL);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use nullptr
+ // CHECK-FIXES: EQUALS_PTR(nullptr);
+
+ // Same as above but testing extra macro expansion.
+#define EQUALS_PTR_I(X) EQUALS_PTR(X)
+ EQUALS_PTR_I(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr
+ // CHECK-FIXES: EQUALS_PTR_I(nullptr);
+ EQUALS_PTR_I(NULL);
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr
+ // CHECK-FIXES: EQUALS_PTR_I(nullptr);
+
+ // Ok since null literal not within macro. However, now testing macro
+ // used as arg to another macro.
+#define decorate(EXPR) side_effect(); EXPR;
+ decorate(IS_EQ(NULL, Ptr));
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr
+ // CHECK-FIXES: decorate(IS_EQ(nullptr, Ptr));
+ decorate(IS_EQ(0, Ptr));
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr
+ // CHECK-FIXES: decorate(IS_EQ(nullptr, Ptr));
+
+ // This macro causes a NullToPointer cast to happen where 0 is assigned to z
+ // but the 0 literal cannot be replaced because it is also used as an
+ // integer in the comparison.
+#define INT_AND_PTR_USE(X) do { int *z = X; if (X == 4) break; } while(false)
+ INT_AND_PTR_USE(0);
+
+ // Both uses of X in this case result in NullToPointer casts so replacement
+ // is possible.
+#define PTR_AND_PTR_USE(X) do { int *z = X; if (X != z) break; } while(false)
+ PTR_AND_PTR_USE(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr
+ // CHECK-FIXES: PTR_AND_PTR_USE(nullptr);
+ PTR_AND_PTR_USE(NULL);
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr
+ // CHECK-FIXES: PTR_AND_PTR_USE(nullptr);
+
+#define OPTIONAL_CODE(...) __VA_ARGS__
+#define NOT_NULL dummy(0)
+#define CALL(X) X
+ OPTIONAL_CODE(NOT_NULL);
+ CALL(NOT_NULL);
+
+#define ENTRY(X) {X}
+ struct A {
+ int *Ptr;
+ } a[2] = {ENTRY(0), {0}};
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr
+ // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: use nullptr
+ // CHECK-FIXES: a[2] = {ENTRY(nullptr), {nullptr}};
+#undef ENTRY
+
+#define assert1(expr) (expr) ? 0 : 1
+#define assert2 assert1
+ int *p;
+ assert2(p == 0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr
+ // CHECK-FIXES: assert2(p == nullptr);
+ assert2(p == NULL);
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr
+ // CHECK-FIXES: assert2(p == nullptr);
+#undef assert2
+#undef assert1
+
+#define ASSERT_EQ(a, b) a == b
+#define ASSERT_NULL(x) ASSERT_EQ(static_cast<void *>(NULL), x)
+ int *pp;
+ ASSERT_NULL(pp);
+ ASSERT_NULL(NULL);
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use nullptr
+ // CHECK-FIXES: ASSERT_NULL(nullptr);
+#undef ASSERT_NULL
+#undef ASSERT_EQ
+}
+
+// One of the ancestor of the cast is a NestedNameSpecifierLoc.
+class NoDef;
+char function(NoDef *p);
+#define F(x) (sizeof(function(x)) == 1)
+template<class T, T t>
+class C {};
+C<bool, F(0)> c;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use nullptr
+// CHECK-FIXES: C<bool, F(nullptr)> c;
+#undef F
+
+// Test default argument expression.
+struct D {
+ explicit D(void *t, int *c = NULL) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use nullptr
+ // CHECK-FIXES: explicit D(void *t, int *c = nullptr) {}
+};
+
+void test_default_argument() {
+ D(nullptr);
+}
+
+// Test on two neighbour CXXDefaultArgExprs nodes.
+typedef unsigned long long uint64;
+struct ZZ {
+ explicit ZZ(uint64, const uint64* = NULL) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:39: warning: use nullptr
+// CHECK-FIXES: explicit ZZ(uint64, const uint64* = nullptr) {}
+ operator bool() { return true; }
+};
+
+uint64 Hash(uint64 seed = 0) { return 0; }
+
+void f() {
+ bool a;
+ a = ZZ(Hash());
+}
+
+// Test on ignoring substituted template types.
+template<typename T>
+class TemplateClass {
+ public:
+ explicit TemplateClass(int a, T default_value = 0) {}
+
+ void h(T *default_value = 0) {}
+
+ void f(int* p = 0) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr
+// CHECK-FIXES: void f(int* p = nullptr) {}
+};
+
+void IgnoreSubstTemplateType() {
+ TemplateClass<int*> a(1);
+}
+
+// Test on casting nullptr.
+struct G {
+ explicit G(bool, const char * = NULL) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use nullptr
+ // CHECK-FIXES: explicit G(bool, const char * = nullptr) {}
+};
+bool g(const char*);
+void test_cast_nullptr() {
+ G(g(nullptr));
+ G(g((nullptr)));
+ G(g(static_cast<char*>(nullptr)));
+ G(g(static_cast<const char*>(nullptr)));
+}
+
+// Test on recognizing multiple NULLs.
+class H {
+public:
+ H(bool);
+};
+
+#define T(expression) H(expression);
+bool h(int *, int *, int * = nullptr);
+void test_multiple_nulls() {
+ T(h(NULL, NULL));
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use nullptr
+// CHECK-MESSAGES: :[[@LINE-2]]:13: warning: use nullptr
+// CHECK-FIXES: T(h(nullptr, nullptr));
+ T(h(NULL, nullptr));
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use nullptr
+// CHECK-FIXES: T(h(nullptr, nullptr));
+ T(h(nullptr, NULL));
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr
+// CHECK-FIXES: T(h(nullptr, nullptr));
+ T(h(nullptr, nullptr));
+ T(h(NULL, NULL, NULL));
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use nullptr
+// CHECK-MESSAGES: :[[@LINE-2]]:13: warning: use nullptr
+// CHECK-MESSAGES: :[[@LINE-3]]:19: warning: use nullptr
+// CHECK-FIXES: T(h(nullptr, nullptr, nullptr));
+}
+#undef T
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-override-cxx98.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-override-cxx98.cpp
new file mode 100644
index 0000000..bc162d6
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-override-cxx98.cpp
@@ -0,0 +1,19 @@
+// RUN: %check_clang_tidy %s modernize-use-override %t -- -- -std=c++98
+
+struct Base {
+ virtual ~Base() {}
+ virtual void a();
+ virtual void b();
+};
+
+struct SimpleCases : public Base {
+public:
+ virtual ~SimpleCases();
+ // CHECK-FIXES: {{^}} virtual ~SimpleCases();
+
+ void a();
+ // CHECK-FIXES: {{^}} void a();
+
+ virtual void b();
+ // CHECK-FIXES: {{^}} virtual void b();
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-override-ms.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-override-ms.cpp
new file mode 100644
index 0000000..0cee917
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-override-ms.cpp
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s modernize-use-override %t -- -- -fms-extensions -std=c++11
+
+// This test is designed to test ms-extension __declspec(dllexport) attributes.
+#define EXPORT __declspec(dllexport)
+
+class Base {
+ virtual EXPORT void a();
+};
+
+class EXPORT InheritedBase {
+ virtual void a();
+};
+
+class Derived : public Base {
+ virtual EXPORT void a();
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual' [modernize-use-override]
+ // CHECK-FIXES: {{^}} EXPORT void a() override;
+};
+
+class EXPORT InheritedDerived : public InheritedBase {
+ virtual void a();
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual' [modernize-use-override]
+ // CHECK-FIXES: {{^}} void a() override;
+};
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-override.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-override.cpp
new file mode 100644
index 0000000..24aafe5
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-override.cpp
@@ -0,0 +1,318 @@
+// RUN: %check_clang_tidy %s modernize-use-override %t -- -- -std=c++11 -fexceptions
+
+#define ABSTRACT = 0
+
+#define OVERRIDE override
+#define VIRTUAL virtual
+#define NOT_VIRTUAL
+#define NOT_OVERRIDE
+
+#define MUST_USE_RESULT __attribute__((warn_unused_result))
+#define UNUSED __attribute__((unused))
+
+struct MUST_USE_RESULT MustUseResultObject {};
+
+struct IntPair {
+ int First, Second;
+};
+
+struct Base {
+ virtual ~Base() {}
+ virtual void a();
+ virtual void b();
+ virtual void c();
+ virtual void d();
+ virtual void d2();
+ virtual void e() = 0;
+ virtual void f() = 0;
+ virtual void f2() const = 0;
+ virtual void g() = 0;
+
+ virtual void j() const;
+ virtual MustUseResultObject k();
+ virtual bool l() MUST_USE_RESULT UNUSED;
+ virtual bool n() MUST_USE_RESULT UNUSED;
+
+ virtual void m();
+ virtual void m2();
+ virtual void o() __attribute__((unused));
+
+ virtual void r() &;
+ virtual void rr() &&;
+
+ virtual void cv() const volatile;
+ virtual void cv2() const volatile;
+
+ virtual void ne() noexcept(false);
+ virtual void t() throw();
+
+ virtual void il(IntPair);
+};
+
+struct SimpleCases : public Base {
+public:
+ virtual ~SimpleCases();
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual' [modernize-use-override]
+ // CHECK-FIXES: {{^}} ~SimpleCases() override;
+
+ void a();
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this
+ // CHECK-FIXES: {{^}} void a() override;
+
+ void b() override;
+ // CHECK-MESSAGES-NOT: warning:
+ // CHECK-FIXES: {{^}} void b() override;
+
+ virtual void c();
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} void c() override;
+
+ virtual void d() override;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant since the function is already declared 'override'
+ // CHECK-FIXES: {{^}} void d() override;
+
+ virtual void d2() final;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant since the function is already declared 'final'
+ // CHECK-FIXES: {{^}} void d2() final;
+
+ virtual void e() = 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} void e() override = 0;
+
+ virtual void f()=0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} void f() override =0;
+
+ virtual void f2() const=0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} void f2() const override =0;
+
+ virtual void g() ABSTRACT;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} void g() override ABSTRACT;
+
+ virtual void j() const;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} void j() const override;
+
+ virtual MustUseResultObject k(); // Has an implicit attribute.
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer using
+ // CHECK-FIXES: {{^}} MustUseResultObject k() override;
+
+ virtual bool l() MUST_USE_RESULT UNUSED;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} bool l() override MUST_USE_RESULT UNUSED;
+
+ virtual bool n() UNUSED MUST_USE_RESULT;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} bool n() override UNUSED MUST_USE_RESULT;
+
+ void m() override final;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'override' is redundant since the function is already declared 'final'
+ // CHECK-FIXES: {{^}} void m() final;
+
+ virtual void m2() override final;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' and 'override' are redundant since the function is already declared 'final'
+ // CHECK-FIXES: {{^}} void m2() final;
+
+ virtual void o() __attribute__((unused));
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} void o() override __attribute__((unused));
+
+ virtual void ne() noexcept(false);
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} void ne() noexcept(false) override;
+
+ virtual void t() throw();
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} void t() throw() override;
+};
+
+// CHECK-MESSAGES-NOT: warning:
+
+void SimpleCases::c() {}
+// CHECK-FIXES: {{^}}void SimpleCases::c() {}
+
+SimpleCases::~SimpleCases() {}
+// CHECK-FIXES: {{^}}SimpleCases::~SimpleCases() {}
+
+struct DefaultedDestructor : public Base {
+ DefaultedDestructor() {}
+ virtual ~DefaultedDestructor() = default;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using
+ // CHECK-FIXES: {{^}} ~DefaultedDestructor() override = default;
+};
+
+struct FinalSpecified : public Base {
+public:
+ virtual ~FinalSpecified() final;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: 'virtual' is redundant since the function is already declared 'final'
+ // CHECK-FIXES: {{^}} ~FinalSpecified() final;
+
+ void b() final;
+ // CHECK-MESSAGES-NOT: warning:
+ // CHECK-FIXES: {{^}} void b() final;
+
+ virtual void d() final;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant
+ // CHECK-FIXES: {{^}} void d() final;
+
+ virtual void e() final = 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant
+ // CHECK-FIXES: {{^}} void e() final = 0;
+
+ virtual void j() const final;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant
+ // CHECK-FIXES: {{^}} void j() const final;
+
+ virtual bool l() final MUST_USE_RESULT UNUSED;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant
+ // CHECK-FIXES: {{^}} bool l() final MUST_USE_RESULT UNUSED;
+};
+
+struct InlineDefinitions : public Base {
+public:
+ virtual ~InlineDefinitions() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using
+ // CHECK-FIXES: {{^}} ~InlineDefinitions() override {}
+
+ void a() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this
+ // CHECK-FIXES: {{^}} void a() override {}
+
+ void b() override {}
+ // CHECK-MESSAGES-NOT: warning:
+ // CHECK-FIXES: {{^}} void b() override {}
+
+ virtual void c()
+ {}
+ // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} void c() override
+
+ virtual void d() override {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant
+ // CHECK-FIXES: {{^}} void d() override {}
+
+ virtual void j() const
+ {}
+ // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} void j() const override
+
+ virtual MustUseResultObject k() {} // Has an implicit attribute.
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer using
+ // CHECK-FIXES: {{^}} MustUseResultObject k() override {}
+
+ virtual bool l() MUST_USE_RESULT UNUSED {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} bool l() override MUST_USE_RESULT UNUSED {}
+
+ virtual void r() &
+ {}
+ // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} void r() & override
+
+ virtual void rr() &&
+ {}
+ // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} void rr() && override
+
+ virtual void cv() const volatile
+ {}
+ // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} void cv() const volatile override
+
+ virtual void cv2() const volatile // some comment
+ {}
+ // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} void cv2() const volatile override // some comment
+};
+
+struct DefaultArguments : public Base {
+ // Tests for default arguments (with initializer lists).
+ // Make sure the override fix is placed after the argument list.
+ void il(IntPair p = {1, (2 + (3))}) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this
+ // CHECK-FIXES: {{^}} void il(IntPair p = {1, (2 + (3))}) override {}
+};
+
+struct Macros : public Base {
+ // Tests for 'virtual' and 'override' being defined through macros. Basically
+ // give up for now.
+ NOT_VIRTUAL void a() NOT_OVERRIDE;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: annotate this
+ // CHECK-FIXES: {{^}} NOT_VIRTUAL void a() override NOT_OVERRIDE;
+
+ VIRTUAL void b() NOT_OVERRIDE;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} VIRTUAL void b() override NOT_OVERRIDE;
+
+ NOT_VIRTUAL void c() OVERRIDE;
+ // CHECK-MESSAGES-NOT: warning:
+ // CHECK-FIXES: {{^}} NOT_VIRTUAL void c() OVERRIDE;
+
+ VIRTUAL void d() OVERRIDE;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant
+ // CHECK-FIXES: {{^}} VIRTUAL void d() OVERRIDE;
+
+#define FUNC(return_type, name) return_type name()
+ FUNC(void, e);
+ // CHECK-FIXES: {{^}} FUNC(void, e);
+
+#define F virtual void f();
+ F
+ // CHECK-FIXES: {{^}} F
+
+ VIRTUAL void g() OVERRIDE final;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' and 'override' are redundant
+ // CHECK-FIXES: {{^}} VIRTUAL void g() final;
+};
+
+// Tests for templates.
+template <typename T> struct TemplateBase {
+ virtual void f(T t);
+};
+
+template <typename T> struct DerivedFromTemplate : public TemplateBase<T> {
+ virtual void f(T t);
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} void f(T t) override;
+};
+void f() { DerivedFromTemplate<int>().f(2); }
+
+template <class C>
+struct UnusedMemberInstantiation : public C {
+ virtual ~UnusedMemberInstantiation() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using
+ // CHECK-FIXES: {{^}} ~UnusedMemberInstantiation() override {}
+};
+struct IntantiateWithoutUse : public UnusedMemberInstantiation<Base> {};
+
+struct Base2 {
+ virtual ~Base2() {}
+ virtual void a();
+};
+
+// The OverrideAttr isn't propagated to specializations in all cases. Make sure
+// we don't add "override" a second time.
+template <int I>
+struct MembersOfSpecializations : public Base2 {
+ void a() override;
+ // CHECK-MESSAGES-NOT: warning:
+ // CHECK-FIXES: {{^}} void a() override;
+};
+template <> void MembersOfSpecializations<3>::a() {}
+void ff() { MembersOfSpecializations<3>().a(); };
+
+// In case try statement is used as a method body,
+// make sure that override fix is placed before try keyword.
+struct TryStmtAsBody : public Base {
+ void a() try
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this
+ // CHECK-FIXES: {{^}} void a() override try
+ { b(); } catch(...) { c(); }
+
+ virtual void d() try
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} void d() override try
+ { e(); } catch(...) { f(); }
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-transparent-functors.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-transparent-functors.cpp
new file mode 100644
index 0000000..3efa916
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-transparent-functors.cpp
@@ -0,0 +1,110 @@
+// RUN: %check_clang_tidy %s modernize-use-transparent-functors %t -- -- -std=c++14
+
+namespace std {
+template<class T>
+struct remove_reference;
+
+template <class T>
+constexpr T &&forward(typename std::remove_reference<T>::type &t);
+
+template <class T>
+constexpr T &&forward(typename std::remove_reference<T>::type &&t);
+
+template <typename T = void>
+struct plus {
+ constexpr T operator()(const T &Lhs, const T &Rhs) const;
+};
+
+template <>
+struct plus<void> {
+ template <typename T, typename U>
+ constexpr auto operator()(T &&Lhs, U &&Rhs) const ->
+ decltype(forward<T>(Lhs) + forward<U>(Rhs));
+};
+
+template <typename T = void>
+struct less {
+ constexpr bool operator()(const T &Lhs, const T &Rhs) const;
+};
+
+template <>
+struct less<void> {
+ template <typename T, typename U>
+ constexpr bool operator()(T &&Lhs, U &&Rhs) const;
+};
+
+template <typename T = void>
+struct logical_not {
+ constexpr bool operator()(const T &Arg) const;
+};
+
+template <>
+struct logical_not<void> {
+ template <typename T>
+ constexpr bool operator()(T &&Arg) const;
+};
+
+template <typename T>
+class allocator;
+
+template <
+ class Key,
+ class Compare = std::less<>,
+ class Allocator = std::allocator<Key>>
+class set {};
+
+template <
+ class Key,
+ class Compare = std::less<Key>,
+ class Allocator = std::allocator<Key>>
+class set2 {};
+
+template <class InputIt, class UnaryPredicate>
+InputIt find_if(InputIt first, InputIt last,
+ UnaryPredicate p);
+
+template <class RandomIt, class Compare>
+void sort(RandomIt first, RandomIt last, Compare comp);
+
+class iterator {};
+class string {};
+}
+
+int main() {
+ using std::set;
+ using std::less;
+ std::set<int, std::less<int>> s;
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: prefer transparent functors 'less<>' [modernize-use-transparent-functors]
+ // CHECK-FIXES: {{^}} std::set<int, std::less<>> s;{{$}}
+ set<int, std::less<int>> s2;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: prefer transparent functors
+ // CHECK-FIXES: {{^}} set<int, std::less<>> s2;{{$}}
+ set<int, less<int>> s3;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: prefer transparent functors
+ // CHECK-FIXES: {{^}} set<int, less<>> s3;{{$}}
+ std::set<int, std::less<>> s4;
+ std::set<char *, std::less<std::string>> s5;
+ std::set<set<int, less<int>>, std::less<>> s6;
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: prefer transparent functors
+ // CHECK-FIXES: {{^}} std::set<set<int, less<>>, std::less<>> s6;{{$}}
+ std::iterator begin, end;
+ sort(begin, end, std::less<int>());
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: prefer transparent functors
+ std::sort(begin, end, std::less<>());
+ find_if(begin, end, std::logical_not<bool>());
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: prefer transparent functors
+ std::find_if(begin, end, std::logical_not<>());
+ using my_set = std::set<int, std::less<int>>;
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer transparent functors
+ // CHECK-FIXES: {{^}} using my_set = std::set<int, std::less<>>;{{$}}
+ using my_set2 = std::set<char*, std::less<std::string>>;
+ using my_less = std::less<std::string>;
+ find_if(begin, end, my_less());
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: prefer transparent functors
+ std::set2<int> control;
+}
+
+struct ImplicitTypeLoc : std::set2<std::less<int>> {
+ // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: prefer transparent functors
+ ImplicitTypeLoc() {}
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-uncaught-exceptions.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-uncaught-exceptions.cpp
new file mode 100644
index 0000000..e6bae2b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-uncaught-exceptions.cpp
@@ -0,0 +1,79 @@
+// RUN: %check_clang_tidy %s modernize-use-uncaught-exceptions %t -- -- -std=c++1z
+#define MACRO std::uncaught_exception
+// CHECK-FIXES: #define MACRO std::uncaught_exception
+
+bool uncaught_exception() {
+ return 0;
+}
+
+namespace std {
+ bool uncaught_exception() {
+ return false;
+ }
+
+ int uncaught_exceptions() {
+ return 0;
+ }
+}
+
+template <typename T>
+bool doSomething(T t) {
+ return t();
+ // CHECK-FIXES: return t();
+}
+
+template <bool (*T)()>
+bool doSomething2() {
+ return T();
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: 'std::uncaught_exception' is deprecated, use 'std::uncaught_exceptions' instead
+ // CHECK-FIXES: return T();
+}
+
+void no_warn() {
+
+ uncaught_exception();
+ // CHECK-FIXES: uncaught_exception();
+
+ doSomething(uncaught_exception);
+ // CHECK-FIXES: doSomething(uncaught_exception);
+}
+
+void warn() {
+
+ std::uncaught_exception();
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'std::uncaught_exception' is deprecated, use 'std::uncaught_exceptions' instead
+ // CHECK-FIXES: std::uncaught_exceptions();
+
+ using std::uncaught_exception;
+ // CHECK-MESSAGES: [[@LINE-1]]:14: warning: 'std::uncaught_exception' is deprecated, use 'std::uncaught_exceptions' instead
+ // CHECK-FIXES: using std::uncaught_exceptions;
+
+ uncaught_exception();
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'std::uncaught_exception' is deprecated, use 'std::uncaught_exceptions' instead
+ // CHECK-FIXES: uncaught_exceptions();
+
+ bool b{uncaught_exception()};
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: 'std::uncaught_exception' is deprecated, use 'std::uncaught_exceptions' instead
+ // CHECK-FIXES: bool b{std::uncaught_exceptions() > 0};
+
+ MACRO();
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'std::uncaught_exception' is deprecated, use 'std::uncaught_exceptions' instead
+ // CHECK-FIXES: MACRO();
+
+ doSomething(std::uncaught_exception);
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: 'std::uncaught_exception' is deprecated, use 'std::uncaught_exceptions' instead
+ // CHECK-FIXES: doSomething(std::uncaught_exception);
+
+ doSomething(uncaught_exception);
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: 'std::uncaught_exception' is deprecated, use 'std::uncaught_exceptions' instead
+ // CHECK-FIXES: doSomething(uncaught_exception);
+
+ bool (*foo)();
+ foo = &uncaught_exception;
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: 'std::uncaught_exception' is deprecated, use 'std::uncaught_exceptions' instead
+ // CHECK-FIXES: foo = &uncaught_exception;
+
+ doSomething2<uncaught_exception>();
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: 'std::uncaught_exception' is deprecated, use 'std::uncaught_exceptions' instead
+ // CHECK-FIXES: doSomething2<uncaught_exception>();
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-using-macros.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-using-macros.cpp
new file mode 100644
index 0000000..5d88d1d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-using-macros.cpp
@@ -0,0 +1,23 @@
+// RUN: %check_clang_tidy %s modernize-use-using %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-using.IgnoreMacros, value: 0}]}" \
+// RUN: -- -std=c++11
+
+#define CODE typedef int INT
+
+CODE;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: #define CODE typedef int INT
+// CHECK-FIXES: CODE;
+
+struct Foo;
+#define Bar Baz
+typedef Foo Bar;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: #define Bar Baz
+// CHECK-FIXES: using Baz = Foo;
+
+#define TYPEDEF typedef
+TYPEDEF Foo Bak;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: #define TYPEDEF typedef
+// CHECK-FIXES: TYPEDEF Foo Bak;
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-using.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-using.cpp
new file mode 100644
index 0000000..efa4030
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/modernize-use-using.cpp
@@ -0,0 +1,185 @@
+// RUN: %check_clang_tidy %s modernize-use-using %t
+
+typedef int Type;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using]
+// CHECK-FIXES: using Type = int;
+
+typedef long LL;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using LL = long;
+
+typedef int Bla;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using Bla = int;
+
+typedef Bla Bla2;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using Bla2 = Bla;
+
+typedef void (*type)(int, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using type = void (*)(int, int);
+
+typedef void (*type2)();
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using type2 = void (*)();
+
+class Class {
+ typedef long long Type;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef'
+ // CHECK-FIXES: using Type = long long;
+};
+
+typedef void (Class::*MyPtrType)(Bla) const;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using MyPtrType = void (Class::*)(Bla)[[ATTR:( __attribute__\(\(thiscall\)\))?]] const;
+
+class Iterable {
+public:
+ class Iterator {};
+};
+
+template <typename T>
+class Test {
+ typedef typename T::iterator Iter;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef'
+ // CHECK-FIXES: using Iter = typename T::iterator;
+};
+
+using balba = long long;
+
+union A {};
+
+typedef void (A::*PtrType)(int, int) const;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using PtrType = void (A::*)(int, int)[[ATTR]] const;
+
+typedef Class some_class;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using some_class = Class;
+
+typedef Class Cclass;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using Cclass = Class;
+
+typedef Cclass cclass2;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using cclass2 = Cclass;
+
+class cclass {};
+
+typedef void (cclass::*MyPtrType3)(Bla);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using MyPtrType3 = void (cclass::*)(Bla)[[ATTR]];
+
+using my_class = int;
+
+typedef Test<my_class *> another;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using another = Test<my_class *>;
+
+typedef int* PInt;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using PInt = int *;
+
+typedef int bla1, bla2, bla3;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: typedef int bla1, bla2, bla3;
+
+#define CODE typedef int INT
+
+CODE;
+// CHECK-FIXES: #define CODE typedef int INT
+// CHECK-FIXES: CODE;
+
+struct Foo;
+#define Bar Baz
+typedef Foo Bar;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: #define Bar Baz
+// CHECK-FIXES: using Baz = Foo;
+
+#define TYPEDEF typedef
+TYPEDEF Foo Bak;
+// CHECK-FIXES: #define TYPEDEF typedef
+// CHECK-FIXES: TYPEDEF Foo Bak;
+
+#define FOO Foo
+typedef FOO Bam;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: #define FOO Foo
+// CHECK-FIXES: using Bam = Foo;
+
+typedef struct Foo Bap;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using Bap = struct Foo;
+
+struct Foo typedef Bap2;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using Bap2 = struct Foo;
+
+Foo typedef Bap3;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using Bap3 = Foo;
+
+typedef struct Unknown Baq;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using Baq = struct Unknown;
+
+struct Unknown2 typedef Baw;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using Baw = struct Unknown2;
+
+int typedef Bax;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using Bax = int;
+
+typedef struct Q1 { int a; } S1;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: typedef struct Q1 { int a; } S1;
+typedef struct { int b; } S2;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: typedef struct { int b; } S2;
+struct Q2 { int c; } typedef S3;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: struct Q2 { int c; } typedef S3;
+struct { int d; } typedef S4;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: struct { int d; } typedef S4;
+
+namespace my_space {
+ class my_cclass {};
+ typedef my_cclass FuncType;
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using FuncType = my_cclass;
+}
+
+#define lol 4
+typedef unsigned Map[lol];
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: typedef unsigned Map[lol];
+
+typedef void (*fun_type)();
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
+// CHECK-FIXES: using fun_type = void (*)();
+
+namespace template_instantiations {
+template <typename T>
+class C {
+ protected:
+ typedef C<T> super;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef'
+ // CHECK-FIXES: using super = C<T>;
+ virtual void f();
+
+public:
+ virtual ~C();
+};
+
+class D : public C<D> {
+ void f() override { super::f(); }
+};
+class E : public C<E> {
+ void f() override { super::f(); }
+};
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/mpi-buffer-deref.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/mpi-buffer-deref.cpp
new file mode 100644
index 0000000..47d58a5
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/mpi-buffer-deref.cpp
@@ -0,0 +1,51 @@
+// REQUIRES: static-analyzer
+// RUN: %check_clang_tidy %s mpi-buffer-deref %t -- -- -I %S/Inputs/mpi-type-mismatch
+
+#include "mpimock.h"
+
+void negativeTests() {
+ char *buf;
+ MPI_Send(&buf, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer is insufficiently dereferenced: pointer->pointer [mpi-buffer-deref]
+
+ unsigned **buf2;
+ MPI_Send(buf2, 1, MPI_UNSIGNED, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer is insufficiently dereferenced: pointer->pointer
+
+ short buf3[1][1];
+ MPI_Send(buf3, 1, MPI_SHORT, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer is insufficiently dereferenced: array->array
+
+ long double _Complex *buf4[1];
+ MPI_Send(buf4, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer is insufficiently dereferenced: pointer->array
+
+ std::complex<float> *buf5[1][1];
+ MPI_Send(&buf5, 1, MPI_CXX_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer is insufficiently dereferenced: pointer->array->array->pointer
+}
+
+void positiveTests() {
+ char buf;
+ MPI_Send(&buf, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+
+ unsigned *buf2;
+ MPI_Send(buf2, 1, MPI_UNSIGNED, 0, 0, MPI_COMM_WORLD);
+
+ short buf3[1][1];
+ MPI_Send(buf3[0], 1, MPI_SHORT, 0, 0, MPI_COMM_WORLD);
+
+ long double _Complex *buf4[1];
+ MPI_Send(*buf4, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+
+ long double _Complex buf5[1];
+ MPI_Send(buf5, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+
+ std::complex<float> *buf6[1][1];
+ MPI_Send(*buf6[0], 1, MPI_CXX_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD);
+
+ // Referencing an array with '&' is valid, as this also points to the
+ // beginning of the array.
+ long double _Complex buf7[1];
+ MPI_Send(&buf7, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/mpi-type-mismatch.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/mpi-type-mismatch.cpp
new file mode 100644
index 0000000..bf978dc
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/mpi-type-mismatch.cpp
@@ -0,0 +1,256 @@
+// REQUIRES: static-analyzer
+// RUN: %check_clang_tidy %s mpi-type-mismatch %t -- -- -I %S/Inputs/mpi-type-mismatch
+
+#include "mpimock.h"
+
+void charNegativeTest() {
+ int buf;
+ MPI_Send(&buf, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'int' does not match the MPI datatype 'MPI_CHAR'
+
+ short buf2;
+ MPI_Send(&buf2, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'short' does not match the MPI datatype 'MPI_CHAR'
+
+ long buf3;
+ MPI_Send(&buf3, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'long' does not match the MPI datatype 'MPI_CHAR'
+
+ int8_t buf4;
+ MPI_Send(&buf4, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'int8_t' does not match the MPI datatype 'MPI_CHAR'
+
+ uint16_t buf5;
+ MPI_Send(&buf5, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'uint16_t' does not match the MPI datatype 'MPI_CHAR'
+
+ long double _Complex buf6;
+ MPI_Send(&buf6, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'long double _Complex' does not match the MPI datatype 'MPI_CHAR'
+
+ std::complex<float> buf7;
+ MPI_Send(&buf7, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'complex<float>' does not match the MPI datatype 'MPI_CHAR'
+}
+
+void intNegativeTest() {
+ unsigned char buf;
+ MPI_Send(&buf, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'unsigned char' does not match the MPI datatype 'MPI_INT'
+
+ unsigned buf2;
+ MPI_Send(&buf2, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'unsigned int' does not match the MPI datatype 'MPI_INT'
+
+ short buf3;
+ MPI_Send(&buf3, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'short' does not match the MPI datatype 'MPI_INT'
+
+ long buf4;
+ MPI_Send(&buf4, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'long' does not match the MPI datatype 'MPI_INT'
+
+ int8_t buf5;
+ MPI_Send(&buf5, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'int8_t' does not match the MPI datatype 'MPI_INT'
+
+ uint16_t buf6;
+ MPI_Send(&buf6, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'uint16_t' does not match the MPI datatype 'MPI_INT'
+
+ long double _Complex buf7;
+ MPI_Send(&buf7, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'long double _Complex' does not match the MPI datatype 'MPI_INT'
+
+ std::complex<float> buf8;
+ MPI_Send(&buf8, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'complex<float>' does not match the MPI datatype 'MPI_INT'
+}
+
+void longNegativeTest() {
+ char buf;
+ MPI_Send(&buf, 1, MPI_LONG, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'char' does not match the MPI datatype 'MPI_LONG'
+
+ unsigned buf2;
+ MPI_Send(&buf2, 1, MPI_LONG, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'unsigned int' does not match the MPI datatype 'MPI_LONG'
+
+ unsigned short buf3;
+ MPI_Send(&buf3, 1, MPI_LONG, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'unsigned short' does not match the MPI datatype 'MPI_LONG'
+
+ unsigned long buf4;
+ MPI_Send(&buf4, 1, MPI_LONG, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'unsigned long' does not match the MPI datatype 'MPI_LONG'
+
+ int8_t buf5;
+ MPI_Send(&buf5, 1, MPI_LONG, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'int8_t' does not match the MPI datatype 'MPI_LONG'
+
+ uint16_t buf6;
+ MPI_Send(&buf6, 1, MPI_LONG, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'uint16_t' does not match the MPI datatype 'MPI_LONG'
+
+ long double _Complex buf7;
+ MPI_Send(&buf7, 1, MPI_LONG, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'long double _Complex' does not match the MPI datatype 'MPI_LONG'
+
+ std::complex<float> buf8;
+ MPI_Send(&buf8, 1, MPI_LONG, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'complex<float>' does not match the MPI datatype 'MPI_LONG'
+}
+
+void int8_tNegativeTest() {
+ char buf;
+ MPI_Send(&buf, 1, MPI_INT8_T, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'char' does not match the MPI datatype 'MPI_INT8_T'
+
+ unsigned buf2;
+ MPI_Send(&buf2, 1, MPI_INT8_T, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'unsigned int' does not match the MPI datatype 'MPI_INT8_T'
+
+ short buf3;
+ MPI_Send(&buf3, 1, MPI_INT8_T, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'short' does not match the MPI datatype 'MPI_INT8_T'
+
+ unsigned long buf4;
+ MPI_Send(&buf4, 1, MPI_INT8_T, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'unsigned long' does not match the MPI datatype 'MPI_INT8_T'
+
+ uint8_t buf5;
+ MPI_Send(&buf5, 1, MPI_INT8_T, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'uint8_t' does not match the MPI datatype 'MPI_INT8_T'
+
+ uint16_t buf6;
+ MPI_Send(&buf6, 1, MPI_INT8_T, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'uint16_t' does not match the MPI datatype 'MPI_INT8_T'
+
+ long double _Complex buf7;
+ MPI_Send(&buf7, 1, MPI_INT8_T, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'long double _Complex' does not match the MPI datatype 'MPI_INT8_T'
+
+ std::complex<float> buf8;
+ MPI_Send(&buf8, 1, MPI_INT8_T, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'complex<float>' does not match the MPI datatype 'MPI_INT8_T'
+}
+
+void complex_c_long_double_complexNegativeTest() {
+ char buf;
+ MPI_Send(&buf, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'char' does not match the MPI datatype 'MPI_C_LONG_DOUBLE_COMPLEX'
+
+ unsigned buf2;
+ MPI_Send(&buf2, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'unsigned int' does not match the MPI datatype 'MPI_C_LONG_DOUBLE_COMPLEX'
+
+ short buf3;
+ MPI_Send(&buf3, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'short' does not match the MPI datatype 'MPI_C_LONG_DOUBLE_COMPLEX'
+
+ unsigned long buf4;
+ MPI_Send(&buf4, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'unsigned long' does not match the MPI datatype 'MPI_C_LONG_DOUBLE_COMPLEX'
+
+ uint8_t buf5;
+ MPI_Send(&buf5, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'uint8_t' does not match the MPI datatype 'MPI_C_LONG_DOUBLE_COMPLEX'
+
+ uint16_t buf6;
+ MPI_Send(&buf6, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'uint16_t' does not match the MPI datatype 'MPI_C_LONG_DOUBLE_COMPLEX'
+
+ double _Complex buf7;
+ MPI_Send(&buf7, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'double _Complex' does not match the MPI datatype 'MPI_C_LONG_DOUBLE_COMPLEX'
+
+ std::complex<float> buf8;
+ MPI_Send(&buf8, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'complex<float>' does not match the MPI datatype 'MPI_C_LONG_DOUBLE_COMPLEX'
+}
+
+void complex_cxx_float_complexNegativeTest() {
+ char buf;
+ MPI_Send(&buf, 1, MPI_CXX_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'char' does not match the MPI datatype 'MPI_CXX_FLOAT_COMPLEX'
+
+ unsigned buf2;
+ MPI_Send(&buf2, 1, MPI_CXX_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'unsigned int' does not match the MPI datatype 'MPI_CXX_FLOAT_COMPLEX'
+
+ short buf3;
+ MPI_Send(&buf3, 1, MPI_CXX_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'short' does not match the MPI datatype 'MPI_CXX_FLOAT_COMPLEX'
+
+ unsigned long buf4;
+ MPI_Send(&buf4, 1, MPI_CXX_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'unsigned long' does not match the MPI datatype 'MPI_CXX_FLOAT_COMPLEX'
+
+ uint8_t buf5;
+ MPI_Send(&buf5, 1, MPI_CXX_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'uint8_t' does not match the MPI datatype 'MPI_CXX_FLOAT_COMPLEX'
+
+ uint16_t buf6;
+ MPI_Send(&buf6, 1, MPI_CXX_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'uint16_t' does not match the MPI datatype 'MPI_CXX_FLOAT_COMPLEX'
+
+ double _Complex buf7;
+ MPI_Send(&buf7, 1, MPI_CXX_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'double _Complex' does not match the MPI datatype 'MPI_CXX_FLOAT_COMPLEX'
+
+ std::complex<double> buf8;
+ MPI_Send(&buf8, 1, MPI_CXX_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'complex<double>' does not match the MPI datatype 'MPI_CXX_FLOAT_COMPLEX'
+}
+
+void skippedTypesTests() {
+ // typedefs, user defined MPI and nullptr types are skipped
+ typedef char CHAR;
+ CHAR buf;
+ MPI_Send(&buf, 1, MPI_CXX_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD);
+
+ typedef unsigned UNSIGNED;
+ UNSIGNED buf2;
+ MPI_Send(&buf2, 1, MPI_CXX_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD);
+
+#define _MPI_LONG MPI_LONG
+ int buf3;
+ MPI_Send(&buf3, 1, _MPI_LONG, 0, 0, MPI_COMM_WORLD);
+
+#define _MPI_CXX_FLOAT_COMPLEX MPI_CXX_FLOAT_COMPLEX
+ short buf4;
+ MPI_Send(&buf4, 1, _MPI_CXX_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD);
+
+ MPI_Send(NULL, 1, MPI_LONG, 0, 0, MPI_COMM_WORLD);
+}
+
+void positiveTests() {
+ char buf;
+ MPI_Send(&buf, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+
+ int buf2;
+ MPI_Send(&buf2, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
+
+ long buf3;
+ MPI_Send(&buf3, 1, MPI_LONG, 0, 0, MPI_COMM_WORLD);
+
+ int8_t buf4;
+ MPI_Send(&buf4, 1, MPI_INT8_T, 0, 0, MPI_COMM_WORLD);
+
+ long double _Complex buf5;
+ MPI_Send(&buf5, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+
+ std::complex<float> buf6;
+ MPI_Send(&buf6, 1, MPI_CXX_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD);
+
+ uint8_t buf7;
+ MPI_Send(&buf7, 1, MPI_UINT8_T, 0, 0, MPI_COMM_WORLD);
+
+ uint16_t buf8;
+ MPI_Send(&buf8, 1, MPI_UINT16_T, 0, 0, MPI_COMM_WORLD);
+
+ // On some systems like PPC or ARM, 'char' is unsigned by default which is why
+ // distinct signedness for the buffer and MPI type is tolerated.
+ unsigned char buf9;
+ MPI_Send(&buf9, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/nolint.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/nolint.cpp
new file mode 100644
index 0000000..24c3722
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/nolint.cpp
@@ -0,0 +1,50 @@
+// REQUIRES: static-analyzer
+// RUN: %check_clang_tidy %s google-explicit-constructor,clang-diagnostic-unused-variable,clang-analyzer-core.UndefinedBinaryOperatorResult %t -- -extra-arg=-Wunused-variable -- -I%S/Inputs/nolint
+
+#include "trigger_warning.h"
+void I(int& Out) {
+ int In;
+ A1(In, Out);
+}
+// CHECK-MESSAGES-NOT: trigger_warning.h:{{.*}} warning
+// CHECK-MESSAGES-NOT: :[[@LINE-4]]:{{.*}} note
+
+class A { A(int i); };
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: single-argument constructors must be marked explicit
+
+class B { B(int i); }; // NOLINT
+
+class C { C(int i); }; // NOLINT(for-some-other-check)
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: single-argument constructors must be marked explicit
+
+class C1 { C1(int i); }; // NOLINT(*)
+
+class C2 { C2(int i); }; // NOLINT(not-closed-bracket-is-treated-as-skip-all
+
+class C3 { C3(int i); }; // NOLINT(google-explicit-constructor)
+
+class C4 { C4(int i); }; // NOLINT(some-check, google-explicit-constructor)
+
+class C5 { C5(int i); }; // NOLINT without-brackets-skip-all, another-check
+
+void f() {
+ int i;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: unused variable 'i' [clang-diagnostic-unused-variable]
+ int j; // NOLINT
+}
+
+#define MACRO(X) class X { X(int i); };
+MACRO(D)
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: single-argument constructors must be marked explicit
+MACRO(E) // NOLINT
+
+#define MACRO_NOARG class F { F(int i); };
+MACRO_NOARG // NOLINT
+
+#define MACRO_NOLINT class G { G(int i); }; // NOLINT
+MACRO_NOLINT
+
+#define DOUBLE_MACRO MACRO(H) // NOLINT
+DOUBLE_MACRO
+
+// CHECK-MESSAGES: Suppressed 12 warnings (12 NOLINT)
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/nolintnextline.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/nolintnextline.cpp
new file mode 100644
index 0000000..a97928a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/nolintnextline.cpp
@@ -0,0 +1,49 @@
+class A { A(int i); };
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: single-argument constructors must be marked explicit
+
+// NOLINTNEXTLINE
+class B { B(int i); };
+
+// NOLINTNEXTLINE(for-some-other-check)
+class C { C(int i); };
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: single-argument constructors must be marked explicit
+
+// NOLINTNEXTLINE(*)
+class C1 { C1(int i); };
+
+// NOLINTNEXTLINE(not-closed-bracket-is-treated-as-skip-all
+class C2 { C2(int i); };
+
+// NOLINTNEXTLINE(google-explicit-constructor)
+class C3 { C3(int i); };
+
+// NOLINTNEXTLINE(some-check, google-explicit-constructor)
+class C4 { C4(int i); };
+
+// NOLINTNEXTLINE without-brackets-skip-all, another-check
+class C5 { C5(int i); };
+
+
+// NOLINTNEXTLINE
+
+class D { D(int i); };
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: single-argument constructors must be marked explicit
+
+// NOLINTNEXTLINE
+//
+class E { E(int i); };
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: single-argument constructors must be marked explicit
+
+#define MACRO(X) class X { X(int i); };
+MACRO(F)
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: single-argument constructors must be marked explicit
+// NOLINTNEXTLINE
+MACRO(G)
+
+#define MACRO_NOARG class H { H(int i); };
+// NOLINTNEXTLINE
+MACRO_NOARG
+
+// CHECK-MESSAGES: Suppressed 8 warnings (8 NOLINT)
+
+// RUN: %check_clang_tidy %s google-explicit-constructor %t --
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/nonstandard-file-extension.test b/src/llvm-project/clang-tools-extra/test/clang-tidy/nonstandard-file-extension.test
new file mode 100644
index 0000000..4cb4d11
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/nonstandard-file-extension.test
@@ -0,0 +1,6 @@
+// RUN: %check_clang_tidy -assume-filename=const-cast.cpp %s cppcoreguidelines-pro-type-const-cast %t
+
+const int *i;
+int *j;
+void f() { j = const_cast<int *>(i); }
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-arc-and-properties.m b/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-arc-and-properties.m
new file mode 100644
index 0000000..7fbd796
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-arc-and-properties.m
@@ -0,0 +1,21 @@
+// RUN: %check_clang_tidy %s bugprone-suspicious-semicolon %t
+
+// This test checks if Objective-C 2.0 (@properties) and
+// Automatic Reference Counting (ARC) are enabled for .m files
+// checked via check_clang_tidy.py.
+
+#if !__has_feature(objc_arc)
+#error Objective-C ARC not enabled as expected
+#endif
+
+@interface Foo
+@property (nonatomic, assign) int shouldDoStuff;
+- (void)nop;
+@end
+
+void fail(Foo *f)
+{
+ if(f.shouldDoStuff); [f nop];
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: potentially unintended semicolon [bugprone-suspicious-semicolon]
+ // CHECK-FIXES: if(f.shouldDoStuff) [f nop];
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-avoid-nserror-init.m b/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-avoid-nserror-init.m
new file mode 100644
index 0000000..7794077
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-avoid-nserror-init.m
@@ -0,0 +1,12 @@
+// RUN: %check_clang_tidy %s objc-avoid-nserror-init %t
+@interface NSError
++ (instancetype)alloc;
+- (instancetype)init;
+@end
+
+@implementation foo
+- (void)bar {
+ NSError *error = [[NSError alloc] init];
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use errorWithDomain:code:userInfo: or initWithDomain:code:userInfo: to create a new NSError [objc-avoid-nserror-init]
+}
+@end
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-avoid-spinlock.m b/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-avoid-spinlock.m
new file mode 100644
index 0000000..f9f05cb
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-avoid-spinlock.m
@@ -0,0 +1,15 @@
+// RUN: %check_clang_tidy %s objc-avoid-spinlock %t
+
+typedef int OSSpinLock;
+
+@implementation Foo
+- (void)f {
+ int i = 1;
+ OSSpinlockLock(&i);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use os_unfair_lock_lock() or dispatch queue APIs instead of the deprecated OSSpinLock [objc-avoid-spinlock]
+ OSSpinlockTry(&i);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use os_unfair_lock_lock() or dispatch queue APIs instead of the deprecated OSSpinLock [objc-avoid-spinlock]
+ OSSpinlockUnlock(&i);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use os_unfair_lock_lock() or dispatch queue APIs instead of the deprecated OSSpinLock [objc-avoid-spinlock]
+}
+@end
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-forbidden-subclassing-custom.m b/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-forbidden-subclassing-custom.m
new file mode 100644
index 0000000..59e6a88
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-forbidden-subclassing-custom.m
@@ -0,0 +1,39 @@
+// RUN: %check_clang_tidy %s objc-forbidden-subclassing %t \
+// RUN: -config='{CheckOptions: \
+// RUN: [{key: objc-forbidden-subclassing.ClassNames, value: "Foo;Quux"}]}' \
+// RUN: --
+
+@interface UIImagePickerController
+@end
+
+// Make sure custom config options replace (not add to) the default list.
+@interface Waldo : UIImagePickerController
+// CHECK-MESSAGES-NOT: :[[@LINE-1]]:12: warning: Objective-C interface 'Waldo' subclasses 'UIImagePickerController', which is not intended to be subclassed [objc-forbidden-subclassing]
+@end
+
+@interface Foo
+@end
+
+@interface Bar : Foo
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Objective-C interface 'Bar' subclasses 'Foo', which is not intended to be subclassed [objc-forbidden-subclassing]
+@end
+
+// Check subclasses of subclasses.
+@interface Baz : Bar
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Objective-C interface 'Baz' subclasses 'Foo', which is not intended to be subclassed [objc-forbidden-subclassing]
+@end
+
+@interface Quux
+@end
+
+// Check that more than one forbidden superclass can be specified.
+@interface Xyzzy : Quux
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Objective-C interface 'Xyzzy' subclasses 'Quux', which is not intended to be subclassed [objc-forbidden-subclassing]
+@end
+
+@interface Plugh
+@end
+
+@interface Corge : Plugh
+// CHECK-MESSAGES-NOT: :[[@LINE-1]]:12: warning: Objective-C interface 'Corge' subclasses 'Plugh', which is not intended to be subclassed [objc-forbidden-subclassing]
+@end
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-forbidden-subclassing.m b/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-forbidden-subclassing.m
new file mode 100644
index 0000000..3ad38bf
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-forbidden-subclassing.m
@@ -0,0 +1,21 @@
+// RUN: %check_clang_tidy %s objc-forbidden-subclassing %t
+
+@interface UIImagePickerController
+@end
+
+@interface Foo : UIImagePickerController
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Objective-C interface 'Foo' subclasses 'UIImagePickerController', which is not intended to be subclassed [objc-forbidden-subclassing]
+@end
+
+// Check subclasses of subclasses.
+@interface Bar : Foo
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Objective-C interface 'Bar' subclasses 'UIImagePickerController', which is not intended to be subclassed [objc-forbidden-subclassing]
+@end
+
+@interface Baz
+@end
+
+// Make sure innocent subclasses aren't caught by the check.
+@interface Blech : Baz
+// CHECK-MESSAGES-NOT: :[[@LINE-1]]:12: warning: Objective-C interface 'Blech' subclasses 'Baz', which is not intended to be subclassed [objc-forbidden-subclassing]
+@end
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-no-arc-or-properties.m b/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-no-arc-or-properties.m
new file mode 100644
index 0000000..c1e73ed
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-no-arc-or-properties.m
@@ -0,0 +1,29 @@
+// RUN: %check_clang_tidy %s bugprone-suspicious-semicolon %t -- -- -fno-objc-arc -fobjc-abi-version=1
+
+// This test ensures check_clang_tidy.py allows disabling Objective-C ARC and
+// Objective-C 2.0 via passing arguments after -- on the command line.
+//
+// (We could include a test which doesn't pass any arguments after --
+// to check if ARC and ObjC 2.0 are disabled by default, but that test
+// could change behavior based on the default Objective-C runtime for
+// the platform, which would make this test flaky.)
+
+#if __has_feature(objc_arc)
+#error Objective-C ARC unexpectedly enabled even with -fno-objc-arc
+#endif
+
+#ifdef __OBJC2__
+#error Objective-C 2.0 unexpectedly enabled even with -fobjc-abi-version=1
+#endif
+
+@interface Foo
+- (int)shouldDoStuff;
+- (void)nop;
+@end
+
+void fail(Foo *f)
+{
+ if([f shouldDoStuff]); [f nop];
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: potentially unintended semicolon [bugprone-suspicious-semicolon]
+ // CHECK-FIXES: if([f shouldDoStuff]) [f nop];
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-property-declaration.m b/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-property-declaration.m
new file mode 100644
index 0000000..07a0620
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/objc-property-declaration.m
@@ -0,0 +1,54 @@
+// RUN: %check_clang_tidy %s objc-property-declaration %t
+@class CIColor;
+@class NSArray;
+@class NSData;
+@class NSString;
+@class UIViewController;
+
+typedef void *CGColorRef;
+
+@interface Foo
+@property(assign, nonatomic) int NotCamelCase;
+// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: property name 'NotCamelCase' not using lowerCamelCase style or not prefixed in a category, according to the Apple Coding Guidelines [objc-property-declaration]
+// CHECK-FIXES: @property(assign, nonatomic) int notCamelCase;
+@property(assign, nonatomic) int camelCase;
+@property(strong, nonatomic) NSString *URLString;
+@property(strong, nonatomic) NSString *bundleID;
+@property(strong, nonatomic) NSData *RGBABytes;
+@property(strong, nonatomic) UIViewController *notificationsVC;
+@property(strong, nonatomic) NSString *URL_string;
+// CHECK-MESSAGES: :[[@LINE-1]]:40: warning: property name 'URL_string' not using lowerCamelCase style or not prefixed in a category, according to the Apple Coding Guidelines [objc-property-declaration]
+@property(strong, nonatomic) NSString *supportURLsCamelCase;
+@property(strong, nonatomic) NSString *supportURLCamelCase;
+@property(strong, nonatomic) NSString *VCsPluralToAdd;
+@property(assign, nonatomic) int centerX;
+@property(assign, nonatomic) int enable2GBackgroundFetch;
+@property(assign, nonatomic) int shouldUseCFPreferences;
+@property(assign, nonatomic) int enableGLAcceleration;
+@property(assign, nonatomic) int ID;
+@property(assign, nonatomic) int hasADog;
+@property(nonatomic, readonly) CGColorRef CGColor;
+@property(nonatomic, readonly) CIColor *CIColor;
+@property(nonatomic, copy) NSArray *IDs;
+@end
+
+@interface Foo (Bar)
+@property(assign, nonatomic) int abc_NotCamelCase;
+// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: property name 'abc_NotCamelCase' not using lowerCamelCase style or not prefixed in a category, according to the Apple Coding Guidelines [objc-property-declaration]
+@property(assign, nonatomic) int abCD_camelCase;
+// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: property name 'abCD_camelCase' not using lowerCamelCase style or not prefixed in a category, according to the Apple Coding Guidelines [objc-property-declaration]
+// CHECK-FIXES: @property(assign, nonatomic) int abcd_camelCase;
+@property(assign, nonatomic) int abCD_NotCamelCase;
+// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: property name 'abCD_NotCamelCase' not using lowerCamelCase style or not prefixed in a category, according to the Apple Coding Guidelines [objc-property-declaration]
+// CHECK-FIXES: @property(assign, nonatomic) int abcd_notCamelCase;
+@property(assign, nonatomic) int wrongFormat_;
+// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: property name 'wrongFormat_' not using lowerCamelCase style or not prefixed in a category, according to the Apple Coding Guidelines [objc-property-declaration]
+@property(strong, nonatomic) NSString *URLStr;
+@property(assign, nonatomic) int abc_camelCase;
+@property(strong, nonatomic) NSString *abc_URL;
+@end
+
+@interface Foo ()
+@property(assign, nonatomic) int abc_inClassExtension;
+// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: property name 'abc_inClassExtension' not using lowerCamelCase style or not prefixed in a category, according to the Apple Coding Guidelines [objc-property-declaration]
+@end
\ No newline at end of file
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/overlapping.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/overlapping.cpp
new file mode 100644
index 0000000..f970a13
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/overlapping.cpp
@@ -0,0 +1,10 @@
+// RUN: clang-tidy -checks=-*,llvm-include-order -header-filter=.* %s \
+// RUN: -- -isystem %S/Inputs/Headers -I %S/Inputs/overlapping | \
+// RUN: not grep "note: this fix will not be applied because it overlaps with another fix"
+
+#include <s.h>
+#include "o.h"
+
+// Test that clang-tidy takes into account in which file we are doing the
+// replacements to determine if they overlap or not. In the file "o.h" there is
+// a similar error at the same file offset, but they do not overlap.
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-faster-string-find.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-faster-string-find.cpp
new file mode 100644
index 0000000..b36e323
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-faster-string-find.cpp
@@ -0,0 +1,110 @@
+// RUN: %check_clang_tidy %s performance-faster-string-find %t -- \
+// RUN: -config="{CheckOptions: \
+// RUN: [{key: performance-faster-string-find.StringLikeClasses, \
+// RUN: value: 'std::basic_string; ::llvm::StringRef;'}]}" --
+
+namespace std {
+template <typename Char>
+struct basic_string {
+ int find(const Char *, int = 0) const;
+ int find(const Char *, int, int) const;
+ int rfind(const Char *) const;
+ int find_first_of(const Char *) const;
+ int find_first_not_of(const Char *) const;
+ int find_last_of(const Char *) const;
+ int find_last_not_of(const Char *) const;
+};
+
+typedef basic_string<char> string;
+typedef basic_string<wchar_t> wstring;
+} // namespace std
+
+namespace llvm {
+struct StringRef {
+ int find(const char *) const;
+};
+} // namespace llvm
+
+struct NotStringRef {
+ int find(const char *);
+};
+
+void StringFind() {
+ std::string Str;
+
+ Str.find("a");
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: 'find' called with a string literal consisting of a single character; consider using the more effective overload accepting a character [performance-faster-string-find]
+ // CHECK-FIXES: Str.find('a');
+
+ // Works with the pos argument.
+ Str.find("a", 1);
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: 'find' called with a string literal
+ // CHECK-FIXES: Str.find('a', 1);
+
+ // Doens't work with strings smaller or larger than 1 char.
+ Str.find("");
+ Str.find("ab");
+
+ // Doesn't do anything with the 3 argument overload.
+ Str.find("a", 1, 1);
+
+ // Other methods that can also be replaced
+ Str.rfind("a");
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: 'rfind' called with a string literal
+ // CHECK-FIXES: Str.rfind('a');
+ Str.find_first_of("a");
+ // CHECK-MESSAGES: [[@LINE-1]]:21: warning: 'find_first_of' called with a string
+ // CHECK-FIXES: Str.find_first_of('a');
+ Str.find_first_not_of("a");
+ // CHECK-MESSAGES: [[@LINE-1]]:25: warning: 'find_first_not_of' called with a
+ // CHECK-FIXES: Str.find_first_not_of('a');
+ Str.find_last_of("a");
+ // CHECK-MESSAGES: [[@LINE-1]]:20: warning: 'find_last_of' called with a string
+ // CHECK-FIXES: Str.find_last_of('a');
+ Str.find_last_not_of("a");
+ // CHECK-MESSAGES: [[@LINE-1]]:24: warning: 'find_last_not_of' called with a
+ // CHECK-FIXES: Str.find_last_not_of('a');
+
+ // std::wstring should work.
+ std::wstring WStr;
+ WStr.find(L"n");
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: 'find' called with a string literal
+ // CHECK-FIXES: Str.find(L'n');
+ // Even with unicode that fits in one wide char.
+ WStr.find(L"\x3A9");
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: 'find' called with a string literal
+ // CHECK-FIXES: Str.find(L'\x3A9');
+
+ // Also with other types, but only if it was specified in the options.
+ llvm::StringRef sr;
+ sr.find("x");
+ // CHECK-MESSAGES: [[@LINE-1]]:11: warning: 'find' called with a string literal
+ // CHECK-FIXES: sr.find('x');
+ NotStringRef nsr;
+ nsr.find("x");
+}
+
+
+template <typename T>
+int FindTemplateDependant(T value) {
+ return value.find("A");
+}
+template <typename T>
+int FindTemplateNotDependant(T pos) {
+ return std::string().find("A", pos);
+ // CHECK-MESSAGES: [[@LINE-1]]:29: warning: 'find' called with a string literal
+ // CHECK-FIXES: return std::string().find('A', pos);
+}
+
+int FindStr() {
+ return FindTemplateDependant(std::string()) + FindTemplateNotDependant(1);
+}
+
+#define STR_MACRO(str) str.find("A")
+#define POS_MACRO(pos) std::string().find("A",pos)
+
+int Macros() {
+ return STR_MACRO(std::string()) + POS_MACRO(1);
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: 'find' called with a string literal
+ // CHECK-MESSAGES: [[@LINE-2]]:37: warning: 'find' called with a string literal
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-for-range-copy-allowed-types.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-for-range-copy-allowed-types.cpp
new file mode 100644
index 0000000..a3e7a6b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-for-range-copy-allowed-types.cpp
@@ -0,0 +1,124 @@
+// RUN: %check_clang_tidy %s performance-for-range-copy %t -- -config="{CheckOptions: [{key: performance-for-range-copy.AllowedTypes, value: '[Pp]ointer$;[Pp]tr$;[Rr]ef(erence)?$'}]}" -- -std=c++11 -fno-delayed-template-parsing
+
+template <typename T>
+struct Iterator {
+ void operator++() {}
+ const T& operator*() {
+ static T* TT = new T();
+ return *TT;
+ }
+ bool operator!=(const Iterator &) { return false; }
+ typedef const T& const_reference;
+};
+template <typename T>
+struct View {
+ T begin() { return T(); }
+ T begin() const { return T(); }
+ T end() { return T(); }
+ T end() const { return T(); }
+ typedef typename T::const_reference const_reference;
+};
+
+struct SmartPointer {
+ ~SmartPointer();
+};
+
+struct smart_pointer {
+ ~smart_pointer();
+};
+
+struct SmartPtr {
+ ~SmartPtr();
+};
+
+struct smart_ptr {
+ ~smart_ptr();
+};
+
+struct SmartReference {
+ ~SmartReference();
+};
+
+struct smart_reference {
+ ~smart_reference();
+};
+
+struct SmartRef {
+ ~SmartRef();
+};
+
+struct smart_ref {
+ ~smart_ref();
+};
+
+struct OtherType {
+ ~OtherType();
+};
+
+template <typename T> struct SomeComplexTemplate {
+ ~SomeComplexTemplate();
+};
+
+typedef SomeComplexTemplate<int> NotTooComplexRef;
+
+void negativeSmartPointer() {
+ for (auto P : View<Iterator<SmartPointer>>()) {
+ auto P2 = P;
+ }
+}
+
+void negative_smart_pointer() {
+ for (auto p : View<Iterator<smart_pointer>>()) {
+ auto p2 = p;
+ }
+}
+
+void negativeSmartPtr() {
+ for (auto P : View<Iterator<SmartPtr>>()) {
+ auto P2 = P;
+ }
+}
+
+void negative_smart_ptr() {
+ for (auto p : View<Iterator<smart_ptr>>()) {
+ auto p2 = p;
+ }
+}
+
+void negativeSmartReference() {
+ for (auto R : View<Iterator<SmartReference>>()) {
+ auto R2 = R;
+ }
+}
+
+void negative_smart_reference() {
+ for (auto r : View<Iterator<smart_reference>>()) {
+ auto r2 = r;
+ }
+}
+
+void negativeSmartRef() {
+ for (auto R : View<Iterator<SmartRef>>()) {
+ auto R2 = R;
+ }
+}
+
+void negative_smart_ref() {
+ for (auto r : View<Iterator<smart_ref>>()) {
+ auto r2 = r;
+ }
+}
+
+void positiveOtherType() {
+ for (auto O : View<Iterator<OtherType>>()) {
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but only used as const reference; consider making it a const reference [performance-for-range-copy]
+ // CHECK-FIXES: for (const auto& O : View<Iterator<OtherType>>()) {
+ auto O2 = O;
+ }
+}
+
+void negativeNotTooComplexRef() {
+ for (NotTooComplexRef R : View<Iterator<NotTooComplexRef>>()) {
+ auto R2 = R;
+ }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-for-range-copy-warn-on-all-auto-copies.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-for-range-copy-warn-on-all-auto-copies.cpp
new file mode 100644
index 0000000..75655a6
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-for-range-copy-warn-on-all-auto-copies.cpp
@@ -0,0 +1,39 @@
+// RUN: %check_clang_tidy %s performance-for-range-copy %t -config="{CheckOptions: [{key: "performance-for-range-copy.WarnOnAllAutoCopies", value: 1}]}" -- -std=c++11
+
+template <typename T>
+struct Iterator {
+ void operator++() {}
+ const T& operator*() {
+ static T* TT = new T();
+ return *TT;
+ }
+ bool operator!=(const Iterator &) { return false; }
+};
+template <typename T>
+struct View {
+ T begin() { return T(); }
+ T begin() const { return T(); }
+ T end() { return T(); }
+ T end() const { return T(); }
+};
+
+struct S {
+ S();
+ S(const S &);
+ ~S();
+ S &operator=(const S &);
+};
+
+void NegativeLoopVariableNotAuto() {
+ for (S S1 : View<Iterator<S>>()) {
+ S* S2 = &S1;
+ }
+}
+
+void PositiveTriggeredForAutoLoopVariable() {
+ for (auto S1 : View<Iterator<S>>()) {
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: the loop variable's type is not a reference type; this creates a copy in each iteration; consider making this a reference [performance-for-range-copy]
+ // CHECK-FIXES: for (const auto& S1 : View<Iterator<S>>()) {
+ S* S2 = &S1;
+ }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-for-range-copy.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-for-range-copy.cpp
new file mode 100644
index 0000000..5e174fa
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-for-range-copy.cpp
@@ -0,0 +1,272 @@
+// RUN: %check_clang_tidy %s performance-for-range-copy %t -- -- -std=c++11 -fno-delayed-template-parsing
+
+namespace std {
+
+template <typename _Tp>
+struct remove_reference { typedef _Tp type; };
+template <typename _Tp>
+struct remove_reference<_Tp&> { typedef _Tp type; };
+template <typename _Tp>
+struct remove_reference<_Tp&&> { typedef _Tp type; };
+
+template <typename _Tp>
+constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) {
+ return static_cast<typename std::remove_reference<_Tp>::type &&>(__t);
+}
+
+} // std
+
+template <typename T>
+struct Iterator {
+ void operator++() {}
+ const T& operator*() {
+ static T* TT = new T();
+ return *TT;
+ }
+ bool operator!=(const Iterator &) { return false; }
+ typedef const T& const_reference;
+};
+template <typename T>
+struct View {
+ T begin() { return T(); }
+ T begin() const { return T(); }
+ T end() { return T(); }
+ T end() const { return T(); }
+ typedef typename T::const_reference const_reference;
+};
+
+struct ConstructorConvertible {
+};
+
+struct S {
+ S();
+ S(const S &);
+ S(const ConstructorConvertible&) {}
+ ~S();
+ S &operator=(const S &);
+};
+
+struct Convertible {
+ operator S() const {
+ return S();
+ }
+};
+
+void negativeConstReference() {
+ for (const S &S1 : View<Iterator<S>>()) {
+ }
+}
+
+void negativeUserDefinedConversion() {
+ Convertible C[0];
+ for (const S &S1 : C) {
+ }
+}
+
+void negativeImplicitConstructorConversion() {
+ ConstructorConvertible C[0];
+ for (const S &S1 : C) {
+ }
+}
+
+template <typename T>
+void uninstantiated() {
+ for (const S S1 : View<Iterator<S>>()) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: the loop variable's type is not a reference type; this creates a copy in each iteration; consider making this a reference [performance-for-range-copy]
+ // CHECK-FIXES: {{^}} for (const S& S1 : View<Iterator<S>>()) {}
+
+ // Don't warn on dependent types.
+ for (const T t1 : View<Iterator<T>>()) {
+ }
+}
+
+template <typename T>
+void instantiated() {
+ for (const S S2 : View<Iterator<S>>()) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: the loop variable's type is {{.*}}
+ // CHECK-FIXES: {{^}} for (const S& S2 : View<Iterator<S>>()) {}
+
+ for (const T T2 : View<Iterator<T>>()) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: the loop variable's type is {{.*}}
+ // CHECK-FIXES: {{^}} for (const T& T2 : View<Iterator<T>>()) {}
+}
+
+template <typename T>
+void instantiatedNegativeTypedefConstReference() {
+ for (typename T::const_reference T2 : T()) {
+ S S1 = T2;
+ }
+}
+
+void f() {
+ instantiated<int>();
+ instantiated<S>();
+ instantiatedNegativeTypedefConstReference<View<Iterator<S>>>();
+}
+
+struct Mutable {
+ Mutable() {}
+ Mutable(const Mutable &) = default;
+ Mutable(Mutable&&) = default;
+ Mutable(const Mutable &, const Mutable &) {}
+ void setBool(bool B) {}
+ bool constMethod() const {
+ return true;
+ }
+ Mutable& operator[](int I) {
+ return *this;
+ }
+ bool operator==(const Mutable &Other) const {
+ return true;
+ }
+ ~Mutable() {}
+};
+
+struct Point {
+ ~Point() {}
+ int x, y;
+};
+
+Mutable& operator<<(Mutable &Out, bool B) {
+ Out.setBool(B);
+ return Out;
+}
+
+bool operator!=(const Mutable& M1, const Mutable& M2) {
+ return false;
+}
+
+void use(const Mutable &M);
+void use(int I);
+void useTwice(const Mutable &M1, const Mutable &M2);
+void useByValue(Mutable M);
+void useByConstValue(const Mutable M);
+void mutate(Mutable *M);
+void mutate(Mutable &M);
+void onceConstOnceMutated(const Mutable &M1, Mutable &M2);
+
+void negativeVariableIsMutated() {
+ for (auto M : View<Iterator<Mutable>>()) {
+ mutate(M);
+ }
+ for (auto M : View<Iterator<Mutable>>()) {
+ mutate(&M);
+ }
+ for (auto M : View<Iterator<Mutable>>()) {
+ M.setBool(true);
+ }
+}
+
+void negativeOnceConstOnceMutated() {
+ for (auto M : View<Iterator<Mutable>>()) {
+ onceConstOnceMutated(M, M);
+ }
+}
+
+void negativeVarIsMoved() {
+ for (auto M : View<Iterator<Mutable>>()) {
+ auto Moved = std::move(M);
+ }
+}
+
+void negativeNonConstOperatorIsInvoked() {
+ for (auto NonConstOperatorInvokee : View<Iterator<Mutable>>()) {
+ auto& N = NonConstOperatorInvokee[0];
+ }
+}
+
+void negativeNonConstNonMemberOperatorInvoked() {
+ for (auto NonConstOperatorInvokee : View<Iterator<Mutable>>()) {
+ NonConstOperatorInvokee << true;
+ }
+}
+
+void negativeConstCheapToCopy() {
+ for (const int I : View<Iterator<int>>()) {
+ }
+}
+
+void negativeConstCheapToCopyTypedef() {
+ typedef const int ConstInt;
+ for (ConstInt C : View<Iterator<ConstInt>>()) {
+ }
+}
+
+void negativeCheapToCopy() {
+ for (int I : View<Iterator<int>>()) {
+ use(I);
+ }
+}
+
+void negativeCheapToCopyTypedef() {
+ typedef int Int;
+ for (Int I : View<Iterator<Int>>()) {
+ use(I);
+ }
+}
+
+void positiveOnlyConstMethodInvoked() {
+ for (auto M : View<Iterator<Mutable>>()) {
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but only used as const reference; consider making it a const reference [performance-for-range-copy]
+ // CHECK-FIXES: for (const auto& M : View<Iterator<Mutable>>()) {
+ M.constMethod();
+ }
+}
+
+void positiveOnlyUsedAsConstArguments() {
+ for (auto UsedAsConst : View<Iterator<Mutable>>()) {
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but only used as const reference; consider making it a const reference [performance-for-range-copy]
+ // CHECK-FIXES: for (const auto& UsedAsConst : View<Iterator<Mutable>>()) {
+ use(UsedAsConst);
+ useTwice(UsedAsConst, UsedAsConst);
+ useByValue(UsedAsConst);
+ useByConstValue(UsedAsConst);
+ }
+}
+
+void positiveOnlyAccessedFieldAsConst() {
+ for (auto UsedAsConst : View<Iterator<Point>>()) {
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but only used as const reference; consider making it a const reference [performance-for-range-copy]
+ // CHECK-FIXES: for (const auto& UsedAsConst : View<Iterator<Point>>()) {
+ use(UsedAsConst.x);
+ use(UsedAsConst.y);
+ }
+}
+
+void positiveOnlyUsedInCopyConstructor() {
+ for (auto A : View<Iterator<Mutable>>()) {
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but only used as const reference; consider making it a const reference [performance-for-range-copy]
+ // CHECK-FIXES: for (const auto& A : View<Iterator<Mutable>>()) {
+ Mutable Copy = A;
+ Mutable Copy2(A);
+ }
+}
+
+void positiveTwoConstConstructorArgs() {
+ for (auto A : View<Iterator<Mutable>>()) {
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but only used as const reference; consider making it a const reference [performance-for-range-copy]
+ // CHECK-FIXES: for (const auto& A : View<Iterator<Mutable>>()) {
+ Mutable Copy(A, A);
+ }
+}
+
+void PositiveConstMemberOperatorInvoked() {
+ for (auto ConstOperatorInvokee : View<Iterator<Mutable>>()) {
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but only used as const reference; consider making it a const reference [performance-for-range-copy]
+ // CHECK-FIXES: for (const auto& ConstOperatorInvokee : View<Iterator<Mutable>>()) {
+ bool result = ConstOperatorInvokee == Mutable();
+ }
+}
+
+void PositiveConstNonMemberOperatorInvoked() {
+ for (auto ConstOperatorInvokee : View<Iterator<Mutable>>()) {
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but only used as const reference; consider making it a const reference [performance-for-range-copy]
+ // CHECK-FIXES: for (const auto& ConstOperatorInvokee : View<Iterator<Mutable>>()) {
+ bool result = ConstOperatorInvokee != Mutable();
+ }
+}
+
+void IgnoreLoopVariableNotUsedInLoopBody() {
+ for (auto _ : View<Iterator<S>>()) {
+ }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-implicit-conversion-in-loop.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-implicit-conversion-in-loop.cpp
new file mode 100644
index 0000000..72f9e52
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-implicit-conversion-in-loop.cpp
@@ -0,0 +1,197 @@
+// RUN: %check_clang_tidy %s performance-implicit-conversion-in-loop %t
+
+// ---------- Classes used in the tests ----------
+
+// Iterator returning by value.
+template <typename T>
+struct Iterator {
+ void operator++();
+ T operator*();
+ bool operator!=(const Iterator& other);
+};
+
+// Iterator returning by reference.
+template <typename T>
+struct RefIterator {
+ void operator++();
+ T& operator*();
+ bool operator!=(const RefIterator& other);
+};
+
+// The template argument is an iterator type, and a view is an object you can
+// run a for loop on.
+template <typename T>
+struct View {
+ T begin();
+ T end();
+};
+
+// With this class, the implicit conversion is a call to the (implicit)
+// constructor of the class.
+template <typename T>
+class ImplicitWrapper {
+ public:
+ // Implicit!
+ ImplicitWrapper(const T& t);
+};
+
+// With this class, the implicit conversion is a call to the conversion
+// operators of SimpleClass and ComplexClass.
+template <typename T>
+class OperatorWrapper {
+ public:
+ OperatorWrapper() = delete;
+};
+
+struct SimpleClass {
+ int foo;
+ operator OperatorWrapper<SimpleClass>();
+};
+
+// The materialize expression is not the same when the class has a destructor,
+// so we make sure we cover that case too.
+class ComplexClass {
+ public:
+ ComplexClass();
+ ~ComplexClass();
+ operator OperatorWrapper<ComplexClass>();
+};
+
+typedef View<Iterator<SimpleClass>> SimpleView;
+typedef View<RefIterator<SimpleClass>> SimpleRefView;
+typedef View<Iterator<ComplexClass>> ComplexView;
+typedef View<RefIterator<ComplexClass>> ComplexRefView;
+
+// ---------- The test themselves ----------
+// For each test we do, in the same order, const ref, non const ref, const
+// value, non const value.
+
+void SimpleClassIterator() {
+ for (const SimpleClass& foo : SimpleView()) {}
+ // This line does not compile because a temporary cannot be assigned to a non
+ // const reference.
+ // for (SimpleClass& foo : SimpleView()) {}
+ for (const SimpleClass foo : SimpleView()) {}
+ for (SimpleClass foo : SimpleView()) {}
+}
+
+void SimpleClassRefIterator() {
+ for (const SimpleClass& foo : SimpleRefView()) {}
+ for (SimpleClass& foo : SimpleRefView()) {}
+ for (const SimpleClass foo : SimpleRefView()) {}
+ for (SimpleClass foo : SimpleRefView()) {}
+}
+
+void ComplexClassIterator() {
+ for (const ComplexClass& foo : ComplexView()) {}
+ // for (ComplexClass& foo : ComplexView()) {}
+ for (const ComplexClass foo : ComplexView()) {}
+ for (ComplexClass foo : ComplexView()) {}
+}
+
+void ComplexClassRefIterator() {
+ for (const ComplexClass& foo : ComplexRefView()) {}
+ for (ComplexClass& foo : ComplexRefView()) {}
+ for (const ComplexClass foo : ComplexRefView()) {}
+ for (ComplexClass foo : ComplexRefView()) {}
+}
+
+void ImplicitSimpleClassIterator() {
+ for (const ImplicitWrapper<SimpleClass>& foo : SimpleView()) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the loop variable 'foo' is different from the one returned by the iterator and generates an implicit conversion; you can either change the type to the matching one ('const SimpleClass &' but 'const auto&' is always a valid option) or remove the reference to make it explicit that you are creating a new value [performance-implicit-conversion-in-loop]
+ // for (ImplicitWrapper<SimpleClass>& foo : SimpleView()) {}
+ for (const ImplicitWrapper<SimpleClass> foo : SimpleView()) {}
+ for (ImplicitWrapper<SimpleClass> foo : SimpleView()) {}
+}
+
+void ImplicitSimpleClassRefIterator() {
+ for (const ImplicitWrapper<SimpleClass>& foo : SimpleRefView()) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const SimpleClass &'.*}}
+ // for (ImplicitWrapper<SimpleClass>& foo : SimpleRefView()) {}
+ for (const ImplicitWrapper<SimpleClass> foo : SimpleRefView()) {}
+ for (ImplicitWrapper<SimpleClass> foo : SimpleRefView()) {}
+}
+
+void ImplicitSimpleClassArray() {
+ SimpleClass array[5];
+ for (const ImplicitWrapper<SimpleClass>& foo : array) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const SimpleClass &'.*}}
+ // for (ImplicitWrapper<SimpleClass>& foo : array) {}
+ for (const ImplicitWrapper<SimpleClass> foo : array) {}
+ for (ImplicitWrapper<SimpleClass> foo : array) {}
+}
+
+void ImplicitComplexClassIterator() {
+ for (const ImplicitWrapper<ComplexClass>& foo : ComplexView()) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const ComplexClass &'.*}}
+ // for (ImplicitWrapper<ComplexClass>& foo : ComplexView()) {}
+ for (const ImplicitWrapper<ComplexClass> foo : ComplexView()) {}
+ for (ImplicitWrapper<ComplexClass> foo : ComplexView()) {}
+}
+
+void ImplicitComplexClassRefIterator() {
+ ComplexClass array[5];
+ for (const ImplicitWrapper<ComplexClass>& foo : array) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const ComplexClass &'.*}}
+ // for (ImplicitWrapper<ComplexClass>& foo : array) {}
+ for (const ImplicitWrapper<ComplexClass> foo : array) {}
+ for (ImplicitWrapper<ComplexClass> foo : array) {}
+}
+
+void ImplicitComplexClassArray() {
+ for (const ImplicitWrapper<ComplexClass>& foo : ComplexRefView()) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const ComplexClass &'.*}}
+ // for (ImplicitWrapper<ComplexClass>& foo : ComplexRefView()) {}
+ for (const ImplicitWrapper<ComplexClass> foo : ComplexRefView()) {}
+ for (ImplicitWrapper<ComplexClass> foo : ComplexRefView()) {}
+}
+
+void OperatorSimpleClassIterator() {
+ for (const OperatorWrapper<SimpleClass>& foo : SimpleView()) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const SimpleClass &'.*}}
+ // for (OperatorWrapper<SimpleClass>& foo : SimpleView()) {}
+ for (const OperatorWrapper<SimpleClass> foo : SimpleView()) {}
+ for (OperatorWrapper<SimpleClass> foo : SimpleView()) {}
+}
+
+void OperatorSimpleClassRefIterator() {
+ for (const OperatorWrapper<SimpleClass>& foo : SimpleRefView()) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const SimpleClass &'.*}}
+ // for (OperatorWrapper<SimpleClass>& foo : SimpleRefView()) {}
+ for (const OperatorWrapper<SimpleClass> foo : SimpleRefView()) {}
+ for (OperatorWrapper<SimpleClass> foo : SimpleRefView()) {}
+}
+
+void OperatorSimpleClassArray() {
+ SimpleClass array[5];
+ for (const OperatorWrapper<SimpleClass>& foo : array) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const SimpleClass &'.*}}
+ // for (OperatorWrapper<SimpleClass>& foo : array) {}
+ for (const OperatorWrapper<SimpleClass> foo : array) {}
+ for (OperatorWrapper<SimpleClass> foo : array) {}
+}
+
+void OperatorComplexClassIterator() {
+ for (const OperatorWrapper<ComplexClass>& foo : ComplexView()) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const ComplexClass &'.*}}
+ // for (OperatorWrapper<ComplexClass>& foo : ComplexView()) {}
+ for (const OperatorWrapper<ComplexClass> foo : ComplexView()) {}
+ for (OperatorWrapper<ComplexClass> foo : ComplexView()) {}
+}
+
+void OperatorComplexClassRefIterator() {
+ for (const OperatorWrapper<ComplexClass>& foo : ComplexRefView()) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const ComplexClass &'.*}}
+ // for (OperatorWrapper<ComplexClass>& foo : ComplexRefView()) {}
+ for (const OperatorWrapper<ComplexClass> foo : ComplexRefView()) {}
+ for (OperatorWrapper<ComplexClass> foo : ComplexRefView()) {}
+}
+
+void OperatorComplexClassArray() {
+ ComplexClass array[5];
+ for (const OperatorWrapper<ComplexClass>& foo : array) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const ComplexClass &'.*}}
+ // for (OperatorWrapper<ComplexClass>& foo : array) {}
+ for (const OperatorWrapper<ComplexClass> foo : array) {}
+ for (OperatorWrapper<ComplexClass> foo : array) {}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-inefficient-algorithm.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-inefficient-algorithm.cpp
new file mode 100644
index 0000000..19a6701
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-inefficient-algorithm.cpp
@@ -0,0 +1,166 @@
+// RUN: %check_clang_tidy %s performance-inefficient-algorithm %t
+
+namespace std {
+template <typename T> struct less {
+ bool operator()(const T &lhs, const T &rhs) { return lhs < rhs; }
+};
+
+template <typename T> struct greater {
+ bool operator()(const T &lhs, const T &rhs) { return lhs > rhs; }
+};
+
+struct iterator_type {};
+
+template <typename K, typename Cmp = less<K>> struct set {
+ typedef iterator_type iterator;
+ iterator find(const K &k);
+ unsigned count(const K &k);
+
+ iterator begin();
+ iterator end();
+ iterator begin() const;
+ iterator end() const;
+};
+
+struct other_iterator_type {};
+
+template <typename K, typename V, typename Cmp = less<K>> struct map {
+ typedef other_iterator_type iterator;
+ iterator find(const K &k);
+ unsigned count(const K &k);
+
+ iterator begin();
+ iterator end();
+ iterator begin() const;
+ iterator end() const;
+};
+
+template <typename K, typename V> struct multimap : map<K, V> {};
+template <typename K> struct unordered_set : set<K> {};
+template <typename K, typename V> struct unordered_map : map<K, V> {};
+template <typename K> struct unordered_multiset : set<K> {};
+template <typename K, typename V> struct unordered_multimap : map<K, V> {};
+
+template <typename K, typename Cmp = less<K>> struct multiset : set<K, Cmp> {};
+
+template <typename FwIt, typename K>
+FwIt find(FwIt, FwIt end, const K &) { return end; }
+
+template <typename FwIt, typename K, typename Cmp>
+FwIt find(FwIt, FwIt end, const K &, Cmp) { return end; }
+
+template <typename FwIt, typename Pred>
+FwIt find_if(FwIt, FwIt end, Pred) { return end; }
+
+template <typename FwIt, typename K>
+unsigned count(FwIt, FwIt, const K &) { return 0; }
+
+template <typename FwIt, typename K>
+FwIt lower_bound(FwIt, FwIt end, const K &) { return end; }
+
+template <typename FwIt, typename K, typename Ord>
+FwIt lower_bound(FwIt, FwIt end, const K &, Ord) { return end; }
+}
+
+#define FIND_IN_SET(x) find(x.begin(), x.end(), 10)
+// CHECK-FIXES: #define FIND_IN_SET(x) find(x.begin(), x.end(), 10)
+
+template <typename T> void f(const T &t) {
+ std::set<int> s;
+ find(s.begin(), s.end(), 46);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be
+ // CHECK-FIXES: {{^ }}s.find(46);{{$}}
+
+ find(t.begin(), t.end(), 46);
+ // CHECK-FIXES: {{^ }}find(t.begin(), t.end(), 46);{{$}}
+}
+
+int main() {
+ std::set<int> s;
+ auto it = std::find(s.begin(), s.end(), 43);
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: this STL algorithm call should be replaced with a container method [performance-inefficient-algorithm]
+ // CHECK-FIXES: {{^ }}auto it = s.find(43);{{$}}
+ auto c = count(s.begin(), s.end(), 43);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: this STL algorithm call should be
+ // CHECK-FIXES: {{^ }}auto c = s.count(43);{{$}}
+
+#define SECOND(x, y, z) y
+ SECOND(q,std::count(s.begin(), s.end(), 22),w);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: this STL algorithm call should be
+ // CHECK-FIXES: {{^ }}SECOND(q,s.count(22),w);{{$}}
+
+ it = find_if(s.begin(), s.end(), [](int) { return false; });
+
+ std::multiset<int> ms;
+ find(ms.begin(), ms.end(), 46);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be
+ // CHECK-FIXES: {{^ }}ms.find(46);{{$}}
+
+ const std::multiset<int> &msref = ms;
+ find(msref.begin(), msref.end(), 46);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be
+ // CHECK-FIXES: {{^ }}msref.find(46);{{$}}
+
+ std::multiset<int> *msptr = &ms;
+ find(msptr->begin(), msptr->end(), 46);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be
+ // CHECK-FIXES: {{^ }}msptr->find(46);{{$}}
+
+ it = std::find(s.begin(), s.end(), 43, std::greater<int>());
+ // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: different comparers used in the algorithm and the container [performance-inefficient-algorithm]
+
+ FIND_IN_SET(s);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be
+ // CHECK-FIXES: {{^ }}FIND_IN_SET(s);{{$}}
+
+ f(s);
+
+ std::unordered_set<int> us;
+ lower_bound(us.begin(), us.end(), 10);
+ // CHECK-FIXES: {{^ }}lower_bound(us.begin(), us.end(), 10);{{$}}
+ find(us.begin(), us.end(), 10);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be
+ // CHECK-FIXES: {{^ }}us.find(10);{{$}}
+
+ std::unordered_multiset<int> ums;
+ find(ums.begin(), ums.end(), 10);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be
+ // CHECK-FIXES: {{^ }}ums.find(10);{{$}}
+
+ std::map<int, int> intmap;
+ find(intmap.begin(), intmap.end(), 46);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be
+ // CHECK-FIXES: {{^ }}find(intmap.begin(), intmap.end(), 46);{{$}}
+
+ std::multimap<int, int> intmmap;
+ find(intmmap.begin(), intmmap.end(), 46);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be
+ // CHECK-FIXES: {{^ }}find(intmmap.begin(), intmmap.end(), 46);{{$}}
+
+ std::unordered_map<int, int> umap;
+ find(umap.begin(), umap.end(), 46);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be
+ // CHECK-FIXES: {{^ }}find(umap.begin(), umap.end(), 46);{{$}}
+
+ std::unordered_multimap<int, int> ummap;
+ find(ummap.begin(), ummap.end(), 46);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be
+ // CHECK-FIXES: {{^ }}find(ummap.begin(), ummap.end(), 46);{{$}}
+}
+
+struct Value {
+ int value;
+};
+
+struct Ordering {
+ bool operator()(const Value &lhs, const Value &rhs) const {
+ return lhs.value < rhs.value;
+ }
+ bool operator()(int lhs, const Value &rhs) const { return lhs < rhs.value; }
+};
+
+void g(std::set<Value, Ordering> container, int value) {
+ lower_bound(container.begin(), container.end(), value, Ordering());
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be
+ // CHECK-FIXES: {{^ }}lower_bound(container.begin(), container.end(), value, Ordering());{{$}}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-inefficient-string-concatenation.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-inefficient-string-concatenation.cpp
new file mode 100644
index 0000000..1dbd56b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-inefficient-string-concatenation.cpp
@@ -0,0 +1,48 @@
+// RUN: %check_clang_tidy %s performance-inefficient-string-concatenation %t
+
+namespace std {
+template <typename T>
+class basic_string {
+public:
+ basic_string() {}
+ ~basic_string() {}
+ basic_string<T> *operator+=(const basic_string<T> &) {}
+ friend basic_string<T> operator+(const basic_string<T> &, const basic_string<T> &) {}
+};
+typedef basic_string<char> string;
+typedef basic_string<wchar_t> wstring;
+}
+
+void f(std::string) {}
+std::string g(std::string) {}
+
+int main() {
+ std::string mystr1, mystr2;
+ std::wstring mywstr1, mywstr2;
+ auto myautostr1 = mystr1;
+ auto myautostr2 = mystr2;
+
+ for (int i = 0; i < 10; ++i) {
+ f(mystr1 + mystr2 + mystr1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: string concatenation results in allocation of unnecessary temporary strings; consider using 'operator+=' or 'string::append()' instead
+ mystr1 = mystr1 + mystr2;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: string concatenation
+ mystr1 = mystr2 + mystr2 + mystr2;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: string concatenation
+ mystr1 = mystr2 + mystr1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: string concatenation
+ mywstr1 = mywstr2 + mywstr1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: string concatenation
+ mywstr1 = mywstr2 + mywstr2 + mywstr2;
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: string concatenation
+ myautostr1 = myautostr1 + myautostr2;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: string concatenation
+
+ mywstr1 = mywstr2 + mywstr2;
+ mystr1 = mystr2 + mystr2;
+ mystr1 += mystr2;
+ f(mystr2 + mystr1);
+ mystr1 = g(mystr1);
+ }
+ return 0;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
new file mode 100644
index 0000000..a04f66e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
@@ -0,0 +1,277 @@
+// RUN: %check_clang_tidy %s performance-inefficient-vector-operation %t -- -format-style=llvm -- --std=c++11
+
+namespace std {
+
+typedef int size_t;
+
+template<class E> class initializer_list {
+public:
+ using value_type = E;
+ using reference = E&;
+ using const_reference = const E&;
+ using size_type = size_t;
+ using iterator = const E*;
+ using const_iterator = const E*;
+ initializer_list();
+ size_t size() const; // number of elements
+ const E* begin() const; // first element
+ const E* end() const; // one past the last element
+};
+
+// initializer list range access
+template<class E> const E* begin(initializer_list<E> il);
+template<class E> const E* end(initializer_list<E> il);
+
+template <class T>
+class vector {
+ public:
+ typedef T* iterator;
+ typedef const T* const_iterator;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef size_t size_type;
+
+ explicit vector();
+ explicit vector(size_type n);
+
+ void push_back(const T& val);
+
+ template <class... Args> void emplace_back(Args &&... args);
+
+ void reserve(size_t n);
+ void resize(size_t n);
+
+ size_t size();
+ const_reference operator[] (size_type) const;
+ reference operator[] (size_type);
+
+ const_iterator begin() const;
+ const_iterator end() const;
+};
+} // namespace std
+
+class Foo {
+ public:
+ explicit Foo(int);
+};
+
+class Bar {
+ public:
+ Bar(int);
+};
+
+int Op(int);
+
+void f(std::vector<int>& t) {
+ {
+ std::vector<int> v0;
+ // CHECK-FIXES: v0.reserve(10);
+ for (int i = 0; i < 10; ++i)
+ v0.push_back(i);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the vector capacity before the loop
+ }
+ {
+ std::vector<int> v1;
+ // CHECK-FIXES: v1.reserve(10);
+ for (int i = 0; i < 10; i++)
+ v1.push_back(i);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called
+ }
+ {
+ std::vector<int> v2;
+ // CHECK-FIXES: v2.reserve(10);
+ for (int i = 0; i < 10; ++i)
+ v2.push_back(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called
+ }
+ {
+ std::vector<int> v3;
+ // CHECK-FIXES: v3.reserve(5);
+ for (int i = 0; i < 5; ++i) {
+ v3.push_back(i);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called
+ }
+ // CHECK-FIXES-NOT: v3.reserve(10);
+ for (int i = 0; i < 10; ++i) {
+ // No fix for this loop as we encounter the prior loops.
+ v3.push_back(i);
+ }
+ }
+ {
+ std::vector<int> v4;
+ std::vector<int> v5;
+ v5.reserve(3);
+ // CHECK-FIXES: v4.reserve(10);
+ for (int i = 0; i < 10; ++i)
+ v4.push_back(i);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called
+ }
+ {
+ std::vector<int> v6;
+ // CHECK-FIXES: v6.reserve(t.size());
+ for (std::size_t i = 0; i < t.size(); ++i) {
+ v6.push_back(t[i]);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called
+ }
+ }
+ {
+ std::vector<int> v7;
+ // CHECK-FIXES: v7.reserve(t.size() - 1);
+ for (std::size_t i = 0; i < t.size() - 1; ++i) {
+ v7.push_back(t[i]);
+ } // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called
+ }
+ {
+ std::vector<int> v8;
+ // CHECK-FIXES: v8.reserve(t.size());
+ for (const auto &e : t) {
+ v8.push_back(e);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called
+ }
+ }
+ {
+ std::vector<int> v9;
+ // CHECK-FIXES: v9.reserve(t.size());
+ for (const auto &e : t) {
+ v9.push_back(Op(e));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called
+ }
+ }
+ {
+ std::vector<Foo> v10;
+ // CHECK-FIXES: v10.reserve(t.size());
+ for (const auto &e : t) {
+ v10.push_back(Foo(e));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called
+ }
+ }
+ {
+ std::vector<Bar> v11;
+ // CHECK-FIXES: v11.reserve(t.size());
+ for (const auto &e : t) {
+ v11.push_back(e);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called
+ }
+ }
+ {
+ std::vector<Foo> v12;
+ // CHECK-FIXES: v12.reserve(t.size());
+ for (const auto &e : t) {
+ v12.emplace_back(e);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'emplace_back' is called
+ }
+ }
+
+ // ---- Non-fixed Cases ----
+ {
+ std::vector<int> z0;
+ z0.reserve(20);
+ // CHECK-FIXES-NOT: z0.reserve(10);
+ // There is a "reserve" call already.
+ for (int i = 0; i < 10; ++i) {
+ z0.push_back(i);
+ }
+ }
+ {
+ std::vector<int> z1;
+ z1.reserve(5);
+ // CHECK-FIXES-NOT: z1.reserve(10);
+ // There is a "reserve" call already.
+ for (int i = 0; i < 10; ++i) {
+ z1.push_back(i);
+ }
+ }
+ {
+ std::vector<int> z2;
+ z2.resize(5);
+ // CHECK-FIXES-NOT: z2.reserve(10);
+ // There is a ref usage of v before the loop.
+ for (int i = 0; i < 10; ++i) {
+ z2.push_back(i);
+ }
+ }
+ {
+ std::vector<int> z3;
+ z3.push_back(0);
+ // CHECK-FIXES-NOT: z3.reserve(10);
+ // There is a ref usage of v before the loop.
+ for (int i = 0; i < 10; ++i) {
+ z3.push_back(i);
+ }
+ }
+ {
+ std::vector<int> z4;
+ f(z4);
+ // CHECK-FIXES-NOT: z4.reserve(10);
+ // There is a ref usage of z4 before the loop.
+ for (int i = 0; i < 10; ++i) {
+ z4.push_back(i);
+ }
+ }
+ {
+ std::vector<int> z5(20);
+ // CHECK-FIXES-NOT: z5.reserve(10);
+ // z5 is not constructed with default constructor.
+ for (int i = 0; i < 10; ++i) {
+ z5.push_back(i);
+ }
+ }
+ {
+ std::vector<int> z6;
+ // CHECK-FIXES-NOT: z6.reserve(10);
+ // For-loop is not started with 0.
+ for (int i = 1; i < 10; ++i) {
+ z6.push_back(i);
+ }
+ }
+ {
+ std::vector<int> z7;
+ // CHECK-FIXES-NOT: z7.reserve(t.size());
+ // z7 isn't referenced in for-loop body.
+ for (std::size_t i = 0; i < t.size(); ++i) {
+ t.push_back(i);
+ }
+ }
+ {
+ std::vector<int> z8;
+ int k;
+ // CHECK-FIXES-NOT: z8.reserve(10);
+ // For-loop isn't a fixable loop.
+ for (std::size_t i = 0; k < 10; ++i) {
+ z8.push_back(t[i]);
+ }
+ }
+ {
+ std::vector<int> z9;
+ // CHECK-FIXES-NOT: z9.reserve(i + 1);
+ // The loop end expression refers to the loop variable i.
+ for (int i = 0; i < i + 1; i++)
+ z9.push_back(i);
+ }
+ {
+ std::vector<int> z10;
+ int k;
+ // CHECK-FIXES-NOT: z10.reserve(10);
+ // For-loop isn't a fixable loop.
+ for (std::size_t i = 0; i < 10; ++k) {
+ z10.push_back(t[i]);
+ }
+ }
+ {
+ std::vector<int> z11;
+ // initializer_list should not trigger the check.
+ for (int e : {1, 2, 3, 4, 5}) {
+ z11.push_back(e);
+ }
+ }
+ {
+ std::vector<int> z12;
+ std::vector<int>* z13 = &t;
+ // We only support detecting the range init expression which references
+ // container directly.
+ // Complex range init expressions like `*z13` is not supported.
+ for (const auto &e : *z13) {
+ z12.push_back(e);
+ }
+ }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-move-const-arg-trivially-copyable.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-move-const-arg-trivially-copyable.cpp
new file mode 100644
index 0000000..ea0c2fc
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-move-const-arg-trivially-copyable.cpp
@@ -0,0 +1,98 @@
+// RUN: %check_clang_tidy %s performance-move-const-arg %t \
+// RUN: -config='{CheckOptions: \
+// RUN: [{key: performance-move-const-arg.CheckTriviallyCopyableMove, value: 0}]}' \
+// RUN: -- -std=c++14
+
+namespace std {
+
+template <typename> struct remove_reference;
+template <typename _Tp> struct remove_reference { typedef _Tp type; };
+template <typename _Tp> struct remove_reference<_Tp &> { typedef _Tp type; };
+template <typename _Tp> struct remove_reference<_Tp &&> { typedef _Tp type; };
+
+template <typename _Tp>
+constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) {
+ return static_cast<typename std::remove_reference<_Tp>::type &&>(__t);
+}
+
+template <typename _Tp>
+constexpr _Tp &&
+forward(typename remove_reference<_Tp>::type &__t) noexcept {
+ return static_cast<_Tp &&>(__t);
+}
+
+} // namespace std
+
+class NoMoveSemantics {
+ public:
+ NoMoveSemantics();
+ NoMoveSemantics(const NoMoveSemantics &);
+
+ NoMoveSemantics &operator=(const NoMoveSemantics &);
+};
+
+void callByConstRef(const NoMoveSemantics &);
+void callByConstRef(int i, const NoMoveSemantics &);
+
+void moveToConstReferencePositives() {
+ NoMoveSemantics obj;
+
+ // Basic case. It is here just to have a single "detected and fixed" case.
+ callByConstRef(std::move(obj));
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: passing result of std::move() as a const reference argument; no move will actually happen [performance-move-const-arg]
+ // CHECK-FIXES: callByConstRef(obj);
+}
+
+struct TriviallyCopyable {
+ int i;
+};
+
+void f(TriviallyCopyable) {}
+
+void g() {
+ TriviallyCopyable obj;
+ f(std::move(obj));
+}
+
+class MoveSemantics {
+ public:
+ MoveSemantics();
+ MoveSemantics(MoveSemantics &&);
+
+ MoveSemantics &operator=(MoveSemantics &&);
+};
+
+void fmovable(MoveSemantics);
+
+void lambda1() {
+ auto f = [](MoveSemantics m) {
+ fmovable(std::move(m));
+ };
+ f(MoveSemantics());
+}
+
+template<class T> struct function {};
+
+template<typename Result, typename... Args>
+class function<Result(Args...)> {
+public:
+ function() = default;
+ void operator()(Args... args) const {
+ fmovable(std::forward<Args>(args)...);
+ }
+};
+
+void functionInvocation() {
+ function<void(MoveSemantics)> callback;
+ MoveSemantics m;
+ callback(std::move(m));
+}
+
+void lambda2() {
+ function<void(MoveSemantics)> callback;
+
+ auto f = [callback = std::move(callback)](MoveSemantics m) mutable {
+ callback(std::move(m));
+ };
+ f(MoveSemantics());
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-move-const-arg.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-move-const-arg.cpp
new file mode 100644
index 0000000..06ed6e0
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-move-const-arg.cpp
@@ -0,0 +1,248 @@
+// RUN: %check_clang_tidy %s performance-move-const-arg %t
+
+namespace std {
+template <typename>
+struct remove_reference;
+
+template <typename _Tp>
+struct remove_reference {
+ typedef _Tp type;
+};
+
+template <typename _Tp>
+struct remove_reference<_Tp &> {
+ typedef _Tp type;
+};
+
+template <typename _Tp>
+struct remove_reference<_Tp &&> {
+ typedef _Tp type;
+};
+
+template <typename _Tp>
+constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) {
+ return static_cast<typename std::remove_reference<_Tp>::type &&>(__t);
+}
+
+template <typename _Tp>
+constexpr _Tp &&
+forward(typename remove_reference<_Tp>::type &__t) noexcept {
+ return static_cast<_Tp &&>(__t);
+}
+
+} // namespace std
+
+class A {
+public:
+ A() {}
+ A(const A &rhs) {}
+ A(A &&rhs) {}
+};
+
+struct TriviallyCopyable {
+ int i;
+};
+
+void f(TriviallyCopyable) {}
+
+void g() {
+ TriviallyCopyable obj;
+ f(std::move(obj));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: std::move of the variable 'obj' of the trivially-copyable type 'TriviallyCopyable' has no effect; remove std::move() [performance-move-const-arg]
+ // CHECK-FIXES: f(obj);
+}
+
+int f1() {
+ return std::move(42);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the expression of the trivially-copyable type 'int' has no effect; remove std::move() [performance-move-const-arg]
+ // CHECK-FIXES: return 42;
+}
+
+int f2(int x2) {
+ return std::move(x2);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the variable 'x2' of the trivially-copyable type 'int'
+ // CHECK-FIXES: return x2;
+}
+
+int *f3(int *x3) {
+ return std::move(x3);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the variable 'x3' of the trivially-copyable type 'int *'
+ // CHECK-FIXES: return x3;
+}
+
+A f4(A x4) { return std::move(x4); }
+
+A f5(const A x5) {
+ return std::move(x5);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the const variable 'x5' has no effect; remove std::move() or make the variable non-const [performance-move-const-arg]
+ // CHECK-FIXES: return x5;
+}
+
+template <typename T>
+T f6(const T x6) {
+ return std::move(x6);
+}
+
+void f7() { int a = f6(10); }
+
+#define M1(x) x
+void f8() {
+ const A a;
+ M1(A b = std::move(a);)
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: std::move of the const variable 'a' has no effect; remove std::move() or make the variable non-const
+ // CHECK-FIXES: M1(A b = a;)
+}
+
+#define M2(x) std::move(x)
+int f9() { return M2(1); }
+
+template <typename T>
+T f10(const int x10) {
+ return std::move(x10);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the const variable 'x10' of the trivially-copyable type 'const int' has no effect; remove std::move() [performance-move-const-arg]
+ // CHECK-FIXES: return x10;
+}
+void f11() {
+ f10<int>(1);
+ f10<double>(1);
+}
+
+class NoMoveSemantics {
+public:
+ NoMoveSemantics();
+ NoMoveSemantics(const NoMoveSemantics &);
+
+ NoMoveSemantics &operator=(const NoMoveSemantics &);
+};
+
+void callByConstRef(const NoMoveSemantics &);
+void callByConstRef(int i, const NoMoveSemantics &);
+
+void moveToConstReferencePositives() {
+ NoMoveSemantics obj;
+
+ // Basic case.
+ callByConstRef(std::move(obj));
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: passing result of std::move() as
+ // CHECK-FIXES: callByConstRef(obj);
+
+ // Also works for second argument.
+ callByConstRef(1, std::move(obj));
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: passing result of std::move() as
+ // CHECK-FIXES: callByConstRef(1, obj);
+
+ // Works if std::move() applied to a temporary.
+ callByConstRef(std::move(NoMoveSemantics()));
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: passing result of std::move() as
+ // CHECK-FIXES: callByConstRef(NoMoveSemantics());
+
+ // Works if calling a copy constructor.
+ NoMoveSemantics other(std::move(obj));
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: passing result of std::move() as
+ // CHECK-FIXES: NoMoveSemantics other(obj);
+
+ // Works if calling assignment operator.
+ other = std::move(obj);
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: passing result of std::move() as
+ // CHECK-FIXES: other = obj;
+}
+
+class MoveSemantics {
+public:
+ MoveSemantics();
+ MoveSemantics(MoveSemantics &&);
+
+ MoveSemantics &operator=(MoveSemantics &&);
+};
+
+void callByValue(MoveSemantics);
+
+void callByRValueRef(MoveSemantics &&);
+
+template <class T>
+void templateFunction(T obj) {
+ T other = std::move(obj);
+}
+
+#define M3(T, obj) \
+ do { \
+ T other = std::move(obj); \
+ } while (true)
+
+#define CALL(func) (func)()
+
+void moveToConstReferenceNegatives() {
+ // No warning when actual move takes place.
+ MoveSemantics move_semantics;
+ callByValue(std::move(move_semantics));
+ callByRValueRef(std::move(move_semantics));
+ MoveSemantics other(std::move(move_semantics));
+ other = std::move(move_semantics);
+
+ // No warning if std::move() not used.
+ NoMoveSemantics no_move_semantics;
+ callByConstRef(no_move_semantics);
+
+ // No warning if instantiating a template.
+ templateFunction(no_move_semantics);
+
+ // No warning inside of macro expansions.
+ M3(NoMoveSemantics, no_move_semantics);
+
+ // No warning inside of macro expansion, even if the macro expansion is inside
+ // a lambda that is, in turn, an argument to a macro.
+ CALL([no_move_semantics] { M3(NoMoveSemantics, no_move_semantics); });
+
+ auto lambda = [] {};
+ auto lambda2 = std::move(lambda);
+}
+
+class MoveOnly {
+public:
+ MoveOnly(const MoveOnly &other) = delete;
+ MoveOnly &operator=(const MoveOnly &other) = delete;
+ MoveOnly(MoveOnly &&other) = default;
+ MoveOnly &operator=(MoveOnly &&other) = default;
+};
+template <class T>
+void Q(T);
+void moveOnlyNegatives(MoveOnly val) {
+ Q(std::move(val));
+}
+
+void fmovable(MoveSemantics);
+
+void lambda1() {
+ auto f = [](MoveSemantics m) {
+ fmovable(std::move(m));
+ };
+ f(MoveSemantics());
+}
+
+template<class T> struct function {};
+
+template<typename Result, typename... Args>
+class function<Result(Args...)> {
+public:
+ function() = default;
+ void operator()(Args... args) const {
+ fmovable(std::forward<Args>(args)...);
+ }
+};
+
+void functionInvocation() {
+ function<void(MoveSemantics)> callback;
+ MoveSemantics m;
+ callback(std::move(m));
+}
+
+void lambda2() {
+ function<void(MoveSemantics)> callback;
+
+ auto f = [callback = std::move(callback)](MoveSemantics m) mutable {
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: std::move of the variable 'callback' of the trivially-copyable type 'function<void (MoveSemantics)>' has no effect; remove std::move()
+ // CHECK-FIXES: auto f = [callback = callback](MoveSemantics m) mutable {
+ callback(std::move(m));
+ };
+ f(MoveSemantics());
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-move-constructor-init.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-move-constructor-init.cpp
new file mode 100644
index 0000000..09108fc
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-move-constructor-init.cpp
@@ -0,0 +1,156 @@
+// RUN: %check_clang_tidy %s performance-move-constructor-init,modernize-pass-by-value %t -- \
+// RUN: -config='{CheckOptions: \
+// RUN: [{key: modernize-pass-by-value.ValuesOnly, value: 1}]}' \
+// RUN: -- -std=c++11 -isystem %S/Inputs/Headers
+
+#include <s.h>
+
+// CHECK-FIXES: #include <utility>
+
+template <class T> struct remove_reference {typedef T type;};
+template <class T> struct remove_reference<T&> {typedef T type;};
+template <class T> struct remove_reference<T&&> {typedef T type;};
+
+template <typename T>
+typename remove_reference<T>::type&& move(T&& arg) {
+ return static_cast<typename remove_reference<T>::type&&>(arg);
+}
+
+struct C {
+ C() = default;
+ C(const C&) = default;
+};
+
+struct B {
+ B() {}
+ B(const B&) {}
+ B(B &&) {}
+};
+
+struct D : B {
+ D() : B() {}
+ D(const D &RHS) : B(RHS) {}
+ // CHECK-NOTES: :[[@LINE+3]]:16: warning: move constructor initializes base class by calling a copy constructor [performance-move-constructor-init]
+ // CHECK-NOTES: 26:3: note: copy constructor being called
+ // CHECK-NOTES: 27:3: note: candidate move constructor here
+ D(D &&RHS) : B(RHS) {}
+};
+
+struct E : B {
+ E() : B() {}
+ E(const E &RHS) : B(RHS) {}
+ E(E &&RHS) : B(move(RHS)) {} // ok
+};
+
+struct F {
+ C M;
+
+ F(F &&) : M(C()) {} // ok
+};
+
+struct G {
+ G() = default;
+ G(const G&) = default;
+ G(G&&) = delete;
+};
+
+struct H : G {
+ H() = default;
+ H(const H&) = default;
+ H(H &&RHS) : G(RHS) {} // ok
+};
+
+struct I {
+ I(const I &) = default; // suppresses move constructor creation
+};
+
+struct J : I {
+ J(J &&RHS) : I(RHS) {} // ok
+};
+
+struct K {}; // Has implicit copy and move constructors, is trivially copyable
+struct L : K {
+ L(L &&RHS) : K(RHS) {} // ok
+};
+
+struct M {
+ B Mem;
+ // CHECK-NOTES: :[[@LINE+1]]:16: warning: move constructor initializes class member by calling a copy constructor [performance-move-constructor-init]
+ M(M &&RHS) : Mem(RHS.Mem) {}
+ // CHECK-NOTES: 26:3: note: copy constructor being called
+ // CHECK-NOTES: 27:3: note: candidate move constructor here
+};
+
+struct N {
+ B Mem;
+ N(N &&RHS) : Mem(move(RHS.Mem)) {}
+};
+
+struct O {
+ O(O&& other) : b(other.b) {} // ok
+ const B b;
+};
+
+struct P {
+ P(O&& other) : b(other.b) {} // ok
+ B b;
+};
+
+struct Movable {
+ Movable(Movable &&) = default;
+ Movable(const Movable &) = default;
+ Movable &operator=(const Movable &) = default;
+ ~Movable() {}
+};
+
+struct TriviallyCopyable {
+ TriviallyCopyable() = default;
+ TriviallyCopyable(TriviallyCopyable &&) = default;
+ TriviallyCopyable(const TriviallyCopyable &) = default;
+};
+
+struct Positive {
+ Positive(Movable M) : M_(M) {}
+ // CHECK-NOTES: [[@LINE-1]]:12: warning: pass by value and use std::move [modernize-pass-by-value]
+ // CHECK-FIXES: Positive(Movable M) : M_(std::move(M)) {}
+ Movable M_;
+};
+
+struct NegativeMultipleInitializerReferences {
+ NegativeMultipleInitializerReferences(Movable M) : M_(M), n_(M) {}
+ Movable M_;
+ Movable n_;
+};
+
+struct NegativeReferencedInConstructorBody {
+ NegativeReferencedInConstructorBody(Movable M) : M_(M) { M_ = M; }
+ Movable M_;
+};
+
+struct NegativeParamTriviallyCopyable {
+ NegativeParamTriviallyCopyable(TriviallyCopyable T) : T_(T) {}
+ NegativeParamTriviallyCopyable(int I) : I_(I) {}
+
+ TriviallyCopyable T_;
+ int I_;
+};
+
+struct NegativeNotPassedByValue {
+ // This const ref constructor isn't warned about because the ValuesOnly option is set.
+ NegativeNotPassedByValue(const Movable &M) : M_(M) {}
+ NegativeNotPassedByValue(const Movable M) : M_(M) {}
+ NegativeNotPassedByValue(Movable &M) : M_(M) {}
+ NegativeNotPassedByValue(Movable *M) : M_(*M) {}
+ NegativeNotPassedByValue(const Movable *M) : M_(*M) {}
+ Movable M_;
+};
+
+struct Immovable {
+ Immovable(const Immovable &) = default;
+ Immovable(Immovable &&) = delete;
+};
+
+struct NegativeImmovableParameter {
+ NegativeImmovableParameter(Immovable I) : I_(I) {}
+ Immovable I_;
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-noexcept-move-constructor.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-noexcept-move-constructor.cpp
new file mode 100644
index 0000000..70d7065
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-noexcept-move-constructor.cpp
@@ -0,0 +1,54 @@
+// RUN: %check_clang_tidy %s performance-noexcept-move-constructor %t
+
+class A {
+ A(A &&);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: move constructors should be marked noexcept [performance-noexcept-move-constructor]
+ A &operator=(A &&);
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: move assignment operators should
+};
+
+struct B {
+ static constexpr bool kFalse = false;
+ B(B &&) noexcept(kFalse);
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: noexcept specifier on the move constructor evaluates to 'false' [performance-noexcept-move-constructor]
+};
+
+class OK {};
+
+void f() {
+ OK a;
+ a = OK();
+}
+
+class OK1 {
+public:
+ OK1();
+ OK1(const OK1 &);
+ OK1(OK1 &&) noexcept;
+ OK1 &operator=(OK1 &&) noexcept;
+ void f();
+ void g() noexcept;
+};
+
+class OK2 {
+ static constexpr bool kTrue = true;
+
+public:
+ OK2(OK2 &&) noexcept(true) {}
+ OK2 &operator=(OK2 &&) noexcept(kTrue) { return *this; }
+};
+
+struct OK3 {
+ OK3(OK3 &&) noexcept(false) {}
+ OK3 &operator=(OK3 &&) = delete;
+};
+
+struct OK4 {
+ OK4(OK4 &&) noexcept = default;
+ OK4 &operator=(OK4 &&) noexcept = default;
+};
+
+struct OK5 {
+ OK5(OK5 &&) noexcept(true) = default;
+ OK5 &operator=(OK5 &&) noexcept(true) = default;
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-type-promotion-in-math-fn.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-type-promotion-in-math-fn.cpp
new file mode 100644
index 0000000..b2da7cc
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-type-promotion-in-math-fn.cpp
@@ -0,0 +1,316 @@
+// RUN: %check_clang_tidy %s performance-type-promotion-in-math-fn %t
+
+// CHECK-FIXES: #include <cmath>
+
+double acos(double);
+double acosh(double);
+double asin(double);
+double asinh(double);
+double atan2(double, double);
+double atan(double);
+double atanh(double);
+double cbrt(double);
+double ceil(double);
+double copysign(double, double);
+double cos(double);
+double cosh(double);
+double erfc(double);
+double erf(double);
+double exp2(double);
+double exp(double);
+double expm1(double);
+double fabs(double);
+double fdim(double, double);
+double floor(double);
+double fma(double, double, double);
+double fmax(double, double);
+double fmin(double, double);
+double fmod(double, double);
+double frexp(double, int *);
+double hypot(double, double);
+double ilogb(double);
+double ldexp(double, double);
+double lgamma(double);
+long long llrint(double);
+double log10(double);
+double log1p(double);
+double log2(double);
+double logb(double);
+double log(double);
+long lrint(double);
+double modf(double);
+double nearbyint(double);
+double nextafter(double, double);
+double nexttoward(double, long double);
+double pow(double, double);
+double remainder(double, double);
+double remquo(double, double, int *);
+double rint(double);
+double round(double);
+double scalbln(double, long);
+double scalbn(double, int);
+double sin(double);
+double sinh(double);
+double sqrt(double);
+double tan(double);
+double tanh(double);
+double tgamma(double);
+double trunc(double);
+long long llround(double);
+long lround(double);
+
+void check_all_fns() {
+ float a, b, c;
+ int i;
+ long l;
+ int *int_ptr;
+
+ acos(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'acos' promotes float to double [performance-type-promotion-in-math-fn]
+ // CHECK-FIXES: {{^}} std::acos(a);{{$}}
+ acosh(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'acosh'
+ // CHECK-FIXES: {{^}} std::acosh(a);{{$}}
+ asin(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'asin'
+ // CHECK-FIXES: {{^}} std::asin(a);{{$}}
+ asinh(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'asinh'
+ // CHECK-FIXES: {{^}} std::asinh(a);{{$}}
+ atan2(a, b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'atan2'
+ // CHECK-FIXES: {{^}} std::atan2(a, b);{{$}}
+ atan(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'atan'
+ // CHECK-FIXES: {{^}} std::atan(a);{{$}}
+ atanh(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'atanh'
+ // CHECK-FIXES: {{^}} std::atanh(a);{{$}}
+ cbrt(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'cbrt'
+ // CHECK-FIXES: {{^}} std::cbrt(a);{{$}}
+ ceil(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'ceil'
+ // CHECK-FIXES: {{^}} std::ceil(a);{{$}}
+ copysign(a, b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'copysign'
+ // CHECK-FIXES: {{^}} std::copysign(a, b);{{$}}
+ cos(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'cos'
+ // CHECK-FIXES: {{^}} std::cos(a);{{$}}
+ cosh(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'cosh'
+ // CHECK-FIXES: {{^}} std::cosh(a);{{$}}
+ erf(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'erf'
+ // CHECK-FIXES: {{^}} std::erf(a);{{$}}
+ erfc(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'erfc'
+ // CHECK-FIXES: {{^}} std::erfc(a);{{$}}
+ exp2(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'exp2'
+ // CHECK-FIXES: {{^}} std::exp2(a);{{$}}
+ exp(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'exp'
+ // CHECK-FIXES: {{^}} std::exp(a);{{$}}
+ expm1(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'expm1'
+ // CHECK-FIXES: {{^}} std::expm1(a);{{$}}
+ fabs(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'fabs'
+ // CHECK-FIXES: {{^}} std::fabs(a);{{$}}
+ fdim(a, b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'fdim'
+ // CHECK-FIXES: {{^}} std::fdim(a, b);{{$}}
+ floor(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'floor'
+ // CHECK-FIXES: {{^}} std::floor(a);{{$}}
+ fma(a, b, c);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'fma'
+ // CHECK-FIXES: {{^}} std::fma(a, b, c);{{$}}
+ fmax(a, b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'fmax'
+ // CHECK-FIXES: {{^}} std::fmax(a, b);{{$}}
+ fmin(a, b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'fmin'
+ // CHECK-FIXES: {{^}} std::fmin(a, b);{{$}}
+ fmod(a, b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'fmod'
+ // CHECK-FIXES: {{^}} std::fmod(a, b);{{$}}
+ frexp(a, int_ptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'frexp'
+ // CHECK-FIXES: {{^}} std::frexp(a, int_ptr);{{$}}
+ hypot(a, b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'hypot'
+ // CHECK-FIXES: {{^}} std::hypot(a, b);{{$}}
+ ilogb(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'ilogb'
+ // CHECK-FIXES: {{^}} std::ilogb(a);{{$}}
+ ldexp(a, b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'ldexp'
+ // CHECK-FIXES: {{^}} std::ldexp(a, b);{{$}}
+ lgamma(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'lgamma'
+ // CHECK-FIXES: {{^}} std::lgamma(a);{{$}}
+ llrint(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'llrint'
+ // CHECK-FIXES: {{^}} std::llrint(a);{{$}}
+ llround(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'llround'
+ // CHECK-FIXES: {{^}} std::llround(a);{{$}}
+ log10(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'log10'
+ // CHECK-FIXES: {{^}} std::log10(a);{{$}}
+ log1p(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'log1p'
+ // CHECK-FIXES: {{^}} std::log1p(a);{{$}}
+ log2(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'log2'
+ // CHECK-FIXES: {{^}} std::log2(a);{{$}}
+ log(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'log'
+ // CHECK-FIXES: {{^}} std::log(a);{{$}}
+ logb(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'logb'
+ // CHECK-FIXES: {{^}} std::logb(a);{{$}}
+ lrint(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'lrint'
+ // CHECK-FIXES: {{^}} std::lrint(a);{{$}}
+ lround(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'lround'
+ // CHECK-FIXES: {{^}} std::lround(a);{{$}}
+ nearbyint(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'nearbyint'
+ // CHECK-FIXES: {{^}} std::nearbyint(a);{{$}}
+ nextafter(a, b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'nextafter'
+ // CHECK-FIXES: {{^}} std::nextafter(a, b);{{$}}
+ nexttoward(a, b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'nexttoward'
+ // CHECK-FIXES: {{^}} std::nexttoward(a, b);{{$}}
+ pow(a, b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'pow'
+ // CHECK-FIXES: {{^}} std::pow(a, b);{{$}}
+ remainder(a, b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'remainder'
+ // CHECK-FIXES: {{^}} std::remainder(a, b);{{$}}
+ remquo(a, b, int_ptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'remquo'
+ // CHECK-FIXES: {{^}} std::remquo(a, b, int_ptr);{{$}}
+ rint(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'rint'
+ // CHECK-FIXES: {{^}} std::rint(a);{{$}}
+ round(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'round'
+ // CHECK-FIXES: {{^}} std::round(a);{{$}}
+ scalbln(a, l);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'scalbln'
+ // CHECK-FIXES: {{^}} std::scalbln(a, l);{{$}}
+ scalbn(a, i);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'scalbn'
+ // CHECK-FIXES: {{^}} std::scalbn(a, i);{{$}}
+ sin(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'sin'
+ // CHECK-FIXES: {{^}} std::sin(a);{{$}}
+ sinh(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'sinh'
+ // CHECK-FIXES: {{^}} std::sinh(a);{{$}}
+ sqrt(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'sqrt'
+ // CHECK-FIXES: {{^}} std::sqrt(a);{{$}}
+ tan(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'tan'
+ // CHECK-FIXES: {{^}} std::tan(a);{{$}}
+ tanh(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'tanh'
+ // CHECK-FIXES: {{^}} std::tanh(a);{{$}}
+ tgamma(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'tgamma'
+ // CHECK-FIXES: {{^}} std::tgamma(a);{{$}}
+ trunc(a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'trunc'
+ // CHECK-FIXES: {{^}} std::trunc(a);{{$}}
+}
+
+// nexttoward/nexttowardf are weird -- the second param is always long double.
+// So we warn if the first arg is a float, regardless of what the second arg is.
+void check_nexttoward() {
+ nexttoward(0.f, 0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'nexttoward'
+ // CHECK-FIXES: {{^}} std::nexttoward(0.f, 0);{{$}}
+ nexttoward(0.f, 0l);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'nexttoward'
+ // CHECK-FIXES: {{^}} std::nexttoward(0.f, 0l);{{$}}
+ nexttoward(0.f, 0.f);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'nexttoward'
+ // CHECK-FIXES: {{^}} std::nexttoward(0.f, 0.f);{{$}}
+ nexttoward(0.f, 0.);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'nexttoward'
+ // CHECK-FIXES: {{^}} std::nexttoward(0.f, 0.);{{$}}
+
+ // No warnings for these.
+ nexttoward(0., 0);
+ nexttoward(0., 0.f);
+ nexttoward(0., 0.);
+}
+
+// The second parameter to scalbn and scalbnf is an int, so we don't care what
+// type you pass as that argument; we warn iff the first argument is a float.
+void check_scalbn() {
+ scalbn(0.f, 0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'scalbn'
+ // CHECK-FIXES: {{^}} std::scalbn(0.f, 0);{{$}}
+ scalbn(0.f, static_cast<char>(0));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'scalbn'
+ // CHECK-FIXES: {{^}} std::scalbn(0.f, static_cast<char>(0));{{$}}
+
+ // No warnings for these.
+ scalbn(0., 0);
+ scalbn(0., static_cast<char>(0));
+}
+
+// scalbln/scalblnf are like scalbn/scalbnf except their second arg is a long.
+// Again, doesn't matter what we pass for the second arg; we warn iff the first
+// arg is a float.
+void check_scalbln() {
+ scalbln(0.f, 0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'scalbln'
+ // CHECK-FIXES: {{^}} std::scalbln(0.f, 0);{{$}}
+ scalbln(0.f, 0l);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: call to 'scalbln'
+ // CHECK-FIXES: {{^}} std::scalbln(0.f, 0l);{{$}}
+
+ // No warnings for these.
+ scalbln(0., 0);
+ scalbln(0., 0l);
+}
+
+float cosf(float);
+double foo(double); // not a math.h function
+float cos(float); // not a math.h function (wrong signature)
+double cos(double, double); // not a math.h function (wrong signature)
+
+namespace std {
+void cos(float);
+} // namespace std
+
+void check_no_warnings() {
+ foo(0.); // no warning because not a math.h function.
+
+ sin(0); // no warning because arg is an int
+ cos(0.); // no warning because arg is a double
+ std::cos(0.f); // no warning because not ::cos.
+ cosf(0.f); // no warning; we expect this to take a float
+ cos(0.f); // does not match the expected signature of ::cos
+ cos(0.f, 0.f); // does not match the expected signature of ::cos
+
+ // No warnings because all args are not floats.
+ remainder(0., 0.f);
+ remainder(0.f, 0.);
+ remainder(0, 0.f);
+ remainder(0.f, 0);
+ fma(0.f, 0.f, 0);
+ fma(0.f, 0.f, 0.);
+ fma(0.f, 0., 0.f);
+ fma(0., 0.f, 0.f);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-copy-initialization-allowed-types.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-copy-initialization-allowed-types.cpp
new file mode 100644
index 0000000..420efa8
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-copy-initialization-allowed-types.cpp
@@ -0,0 +1,98 @@
+// RUN: %check_clang_tidy %s performance-unnecessary-copy-initialization %t -- -config="{CheckOptions: [{key: performance-unnecessary-copy-initialization.AllowedTypes, value: '[Pp]ointer$;[Pp]tr$;[Rr]ef(erence)?$'}]}" --
+
+struct SmartPointer {
+ ~SmartPointer();
+};
+
+struct smart_pointer {
+ ~smart_pointer();
+};
+
+struct SmartPtr {
+ ~SmartPtr();
+};
+
+struct smart_ptr {
+ ~smart_ptr();
+};
+
+struct SmartReference {
+ ~SmartReference();
+};
+
+struct smart_reference {
+ ~smart_reference();
+};
+
+struct SmartRef {
+ ~SmartRef();
+};
+
+struct smart_ref {
+ ~smart_ref();
+};
+
+struct OtherType {
+ ~OtherType();
+};
+
+template <typename T> struct SomeComplexTemplate {
+ ~SomeComplexTemplate();
+};
+
+typedef SomeComplexTemplate<int> NotTooComplexRef;
+
+const SmartPointer &getSmartPointer();
+const smart_pointer &get_smart_pointer();
+const SmartPtr &getSmartPtr();
+const smart_ptr &get_smart_ptr();
+const SmartReference &getSmartReference();
+const smart_reference &get_smart_reference();
+const SmartRef &getSmartRef();
+const smart_ref &get_smart_ref();
+const OtherType &getOtherType();
+const NotTooComplexRef &getNotTooComplexRef();
+
+void negativeSmartPointer() {
+ const auto P = getSmartPointer();
+}
+
+void negative_smart_pointer() {
+ const auto p = get_smart_pointer();
+}
+
+void negativeSmartPtr() {
+ const auto P = getSmartPtr();
+}
+
+void negative_smart_ptr() {
+ const auto p = get_smart_ptr();
+}
+
+void negativeSmartReference() {
+ const auto R = getSmartReference();
+}
+
+void negative_smart_reference() {
+ const auto r = get_smart_reference();
+}
+
+void negativeSmartRef() {
+ const auto R = getSmartRef();
+}
+
+void negative_smart_ref() {
+ const auto r = get_smart_ref();
+}
+
+void positiveOtherType() {
+ const auto O = getOtherType();
+ // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'O' is copy-constructed from a const reference; consider making it a const reference [performance-unnecessary-copy-initialization]
+ // CHECK-FIXES: const auto& O = getOtherType();
+}
+
+void negativeNotTooComplexRef() {
+ const NotTooComplexRef R = getNotTooComplexRef();
+ // Using `auto` here would result in the "canonical" type which does not match
+ // the pattern.
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-copy-initialization.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-copy-initialization.cpp
new file mode 100644
index 0000000..50dcfd8
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-copy-initialization.cpp
@@ -0,0 +1,389 @@
+// RUN: %check_clang_tidy %s performance-unnecessary-copy-initialization %t
+
+struct ExpensiveToCopyType {
+ ExpensiveToCopyType();
+ virtual ~ExpensiveToCopyType();
+ const ExpensiveToCopyType &reference() const;
+ void nonConstMethod();
+ bool constMethod() const;
+};
+
+struct TrivialToCopyType {
+ const TrivialToCopyType &reference() const;
+};
+
+struct WeirdCopyCtorType {
+ WeirdCopyCtorType();
+ WeirdCopyCtorType(const WeirdCopyCtorType &w, bool oh_yes = true);
+
+ void nonConstMethod();
+ bool constMethod() const;
+};
+
+ExpensiveToCopyType global_expensive_to_copy_type;
+
+const ExpensiveToCopyType &ExpensiveTypeReference();
+const TrivialToCopyType &TrivialTypeReference();
+
+void mutate(ExpensiveToCopyType &);
+void mutate(ExpensiveToCopyType *);
+void useAsConstPointer(const ExpensiveToCopyType *);
+void useAsConstReference(const ExpensiveToCopyType &);
+void useByValue(ExpensiveToCopyType);
+
+void PositiveFunctionCall() {
+ const auto AutoAssigned = ExpensiveTypeReference();
+ // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned' is copy-constructed from a const reference; consider making it a const reference [performance-unnecessary-copy-initialization]
+ // CHECK-FIXES: const auto& AutoAssigned = ExpensiveTypeReference();
+ const auto AutoCopyConstructed(ExpensiveTypeReference());
+ // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoCopyConstructed'
+ // CHECK-FIXES: const auto& AutoCopyConstructed(ExpensiveTypeReference());
+ const ExpensiveToCopyType VarAssigned = ExpensiveTypeReference();
+ // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarAssigned'
+ // CHECK-FIXES: const ExpensiveToCopyType& VarAssigned = ExpensiveTypeReference();
+ const ExpensiveToCopyType VarCopyConstructed(ExpensiveTypeReference());
+ // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarCopyConstructed'
+ // CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(ExpensiveTypeReference());
+}
+
+void PositiveMethodCallConstReferenceParam(const ExpensiveToCopyType &Obj) {
+ const auto AutoAssigned = Obj.reference();
+ // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
+ // CHECK-FIXES: const auto& AutoAssigned = Obj.reference();
+ const auto AutoCopyConstructed(Obj.reference());
+ // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoCopyConstructed'
+ // CHECK-FIXES: const auto& AutoCopyConstructed(Obj.reference());
+ const ExpensiveToCopyType VarAssigned = Obj.reference();
+ // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarAssigned'
+ // CHECK-FIXES: const ExpensiveToCopyType& VarAssigned = Obj.reference();
+ const ExpensiveToCopyType VarCopyConstructed(Obj.reference());
+ // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarCopyConstructed'
+ // CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(Obj.reference());
+}
+
+void PositiveMethodCallConstParam(const ExpensiveToCopyType Obj) {
+ const auto AutoAssigned = Obj.reference();
+ // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
+ // CHECK-FIXES: const auto& AutoAssigned = Obj.reference();
+ const auto AutoCopyConstructed(Obj.reference());
+ // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoCopyConstructed'
+ // CHECK-FIXES: const auto& AutoCopyConstructed(Obj.reference());
+ const ExpensiveToCopyType VarAssigned = Obj.reference();
+ // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarAssigned'
+ // CHECK-FIXES: const ExpensiveToCopyType& VarAssigned = Obj.reference();
+ const ExpensiveToCopyType VarCopyConstructed(Obj.reference());
+ // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarCopyConstructed'
+ // CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(Obj.reference());
+}
+
+void PositiveMethodCallConstPointerParam(const ExpensiveToCopyType *const Obj) {
+ const auto AutoAssigned = Obj->reference();
+ // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
+ // CHECK-FIXES: const auto& AutoAssigned = Obj->reference();
+ const auto AutoCopyConstructed(Obj->reference());
+ // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoCopyConstructed'
+ // CHECK-FIXES: const auto& AutoCopyConstructed(Obj->reference());
+ const ExpensiveToCopyType VarAssigned = Obj->reference();
+ // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarAssigned'
+ // CHECK-FIXES: const ExpensiveToCopyType& VarAssigned = Obj->reference();
+ const ExpensiveToCopyType VarCopyConstructed(Obj->reference());
+ // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarCopyConstructed'
+ // CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(Obj->reference());
+}
+
+void PositiveLocalConstValue() {
+ const ExpensiveToCopyType Obj;
+ const auto UnnecessaryCopy = Obj.reference();
+ // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'UnnecessaryCopy'
+ // CHECK-FIXES: const auto& UnnecessaryCopy = Obj.reference();
+}
+
+void PositiveLocalConstRef() {
+ const ExpensiveToCopyType Obj;
+ const ExpensiveToCopyType &ConstReference = Obj.reference();
+ const auto UnnecessaryCopy = ConstReference.reference();
+ // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'UnnecessaryCopy'
+ // CHECK-FIXES: const auto& UnnecessaryCopy = ConstReference.reference();
+}
+
+void PositiveLocalConstPointer() {
+ const ExpensiveToCopyType Obj;
+ const ExpensiveToCopyType *const ConstPointer = &Obj;
+ const auto UnnecessaryCopy = ConstPointer->reference();
+ // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'UnnecessaryCopy'
+ // CHECK-FIXES: const auto& UnnecessaryCopy = ConstPointer->reference();
+}
+
+void NegativeFunctionCallTrivialType() {
+ const auto AutoAssigned = TrivialTypeReference();
+ const auto AutoCopyConstructed(TrivialTypeReference());
+ const TrivialToCopyType VarAssigned = TrivialTypeReference();
+ const TrivialToCopyType VarCopyConstructed(TrivialTypeReference());
+}
+
+void NegativeStaticLocalVar(const ExpensiveToCopyType &Obj) {
+ static const auto StaticVar = Obj.reference();
+}
+
+void PositiveFunctionCallExpensiveTypeNonConstVariable() {
+ auto AutoAssigned = ExpensiveTypeReference();
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: the variable 'AutoAssigned' is copy-constructed from a const reference but is only used as const reference; consider making it a const reference [performance-unnecessary-copy-initialization]
+ // CHECK-FIXES: const auto& AutoAssigned = ExpensiveTypeReference();
+ auto AutoCopyConstructed(ExpensiveTypeReference());
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: the variable 'AutoCopyConstructed'
+ // CHECK-FIXES: const auto& AutoCopyConstructed(ExpensiveTypeReference());
+ ExpensiveToCopyType VarAssigned = ExpensiveTypeReference();
+ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: the variable 'VarAssigned'
+ // CHECK-FIXES: const ExpensiveToCopyType& VarAssigned = ExpensiveTypeReference();
+ ExpensiveToCopyType VarCopyConstructed(ExpensiveTypeReference());
+ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: the variable 'VarCopyConstructed'
+ // CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(ExpensiveTypeReference());
+}
+
+void positiveNonConstVarInCodeBlock(const ExpensiveToCopyType &Obj) {
+ {
+ auto Assigned = Obj.reference();
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: the variable 'Assigned'
+ // CHECK-FIXES: const auto& Assigned = Obj.reference();
+ Assigned.reference();
+ useAsConstReference(Assigned);
+ useByValue(Assigned);
+ }
+}
+
+void negativeNonConstVarWithNonConstUse(const ExpensiveToCopyType &Obj) {
+ {
+ auto NonConstInvoked = Obj.reference();
+ // CHECK-FIXES: auto NonConstInvoked = Obj.reference();
+ NonConstInvoked.nonConstMethod();
+ }
+ {
+ auto Reassigned = Obj.reference();
+ // CHECK-FIXES: auto Reassigned = Obj.reference();
+ Reassigned = ExpensiveToCopyType();
+ }
+ {
+ auto MutatedByReference = Obj.reference();
+ // CHECK-FIXES: auto MutatedByReference = Obj.reference();
+ mutate(MutatedByReference);
+ }
+ {
+ auto MutatedByPointer = Obj.reference();
+ // CHECK-FIXES: auto MutatedByPointer = Obj.reference();
+ mutate(&MutatedByPointer);
+ }
+}
+
+void PositiveMethodCallNonConstRefNotModified(ExpensiveToCopyType &Obj) {
+ const auto AutoAssigned = Obj.reference();
+ // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
+ // CHECK-FIXES: const auto& AutoAssigned = Obj.reference();
+}
+
+void NegativeMethodCallNonConstRefIsModified(ExpensiveToCopyType &Obj) {
+ const auto AutoAssigned = Obj.reference();
+ const auto AutoCopyConstructed(Obj.reference());
+ const ExpensiveToCopyType VarAssigned = Obj.reference();
+ const ExpensiveToCopyType VarCopyConstructed(Obj.reference());
+ mutate(&Obj);
+}
+
+void PositiveMethodCallNonConstNotModified(ExpensiveToCopyType Obj) {
+ const auto AutoAssigned = Obj.reference();
+ // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
+ // CHECK-FIXES: const auto& AutoAssigned = Obj.reference();
+}
+
+void NegativeMethodCallNonConstValueArgumentIsModified(ExpensiveToCopyType Obj) {
+ Obj.nonConstMethod();
+ const auto AutoAssigned = Obj.reference();
+}
+
+void PositiveMethodCallNonConstPointerNotModified(ExpensiveToCopyType *const Obj) {
+ const auto AutoAssigned = Obj->reference();
+ // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
+ // CHECK-FIXES: const auto& AutoAssigned = Obj->reference();
+ Obj->constMethod();
+}
+
+void NegativeMethodCallNonConstPointerIsModified(ExpensiveToCopyType *const Obj) {
+ const auto AutoAssigned = Obj->reference();
+ const auto AutoCopyConstructed(Obj->reference());
+ const ExpensiveToCopyType VarAssigned = Obj->reference();
+ const ExpensiveToCopyType VarCopyConstructed(Obj->reference());
+ mutate(Obj);
+}
+
+void PositiveLocalVarIsNotModified() {
+ ExpensiveToCopyType LocalVar;
+ const auto AutoAssigned = LocalVar.reference();
+ // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
+ // CHECK-FIXES: const auto& AutoAssigned = LocalVar.reference();
+}
+
+void NegativeLocalVarIsModified() {
+ ExpensiveToCopyType Obj;
+ const auto AutoAssigned = Obj.reference();
+ Obj = AutoAssigned;
+}
+
+struct NegativeConstructor {
+ NegativeConstructor(const ExpensiveToCopyType &Obj) : Obj(Obj) {}
+ ExpensiveToCopyType Obj;
+};
+
+#define UNNECESSARY_COPY_INIT_IN_MACRO_BODY(TYPE) \
+ void functionWith##TYPE(const TYPE &T) { \
+ auto AssignedInMacro = T.reference(); \
+ } \
+// Ensure fix is not applied.
+// CHECK-FIXES: auto AssignedInMacro = T.reference();
+
+UNNECESSARY_COPY_INIT_IN_MACRO_BODY(ExpensiveToCopyType)
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: the variable 'AssignedInMacro' is copy-constructed
+
+#define UNNECESSARY_COPY_INIT_IN_MACRO_ARGUMENT(ARGUMENT) ARGUMENT
+
+void PositiveMacroArgument(const ExpensiveToCopyType &Obj) {
+ UNNECESSARY_COPY_INIT_IN_MACRO_ARGUMENT(auto CopyInMacroArg = Obj.reference());
+ // CHECK-MESSAGES: [[@LINE-1]]:48: warning: the variable 'CopyInMacroArg' is copy-constructed
+ // Ensure fix is not applied.
+ // CHECK-FIXES: auto CopyInMacroArg = Obj.reference()
+}
+
+void PositiveLocalCopyConstMethodInvoked() {
+ ExpensiveToCopyType orig;
+ ExpensiveToCopyType copy_1 = orig;
+ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: local copy 'copy_1' of the variable 'orig' is never modified; consider avoiding the copy [performance-unnecessary-copy-initialization]
+ // CHECK-FIXES: const ExpensiveToCopyType& copy_1 = orig;
+ copy_1.constMethod();
+ orig.constMethod();
+}
+
+void PositiveLocalCopyUsingExplicitCopyCtor() {
+ ExpensiveToCopyType orig;
+ ExpensiveToCopyType copy_2(orig);
+ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: local copy 'copy_2'
+ // CHECK-FIXES: const ExpensiveToCopyType& copy_2(orig);
+ copy_2.constMethod();
+ orig.constMethod();
+}
+
+void PositiveLocalCopyCopyIsArgument(const ExpensiveToCopyType &orig) {
+ ExpensiveToCopyType copy_3 = orig;
+ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: local copy 'copy_3'
+ // CHECK-FIXES: const ExpensiveToCopyType& copy_3 = orig;
+ copy_3.constMethod();
+}
+
+void PositiveLocalCopyUsedAsConstRef() {
+ ExpensiveToCopyType orig;
+ ExpensiveToCopyType copy_4 = orig;
+ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: local copy 'copy_4'
+ // CHECK-FIXES: const ExpensiveToCopyType& copy_4 = orig;
+ useAsConstReference(orig);
+}
+
+void PositiveLocalCopyTwice() {
+ ExpensiveToCopyType orig;
+ ExpensiveToCopyType copy_5 = orig;
+ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: local copy 'copy_5'
+ // CHECK-FIXES: const ExpensiveToCopyType& copy_5 = orig;
+ ExpensiveToCopyType copy_6 = copy_5;
+ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: local copy 'copy_6'
+ // CHECK-FIXES: const ExpensiveToCopyType& copy_6 = copy_5;
+ copy_5.constMethod();
+ copy_6.constMethod();
+ orig.constMethod();
+}
+
+
+void PositiveLocalCopyWeirdCopy() {
+ WeirdCopyCtorType orig;
+ WeirdCopyCtorType weird_1(orig);
+ // CHECK-MESSAGES: [[@LINE-1]]:21: warning: local copy 'weird_1'
+ // CHECK-FIXES: const WeirdCopyCtorType& weird_1(orig);
+ weird_1.constMethod();
+
+ WeirdCopyCtorType weird_2 = orig;
+ // CHECK-MESSAGES: [[@LINE-1]]:21: warning: local copy 'weird_2'
+ // CHECK-FIXES: const WeirdCopyCtorType& weird_2 = orig;
+ weird_2.constMethod();
+}
+
+void NegativeLocalCopySimpleTypes() {
+ int i1 = 0;
+ int i2 = i1;
+}
+
+void NegativeLocalCopyCopyIsModified() {
+ ExpensiveToCopyType orig;
+ ExpensiveToCopyType neg_copy_1 = orig;
+ neg_copy_1.nonConstMethod();
+}
+
+void NegativeLocalCopyOriginalIsModified() {
+ ExpensiveToCopyType orig;
+ ExpensiveToCopyType neg_copy_2 = orig;
+ orig.nonConstMethod();
+}
+
+void NegativeLocalCopyUsedAsRefArg() {
+ ExpensiveToCopyType orig;
+ ExpensiveToCopyType neg_copy_3 = orig;
+ mutate(neg_copy_3);
+}
+
+void NegativeLocalCopyUsedAsPointerArg() {
+ ExpensiveToCopyType orig;
+ ExpensiveToCopyType neg_copy_4 = orig;
+ mutate(&neg_copy_4);
+}
+
+void NegativeLocalCopyCopyFromGlobal() {
+ ExpensiveToCopyType neg_copy_5 = global_expensive_to_copy_type;
+}
+
+void NegativeLocalCopyCopyToStatic() {
+ ExpensiveToCopyType orig;
+ static ExpensiveToCopyType neg_copy_6 = orig;
+}
+
+void NegativeLocalCopyNonConstInForLoop() {
+ ExpensiveToCopyType orig;
+ for (ExpensiveToCopyType neg_copy_7 = orig; orig.constMethod();
+ orig.nonConstMethod()) {
+ orig.constMethod();
+ }
+}
+
+void NegativeLocalCopyWeirdNonCopy() {
+ WeirdCopyCtorType orig;
+ WeirdCopyCtorType neg_weird_1(orig, false);
+ WeirdCopyCtorType neg_weird_2(orig, true);
+}
+void WarningOnlyMultiDeclStmt() {
+ ExpensiveToCopyType orig;
+ ExpensiveToCopyType copy = orig, copy2;
+ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: local copy 'copy' of the variable 'orig' is never modified; consider avoiding the copy [performance-unnecessary-copy-initialization]
+ // CHECK-FIXES: ExpensiveToCopyType copy = orig, copy2;
+}
+
+class Element {};
+class Container {
+public:
+ class Iterator {
+ public:
+ void operator++();
+ Element operator*();
+ bool operator!=(const Iterator &);
+ WeirdCopyCtorType c;
+ };
+ const Iterator &begin() const;
+ const Iterator &end() const;
+};
+
+void implicitVarFalsePositive() {
+ for (const Element &E : Container()) {
+ }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-allowed-types.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-allowed-types.cpp
new file mode 100644
index 0000000..054732c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-allowed-types.cpp
@@ -0,0 +1,75 @@
+// RUN: %check_clang_tidy %s performance-unnecessary-value-param %t -- -config="{CheckOptions: [{key: performance-unnecessary-value-param.AllowedTypes, value: '[Pp]ointer$;[Pp]tr$;[Rr]ef(erence)?$'}]}" --
+
+struct SmartPointer {
+ ~SmartPointer();
+};
+
+struct smart_pointer {
+ ~smart_pointer();
+};
+
+struct SmartPtr {
+ ~SmartPtr();
+};
+
+struct smart_ptr {
+ ~smart_ptr();
+};
+
+struct SmartReference {
+ ~SmartReference();
+};
+
+struct smart_reference {
+ ~smart_reference();
+};
+
+struct SmartRef {
+ ~SmartRef();
+};
+
+struct smart_ref {
+ ~smart_ref();
+};
+
+struct OtherType {
+ ~OtherType();
+};
+
+template <typename T> struct SomeComplexTemplate {
+ ~SomeComplexTemplate();
+};
+
+typedef SomeComplexTemplate<int> NotTooComplexRef;
+
+void negativeSmartPointer(SmartPointer P) {
+}
+
+void negative_smart_pointer(smart_pointer p) {
+}
+
+void negativeSmartPtr(SmartPtr P) {
+}
+
+void negative_smart_ptr(smart_ptr p) {
+}
+
+void negativeSmartReference(SmartReference R) {
+}
+
+void negative_smart_reference(smart_reference r) {
+}
+
+void negativeSmartRef(SmartRef R) {
+}
+
+void negative_smart_ref(smart_ref r) {
+}
+
+void positiveOtherType(OtherType O) {
+ // CHECK-MESSAGES: [[@LINE-1]]:34: warning: the parameter 'O' is copied for each invocation but only used as a const reference; consider making it a const reference [performance-unnecessary-value-param]
+ // CHECK-FIXES: void positiveOtherType(const OtherType& O) {
+}
+
+void negativeNotTooComplexRef(NotTooComplexRef R) {
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-arc.m b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-arc.m
new file mode 100644
index 0000000..0a9ea06
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-arc.m
@@ -0,0 +1,16 @@
+// RUN: clang-tidy %s -checks=-*,performance-unnecessary-value-param -- \
+// RUN: -xobjective-c -fobjc-abi-version=2 -fobjc-arc | count 0
+
+#if !__has_feature(objc_arc)
+#error Objective-C ARC not enabled as expected
+#endif
+
+// Passing an Objective-C ARC-managed object to a C function should
+// not raise performance-unnecessary-value-param.
+void foo(id object) { }
+
+// Same for explcitly non-ARC-managed Objective-C objects.
+void bar(__unsafe_unretained id object) { }
+
+// Same for Objective-c classes.
+void baz(Class c) { }
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-arc.mm b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-arc.mm
new file mode 100644
index 0000000..4ed0506
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-arc.mm
@@ -0,0 +1,16 @@
+// RUN: clang-tidy %s -checks=-*,performance-unnecessary-value-param -- \
+// RUN: -xobjective-c++ -fobjc-abi-version=2 -fobjc-arc | count 0
+
+#if !__has_feature(objc_arc)
+#error Objective-C ARC not enabled as expected
+#endif
+
+// Passing an Objective-C ARC-managed object to a C function should
+// not raise performance-unnecessary-value-param.
+void foo(id object) { }
+
+// Same for explcitly non-ARC-managed Objective-C objects.
+void bar(__unsafe_unretained id object) { }
+
+// Same for Objective-c classes.
+void baz(Class c) { }
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-delayed.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-delayed.cpp
new file mode 100644
index 0000000..623bf8b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-delayed.cpp
@@ -0,0 +1,181 @@
+// RUN: %check_clang_tidy %s performance-unnecessary-value-param %t -- -- -fdelayed-template-parsing
+
+struct ExpensiveToCopyType {
+ const ExpensiveToCopyType & constReference() const {
+ return *this;
+ }
+ void nonConstMethod();
+ virtual ~ExpensiveToCopyType();
+};
+
+void mutate(ExpensiveToCopyType &);
+void mutate(ExpensiveToCopyType *);
+void useAsConstReference(const ExpensiveToCopyType &);
+void useByValue(ExpensiveToCopyType);
+
+// This class simulates std::pair<>. It is trivially copy constructible
+// and trivially destructible, but not trivially copy assignable.
+class SomewhatTrivial {
+ public:
+ SomewhatTrivial();
+ SomewhatTrivial(const SomewhatTrivial&) = default;
+ ~SomewhatTrivial() = default;
+ SomewhatTrivial& operator=(const SomewhatTrivial&);
+};
+
+void positiveExpensiveConstValue(const ExpensiveToCopyType Obj);
+// CHECK-FIXES: void positiveExpensiveConstValue(const ExpensiveToCopyType& Obj);
+void positiveExpensiveConstValue(const ExpensiveToCopyType Obj) {
+ // CHECK-MESSAGES: [[@LINE-1]]:60: warning: the const qualified parameter 'Obj' is copied for each invocation; consider making it a reference [performance-unnecessary-value-param]
+ // CHECK-FIXES: void positiveExpensiveConstValue(const ExpensiveToCopyType& Obj) {
+}
+
+void positiveExpensiveValue(ExpensiveToCopyType Obj);
+// CHECK-FIXES: void positiveExpensiveValue(const ExpensiveToCopyType& Obj);
+void positiveExpensiveValue(ExpensiveToCopyType Obj) {
+ // CHECK-MESSAGES: [[@LINE-1]]:49: warning: the parameter 'Obj' is copied for each invocation but only used as a const reference; consider making it a const reference [performance-unnecessary-value-param]
+ // CHECK-FIXES: void positiveExpensiveValue(const ExpensiveToCopyType& Obj) {
+ Obj.constReference();
+ useAsConstReference(Obj);
+ auto Copy = Obj;
+ useByValue(Obj);
+}
+
+void positiveWithComment(const ExpensiveToCopyType /* important */ S);
+// CHECK-FIXES: void positiveWithComment(const ExpensiveToCopyType& /* important */ S);
+void positiveWithComment(const ExpensiveToCopyType /* important */ S) {
+ // CHECK-MESSAGES: [[@LINE-1]]:68: warning: the const qualified
+ // CHECK-FIXES: void positiveWithComment(const ExpensiveToCopyType& /* important */ S) {
+}
+
+void positiveUnnamedParam(const ExpensiveToCopyType) {
+ // CHECK-MESSAGES: [[@LINE-1]]:52: warning: the const qualified parameter #1
+ // CHECK-FIXES: void positiveUnnamedParam(const ExpensiveToCopyType&) {
+}
+
+void positiveAndNegative(const ExpensiveToCopyType ConstCopy, const ExpensiveToCopyType& ConstRef, ExpensiveToCopyType Copy);
+// CHECK-FIXES: void positiveAndNegative(const ExpensiveToCopyType& ConstCopy, const ExpensiveToCopyType& ConstRef, const ExpensiveToCopyType& Copy);
+void positiveAndNegative(const ExpensiveToCopyType ConstCopy, const ExpensiveToCopyType& ConstRef, ExpensiveToCopyType Copy) {
+ // CHECK-MESSAGES: [[@LINE-1]]:52: warning: the const qualified parameter 'ConstCopy'
+ // CHECK-MESSAGES: [[@LINE-2]]:120: warning: the parameter 'Copy'
+ // CHECK-FIXES: void positiveAndNegative(const ExpensiveToCopyType& ConstCopy, const ExpensiveToCopyType& ConstRef, const ExpensiveToCopyType& Copy) {
+}
+
+struct PositiveConstValueConstructor {
+ PositiveConstValueConstructor(const ExpensiveToCopyType ConstCopy) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:59: warning: the const qualified parameter 'ConstCopy'
+ // CHECK-FIXES: PositiveConstValueConstructor(const ExpensiveToCopyType& ConstCopy) {}
+};
+
+template <typename T> void templateWithNonTemplatizedParameter(const ExpensiveToCopyType S, T V) {
+ // CHECK-MESSAGES: [[@LINE-1]]:90: warning: the const qualified parameter 'S'
+ // CHECK-FIXES: template <typename T> void templateWithNonTemplatizedParameter(const ExpensiveToCopyType& S, T V) {
+}
+
+void instantiated() {
+ templateWithNonTemplatizedParameter(ExpensiveToCopyType(), ExpensiveToCopyType());
+ templateWithNonTemplatizedParameter(ExpensiveToCopyType(), 5);
+}
+
+template <typename T> void negativeTemplateType(const T V) {
+}
+
+void negativeArray(const ExpensiveToCopyType[]) {
+}
+
+void negativePointer(ExpensiveToCopyType* Obj) {
+}
+
+void negativeConstPointer(const ExpensiveToCopyType* Obj) {
+}
+
+void negativeConstReference(const ExpensiveToCopyType& Obj) {
+}
+
+void negativeReference(ExpensiveToCopyType& Obj) {
+}
+
+void negativeUniversalReference(ExpensiveToCopyType&& Obj) {
+}
+
+void negativeSomewhatTrivialConstValue(const SomewhatTrivial Somewhat) {
+}
+
+void negativeSomewhatTrivialValue(SomewhatTrivial Somewhat) {
+}
+
+void negativeConstBuiltIn(const int I) {
+}
+
+void negativeValueBuiltIn(int I) {
+}
+
+void negativeValueIsMutatedByReference(ExpensiveToCopyType Obj) {
+ mutate(Obj);
+}
+
+void negativeValueIsMutatatedByPointer(ExpensiveToCopyType Obj) {
+ mutate(&Obj);
+}
+
+void negativeValueIsReassigned(ExpensiveToCopyType Obj) {
+ Obj = ExpensiveToCopyType();
+}
+
+void negativeValueNonConstMethodIsCalled(ExpensiveToCopyType Obj) {
+ Obj.nonConstMethod();
+}
+
+struct PositiveValueUnusedConstructor {
+ PositiveValueUnusedConstructor(ExpensiveToCopyType Copy) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:54: warning: the parameter 'Copy'
+ // CHECK-FIXES: PositiveValueUnusedConstructor(const ExpensiveToCopyType& Copy) {}
+};
+
+struct PositiveValueCopiedConstructor {
+ PositiveValueCopiedConstructor(ExpensiveToCopyType Copy) : Field(Copy) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:54: warning: the parameter 'Copy'
+ // CHECK-FIXES: PositiveValueCopiedConstructor(const ExpensiveToCopyType& Copy) : Field(Copy) {}
+ ExpensiveToCopyType Field;
+};
+
+template <typename T>
+struct Container {
+ typedef const T & const_reference;
+};
+
+void NegativeTypedefParam(const Container<ExpensiveToCopyType>::const_reference Param) {
+}
+
+#define UNNECESSARY_VALUE_PARAM_IN_MACRO_BODY() \
+ void inMacro(const ExpensiveToCopyType T) { \
+ } \
+// Ensure fix is not applied.
+// CHECK-FIXES: void inMacro(const ExpensiveToCopyType T) {
+
+UNNECESSARY_VALUE_PARAM_IN_MACRO_BODY()
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: the const qualified parameter 'T'
+
+#define UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(ARGUMENT) \
+ ARGUMENT
+
+UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(void inMacroArgument(const ExpensiveToCopyType InMacroArg) {})
+// CHECK-MESSAGES: [[@LINE-1]]:90: warning: the const qualified parameter 'InMacroArg'
+// CHECK-FIXES: void inMacroArgument(const ExpensiveToCopyType InMacroArg) {}
+
+struct VirtualMethod {
+ virtual ~VirtualMethod() {}
+ virtual void handle(ExpensiveToCopyType T) const = 0;
+};
+
+struct NegativeOverriddenMethod : public VirtualMethod {
+ void handle(ExpensiveToCopyType Overridden) const {
+ // CHECK-FIXES: handle(ExpensiveToCopyType Overridden) const {
+ }
+};
+
+struct NegativeDeletedMethod {
+ ~NegativeDeletedMethod() {}
+ NegativeDeletedMethod& operator=(NegativeDeletedMethod N) = delete;
+ // CHECK-FIXES: NegativeDeletedMethod& operator=(NegativeDeletedMethod N) = delete;
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-header.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-header.cpp
new file mode 100644
index 0000000..9e4c246
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-header.cpp
@@ -0,0 +1,20 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: cp %S/Inputs/performance-unnecessary-value-param/header.h %t/header.h
+// RUN: %check_clang_tidy %s performance-unnecessary-value-param %t/temp -- -- -std=c++11 -I %t
+// RUN: diff %t/header.h %S/Inputs/performance-unnecessary-value-param/header-fixed.h
+
+#include "header.h"
+
+
+
+int f1(int n, ABC v1, ABC v2) {
+ // CHECK-MESSAGES: [[@LINE-1]]:19: warning: the parameter 'v1' is copied for each invocation but only used as a const reference; consider making it a const reference [performance-unnecessary-value-param]
+ // CHECK-MESSAGES: [[@LINE-2]]:27: warning: the parameter 'v2' is copied for each invocation but only used as a const reference; consider making it a const reference [performance-unnecessary-value-param]
+ // CHECK-FIXES: int f1(int n, const ABC& v1, const ABC& v2) {
+ return v1.get(n) + v2.get(n);
+}
+int f2(int n, ABC v2) {
+ // CHECK-MESSAGES: [[@LINE-1]]:19: warning: the parameter 'v2' is copied for each invocation but only used as a const reference; consider making it a const reference [performance-unnecessary-value-param]
+ // CHECK-FIXES: int f2(int n, const ABC& v2) {
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-incomplete-type.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-incomplete-type.cpp
new file mode 100644
index 0000000..cd8c4da
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-incomplete-type.cpp
@@ -0,0 +1,9 @@
+// RUN: %check_clang_tidy %s performance-unnecessary-value-param %t -- -fix-errors -- --std=c++11
+
+// Ensure that incomplete types result in an error from the frontend and not a
+// clang-tidy diagnostic about IncompleteType being expensive to copy.
+struct IncompleteType;
+void NegativeForIncompleteType(IncompleteType I) {
+ // CHECK-MESSAGES: [[@LINE-1]]:47: error: variable has incomplete type 'IncompleteType' [clang-diagnostic-error]
+}
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param.cpp
new file mode 100644
index 0000000..f801494
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param.cpp
@@ -0,0 +1,383 @@
+// RUN: %check_clang_tidy %s performance-unnecessary-value-param %t
+
+// CHECK-FIXES: #include <utility>
+
+struct ExpensiveToCopyType {
+ const ExpensiveToCopyType & constReference() const {
+ return *this;
+ }
+ void nonConstMethod();
+ virtual ~ExpensiveToCopyType();
+};
+
+void mutate(ExpensiveToCopyType &);
+void mutate(ExpensiveToCopyType *);
+void useAsConstReference(const ExpensiveToCopyType &);
+void useByValue(ExpensiveToCopyType);
+
+template <class T> class Vector {
+ public:
+ using iterator = T*;
+ using const_iterator = const T*;
+
+ Vector(const Vector&);
+ Vector& operator=(const Vector&);
+
+ iterator begin();
+ iterator end();
+ const_iterator begin() const;
+ const_iterator end() const;
+};
+
+// This class simulates std::pair<>. It is trivially copy constructible
+// and trivially destructible, but not trivially copy assignable.
+class SomewhatTrivial {
+ public:
+ SomewhatTrivial();
+ SomewhatTrivial(const SomewhatTrivial&) = default;
+ ~SomewhatTrivial() = default;
+ SomewhatTrivial& operator=(const SomewhatTrivial&);
+};
+
+struct MoveOnlyType {
+ MoveOnlyType(const MoveOnlyType &) = delete;
+ MoveOnlyType(MoveOnlyType &&) = default;
+ ~MoveOnlyType();
+ void constMethod() const;
+};
+
+struct ExpensiveMovableType {
+ ExpensiveMovableType();
+ ExpensiveMovableType(ExpensiveMovableType &&);
+ ExpensiveMovableType(const ExpensiveMovableType &) = default;
+ ExpensiveMovableType &operator=(const ExpensiveMovableType &) = default;
+ ExpensiveMovableType &operator=(ExpensiveMovableType &&);
+ ~ExpensiveMovableType();
+};
+
+void positiveExpensiveConstValue(const ExpensiveToCopyType Obj);
+// CHECK-FIXES: void positiveExpensiveConstValue(const ExpensiveToCopyType& Obj);
+void positiveExpensiveConstValue(const ExpensiveToCopyType Obj) {
+ // CHECK-MESSAGES: [[@LINE-1]]:60: warning: the const qualified parameter 'Obj' is copied for each invocation; consider making it a reference [performance-unnecessary-value-param]
+ // CHECK-FIXES: void positiveExpensiveConstValue(const ExpensiveToCopyType& Obj) {
+}
+
+void positiveExpensiveValue(ExpensiveToCopyType Obj);
+// CHECK-FIXES: void positiveExpensiveValue(const ExpensiveToCopyType& Obj);
+void positiveExpensiveValue(ExpensiveToCopyType Obj) {
+ // CHECK-MESSAGES: [[@LINE-1]]:49: warning: the parameter 'Obj' is copied for each invocation but only used as a const reference; consider making it a const reference [performance-unnecessary-value-param]
+ // CHECK-FIXES: void positiveExpensiveValue(const ExpensiveToCopyType& Obj) {
+ Obj.constReference();
+ useAsConstReference(Obj);
+ auto Copy = Obj;
+ useByValue(Obj);
+}
+
+void positiveVector(Vector<ExpensiveToCopyType> V) {
+ // CHECK-MESSAGES: [[@LINE-1]]:49: warning: the parameter 'V' is copied for each invocation but only used as a const reference; consider making it a const reference [performance-unnecessary-value-param]
+ // CHECK-FIXES: void positiveVector(const Vector<ExpensiveToCopyType>& V) {
+ for (const auto& Obj : V) {
+ useByValue(Obj);
+ }
+}
+
+void positiveWithComment(const ExpensiveToCopyType /* important */ S);
+// CHECK-FIXES: void positiveWithComment(const ExpensiveToCopyType& /* important */ S);
+void positiveWithComment(const ExpensiveToCopyType /* important */ S) {
+ // CHECK-MESSAGES: [[@LINE-1]]:68: warning: the const qualified
+ // CHECK-FIXES: void positiveWithComment(const ExpensiveToCopyType& /* important */ S) {
+}
+
+void positiveUnnamedParam(const ExpensiveToCopyType) {
+ // CHECK-MESSAGES: [[@LINE-1]]:52: warning: the const qualified parameter #1
+ // CHECK-FIXES: void positiveUnnamedParam(const ExpensiveToCopyType&) {
+}
+
+void positiveAndNegative(const ExpensiveToCopyType ConstCopy, const ExpensiveToCopyType& ConstRef, ExpensiveToCopyType Copy);
+// CHECK-FIXES: void positiveAndNegative(const ExpensiveToCopyType& ConstCopy, const ExpensiveToCopyType& ConstRef, const ExpensiveToCopyType& Copy);
+void positiveAndNegative(const ExpensiveToCopyType ConstCopy, const ExpensiveToCopyType& ConstRef, ExpensiveToCopyType Copy) {
+ // CHECK-MESSAGES: [[@LINE-1]]:52: warning: the const qualified parameter 'ConstCopy'
+ // CHECK-MESSAGES: [[@LINE-2]]:120: warning: the parameter 'Copy'
+ // CHECK-FIXES: void positiveAndNegative(const ExpensiveToCopyType& ConstCopy, const ExpensiveToCopyType& ConstRef, const ExpensiveToCopyType& Copy) {
+}
+
+struct PositiveConstValueConstructor {
+ PositiveConstValueConstructor(const ExpensiveToCopyType ConstCopy) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:59: warning: the const qualified parameter 'ConstCopy'
+ // CHECK-FIXES: PositiveConstValueConstructor(const ExpensiveToCopyType& ConstCopy) {}
+};
+
+template <typename T> void templateWithNonTemplatizedParameter(const ExpensiveToCopyType S, T V) {
+ // CHECK-MESSAGES: [[@LINE-1]]:90: warning: the const qualified parameter 'S'
+ // CHECK-FIXES: template <typename T> void templateWithNonTemplatizedParameter(const ExpensiveToCopyType& S, T V) {
+}
+
+void instantiated() {
+ templateWithNonTemplatizedParameter(ExpensiveToCopyType(), ExpensiveToCopyType());
+ templateWithNonTemplatizedParameter(ExpensiveToCopyType(), 5);
+}
+
+template <typename T> void negativeTemplateType(const T V) {
+}
+
+void negativeArray(const ExpensiveToCopyType[]) {
+}
+
+void negativePointer(ExpensiveToCopyType* Obj) {
+}
+
+void negativeConstPointer(const ExpensiveToCopyType* Obj) {
+}
+
+void negativeConstReference(const ExpensiveToCopyType& Obj) {
+}
+
+void negativeReference(ExpensiveToCopyType& Obj) {
+}
+
+void negativeUniversalReference(ExpensiveToCopyType&& Obj) {
+}
+
+void negativeSomewhatTrivialConstValue(const SomewhatTrivial Somewhat) {
+}
+
+void negativeSomewhatTrivialValue(SomewhatTrivial Somewhat) {
+}
+
+void negativeConstBuiltIn(const int I) {
+}
+
+void negativeValueBuiltIn(int I) {
+}
+
+void negativeValueIsMutatedByReference(ExpensiveToCopyType Obj) {
+ mutate(Obj);
+}
+
+void negativeValueIsMutatatedByPointer(ExpensiveToCopyType Obj) {
+ mutate(&Obj);
+}
+
+void negativeValueIsReassigned(ExpensiveToCopyType Obj) {
+ Obj = ExpensiveToCopyType();
+}
+
+void negativeValueNonConstMethodIsCalled(ExpensiveToCopyType Obj) {
+ Obj.nonConstMethod();
+}
+
+struct PositiveValueUnusedConstructor {
+ PositiveValueUnusedConstructor(ExpensiveToCopyType Copy) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:54: warning: the parameter 'Copy'
+ // CHECK-FIXES: PositiveValueUnusedConstructor(const ExpensiveToCopyType& Copy) {}
+};
+
+struct PositiveValueCopiedConstructor {
+ PositiveValueCopiedConstructor(ExpensiveToCopyType Copy) : Field(Copy) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:54: warning: the parameter 'Copy'
+ // CHECK-FIXES: PositiveValueCopiedConstructor(const ExpensiveToCopyType& Copy) : Field(Copy) {}
+ ExpensiveToCopyType Field;
+};
+
+struct PositiveValueMovableConstructor {
+ PositiveValueMovableConstructor(ExpensiveMovableType Copy) : Field(Copy) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:70: warning: parameter 'Copy'
+ // CHECK-FIXES: PositiveValueMovableConstructor(ExpensiveMovableType Copy) : Field(std::move(Copy)) {}
+ ExpensiveMovableType Field;
+};
+
+struct NegativeValueMovedConstructor {
+ NegativeValueMovedConstructor(ExpensiveMovableType Copy) : Field(static_cast<ExpensiveMovableType &&>(Copy)) {}
+ ExpensiveMovableType Field;
+};
+
+template <typename T>
+struct Container {
+ typedef const T & const_reference;
+};
+
+void NegativeTypedefParam(const Container<ExpensiveToCopyType>::const_reference Param) {
+}
+
+#define UNNECESSARY_VALUE_PARAM_IN_MACRO_BODY() \
+ void inMacro(const ExpensiveToCopyType T) { \
+ } \
+// Ensure fix is not applied.
+// CHECK-FIXES: void inMacro(const ExpensiveToCopyType T) {
+
+UNNECESSARY_VALUE_PARAM_IN_MACRO_BODY()
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: the const qualified parameter 'T'
+
+#define UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(ARGUMENT) \
+ ARGUMENT
+
+UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(void inMacroArgument(const ExpensiveToCopyType InMacroArg) {})
+// CHECK-MESSAGES: [[@LINE-1]]:90: warning: the const qualified parameter 'InMacroArg'
+// CHECK-FIXES: void inMacroArgument(const ExpensiveToCopyType InMacroArg) {}
+
+struct VirtualMethod {
+ virtual ~VirtualMethod() {}
+ virtual void handle(ExpensiveToCopyType T) const = 0;
+};
+
+struct NegativeOverriddenMethod : public VirtualMethod {
+ void handle(ExpensiveToCopyType Overridden) const {
+ // CHECK-FIXES: handle(ExpensiveToCopyType Overridden) const {
+ }
+};
+
+struct VirtualMethodWarningOnly {
+ virtual void methodWithExpensiveValueParam(ExpensiveToCopyType T) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:66: warning: the parameter 'T' is copied
+ // CHECK-FIXES: virtual void methodWithExpensiveValueParam(ExpensiveToCopyType T) {}
+ virtual ~VirtualMethodWarningOnly() {}
+};
+
+struct PositiveNonVirualMethod {
+ void method(const ExpensiveToCopyType T) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:41: warning: the const qualified parameter 'T' is copied
+ // CHECK-FIXES: void method(const ExpensiveToCopyType& T) {}
+};
+
+struct NegativeDeletedMethod {
+ ~NegativeDeletedMethod() {}
+ NegativeDeletedMethod& operator=(NegativeDeletedMethod N) = delete;
+ // CHECK-FIXES: NegativeDeletedMethod& operator=(NegativeDeletedMethod N) = delete;
+};
+
+void NegativeMoveOnlyTypePassedByValue(MoveOnlyType M) {
+ M.constMethod();
+}
+
+void PositiveMoveOnCopyConstruction(ExpensiveMovableType E) {
+ auto F = E;
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: parameter 'E' is passed by value and only copied once; consider moving it to avoid unnecessary copies [performance-unnecessary-value-param]
+ // CHECK-FIXES: auto F = std::move(E);
+}
+
+void PositiveConstRefNotMoveSinceReferencedMultipleTimes(ExpensiveMovableType E) {
+ // CHECK-MESSAGES: [[@LINE-1]]:79: warning: the parameter 'E' is copied
+ // CHECK-FIXES: void PositiveConstRefNotMoveSinceReferencedMultipleTimes(const ExpensiveMovableType& E) {
+ auto F = E;
+ auto G = E;
+}
+
+void PositiveMoveOnCopyAssignment(ExpensiveMovableType E) {
+ ExpensiveMovableType F;
+ F = E;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: parameter 'E' is passed by value
+ // CHECK-FIXES: F = std::move(E);
+}
+
+struct NotCopyAssigned {
+ NotCopyAssigned &operator=(const ExpensiveMovableType &);
+};
+
+void PositiveNoMoveForNonCopyAssigmentOperator(ExpensiveMovableType E) {
+ // CHECK-MESSAGES: [[@LINE-1]]:69: warning: the parameter 'E' is copied
+ // CHECK-FIXES: void PositiveNoMoveForNonCopyAssigmentOperator(const ExpensiveMovableType& E) {
+ NotCopyAssigned N;
+ N = E;
+}
+
+// The argument could be moved but is not since copy statement is inside a loop.
+void PositiveNoMoveInsideLoop(ExpensiveMovableType E) {
+ // CHECK-MESSAGES: [[@LINE-1]]:52: warning: the parameter 'E' is copied
+ // CHECK-FIXES: void PositiveNoMoveInsideLoop(const ExpensiveMovableType& E) {
+ for (;;) {
+ auto F = E;
+ }
+}
+
+void PositiveConstRefNotMoveConstructible(ExpensiveToCopyType T) {
+ // CHECK-MESSAGES: [[@LINE-1]]:63: warning: the parameter 'T' is copied
+ // CHECK-FIXES: void PositiveConstRefNotMoveConstructible(const ExpensiveToCopyType& T) {
+ auto U = T;
+}
+
+void PositiveConstRefNotMoveAssignable(ExpensiveToCopyType A) {
+ // CHECK-MESSAGES: [[@LINE-1]]:60: warning: the parameter 'A' is copied
+ // CHECK-FIXES: void PositiveConstRefNotMoveAssignable(const ExpensiveToCopyType& A) {
+ ExpensiveToCopyType B;
+ B = A;
+}
+
+// Case where parameter in declaration is already const-qualified but not in
+// implementation. Make sure a second 'const' is not added to the declaration.
+void PositiveConstDeclaration(const ExpensiveToCopyType A);
+// CHECK-FIXES: void PositiveConstDeclaration(const ExpensiveToCopyType& A);
+void PositiveConstDeclaration(ExpensiveToCopyType A) {
+ // CHECK-MESSAGES: [[@LINE-1]]:51: warning: the parameter 'A' is copied
+ // CHECK-FIXES: void PositiveConstDeclaration(const ExpensiveToCopyType& A) {
+}
+
+void PositiveNonConstDeclaration(ExpensiveToCopyType A);
+// CHECK-FIXES: void PositiveNonConstDeclaration(const ExpensiveToCopyType& A);
+void PositiveNonConstDeclaration(const ExpensiveToCopyType A) {
+ // CHECK-MESSAGES: [[@LINE-1]]:60: warning: the const qualified parameter 'A'
+ // CHECK-FIXES: void PositiveNonConstDeclaration(const ExpensiveToCopyType& A) {
+}
+
+void PositiveOnlyMessageAsReferencedInCompilationUnit(ExpensiveToCopyType A) {
+ // CHECK-MESSAGES: [[@LINE-1]]:75: warning: the parameter 'A' is copied
+ // CHECK-FIXES: void PositiveOnlyMessageAsReferencedInCompilationUnit(ExpensiveToCopyType A) {
+}
+
+void ReferenceFunctionOutsideOfCallExpr() {
+ void (*ptr)(ExpensiveToCopyType) = &PositiveOnlyMessageAsReferencedInCompilationUnit;
+}
+
+void PositiveMessageAndFixAsFunctionIsCalled(ExpensiveToCopyType A) {
+ // CHECK-MESSAGES: [[@LINE-1]]:66: warning: the parameter 'A' is copied
+ // CHECK-FIXES: void PositiveMessageAndFixAsFunctionIsCalled(const ExpensiveToCopyType& A) {
+}
+
+void ReferenceFunctionByCallingIt() {
+ PositiveMessageAndFixAsFunctionIsCalled(ExpensiveToCopyType());
+}
+
+// Virtual method overrides of dependent types cannot be recognized unless they
+// are marked as override or final. Test that check is not triggered on methods
+// marked with override or final.
+template <typename T>
+struct NegativeDependentTypeInterface {
+ virtual void Method(ExpensiveToCopyType E) = 0;
+};
+
+template <typename T>
+struct NegativeOverrideImpl : public NegativeDependentTypeInterface<T> {
+ void Method(ExpensiveToCopyType E) override {}
+};
+
+template <typename T>
+struct NegativeFinalImpl : public NegativeDependentTypeInterface<T> {
+ void Method(ExpensiveToCopyType E) final {}
+};
+
+struct PositiveConstructor {
+ PositiveConstructor(ExpensiveToCopyType E) : E(E) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:43: warning: the parameter 'E' is copied
+ // CHECK-FIXES: PositiveConstructor(const ExpensiveToCopyType& E) : E(E) {}
+
+ ExpensiveToCopyType E;
+};
+
+struct NegativeUsingConstructor : public PositiveConstructor {
+ using PositiveConstructor::PositiveConstructor;
+};
+
+void fun() {
+ ExpensiveToCopyType E;
+ NegativeUsingConstructor S(E);
+}
+
+template<typename T>
+void templateFunction(T) {
+}
+
+template<>
+void templateFunction<ExpensiveToCopyType>(ExpensiveToCopyType E) {
+ // CHECK-MESSAGES: [[@LINE-1]]:64: warning: the parameter 'E' is copied
+ // CHECK-FIXES: void templateFunction<ExpensiveToCopyType>(ExpensiveToCopyType E) {
+ E.constReference();
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/portability-simd-intrinsics-ppc.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/portability-simd-intrinsics-ppc.cpp
new file mode 100644
index 0000000..be0ef76
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/portability-simd-intrinsics-ppc.cpp
@@ -0,0 +1,13 @@
+// RUN: %check_clang_tidy %s portability-simd-intrinsics %t -- \
+// RUN: -config='{CheckOptions: [ \
+// RUN: {key: portability-simd-intrinsics.Suggest, value: 1} \
+// RUN: ]}' -- -target ppc64le -maltivec -std=c++11
+
+vector int vec_add(vector int, vector int);
+
+void PPC() {
+ vector int i0, i1;
+
+ vec_add(i0, i1);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'vec_add' can be replaced by operator+ on std::experimental::simd objects [portability-simd-intrinsics]
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/portability-simd-intrinsics-x86.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/portability-simd-intrinsics-x86.cpp
new file mode 100644
index 0000000..1fb2289
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/portability-simd-intrinsics-x86.cpp
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s portability-simd-intrinsics %t -- \
+// RUN: -config='{CheckOptions: [ \
+// RUN: {key: portability-simd-intrinsics.Suggest, value: 1} \
+// RUN: ]}' -- -target x86_64 -std=c++11
+
+typedef long long __m128i __attribute__((vector_size(16)));
+typedef double __m256 __attribute__((vector_size(32)));
+
+__m128i _mm_add_epi32(__m128i, __m128i);
+__m256 _mm256_load_pd(double const *);
+void _mm256_store_pd(double *, __m256);
+
+int _mm_add_fake(int, int);
+
+void X86() {
+ __m128i i0, i1;
+ __m256 d0;
+
+ _mm_add_epi32(i0, i1);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: '_mm_add_epi32' can be replaced by operator+ on std::experimental::simd objects [portability-simd-intrinsics]
+ d0 = _mm256_load_pd(0);
+ _mm256_store_pd(0, d0);
+
+ _mm_add_fake(0, 1);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/pr37091.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/pr37091.cpp
new file mode 100644
index 0000000..e56115a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/pr37091.cpp
@@ -0,0 +1,10 @@
+// REQUIRES: shell
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+
+// This is a reproducer for PR37091.
+//
+// Verify that no temporary files are left behind by the clang-tidy invocation.
+
+// RUN: env TMPDIR=%t TEMP=%t TMP=%t clang-tidy %s -- --target=mips64
+// RUN: rmdir %t
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/read_file_config.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/read_file_config.cpp
new file mode 100644
index 0000000..3e39b4d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/read_file_config.cpp
@@ -0,0 +1,13 @@
+// REQUIRES: static-analyzer
+// RUN: mkdir -p %T/read-file-config/
+// RUN: cp %s %T/read-file-config/test.cpp
+// RUN: echo 'Checks: "-*,modernize-use-nullptr"' > %T/read-file-config/.clang-tidy
+// RUN: echo '[{"command": "cc -c -o test.o test.cpp", "directory": "%/T/read-file-config", "file": "%/T/read-file-config/test.cpp"}]' > %T/read-file-config/compile_commands.json
+// RUN: clang-tidy %T/read-file-config/test.cpp | not grep "warning: .*\[clang-analyzer-deadcode.DeadStores\]$"
+// RUN: clang-tidy -checks="-*,clang-analyzer-*" %T/read-file-config/test.cpp | grep "warning: .*\[clang-analyzer-deadcode.DeadStores\]$"
+
+void f() {
+ int x;
+ x = 1;
+ x = 2;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-avoid-const-params-in-decls.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-avoid-const-params-in-decls.cpp
new file mode 100644
index 0000000..c2c12a4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-avoid-const-params-in-decls.cpp
@@ -0,0 +1,133 @@
+// RUN: %check_clang_tidy %s readability-avoid-const-params-in-decls %t
+
+using alias_type = bool;
+using alias_const_type = const bool;
+
+
+void F1(const int i);
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is const-qualified in the function declaration; const-qualification of parameters only has an effect in function definitions [readability-avoid-const-params-in-decls]
+// CHECK-FIXES: void F1(int i);
+
+void F2(const int *const i);
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is const-qualified
+// CHECK-FIXES: void F2(const int *i);
+
+void F3(int const i);
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is const-qualified
+// CHECK-FIXES: void F3(int i);
+
+void F4(alias_type const i);
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is const-qualified
+// CHECK-FIXES: void F4(alias_type i);
+
+void F5(const int);
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 1 is const-qualified
+// CHECK-FIXES: void F5(int);
+
+void F6(const int *const);
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 1 is const-qualified
+// CHECK-FIXES: void F6(const int *);
+
+void F7(int, const int);
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: parameter 2 is const-qualified
+// CHECK-FIXES: void F7(int, int);
+
+void F8(const int, const int);
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 1 is const-qualified
+// CHECK-MESSAGES: :[[@LINE-2]]:20: warning: parameter 2 is const-qualified
+// CHECK-FIXES: void F8(int, int);
+
+void F9(const int long_name);
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'long_name'
+// CHECK-FIXES: void F9(int long_name);
+
+void F10(const int *const *const long_name);
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: parameter 'long_name'
+// CHECK-FIXES: void F10(const int *const *long_name);
+
+void F11(const unsigned int /*v*/);
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: parameter 1
+// CHECK-FIXES: void F11(unsigned int /*v*/);
+
+void F12(const bool b = true);
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: parameter 'b'
+// CHECK-FIXES: void F12(bool b = true);
+
+template<class T>
+int F13(const bool b = true);
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'b'
+// CHECK-FIXES: int F13(bool b = true);
+int f13 = F13<int>();
+
+struct Foo {
+ Foo(const int i);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: parameter 'i'
+ // CHECK-FIXES: Foo(int i);
+
+ void operator()(const int i);
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: parameter 'i'
+ // CHECK-FIXES: void operator()(int i);
+};
+
+template <class T>
+struct FooT {
+ FooT(const int i);
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: parameter 'i'
+ // CHECK-FIXES: FooT(int i);
+
+ void operator()(const int i);
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: parameter 'i'
+ // CHECK-FIXES: void operator()(int i);
+};
+FooT<int> f(1);
+
+// Do not match on definitions
+void NF1(const int i) {}
+void NF2(const int *const i) {}
+void NF3(int const i) {}
+void NF4(alias_type const i) {}
+void NF5(const int) {}
+void NF6(const int *const) {}
+void NF7(int, const int) {}
+void NF8(const int, const int) {}
+template <class T>
+int NF9(const int, const int) { return 0; }
+int nf9 = NF9<int>(1, 2);
+
+// Do not match on inline member functions
+struct Bar {
+ Bar(const int i) {}
+
+ void operator()(const int i) {}
+};
+
+// Do not match on inline member functions of a templated class
+template <class T>
+struct BarT {
+ BarT(const int i) {}
+
+ void operator()(const int i) {}
+};
+BarT<int> b(1);
+
+// Do not match on other stuff
+void NF(const alias_type& i);
+void NF(const int &i);
+void NF(const int *i);
+void NF(alias_const_type i);
+void NF(const alias_type&);
+void NF(const int&);
+void NF(const int*);
+void NF(const int* const*);
+void NF(alias_const_type);
+
+// Regression test for when the 'const' token is not in the code.
+#define CONCAT(a, b) a##b
+void ConstNotVisible(CONCAT(cons, t) int i);
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: parameter 'i'
+// We warn, but we can't give a fix
+// CHECK-FIXES: void ConstNotVisible(CONCAT(cons, t) int i);
+
+// Regression test. We should not warn (or crash) on lambda expressions
+auto lambda_with_name = [](const int n) {};
+auto lambda_without_name = [](const int) {};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-braces-around-statements-assert-failure.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-braces-around-statements-assert-failure.cpp
new file mode 100644
index 0000000..7d619c0
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-braces-around-statements-assert-failure.cpp
@@ -0,0 +1,12 @@
+// RUN: not clang-tidy -checks='-*,readability-braces-around-statements' %s --
+
+// Note: this test expects no assert failure happened in clang-tidy.
+
+int test_failure() {
+ if (std::rand()) {
+ }
+}
+
+void test_failure2() {
+ for (a b c;;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-braces-around-statements-few-lines.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-braces-around-statements-few-lines.cpp
new file mode 100644
index 0000000..00d253a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-braces-around-statements-few-lines.cpp
@@ -0,0 +1,30 @@
+// RUN: %check_clang_tidy %s readability-braces-around-statements %t -- -config="{CheckOptions: [{key: readability-braces-around-statements.ShortStatementLines, value: 4}]}" --
+
+void do_something(const char *) {}
+
+bool cond(const char *) {
+ return false;
+}
+
+void test() {
+ if (cond("if1") /*comment*/) do_something("same-line");
+
+ if (cond("if2"))
+ do_something("single-line");
+
+ if (cond("if3") /*comment*/)
+ // some comment
+ do_something("three"
+ "lines");
+
+ if (cond("if4") /*comment*/)
+ // some comment
+ do_something("many"
+ "many"
+ "many"
+ "many"
+ "lines");
+ // CHECK-MESSAGES: :[[@LINE-7]]:31: warning: statement should be inside braces
+ // CHECK-FIXES: if (cond("if4") /*comment*/) {
+ // CHECK-FIXES: }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-braces-around-statements-format.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-braces-around-statements-format.cpp
new file mode 100644
index 0000000..81f832d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-braces-around-statements-format.cpp
@@ -0,0 +1,33 @@
+// RUN: %check_clang_tidy %s readability-braces-around-statements %t -- -format-style="{IndentWidth: 3}" --
+
+void do_something(const char *) {}
+
+bool cond(const char *) {
+ return false;
+}
+
+void test() {
+ if (cond("if0") /*comment*/) do_something("same-line");
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: statement should be inside braces
+ // CHECK-FIXES: {{^}} if (cond("if0") /*comment*/) {{{$}}
+ // CHECK-FIXES-NEXT: {{^}} do_something("same-line");{{$}}
+ // CHECK-FIXES-NEXT: {{^}} }{{$}}
+
+ if (1) while (2) if (3) for (;;) do ; while(false) /**/;/**/
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: statement should be inside braces
+ // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: statement should be inside braces
+ // CHECK-MESSAGES: :[[@LINE-3]]:26: warning: statement should be inside braces
+ // CHECK-MESSAGES: :[[@LINE-4]]:35: warning: statement should be inside braces
+ // CHECK-MESSAGES: :[[@LINE-5]]:38: warning: statement should be inside braces
+ // CHECK-FIXES: {{^}} if (1) {{{$}}
+ // CHECK-FIXES-NEXT: {{^}} while (2) {
+ // CHECK-FIXES-NEXT: {{^}} if (3) {
+ // CHECK-FIXES-NEXT: {{^}} for (;;) {
+ // CHECK-FIXES-NEXT: {{^}} do {
+ // CHECK-FIXES-NEXT: {{^}} ;
+ // CHECK-FIXES-NEXT: {{^}} } while (false) /**/; /**/
+ // CHECK-FIXES-NEXT: {{^}} }
+ // CHECK-FIXES-NEXT: {{^}} }
+ // CHECK-FIXES-NEXT: {{^}} }
+ // CHECK-FIXES-NEXT: {{^}} }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-braces-around-statements-same-line.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-braces-around-statements-same-line.cpp
new file mode 100644
index 0000000..504043f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-braces-around-statements-same-line.cpp
@@ -0,0 +1,36 @@
+// RUN: %check_clang_tidy %s readability-braces-around-statements %t -- -config="{CheckOptions: [{key: readability-braces-around-statements.ShortStatementLines, value: 1}]}" --
+
+void do_something(const char *) {}
+
+bool cond(const char *) {
+ return false;
+}
+
+void test() {
+ if (cond("if1") /*comment*/) do_something("same-line");
+
+ if (cond("if2"))
+ do_something("single-line");
+ // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: statement should be inside braces
+ // CHECK-FIXES: if (cond("if2")) {
+ // CHECK-FIXES: }
+
+ if (cond("if3") /*comment*/)
+ // some comment
+ do_something("three"
+ "lines");
+ // CHECK-MESSAGES: :[[@LINE-4]]:31: warning: statement should be inside braces
+ // CHECK-FIXES: if (cond("if3") /*comment*/) {
+ // CHECK-FIXES: }
+
+ if (cond("if4") /*comment*/)
+ // some comment
+ do_something("many"
+ "many"
+ "many"
+ "many"
+ "lines");
+ // CHECK-MESSAGES: :[[@LINE-7]]:31: warning: statement should be inside braces
+ // CHECK-FIXES: if (cond("if4") /*comment*/) {
+ // CHECK-FIXES: }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-braces-around-statements-single-line.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-braces-around-statements-single-line.cpp
new file mode 100644
index 0000000..3edbd4b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-braces-around-statements-single-line.cpp
@@ -0,0 +1,33 @@
+// RUN: %check_clang_tidy %s readability-braces-around-statements %t -- -config="{CheckOptions: [{key: readability-braces-around-statements.ShortStatementLines, value: 2}]}" --
+
+void do_something(const char *) {}
+
+bool cond(const char *) {
+ return false;
+}
+
+void test() {
+ if (cond("if1") /*comment*/) do_something("same-line");
+
+ if (cond("if2"))
+ do_something("single-line");
+
+ if (cond("if3") /*comment*/)
+ // some comment
+ do_something("three"
+ "lines");
+ // CHECK-MESSAGES: :[[@LINE-4]]:31: warning: statement should be inside braces
+ // CHECK-FIXES: if (cond("if3") /*comment*/) {
+ // CHECK-FIXES: }
+
+ if (cond("if4") /*comment*/)
+ // some comment
+ do_something("many"
+ "many"
+ "many"
+ "many"
+ "lines");
+ // CHECK-MESSAGES: :[[@LINE-7]]:31: warning: statement should be inside braces
+ // CHECK-FIXES: if (cond("if4") /*comment*/) {
+ // CHECK-FIXES: }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-braces-around-statements.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-braces-around-statements.cpp
new file mode 100644
index 0000000..8dc5bf1
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-braces-around-statements.cpp
@@ -0,0 +1,206 @@
+// RUN: %check_clang_tidy %s readability-braces-around-statements %t
+
+void do_something(const char *) {}
+
+bool cond(const char *) {
+ return false;
+}
+
+#define EMPTY_MACRO
+#define EMPTY_MACRO_FUN()
+
+void test() {
+ if (cond("if0") /*comment*/) do_something("same-line");
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: statement should be inside braces
+ // CHECK-FIXES: if (cond("if0") /*comment*/) { do_something("same-line");
+ // CHECK-FIXES: }
+
+ if (cond("if0.1"))
+ do_something("single-line");
+ // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: statement should be inside braces
+ // CHECK-FIXES: if (cond("if0.1")) {
+ // CHECK-FIXES: }
+
+ if (cond("if1") /*comment*/)
+ // some comment
+ do_something("if1");
+ // CHECK-MESSAGES: :[[@LINE-3]]:31: warning: statement should be inside braces
+ // CHECK-FIXES: if (cond("if1") /*comment*/) {
+ // CHECK-FIXES: }
+ if (cond("if2")) {
+ do_something("if2");
+ }
+ if (cond("if3"))
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: statement should be inside braces
+ // CHECK-FIXES: if (cond("if3")) {
+ // CHECK-FIXES: }
+
+ if (cond("if-else1"))
+ do_something("if-else1");
+ // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: statement should be inside braces
+ // CHECK-FIXES: if (cond("if-else1")) {
+ // CHECK-FIXES: } else {
+ else
+ do_something("if-else1 else");
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: statement should be inside braces
+ // CHECK-FIXES: }
+ if (cond("if-else2")) {
+ do_something("if-else2");
+ } else {
+ do_something("if-else2 else");
+ }
+
+ if (cond("if-else if-else1"))
+ do_something("if");
+ // CHECK-MESSAGES: :[[@LINE-2]]:32: warning: statement should be inside braces
+ // CHECK-FIXES: } else if (cond("else if1")) {
+ else if (cond("else if1"))
+ do_something("else if");
+ // CHECK-MESSAGES: :[[@LINE-2]]:29: warning: statement should be inside braces
+ else
+ do_something("else");
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: statement should be inside braces
+ // CHECK-FIXES: }
+ if (cond("if-else if-else2")) {
+ do_something("if");
+ } else if (cond("else if2")) {
+ do_something("else if");
+ } else {
+ do_something("else");
+ }
+
+ for (;;)
+ do_something("for");
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: statement should be inside braces
+ // CHECK-FIXES: for (;;) {
+ // CHECK-FIXES: }
+ for (;;) {
+ do_something("for");
+ }
+ for (;;)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: statement should be inside braces
+ // CHECK-FIXES: for (;;) {
+ // CHECK-FIXES: }
+
+ int arr[4] = {1, 2, 3, 4};
+ for (int a : arr)
+ do_something("for-range");
+ // CHECK-MESSAGES: :[[@LINE-2]]:20: warning: statement should be inside braces
+ // CHECK-FIXES: for (int a : arr) {
+ // CHECK-FIXES: }
+ for (int a : arr) {
+ do_something("for-range");
+ }
+ for (int a : arr)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:20: warning: statement should be inside braces
+ // CHECK-FIXES: for (int a : arr) {
+ // CHECK-FIXES: }
+
+ while (cond("while1"))
+ do_something("while");
+ // CHECK-MESSAGES: :[[@LINE-2]]:25: warning: statement should be inside braces
+ // CHECK-FIXES: while (cond("while1")) {
+ // CHECK-FIXES: }
+ while (cond("while2")) {
+ do_something("while");
+ }
+ while (false)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: statement should be inside braces
+ // CHECK-FIXES: while (false) {
+ // CHECK-FIXES: }
+
+ do
+ do_something("do1");
+ while (cond("do1"));
+ // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: statement should be inside braces
+ // CHECK-FIXES: do {
+ // CHECK-FIXES: } while (cond("do1"));
+ do {
+ do_something("do2");
+ } while (cond("do2"));
+
+ do
+ ;
+ while (false);
+ // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: statement should be inside braces
+ // CHECK-FIXES: do {
+ // CHECK-FIXES: } while (false);
+
+ if (cond("ifif1"))
+ // comment
+ if (cond("ifif2"))
+ // comment
+ /*comment*/ ; // comment
+ // CHECK-MESSAGES: :[[@LINE-5]]:21: warning: statement should be inside braces
+ // CHECK-MESSAGES: :[[@LINE-4]]:23: warning: statement should be inside braces
+ // CHECK-FIXES: if (cond("ifif1")) {
+ // CHECK-FIXES: if (cond("ifif2")) {
+ // CHECK-FIXES: }
+ // CHECK-FIXES-NEXT: }
+
+ if (cond("ifif3"))
+ // comment
+ if (cond("ifif4")) {
+ // comment
+ /*comment*/; // comment
+ }
+ // CHECK-MESSAGES: :[[@LINE-6]]:21: warning: statement should be inside braces
+ // CHECK-FIXES: if (cond("ifif3")) {
+ // CHECK-FIXES: }
+
+ if (cond("ifif5"))
+ ; /* multi-line
+ comment */
+ // CHECK-MESSAGES: :[[@LINE-3]]:21: warning: statement should be inside braces
+ // CHECK-FIXES: if (cond("ifif5")) {
+ // CHECK-FIXES: }/* multi-line
+
+ if (1) while (2) if (3) for (;;) do ; while(false) /**/;/**/
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: statement should be inside braces
+ // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: statement should be inside braces
+ // CHECK-MESSAGES: :[[@LINE-3]]:26: warning: statement should be inside braces
+ // CHECK-MESSAGES: :[[@LINE-4]]:35: warning: statement should be inside braces
+ // CHECK-MESSAGES: :[[@LINE-5]]:38: warning: statement should be inside braces
+ // CHECK-FIXES: if (1) { while (2) { if (3) { for (;;) { do { ; } while(false) /**/;/**/
+ // CHECK-FIXES-NEXT: }
+ // CHECK-FIXES-NEXT: }
+ // CHECK-FIXES-NEXT: }
+ // CHECK-FIXES-NEXT: }
+}
+
+void f(const char *p) {
+ if (!p)
+ f("\
+");
+} // end of f
+// CHECK-MESSAGES: :[[@LINE-4]]:10: warning: statement should be inside braces
+// CHECK-FIXES: {{^}} if (!p) {{{$}}
+// CHECK-FIXES-NEXT: {{^}} f("\{{$}}
+// CHECK-FIXES-NEXT: {{^}}");{{$}}
+// CHECK-FIXES-NEXT: {{^}}}{{$}}
+// CHECK-FIXES-NEXT: {{^}}} // end of f{{$}}
+
+#define M(x) x
+
+int test_macros(bool b) {
+ if (b) {
+ return 1;
+ } else
+ M(return 2);
+ // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: statement should be inside braces
+ // CHECK-FIXES: } else {
+ // CHECK-FIXES-NEXT: M(return 2);
+ // CHECK-FIXES-NEXT: }
+ M(
+ for (;;)
+ ;
+ );
+ // CHECK-MESSAGES: :[[@LINE-3]]:13: warning: statement should be inside braces
+ // CHECK-FIXES: {{^}} for (;;) {{{$}}
+ // CHECK-FIXES-NEXT: {{^ ;$}}
+ // CHECK-FIXES-NEXT: {{^}$}}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-const-return-type.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-const-return-type.cpp
new file mode 100644
index 0000000..78557c5
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-const-return-type.cpp
@@ -0,0 +1,234 @@
+// RUN: %check_clang_tidy %s readability-const-return-type %t
+
+// p# = positive test
+// n# = negative test
+
+namespace std {
+template< class T >
+struct add_cv { typedef const volatile T type; };
+
+template< class T> struct add_const { typedef const T type; };
+
+template< class T> struct add_volatile { typedef volatile T type; };
+}
+
+const int p1() {
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const int' is 'const'-qualified at the top level, which may reduce code readability without improving const correctness
+// CHECK-FIXES: int p1() {
+ return 1;
+}
+
+const int p15();
+// CHECK-FIXES: int p15();
+
+template <typename T>
+const int p31(T v) { return 2; }
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const int' is 'const'-qu
+// CHECK-FIXES: int p31(T v) { return 2; }
+
+// We detect const-ness even without instantiating T.
+template <typename T>
+const T p32(T t) { return t; }
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const T' is 'const'-qual
+// CHECK-FIXES: T p32(T t) { return t; }
+
+// However, if the return type is itself a template instantiation, Clang does
+// not consider it const-qualified without knowing `T`.
+template <typename T>
+typename std::add_const<T>::type n15(T v) { return v; }
+
+template <typename A>
+class Klazz {
+public:
+ Klazz(A) {}
+};
+
+class Clazz {
+ public:
+ Clazz *const p2() {
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: return type 'Clazz *const' is 'co
+ // CHECK-FIXES: Clazz *p2() {
+ return this;
+ }
+
+ Clazz *const p3();
+ // CHECK-FIXES: Clazz *p3();
+
+ const int p4() const {
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: return type 'const int' is 'const
+ // CHECK-FIXES: int p4() const {
+ return 4;
+ }
+
+ const Klazz<const int>* const p5() const;
+ // CHECK-FIXES: const Klazz<const int>* p5() const;
+
+ const Clazz operator++(int x) { // p12
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: return type 'const Clazz' is 'const
+ // CHECK-FIXES: Clazz operator++(int x) {
+ }
+
+ struct Strukt {
+ int i;
+ };
+
+ const Strukt p6() {}
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: return type 'const Clazz::Strukt' i
+ // CHECK-FIXES: Strukt p6() {}
+
+ // No warning is emitted here, because this is only the declaration. The
+ // warning will be associated with the definition, below.
+ const Strukt* const p7();
+ // CHECK-FIXES: const Strukt* p7();
+
+ // const-qualifier is the first `const` token, but not the first token.
+ static const int p8() {}
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: return type 'const int' is 'const'-
+ // CHECK-FIXES: static int p8() {}
+
+ static const Strukt p9() {}
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: return type 'const Clazz::Strukt' i
+ // CHECK-FIXES: static Strukt p9() {}
+
+ int n0() const { return 0; }
+ const Klazz<const int>& n11(const Klazz<const int>) const;
+};
+
+Clazz *const Clazz::p3() {
+ // CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'Clazz *const' is 'cons
+ // CHECK-FIXES: Clazz *Clazz::p3() {
+ return this;
+}
+
+const Klazz<const int>* const Clazz::p5() const {}
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<const int> *
+// CHECK-FIXES: const Klazz<const int>* Clazz::p5() const {}
+
+const Clazz::Strukt* const Clazz::p7() {}
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Clazz::Strukt *con
+// CHECK-FIXES: const Clazz::Strukt* Clazz::p7() {}
+
+Clazz *const p10();
+// CHECK-FIXES: Clazz *p10();
+
+Clazz *const p10() {
+ // CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'Clazz *const' is 'cons
+ // CHECK-FIXES: Clazz *p10() {
+ return new Clazz();
+}
+
+const Clazz bar;
+const Clazz *const p11() {
+ // CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Clazz *const' is
+ // CHECK-FIXES: const Clazz *p11() {
+ return &bar;
+}
+
+const Klazz<const int> p12() {}
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<const int>'
+// CHECK-FIXES: Klazz<const int> p12() {}
+
+const Klazz<const int>* const p13() {}
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<const int> *
+// CHECK-FIXES: const Klazz<const int>* p13() {}
+
+// re-declaration of p15.
+const int p15();
+// CHECK-FIXES: int p15();
+
+const int p15() {
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning:
+// CHECK-FIXES: int p15() {
+ return 0;
+}
+
+// Exercise the lexer.
+
+const /* comment */ /* another comment*/ int p16() { return 0; }
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning:
+// CHECK-FIXES: /* comment */ /* another comment*/ int p16() { return 0; }
+
+/* comment */ const
+// CHECK-MESSAGES: [[@LINE-1]]:15: warning:
+// CHECK-FIXES: /* comment */
+// more
+/* another comment*/ int p17() { return 0; }
+
+// Test cases where the `const` token lexically is hidden behind some form of
+// indirection.
+
+#define CONSTINT const int
+CONSTINT p18() {}
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const int' is 'const'-qu
+
+#define CONST const
+CONST int p19() {}
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const int' is 'const'-qu
+
+using ty = const int;
+ty p21() {}
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'ty' (aka 'const int') is
+
+typedef const int ty2;
+ty2 p22() {}
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'ty2' (aka 'const int') i
+
+// Declaration uses a macro, while definition doesn't. In this case, we won't
+// fix the declaration, and will instead issue a warning.
+CONST int p23();
+// CHECK-NOTE: [[@LINE-1]]:1: note: could not transform this declaration
+
+const int p23();
+// CHECK-FIXES: int p23();
+
+const int p23() { return 3; }
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const int' is 'const'-qu
+// CHECK-FIXES: int p23() { return 3; }
+
+int const p24() { return 3; }
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const int' is 'const'-qu
+// CHECK-FIXES: int p24() { return 3; }
+
+int const * const p25(const int* p) { return p; }
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const int *const' is 'co
+// CHECK-FIXES: int const * p25(const int* p) { return p; }
+
+// We cannot (yet) fix instances that use trailing return types, but we can
+// warn.
+auto p26() -> const int { return 3; }
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const int' is 'const'-qu
+auto p27() -> int const { return 3; }
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const int' is 'const'-qu
+
+std::add_const<int>::type p28() { return 3; }
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'std::add_const<int>::typ
+
+// p29, p30 are based on
+// llvm/projects/test-suite/SingleSource/Benchmarks/Misc-C++-EH/spirit.cpp:
+template <class T>
+Klazz<T const> const p29(T const &t) { return {}; }
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<const T>' is
+// CHECK-FIXES: Klazz<T const> p29(T const &t) { return {}; }
+
+Klazz<char const *> const p30(char const *s) { return s; }
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<const char *
+// CHECK-FIXES: Klazz<char const *> p30(char const *s) { return s; }
+
+const int n1 = 1;
+const Clazz n2 = Clazz();
+const Clazz* n3 = new Clazz();
+Clazz *const n4 = new Clazz();
+const Clazz *const n5 = new Clazz();
+constexpr int n6 = 6;
+constexpr int n7() { return 8; }
+const int eight = 8;
+constexpr const int* n8() { return &eight; }
+Klazz<const int> n9();
+const Klazz<const int>* n10();
+const Klazz<const int>& Clazz::n11(const Klazz<const int>) const {}
+
+// Declaration only.
+const int n14();
+
+int **const * n_multiple_ptr();
+int *const & n_pointer_ref();
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-container-size-empty.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-container-size-empty.cpp
new file mode 100644
index 0000000..c67d927
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-container-size-empty.cpp
@@ -0,0 +1,444 @@
+// RUN: %check_clang_tidy %s readability-container-size-empty %t
+
+namespace std {
+template <typename T> struct vector {
+ vector();
+ bool operator==(const vector<T>& other) const;
+ bool operator!=(const vector<T>& other) const;
+ unsigned long size() const;
+ bool empty() const;
+};
+
+template <typename T> struct basic_string {
+ basic_string();
+ bool operator==(const basic_string<T>& other) const;
+ bool operator!=(const basic_string<T>& other) const;
+ bool operator==(const char *) const;
+ bool operator!=(const char *) const;
+ basic_string<T> operator+(const basic_string<T>& other) const;
+ unsigned long size() const;
+ bool empty() const;
+};
+
+typedef basic_string<char> string;
+typedef basic_string<wchar_t> wstring;
+
+inline namespace __v2 {
+template <typename T> struct set {
+ set();
+ bool operator==(const set<T>& other) const;
+ bool operator!=(const set<T>& other) const;
+ unsigned long size() const;
+ bool empty() const;
+};
+}
+
+}
+
+template <typename T>
+class TemplatedContainer {
+public:
+ bool operator==(const TemplatedContainer<T>& other) const;
+ bool operator!=(const TemplatedContainer<T>& other) const;
+ int size() const;
+ bool empty() const;
+};
+
+template <typename T>
+class PrivateEmpty {
+public:
+ bool operator==(const PrivateEmpty<T>& other) const;
+ bool operator!=(const PrivateEmpty<T>& other) const;
+ int size() const;
+private:
+ bool empty() const;
+};
+
+struct BoolSize {
+ bool size() const;
+ bool empty() const;
+};
+
+struct EnumSize {
+ enum E { one };
+ enum E size() const;
+ bool empty() const;
+};
+
+class Container {
+public:
+ bool operator==(const Container& other) const;
+ int size() const;
+ bool empty() const;
+};
+
+class Derived : public Container {
+};
+
+class Container2 {
+public:
+ int size() const;
+ bool empty() const { return size() == 0; }
+};
+
+class Container3 {
+public:
+ int size() const;
+ bool empty() const;
+};
+
+bool Container3::empty() const { return this->size() == 0; }
+
+class Container4 {
+public:
+ bool operator==(const Container4& rhs) const;
+ int size() const;
+ bool empty() const { return *this == Container4(); }
+};
+
+std::string s_func() {
+ return std::string();
+}
+
+int main() {
+ std::set<int> intSet;
+ std::string str;
+ std::string str2;
+ std::wstring wstr;
+ (void)(str.size() + 0);
+ (void)(str.size() - 0);
+ (void)(0 + str.size());
+ (void)(0 - str.size());
+ if (intSet.size() == 0)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]
+ // CHECK-FIXES: {{^ }}if (intSet.empty()){{$}}
+ // CHECK-MESSAGES: :32:8: note: method 'set'::empty() defined here
+ if (intSet == std::set<int>())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness
+ // CHECK-FIXES: {{^ }}if (intSet.empty()){{$}}
+ // CHECK-MESSAGES: :32:8: note: method 'set'::empty() defined here
+ if (s_func() == "")
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (s_func().empty()){{$}}
+ if (str.size() == 0)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (str.empty()){{$}}
+ if ((str + str2).size() == 0)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if ((str + str2).empty()){{$}}
+ if (str == "")
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (str.empty()){{$}}
+ if (str + str2 == "")
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if ((str + str2).empty()){{$}}
+ if (wstr.size() == 0)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (wstr.empty()){{$}}
+ if (wstr == "")
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (wstr.empty()){{$}}
+ std::vector<int> vect;
+ if (vect.size() == 0)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (vect.empty()){{$}}
+ if (vect == std::vector<int>())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (vect.empty()){{$}}
+ if (vect.size() != 0)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}}
+ if (vect != std::vector<int>())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}}
+ if (0 == vect.size())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (vect.empty()){{$}}
+ if (0 != vect.size())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}}
+ if (std::vector<int>() == vect)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (vect.empty()){{$}}
+ if (std::vector<int>() != vect)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}}
+ if (vect.size() > 0)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}}
+ if (0 < vect.size())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}}
+ if (vect.size() < 1)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (vect.empty()){{$}}
+ if (1 > vect.size())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (vect.empty()){{$}}
+ if (vect.size() >= 1)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}}
+ if (1 <= vect.size())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}}
+ if (vect.size() > 1) // no warning
+ ;
+ if (1 < vect.size()) // no warning
+ ;
+ if (vect.size() <= 1) // no warning
+ ;
+ if (1 >= vect.size()) // no warning
+ ;
+ if (!vect.size())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (vect.empty()){{$}}
+ if (vect.size())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}}
+
+ if (vect.empty())
+ ;
+
+ const std::vector<int> vect2;
+ if (vect2.size() != 0)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (!vect2.empty()){{$}}
+
+ std::vector<int> *vect3 = new std::vector<int>();
+ if (vect3->size() == 0)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (vect3->empty()){{$}}
+ if ((*vect3).size() == 0)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if ((*vect3).empty()){{$}}
+ if ((*vect3) == std::vector<int>())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (vect3->empty()){{$}}
+ if (*vect3 == std::vector<int>())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (vect3->empty()){{$}}
+
+ delete vect3;
+
+ const std::vector<int> &vect4 = vect2;
+ if (vect4.size() == 0)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (vect4.empty()){{$}}
+ if (vect4 == std::vector<int>())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (vect4.empty()){{$}}
+
+ TemplatedContainer<void> templated_container;
+ if (templated_container.size() == 0)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (templated_container.empty()){{$}}
+ if (templated_container == TemplatedContainer<void>())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (templated_container.empty()){{$}}
+ if (templated_container.size() != 0)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}}
+ if (templated_container != TemplatedContainer<void>())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}}
+ if (0 == templated_container.size())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (templated_container.empty()){{$}}
+ if (TemplatedContainer<void>() == templated_container)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (templated_container.empty()){{$}}
+ if (0 != templated_container.size())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}}
+ if (TemplatedContainer<void>() != templated_container)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}}
+ if (templated_container.size() > 0)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}}
+ if (0 < templated_container.size())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}}
+ if (templated_container.size() < 1)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (templated_container.empty()){{$}}
+ if (1 > templated_container.size())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (templated_container.empty()){{$}}
+ if (templated_container.size() >= 1)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}}
+ if (1 <= templated_container.size())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}}
+ if (templated_container.size() > 1) // no warning
+ ;
+ if (1 < templated_container.size()) // no warning
+ ;
+ if (templated_container.size() <= 1) // no warning
+ ;
+ if (1 >= templated_container.size()) // no warning
+ ;
+ if (!templated_container.size())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (templated_container.empty()){{$}}
+ if (templated_container.size())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}}
+
+ if (templated_container.empty())
+ ;
+
+ // No warnings expected.
+ PrivateEmpty<void> private_empty;
+ if (private_empty.size() == 0)
+ ;
+ if (private_empty == PrivateEmpty<void>())
+ ;
+ if (private_empty.size() != 0)
+ ;
+ if (private_empty != PrivateEmpty<void>())
+ ;
+ if (0 == private_empty.size())
+ ;
+ if (PrivateEmpty<void>() == private_empty)
+ ;
+ if (0 != private_empty.size())
+ ;
+ if (PrivateEmpty<void>() != private_empty)
+ ;
+ if (private_empty.size() > 0)
+ ;
+ if (0 < private_empty.size())
+ ;
+ if (private_empty.size() < 1)
+ ;
+ if (1 > private_empty.size())
+ ;
+ if (private_empty.size() >= 1)
+ ;
+ if (1 <= private_empty.size())
+ ;
+ if (private_empty.size() > 1)
+ ;
+ if (1 < private_empty.size())
+ ;
+ if (private_empty.size() <= 1)
+ ;
+ if (1 >= private_empty.size())
+ ;
+ if (!private_empty.size())
+ ;
+ if (private_empty.size())
+ ;
+
+ // Types with weird size() return type.
+ BoolSize bs;
+ if (bs.size() == 0)
+ ;
+ EnumSize es;
+ if (es.size() == 0)
+ ;
+
+ Derived derived;
+ if (derived.size() == 0)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (derived.empty()){{$}}
+ if (derived == Derived())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-FIXES: {{^ }}if (derived.empty()){{$}}
+}
+
+#define CHECKSIZE(x) if (x.size()) {}
+// CHECK-FIXES: #define CHECKSIZE(x) if (x.size()) {}
+
+template <typename T> void f() {
+ std::vector<T> v;
+ if (v.size())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]
+ // CHECK-MESSAGES: :9:8: note: method 'vector'::empty() defined here
+ // CHECK-FIXES: {{^ }}if (!v.empty()){{$}}
+ if (v == std::vector<T>())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of comparing to an empty object [readability-container-size-empty]
+ // CHECK-FIXES: {{^ }}if (v.empty()){{$}}
+ // CHECK-FIXES-NEXT: ;
+ CHECKSIZE(v);
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used
+ // CHECK-MESSAGES: :9:8: note: method 'vector'::empty() defined here
+ // CHECK-FIXES: CHECKSIZE(v);
+
+ TemplatedContainer<T> templated_container;
+ if (templated_container.size())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-MESSAGES: :44:8: note: method 'TemplatedContainer'::empty() defined here
+ // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}}
+ if (templated_container != TemplatedContainer<T>())
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+ // CHECK-MESSAGES: :44:8: note: method 'TemplatedContainer'::empty() defined here
+ // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}}
+ // CHECK-FIXES-NEXT: ;
+ CHECKSIZE(templated_container);
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used
+ // CHECK-MESSAGES: :44:8: note: method 'TemplatedContainer'::empty() defined here
+ // CHECK-FIXES: CHECKSIZE(templated_container);
+}
+
+void g() {
+ f<int>();
+ f<double>();
+ f<char *>();
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-delete-null-pointer.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-delete-null-pointer.cpp
new file mode 100644
index 0000000..b46e52a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-delete-null-pointer.cpp
@@ -0,0 +1,86 @@
+// RUN: %check_clang_tidy %s readability-delete-null-pointer %t
+
+#define NULL 0
+
+void f() {
+ int *p = 0;
+
+ // #1
+ if (p) { // #2
+ delete p;
+ } // #3
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: 'if' statement is unnecessary; deleting null pointer has no effect [readability-delete-null-pointer]
+
+ // CHECK-FIXES: {{^ }}// #1
+ // CHECK-FIXES-NEXT: {{^ }}// #2
+ // CHECK-FIXES-NEXT: delete p;
+ // CHECK-FIXES-NEXT: {{^ }}// #3
+
+ int *p2 = new int[3];
+ // #4
+ if (p2) // #5
+ delete[] p2;
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: 'if' statement is unnecessary;
+
+ // CHECK-FIXES: // #4
+ // CHECK-FIXES-NEXT: {{^ }}// #5
+ // CHECK-FIXES-NEXT: delete[] p2;
+
+ int *p3 = 0;
+ if (NULL != p3) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'if' statement is unnecessary;
+ delete p3;
+ }
+ // CHECK-FIXES-NOT: if (NULL != p3) {
+ // CHECK-FIXES: delete p3;
+
+ int *p4 = nullptr;
+ if (p4 != nullptr) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'if' statement is unnecessary;
+ delete p4;
+ }
+ // CHECK-FIXES-NOT: if (p4 != nullptr) {
+ // CHECK-FIXES: delete p4;
+
+ char *c;
+ if (c != 0) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'if' statement is unnecessary;
+ delete c;
+ }
+ // CHECK-FIXES-NOT: if (c != 0) {
+ // CHECK-FIXES: delete c;
+
+ char *c2;
+ if (c2) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'if' statement is unnecessary;
+ // CHECK-FIXES: } else {
+ // CHECK-FIXES: c2 = c;
+ delete c2;
+ } else {
+ c2 = c;
+ }
+ struct A {
+ void foo() {
+ if (mp) // #6
+ delete mp;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: 'if' statement is unnecessary; deleting null pointer has no effect [readability-delete-null-pointer]
+ // CHECK-FIXES: {{^ }}// #6
+ // CHECK-FIXES-NEXT: delete mp;
+ }
+ int *mp;
+ };
+}
+
+void g() {
+ int *p5, *p6;
+ if (p5)
+ delete p6;
+
+ if (p5 && p6)
+ delete p5;
+
+ if (p6) {
+ int x = 5;
+ delete p6;
+ }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-deleted-default.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-deleted-default.cpp
new file mode 100644
index 0000000..bf27e00
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-deleted-default.cpp
@@ -0,0 +1,127 @@
+// RUN: %check_clang_tidy %s readability-deleted-default %t -- -- -std=c++11 -fno-ms-compatibility
+
+class NoDefault {
+public:
+ NoDefault() = delete;
+ NoDefault(NoDefault &&Other) = delete;
+ NoDefault(const NoDefault &Other) = delete;
+};
+
+class MissingEverything {
+public:
+ MissingEverything() = default;
+ // CHECK-MESSAGES: warning: default constructor is explicitly defaulted but implicitly deleted, probably because a non-static data member or a base class is lacking a default constructor; definition can either be removed or explicitly deleted [readability-deleted-default]
+ MissingEverything(MissingEverything &&Other) = default;
+ // CHECK-MESSAGES: warning: move constructor is explicitly defaulted but implicitly deleted, probably because a non-static data member or a base class is neither copyable nor movable; definition can either be removed or explicitly deleted [readability-deleted-default]
+ MissingEverything(const MissingEverything &Other) = default;
+ // CHECK-MESSAGES: warning: copy constructor is explicitly defaulted but implicitly deleted, probably because a non-static data member or a base class is not copyable; definition can either be removed or explicitly deleted [readability-deleted-default]
+ MissingEverything &operator=(MissingEverything &&Other) = default;
+ // CHECK-MESSAGES: warning: move assignment operator is explicitly defaulted but implicitly deleted, probably because a base class or a non-static data member is not assignable, e.g. because the latter is marked 'const'; definition can either be removed or explicitly deleted [readability-deleted-default]
+ MissingEverything &operator=(const MissingEverything &Other) = default;
+ // CHECK-MESSAGES: warning: copy assignment operator is explicitly defaulted but implicitly deleted, probably because a base class or a non-static data member is not assignable, e.g. because the latter is marked 'const'; definition can either be removed or explicitly deleted [readability-deleted-default]
+
+private:
+ NoDefault ND;
+};
+
+class NotAssignable {
+public:
+ NotAssignable(NotAssignable &&Other) = default;
+ NotAssignable(const NotAssignable &Other) = default;
+ NotAssignable &operator=(NotAssignable &&Other) = default;
+ // CHECK-MESSAGES: warning: move assignment operator is explicitly defaulted but implicitly deleted
+ NotAssignable &operator=(const NotAssignable &Other) = default;
+ // CHECK-MESSAGES: warning: copy assignment operator is explicitly defaulted but implicitly deleted
+
+private:
+ const int I = 0;
+};
+
+class Movable {
+public:
+ Movable() = default;
+ Movable(Movable &&Other) = default;
+ Movable(const Movable &Other) = delete;
+ Movable &operator=(Movable &&Other) = default;
+ Movable &operator=(const Movable &Other) = delete;
+};
+
+class NotCopyable {
+public:
+ NotCopyable(NotCopyable &&Other) = default;
+ NotCopyable(const NotCopyable &Other) = default;
+ // CHECK-MESSAGES: warning: copy constructor is explicitly defaulted but implicitly deleted
+ NotCopyable &operator=(NotCopyable &&Other) = default;
+ NotCopyable &operator=(const NotCopyable &Other) = default;
+ // CHECK-MESSAGES: warning: copy assignment operator is explicitly defaulted but implicitly deleted
+private:
+ Movable M;
+};
+
+template <typename T> class Templated {
+public:
+ // No warning here, it is a templated class.
+ Templated() = default;
+ Templated(Templated &&Other) = default;
+ Templated(const Templated &Other) = default;
+ Templated &operator=(Templated &&Other) = default;
+ Templated &operator=(const Templated &Other) = default;
+
+ class InnerTemplated {
+ public:
+ // This class is not in itself templated, but we still don't have warning.
+ InnerTemplated() = default;
+ InnerTemplated(InnerTemplated &&Other) = default;
+ InnerTemplated(const InnerTemplated &Other) = default;
+ InnerTemplated &operator=(InnerTemplated &&Other) = default;
+ InnerTemplated &operator=(const InnerTemplated &Other) = default;
+
+ private:
+ T TVar;
+ };
+
+ class InnerNotTemplated {
+ public:
+ // This one could technically have warnings, but currently doesn't.
+ InnerNotTemplated() = default;
+ InnerNotTemplated(InnerNotTemplated &&Other) = default;
+ InnerNotTemplated(const InnerNotTemplated &Other) = default;
+ InnerNotTemplated &operator=(InnerNotTemplated &&Other) = default;
+ InnerNotTemplated &operator=(const InnerNotTemplated &Other) = default;
+
+ private:
+ int I;
+ };
+
+private:
+ const T TVar{};
+};
+
+int FunctionWithInnerClass() {
+ class InnerNotAssignable {
+ public:
+ InnerNotAssignable &operator=(InnerNotAssignable &&Other) = default;
+ // CHECK-MESSAGES: warning: move assignment operator is explicitly defaulted but implicitly deleted
+ private:
+ const int I = 0;
+ };
+ return 1;
+};
+
+template <typename T>
+int TemplateFunctionWithInnerClass() {
+ class InnerNotAssignable {
+ public:
+ InnerNotAssignable &operator=(InnerNotAssignable &&Other) = default;
+ private:
+ const T TVar{};
+ };
+ return 1;
+};
+
+void Foo() {
+ Templated<const int> V1;
+ Templated<int>::InnerTemplated V2;
+ Templated<float>::InnerNotTemplated V3;
+ TemplateFunctionWithInnerClass<int>();
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-else-after-return-if-constexpr.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-else-after-return-if-constexpr.cpp
new file mode 100644
index 0000000..6532940
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-else-after-return-if-constexpr.cpp
@@ -0,0 +1,22 @@
+// RUN: %check_clang_tidy %s readability-else-after-return %t -- -- -std=c++17
+
+// Constexpr if is an exception to the rule, we cannot remove the else.
+void f() {
+ if (sizeof(int) > 4)
+ return;
+ else
+ return;
+ // CHECK-MESSAGES: [[@LINE-2]]:3: warning: do not use 'else' after 'return'
+
+ if constexpr (sizeof(int) > 4)
+ return;
+ else
+ return;
+
+ if constexpr (sizeof(int) > 4)
+ return;
+ else if constexpr (sizeof(long) > 4)
+ return;
+ else
+ return;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-else-after-return.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-else-after-return.cpp
new file mode 100644
index 0000000..7e95092
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-else-after-return.cpp
@@ -0,0 +1,107 @@
+// RUN: %check_clang_tidy %s readability-else-after-return %t -- -- -std=c++11 -fexceptions
+
+namespace std {
+struct string {
+ string(const char *);
+ ~string();
+};
+} // namespace std
+
+struct my_exception {
+ my_exception(const std::string &s);
+};
+
+void f(int a) {
+ if (a > 0)
+ return;
+ else // comment-0
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use 'else' after 'return'
+ // CHECK-FIXES: {{^}} // comment-0
+ return;
+
+ if (a > 0) {
+ return;
+ } else { // comment-1
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use 'else' after 'return'
+ // CHECK-FIXES: {{^}} } // comment-1
+ return;
+ }
+
+ if (a > 0) {
+ f(0);
+ if (a > 10)
+ return;
+ } else {
+ return;
+ }
+
+ if (a > 0)
+ f(0);
+ else if (a > 10)
+ return;
+ else // comment-2
+ // CHECK-FIXES-NOT: {{^}} // comment-2
+ f(0);
+
+ if (a > 0)
+ if (a < 10)
+ return;
+ else // comment-3
+ // CHECK-FIXES-NOT: {{^}} // comment-3
+ f(0);
+ else
+ if (a > 10)
+ return;
+ else // comment-4
+ // CHECK-FIXES-NOT: {{^}} // comment-4
+ f(0);
+
+ if (a > 0) {
+ if (a < 10)
+ return;
+ else // comment-5
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use 'else' after 'return'
+ // CHECK-FIXES: {{^}} // comment-5
+ f(0);
+ } else {
+ if (a > 10)
+ return;
+ else // comment-6
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use 'else' after 'return'
+ // CHECK-FIXES: {{^}} // comment-6
+ f(0);
+ }
+}
+
+void foo() {
+ for (unsigned x = 0; x < 42; ++x) {
+ if (x) {
+ continue;
+ } else { // comment-7
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use 'else' after 'continue'
+ // CHECK-FIXES: {{^}} } // comment-7
+ x++;
+ }
+ if (x) {
+ break;
+ } else { // comment-8
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use 'else' after 'break'
+ // CHECK-FIXES: {{^}} } // comment-8
+ x++;
+ }
+ if (x) {
+ throw 42;
+ } else { // comment-9
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use 'else' after 'throw'
+ // CHECK-FIXES: {{^}} } // comment-9
+ x++;
+ }
+ if (x) {
+ throw my_exception("foo");
+ } else { // comment-10
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use 'else' after 'throw'
+ // CHECK-FIXES: {{^}} } // comment-10
+ x++;
+ }
+ }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-function-size-variables-c++17.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-function-size-variables-c++17.cpp
new file mode 100644
index 0000000..8af0d96
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-function-size-variables-c++17.cpp
@@ -0,0 +1,21 @@
+// RUN: %check_clang_tidy %s readability-function-size %t -- -config='{CheckOptions: [{key: readability-function-size.LineThreshold, value: 0}, {key: readability-function-size.StatementThreshold, value: 0}, {key: readability-function-size.BranchThreshold, value: 0}, {key: readability-function-size.ParameterThreshold, value: 5}, {key: readability-function-size.NestingThreshold, value: 2}, {key: readability-function-size.VariableThreshold, value: 1}]}' -- -std=c++17
+
+void structured_bindings() {
+ int a[2] = {1, 2};
+ auto [x, y] = a;
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:6: warning: function 'structured_bindings' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 3 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 2 statements (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-7]]:6: note: 3 variables (threshold 1)
+
+#define SWAP(x, y) ({auto& [x0, x1] = x; __typeof__(x) t = {x0, x1}; auto& [y0, y1] = y; auto& [t0, t1] = t; x0 = y0; x1 = y1; y0 = t0; y1 = t1; })
+void variables_13() {
+ int a[2] = {1, 2};
+ int b[2] = {3, 4};
+ SWAP(a, b);
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:6: warning: function 'variables_13' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 4 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-7]]:6: note: 11 statements (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-8]]:6: note: 2 variables (threshold 1)
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-function-size.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-function-size.cpp
new file mode 100644
index 0000000..efb41a1
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-function-size.cpp
@@ -0,0 +1,301 @@
+// RUN: %check_clang_tidy %s readability-function-size %t -- -config='{CheckOptions: [{key: readability-function-size.LineThreshold, value: 0}, {key: readability-function-size.StatementThreshold, value: 0}, {key: readability-function-size.BranchThreshold, value: 0}, {key: readability-function-size.ParameterThreshold, value: 5}, {key: readability-function-size.NestingThreshold, value: 2}, {key: readability-function-size.VariableThreshold, value: 1}]}' -- -std=c++11
+
+// Bad formatting is intentional, don't run clang-format over the whole file!
+
+void foo1() {
+}
+
+void foo2() {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'foo2' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-2]]:6: note: 1 statements (threshold 0)
+
+void foo3() {
+;
+
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:6: warning: function 'foo3' exceeds recommended size/complexity
+// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 3 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 1 statements (threshold 0)
+
+void foo4(int i) { if (i) {} else; {}
+}
+// CHECK-MESSAGES: :[[@LINE-2]]:6: warning: function 'foo4' exceeds recommended size/complexity
+// CHECK-MESSAGES: :[[@LINE-3]]:6: note: 1 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-4]]:6: note: 3 statements (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 1 branches (threshold 0)
+
+void foo5(int i) {for(;i;)while(i)
+do;while(i);
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:6: warning: function 'foo5' exceeds recommended size/complexity
+// CHECK-MESSAGES: :[[@LINE-4]]:6: note: 2 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 7 statements (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 3 branches (threshold 0)
+
+template <typename T> T foo6(T i) {return i;
+}
+int x = foo6(0);
+// CHECK-MESSAGES: :[[@LINE-3]]:25: warning: function 'foo6' exceeds recommended size/complexity
+// CHECK-MESSAGES: :[[@LINE-4]]:25: note: 1 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-5]]:25: note: 1 statements (threshold 0)
+
+void foo7(int p1, int p2, int p3, int p4, int p5, int p6) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'foo7' exceeds recommended size/complexity
+// CHECK-MESSAGES: :[[@LINE-2]]:6: note: 1 statements (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-3]]:6: note: 6 parameters (threshold 5)
+
+void bar1() { [](){;;;;;;;;;;;if(1){}}();
+
+
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:6: warning: function 'bar1' exceeds recommended size/complexity
+// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 3 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 14 statements (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-7]]:6: note: 1 branches (threshold 0)
+
+void bar2() { class A { void barx() {;;} }; }
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'bar2' exceeds recommended size/complexity
+// CHECK-MESSAGES: :[[@LINE-2]]:6: note: 3 statements (threshold 0)
+//
+// CHECK-MESSAGES: :[[@LINE-4]]:30: warning: function 'barx' exceeds recommended size/complexity
+// CHECK-MESSAGES: :[[@LINE-5]]:30: note: 2 statements (threshold 0)
+
+#define macro() {int x; {int y; {int z;}}}
+
+void baz0() { // 1
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'baz0' exceeds recommended size/complexity
+ // CHECK-MESSAGES: :[[@LINE-2]]:6: note: 28 lines including whitespace and comments (threshold 0)
+ // CHECK-MESSAGES: :[[@LINE-3]]:6: note: 9 statements (threshold 0)
+ int a;
+ { // 2
+ int b;
+ { // 3
+// CHECK-MESSAGES: :[[@LINE-1]]:5: note: nesting level 3 starts here (threshold 2)
+ int c;
+ { // 4
+ int d;
+ }
+ }
+ }
+ { // 2
+ int e;
+ }
+ { // 2
+ { // 3
+// CHECK-MESSAGES: :[[@LINE-1]]:5: note: nesting level 3 starts here (threshold 2)
+ int j;
+ }
+ }
+ macro()
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: note: nesting level 3 starts here (threshold 2)
+ // CHECK-MESSAGES: :[[@LINE-28]]:25: note: expanded from macro 'macro'
+ // CHECK-MESSAGES: :[[@LINE-27]]:6: note: 9 variables (threshold 1)
+}
+
+// check that nested if's are not reported. this was broken initially
+void nesting_if() { // 1
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'nesting_if' exceeds recommended size/complexity
+ // CHECK-MESSAGES: :[[@LINE-2]]:6: note: 23 lines including whitespace and comments (threshold 0)
+ // CHECK-MESSAGES: :[[@LINE-3]]:6: note: 18 statements (threshold 0)
+ // CHECK-MESSAGES: :[[@LINE-4]]:6: note: 6 branches (threshold 0)
+ if (true) { // 2
+ int j;
+ } else if (true) { // 2
+ int j;
+ if (true) { // 3
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: note: nesting level 3 starts here (threshold 2)
+ int j;
+ }
+ } else if (true) { // 2
+ int j;
+ if (true) { // 3
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: note: nesting level 3 starts here (threshold 2)
+ int j;
+ }
+ } else if (true) { // 2
+ int j;
+ }
+ // CHECK-MESSAGES: :[[@LINE-22]]:6: note: 6 variables (threshold 1)
+}
+
+// however this should warn
+void bad_if_nesting() { // 1
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'bad_if_nesting' exceeds recommended size/complexity
+// CHECK-MESSAGES: :[[@LINE-2]]:6: note: 23 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-3]]:6: note: 12 statements (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-4]]:6: note: 4 branches (threshold 0)
+ if (true) { // 2
+ int j;
+ } else { // 2
+ if (true) { // 3
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: note: nesting level 3 starts here (threshold 2)
+ int j;
+ } else { // 3
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: note: nesting level 3 starts here (threshold 2)
+ if (true) { // 4
+ int j;
+ } else { // 4
+ if (true) { // 5
+ int j;
+ }
+ }
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-22]]:6: note: 4 variables (threshold 1)
+}
+
+void variables_0() {
+ int i;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:6: warning: function 'variables_0' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-4]]:6: note: 2 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 1 statements (threshold 0)
+void variables_1(int i) {
+ int j;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:6: warning: function 'variables_1' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-4]]:6: note: 2 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 1 statements (threshold 0)
+void variables_2(int i, int j) {
+ ;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:6: warning: function 'variables_2' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-4]]:6: note: 2 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 1 statements (threshold 0)
+void variables_3() {
+ int i[2];
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:6: warning: function 'variables_3' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-4]]:6: note: 2 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 1 statements (threshold 0)
+void variables_4() {
+ int i;
+ int j;
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:6: warning: function 'variables_4' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 3 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 2 statements (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-7]]:6: note: 2 variables (threshold 1)
+void variables_5() {
+ int i, j;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:6: warning: function 'variables_5' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-4]]:6: note: 2 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 1 statements (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 2 variables (threshold 1)
+void variables_6() {
+ for (int i;;)
+ for (int j;;)
+ ;
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:6: warning: function 'variables_6' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 4 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-7]]:6: note: 5 statements (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-8]]:6: note: 2 branches (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-9]]:6: note: 2 variables (threshold 1)
+void variables_7() {
+ if (int a = 1)
+ if (int b = 2)
+ ;
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:6: warning: function 'variables_7' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 4 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-7]]:6: note: 7 statements (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-8]]:6: note: 2 branches (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-9]]:6: note: 2 variables (threshold 1)
+void variables_8() {
+ int a[2];
+ for (auto i : a)
+ for (auto j : a)
+ ;
+}
+// CHECK-MESSAGES: :[[@LINE-6]]:6: warning: function 'variables_8' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-7]]:6: note: 5 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-8]]:6: note: 8 statements (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-9]]:6: note: 2 branches (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-10]]:6: note: 3 variables (threshold 1)
+void variables_9() {
+ int a, b;
+ struct A {
+ A(int c, int d) {
+ int e, f;
+ }
+ };
+}
+// CHECK-MESSAGES: :[[@LINE-8]]:6: warning: function 'variables_9' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-9]]:6: note: 7 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-10]]:6: note: 3 statements (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-11]]:6: note: 2 variables (threshold 1)
+// CHECK-MESSAGES: :[[@LINE-9]]:5: warning: function 'A' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-10]]:5: note: 2 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-11]]:5: note: 1 statements (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-12]]:5: note: 2 variables (threshold 1)
+void variables_10() {
+ int a, b;
+ struct A {
+ int c;
+ int d;
+ };
+}
+// CHECK-MESSAGES: :[[@LINE-7]]:6: warning: function 'variables_10' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-8]]:6: note: 6 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-9]]:6: note: 2 statements (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-10]]:6: note: 2 variables (threshold 1)
+void variables_11() {
+ struct S {
+ void bar() {
+ int a, b;
+ }
+ };
+}
+// CHECK-MESSAGES: :[[@LINE-7]]:6: warning: function 'variables_11' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-8]]:6: note: 6 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-7]]:10: warning: function 'bar' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-8]]:10: note: 2 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-9]]:10: note: 2 variables (threshold 1)
+void variables_12() {
+ int v;
+ auto test = [](int a, int b) -> void {};
+ test({}, {});
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:6: warning: function 'variables_12' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 4 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-7]]:6: note: 3 statements (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-8]]:6: note: 2 variables (threshold 1)
+void variables_13() {
+ int v;
+ auto test = []() -> void {
+ int a;
+ int b;
+ };
+ test();
+}
+// CHECK-MESSAGES: :[[@LINE-8]]:6: warning: function 'variables_13' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-9]]:6: note: 7 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-10]]:6: note: 5 statements (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-11]]:6: note: 2 variables (threshold 1)
+void variables_14() {
+ (void)({int a = 12; a; });
+ (void)({int a = 12; a; });
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:6: warning: function 'variables_14' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 3 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 6 statements (threshold 0)
+#define SWAP(x, y) ({__typeof__(x) temp = x; x = y; y = temp; })
+void variables_15() {
+ int a = 10, b = 12;
+ SWAP(a, b);
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:6: warning: function 'variables_15' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 3 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 5 statements (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-7]]:6: note: 2 variables (threshold 1)
+#define vardecl(type, name) type name;
+void variables_16() {
+ vardecl(int, a);
+ vardecl(int, b);
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:6: warning: function 'variables_16' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 3 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 4 statements (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-7]]:6: note: 2 variables (threshold 1)
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-identifier-naming-objc.m b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-identifier-naming-objc.m
new file mode 100644
index 0000000..ab123c2
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-identifier-naming-objc.m
@@ -0,0 +1,12 @@
+// RUN: %check_clang_tidy %s readability-identifier-naming %t \
+// RUN: -config='{CheckOptions: \
+// RUN: [{key: readability-identifier-naming.ObjcIvarPrefix, value: '_'}]}' \
+// RUN: --
+
+@interface Foo {
+ int _bar;
+ int barWithoutPrefix;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for objc ivar 'barWithoutPrefix' [readability-identifier-naming]
+ // CHECK-FIXES: int _barWithoutPrefix;
+}
+@end
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-identifier-naming.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-identifier-naming.cpp
new file mode 100644
index 0000000..211a28b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-identifier-naming.cpp
@@ -0,0 +1,503 @@
+// Remove UNSUPPORTED for powerpc64le when the problem introduced by
+// r288563 is resolved.
+// UNSUPPORTED: powerpc64le
+// RUN: %check_clang_tidy %s readability-identifier-naming %t -- \
+// RUN: -config='{CheckOptions: [ \
+// RUN: {key: readability-identifier-naming.AbstractClassCase, value: CamelCase}, \
+// RUN: {key: readability-identifier-naming.AbstractClassPrefix, value: 'A'}, \
+// RUN: {key: readability-identifier-naming.ClassCase, value: CamelCase}, \
+// RUN: {key: readability-identifier-naming.ClassPrefix, value: 'C'}, \
+// RUN: {key: readability-identifier-naming.ClassConstantCase, value: CamelCase}, \
+// RUN: {key: readability-identifier-naming.ClassConstantPrefix, value: 'k'}, \
+// RUN: {key: readability-identifier-naming.ClassMemberCase, value: CamelCase}, \
+// RUN: {key: readability-identifier-naming.ClassMethodCase, value: camelBack}, \
+// RUN: {key: readability-identifier-naming.ConstantCase, value: UPPER_CASE}, \
+// RUN: {key: readability-identifier-naming.ConstantSuffix, value: '_CST'}, \
+// RUN: {key: readability-identifier-naming.ConstexprFunctionCase, value: lower_case}, \
+// RUN: {key: readability-identifier-naming.ConstexprMethodCase, value: lower_case}, \
+// RUN: {key: readability-identifier-naming.ConstexprVariableCase, value: lower_case}, \
+// RUN: {key: readability-identifier-naming.EnumCase, value: CamelCase}, \
+// RUN: {key: readability-identifier-naming.EnumPrefix, value: 'E'}, \
+// RUN: {key: readability-identifier-naming.EnumConstantCase, value: UPPER_CASE}, \
+// RUN: {key: readability-identifier-naming.FunctionCase, value: camelBack}, \
+// RUN: {key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE}, \
+// RUN: {key: readability-identifier-naming.GlobalFunctionCase, value: CamelCase}, \
+// RUN: {key: readability-identifier-naming.GlobalVariableCase, value: lower_case}, \
+// RUN: {key: readability-identifier-naming.GlobalVariablePrefix, value: 'g_'}, \
+// RUN: {key: readability-identifier-naming.InlineNamespaceCase, value: lower_case}, \
+// RUN: {key: readability-identifier-naming.LocalConstantCase, value: CamelCase}, \
+// RUN: {key: readability-identifier-naming.LocalConstantPrefix, value: 'k'}, \
+// RUN: {key: readability-identifier-naming.LocalVariableCase, value: lower_case}, \
+// RUN: {key: readability-identifier-naming.MemberCase, value: CamelCase}, \
+// RUN: {key: readability-identifier-naming.MemberPrefix, value: 'm_'}, \
+// RUN: {key: readability-identifier-naming.ConstantMemberCase, value: lower_case}, \
+// RUN: {key: readability-identifier-naming.PrivateMemberPrefix, value: '__'}, \
+// RUN: {key: readability-identifier-naming.ProtectedMemberPrefix, value: '_'}, \
+// RUN: {key: readability-identifier-naming.PublicMemberCase, value: lower_case}, \
+// RUN: {key: readability-identifier-naming.MethodCase, value: camelBack}, \
+// RUN: {key: readability-identifier-naming.PrivateMethodPrefix, value: '__'}, \
+// RUN: {key: readability-identifier-naming.ProtectedMethodPrefix, value: '_'}, \
+// RUN: {key: readability-identifier-naming.NamespaceCase, value: lower_case}, \
+// RUN: {key: readability-identifier-naming.ParameterCase, value: camelBack}, \
+// RUN: {key: readability-identifier-naming.ParameterPrefix, value: 'a_'}, \
+// RUN: {key: readability-identifier-naming.ConstantParameterCase, value: camelBack}, \
+// RUN: {key: readability-identifier-naming.ConstantParameterPrefix, value: 'i_'}, \
+// RUN: {key: readability-identifier-naming.ParameterPackCase, value: camelBack}, \
+// RUN: {key: readability-identifier-naming.PureFunctionCase, value: lower_case}, \
+// RUN: {key: readability-identifier-naming.PureMethodCase, value: camelBack}, \
+// RUN: {key: readability-identifier-naming.StaticConstantCase, value: UPPER_CASE}, \
+// RUN: {key: readability-identifier-naming.StaticVariableCase, value: camelBack}, \
+// RUN: {key: readability-identifier-naming.StaticVariablePrefix, value: 's_'}, \
+// RUN: {key: readability-identifier-naming.StructCase, value: lower_case}, \
+// RUN: {key: readability-identifier-naming.TemplateParameterCase, value: UPPER_CASE}, \
+// RUN: {key: readability-identifier-naming.TemplateTemplateParameterCase, value: CamelCase}, \
+// RUN: {key: readability-identifier-naming.TemplateUsingCase, value: lower_case}, \
+// RUN: {key: readability-identifier-naming.TemplateUsingPrefix, value: 'u_'}, \
+// RUN: {key: readability-identifier-naming.TypeTemplateParameterCase, value: camelBack}, \
+// RUN: {key: readability-identifier-naming.TypeTemplateParameterSuffix, value: '_t'}, \
+// RUN: {key: readability-identifier-naming.TypedefCase, value: lower_case}, \
+// RUN: {key: readability-identifier-naming.TypedefSuffix, value: '_t'}, \
+// RUN: {key: readability-identifier-naming.UnionCase, value: CamelCase}, \
+// RUN: {key: readability-identifier-naming.UnionPrefix, value: 'U'}, \
+// RUN: {key: readability-identifier-naming.UsingCase, value: lower_case}, \
+// RUN: {key: readability-identifier-naming.ValueTemplateParameterCase, value: camelBack}, \
+// RUN: {key: readability-identifier-naming.VariableCase, value: lower_case}, \
+// RUN: {key: readability-identifier-naming.VirtualMethodCase, value: Camel_Snake_Case}, \
+// RUN: {key: readability-identifier-naming.VirtualMethodPrefix, value: 'v_'}, \
+// RUN: {key: readability-identifier-naming.MacroDefinitionCase, value: UPPER_CASE}, \
+// RUN: {key: readability-identifier-naming.TypeAliasCase, value: camel_Snake_Back}, \
+// RUN: {key: readability-identifier-naming.TypeAliasSuffix, value: '_t'}, \
+// RUN: {key: readability-identifier-naming.IgnoreFailedSplit, value: 0}, \
+// RUN: {key: readability-identifier-naming.GlobalPointerCase, value: CamelCase}, \
+// RUN: {key: readability-identifier-naming.GlobalPointerSuffix, value: '_Ptr'}, \
+// RUN: {key: readability-identifier-naming.GlobalConstantPointerCase, value: UPPER_CASE}, \
+// RUN: {key: readability-identifier-naming.GlobalConstantPointerSuffix, value: '_Ptr'}, \
+// RUN: {key: readability-identifier-naming.PointerParameterCase, value: lower_case}, \
+// RUN: {key: readability-identifier-naming.PointerParameterPrefix, value: 'p_'}, \
+// RUN: {key: readability-identifier-naming.ConstantPointerParameterCase, value: CamelCase}, \
+// RUN: {key: readability-identifier-naming.ConstantPointerParameterPrefix, value: 'cp_'}, \
+// RUN: {key: readability-identifier-naming.LocalPointerCase, value: CamelCase}, \
+// RUN: {key: readability-identifier-naming.LocalPointerPrefix, value: 'l_'}, \
+// RUN: {key: readability-identifier-naming.LocalConstantPointerCase, value: CamelCase}, \
+// RUN: {key: readability-identifier-naming.LocalConstantPointerPrefix, value: 'lc_'}, \
+// RUN: ]}' -- -std=c++11 -fno-delayed-template-parsing \
+// RUN: -I%S/Inputs/readability-identifier-naming \
+// RUN: -isystem %S/Inputs/readability-identifier-naming/system
+
+// clang-format off
+
+#include <system-header.h>
+#include "user-header.h"
+// NO warnings or fixes expected from declarations within header files without
+// the -header-filter= option
+
+namespace FOO_NS {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: invalid case style for namespace 'FOO_NS' [readability-identifier-naming]
+// CHECK-FIXES: {{^}}namespace foo_ns {{{$}}
+inline namespace InlineNamespace {
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for inline namespace 'InlineNamespace'
+// CHECK-FIXES: {{^}}inline namespace inline_namespace {{{$}}
+
+SYSTEM_NS::structure g_s1;
+// NO warnings or fixes expected as SYSTEM_NS and structure are declared in a header file
+
+USER_NS::object g_s2;
+// NO warnings or fixes expected as USER_NS and object are declared in a header file
+
+SYSTEM_MACRO(var1);
+// NO warnings or fixes expected as var1 is from macro expansion
+
+USER_MACRO(var2);
+// NO warnings or fixes expected as var2 is declared in a macro expansion
+
+#define BLA int FOO_bar
+BLA;
+// NO warnings or fixes expected as FOO_bar is from macro expansion
+
+int global0;
+#define USE_NUMBERED_GLOBAL(number) auto use_global##number = global##number
+USE_NUMBERED_GLOBAL(0);
+// NO warnings or fixes expected as global0 is pieced together in a macro
+// expansion.
+
+int global1;
+#define USE_NUMBERED_BAL(prefix, number) \
+ auto use_##prefix##bal##number = prefix##bal##number
+USE_NUMBERED_BAL(glo, 1);
+// NO warnings or fixes expected as global1 is pieced together in a macro
+// expansion.
+
+int global2;
+#define USE_RECONSTRUCTED(glo, bal) auto use_##glo##bal = glo##bal
+USE_RECONSTRUCTED(glo, bal2);
+// NO warnings or fixes expected as global2 is pieced together in a macro
+// expansion.
+
+int global;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for global variable 'global'
+// CHECK-FIXES: {{^}}int g_global;{{$}}
+#define USE_IN_MACRO(m) auto use_##m = m
+USE_IN_MACRO(global);
+
+int global3;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for global variable 'global3'
+// CHECK-FIXES: {{^}}int g_global3;{{$}}
+#define ADD_TO_SELF(m) (m) + (m)
+int g_twice_global3 = ADD_TO_SELF(global3);
+// CHECK-FIXES: {{^}}int g_twice_global3 = ADD_TO_SELF(g_global3);{{$}}
+
+enum my_enumeration {
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: invalid case style for enum 'my_enumeration'
+// CHECK-FIXES: {{^}}enum EMyEnumeration {{{$}}
+ MyConstant = 1,
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for enum constant 'MyConstant'
+// CHECK-FIXES: {{^}} MY_CONSTANT = 1,{{$}}
+ your_CONST = 1,
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for enum constant 'your_CONST'
+// CHECK-FIXES: {{^}} YOUR_CONST = 1,{{$}}
+ THIS_ConstValue = 1,
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for enum constant 'THIS_ConstValue'
+// CHECK-FIXES: {{^}} THIS_CONST_VALUE = 1,{{$}}
+};
+
+constexpr int ConstExpr_variable = MyConstant;
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: invalid case style for constexpr variable 'ConstExpr_variable'
+// CHECK-FIXES: {{^}}constexpr int const_expr_variable = MY_CONSTANT;{{$}}
+
+class my_class {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for class 'my_class'
+// CHECK-FIXES: {{^}}class CMyClass {{{$}}
+public:
+ my_class();
+// CHECK-FIXES: {{^}} CMyClass();{{$}}
+
+ my_class(void*) : my_class() {}
+// CHECK-FIXES: {{^}} CMyClass(void*) : CMyClass() {}{{$}}
+
+ ~
+ my_class();
+// (space in destructor token test, we could check trigraph but they will be deprecated)
+// CHECK-FIXES: {{^}} ~{{$}}
+// CHECK-FIXES: {{^}} CMyClass();{{$}}
+
+private:
+ const int MEMBER_one_1 = ConstExpr_variable;
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: invalid case style for constant member 'MEMBER_one_1'
+// CHECK-FIXES: {{^}} const int member_one_1 = const_expr_variable;{{$}}
+ int member2 = 2;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for private member 'member2'
+// CHECK-FIXES: {{^}} int __member2 = 2;{{$}}
+ int _memberWithExtraUnderscores_ = 42;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for private member '_memberWithExtraUnderscores_'
+// CHECK-FIXES: {{^}} int __memberWithExtraUnderscores = 42;{{$}}
+
+private:
+ int private_member = 3;
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for private member 'private_member'
+// CHECK-FIXES: {{^}} int __private_member = 3;{{$}}
+
+protected:
+ int ProtMember;
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for protected member 'ProtMember'
+// CHECK-FIXES: {{^}} int _ProtMember;{{$}}
+
+public:
+ int PubMem;
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for public member 'PubMem'
+// CHECK-FIXES: {{^}} int pub_mem;{{$}}
+
+ static const int classConstant;
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: invalid case style for class constant 'classConstant'
+// CHECK-FIXES: {{^}} static const int kClassConstant;{{$}}
+ static int ClassMember_2;
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: invalid case style for class member 'ClassMember_2'
+// CHECK-FIXES: {{^}} static int ClassMember2;{{$}}
+};
+class my_class;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for class 'my_class'
+// CHECK-FIXES: {{^}}class CMyClass;{{$}}
+
+class my_forward_declared_class; // No warning should be triggered.
+
+const int my_class::classConstant = 4;
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: invalid case style for class constant 'classConstant'
+// CHECK-FIXES: {{^}}const int CMyClass::kClassConstant = 4;{{$}}
+
+int my_class::ClassMember_2 = 5;
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: invalid case style for class member 'ClassMember_2'
+// CHECK-FIXES: {{^}}int CMyClass::ClassMember2 = 5;{{$}}
+
+class my_derived_class : public virtual my_class {};
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for class 'my_derived_class'
+// CHECK-FIXES: {{^}}class CMyDerivedClass : public virtual CMyClass {};{{$}}
+
+class CMyWellNamedClass {};
+// No warning expected as this class is well named.
+
+template <typename t_t>
+class CMyWellNamedClass2 : public my_class {
+ // CHECK-FIXES: {{^}}class CMyWellNamedClass2 : public CMyClass {{{$}}
+ t_t my_Bad_Member;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for private member 'my_Bad_Member'
+ // CHECK-FIXES: {{^}} t_t __my_Bad_Member;{{$}}
+ int my_Other_Bad_Member = 42;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for private member 'my_Other_Bad_Member'
+ // CHECK-FIXES: {{^}} int __my_Other_Bad_Member = 42;{{$}}
+public:
+ CMyWellNamedClass2() = default;
+ CMyWellNamedClass2(CMyWellNamedClass2 const&) = default;
+ CMyWellNamedClass2(CMyWellNamedClass2 &&) = default;
+ CMyWellNamedClass2(t_t a_v, void *p_p) : my_class(p_p), my_Bad_Member(a_v) {}
+ // CHECK-FIXES: {{^}} CMyWellNamedClass2(t_t a_v, void *p_p) : CMyClass(p_p), __my_Bad_Member(a_v) {}{{$}}
+
+ CMyWellNamedClass2(t_t a_v) : my_class(), my_Bad_Member(a_v), my_Other_Bad_Member(11) {}
+ // CHECK-FIXES: {{^}} CMyWellNamedClass2(t_t a_v) : CMyClass(), __my_Bad_Member(a_v), __my_Other_Bad_Member(11) {}{{$}}
+};
+void InstantiateClassMethods() {
+ // Ensure we trigger the instantiation of each constructor
+ CMyWellNamedClass2<int> x;
+ CMyWellNamedClass2<int> x2 = x;
+ CMyWellNamedClass2<int> x3 = static_cast<CMyWellNamedClass2<int>&&>(x2);
+ CMyWellNamedClass2<int> x4(42);
+ CMyWellNamedClass2<int> x5(42, nullptr);
+}
+
+template<typename T>
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: invalid case style for type template parameter 'T'
+// CHECK-FIXES: {{^}}template<typename t_t>{{$}}
+class my_templated_class : CMyWellNamedClass {};
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for class 'my_templated_class'
+// CHECK-FIXES: {{^}}class CMyTemplatedClass : CMyWellNamedClass {};{{$}}
+
+template<typename T>
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: invalid case style for type template parameter 'T'
+// CHECK-FIXES: {{^}}template<typename t_t>{{$}}
+class my_other_templated_class : my_templated_class< my_class>, private my_derived_class {};
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for class 'my_other_templated_class'
+// CHECK-FIXES: {{^}}class CMyOtherTemplatedClass : CMyTemplatedClass< CMyClass>, private CMyDerivedClass {};{{$}}
+
+template<typename t_t>
+using mysuper_tpl_t = my_other_templated_class <:: FOO_NS ::my_class>;
+// CHECK-FIXES: {{^}}using mysuper_tpl_t = CMyOtherTemplatedClass <:: foo_ns ::CMyClass>;{{$}}
+
+const int global_Constant = 6;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: invalid case style for global constant 'global_Constant'
+// CHECK-FIXES: {{^}}const int GLOBAL_CONSTANT = 6;{{$}}
+int Global_variable = 7;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for global variable 'Global_variable'
+// CHECK-FIXES: {{^}}int g_global_variable = 7;{{$}}
+
+void global_function(int PARAMETER_1, int const CONST_parameter) {
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: invalid case style for global function 'global_function'
+// CHECK-MESSAGES: :[[@LINE-2]]:26: warning: invalid case style for parameter 'PARAMETER_1'
+// CHECK-MESSAGES: :[[@LINE-3]]:49: warning: invalid case style for constant parameter 'CONST_parameter'
+// CHECK-FIXES: {{^}}void GlobalFunction(int a_parameter1, int const i_constParameter) {{{$}}
+ static const int THIS_static_ConsTant = 4;
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: invalid case style for static constant 'THIS_static_ConsTant'
+// CHECK-FIXES: {{^}} static const int THIS_STATIC_CONS_TANT = 4;{{$}}
+ static int THIS_static_variable;
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: invalid case style for static variable 'THIS_static_variable'
+// CHECK-FIXES: {{^}} static int s_thisStaticVariable;{{$}}
+ int const local_Constant = 3;
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: invalid case style for local constant 'local_Constant'
+// CHECK-FIXES: {{^}} int const kLocalConstant = 3;{{$}}
+ int LOCAL_VARIABLE;
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for local variable 'LOCAL_VARIABLE'
+// CHECK-FIXES: {{^}} int local_variable;{{$}}
+
+ int LOCAL_Array__[] = {0, 1, 2};
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for local variable 'LOCAL_Array__'
+// CHECK-FIXES: {{^}} int local_array[] = {0, 1, 2};{{$}}
+
+ for (auto _ : LOCAL_Array__) {
+ }
+}
+
+template<typename ... TYPE_parameters>
+// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: invalid case style for type template parameter 'TYPE_parameters'
+// CHECK-FIXES: {{^}}template<typename ... typeParameters_t>{{$}}
+void Global_Fun(TYPE_parameters... PARAMETER_PACK) {
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: invalid case style for global function 'Global_Fun'
+// CHECK-MESSAGES: :[[@LINE-2]]:36: warning: invalid case style for parameter pack 'PARAMETER_PACK'
+// CHECK-FIXES: {{^}}void GlobalFun(typeParameters_t... parameterPack) {{{$}}
+ global_function(1, 2);
+// CHECK-FIXES: {{^}} GlobalFunction(1, 2);{{$}}
+ FOO_bar = Global_variable;
+// CHECK-FIXES: {{^}} FOO_bar = g_global_variable;{{$}}
+// NO fix expected for FOO_bar declared in macro expansion
+}
+
+template<template<typename> class TPL_parameter, int COUNT_params, typename ... TYPE_parameters>
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: invalid case style for template template parameter 'TPL_parameter'
+// CHECK-MESSAGES: :[[@LINE-2]]:54: warning: invalid case style for value template parameter 'COUNT_params'
+// CHECK-MESSAGES: :[[@LINE-3]]:81: warning: invalid case style for type template parameter 'TYPE_parameters'
+// CHECK-FIXES: {{^}}template<template<typename> class TplParameter, int countParams, typename ... typeParameters_t>{{$}}
+class test_CLASS {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for class 'test_CLASS'
+// CHECK-FIXES: {{^}}class CTestClass {{{$}}
+};
+
+class abstract_class {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for abstract class 'abstract_class'
+// CHECK-FIXES: {{^}}class AAbstractClass {{{$}}
+ virtual ~abstract_class() = 0;
+// CHECK-FIXES: {{^}} virtual ~AAbstractClass() = 0;{{$}}
+ virtual void VIRTUAL_METHOD();
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for virtual method 'VIRTUAL_METHOD'
+// CHECK-FIXES: {{^}} virtual void v_Virtual_Method();{{$}}
+ void non_Virtual_METHOD() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: invalid case style for private method 'non_Virtual_METHOD'
+// CHECK-FIXES: {{^}} void __non_Virtual_METHOD() {}{{$}}
+
+public:
+ static void CLASS_METHOD() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for class method 'CLASS_METHOD'
+// CHECK-FIXES: {{^}} static void classMethod() {}{{$}}
+
+ constexpr int CST_expr_Method() { return 2; }
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: invalid case style for constexpr method 'CST_expr_Method'
+// CHECK-FIXES: {{^}} constexpr int cst_expr_method() { return 2; }{{$}}
+
+private:
+ void PRIVate_Method();
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: invalid case style for private method 'PRIVate_Method'
+// CHECK-FIXES: {{^}} void __PRIVate_Method();{{$}}
+protected:
+ void protected_Method();
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: invalid case style for protected method 'protected_Method'
+// CHECK-FIXES: {{^}} void _protected_Method();{{$}}
+public:
+ void public_Method();
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: invalid case style for method 'public_Method'
+// CHECK-FIXES: {{^}} void publicMethod();{{$}}
+};
+
+constexpr int CE_function() { return 3; }
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: invalid case style for constexpr function 'CE_function'
+// CHECK-FIXES: {{^}}constexpr int ce_function() { return 3; }{{$}}
+
+struct THIS___Structure {
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: invalid case style for struct 'THIS___Structure'
+// CHECK-FIXES: {{^}}struct this_structure {{{$}}
+ THIS___Structure();
+// CHECK-FIXES: {{^}} this_structure();{{$}}
+
+ union __MyUnion_is_wonderful__ {};
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for union '__MyUnion_is_wonderful__'
+// CHECK-FIXES: {{^}} union UMyUnionIsWonderful {};{{$}}
+};
+
+typedef THIS___Structure struct_type;
+// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: invalid case style for typedef 'struct_type'
+// CHECK-FIXES: {{^}}typedef this_structure struct_type_t;{{$}}
+
+struct_type GlobalTypedefTestFunction(struct_type a_argument1) {
+// CHECK-FIXES: {{^}}struct_type_t GlobalTypedefTestFunction(struct_type_t a_argument1) {
+ struct_type typedef_test_1;
+// CHECK-FIXES: {{^}} struct_type_t typedef_test_1;
+}
+
+using my_struct_type = THIS___Structure;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for type alias 'my_struct_type'
+// CHECK-FIXES: {{^}}using my_Struct_Type_t = this_structure;{{$}}
+
+template<typename t_t>
+using SomeOtherTemplate = my_other_templated_class <:: FOO_NS ::my_class>;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for type alias 'SomeOtherTemplate'
+// CHECK-FIXES: {{^}}using some_Other_Template_t = CMyOtherTemplatedClass <:: foo_ns ::CMyClass>;{{$}}
+
+static void static_Function() {
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: invalid case style for function 'static_Function'
+// CHECK-FIXES: {{^}}static void staticFunction() {{{$}}
+
+ ::FOO_NS::InlineNamespace::abstract_class::CLASS_METHOD();
+// CHECK-FIXES: {{^}} ::foo_ns::inline_namespace::AAbstractClass::classMethod();{{$}}
+ ::FOO_NS::InlineNamespace::static_Function();
+// CHECK-FIXES: {{^}} ::foo_ns::inline_namespace::staticFunction();{{$}}
+
+ using ::FOO_NS::InlineNamespace::CE_function;
+// CHECK-FIXES: {{^}} using ::foo_ns::inline_namespace::ce_function;{{$}}
+
+ unsigned MY_LOCAL_array[] = {1,2,3};
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: invalid case style for local variable 'MY_LOCAL_array'
+// CHECK-FIXES: {{^}} unsigned my_local_array[] = {1,2,3};{{$}}
+
+ unsigned const MyConstLocal_array[] = {1,2,3};
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for local constant 'MyConstLocal_array'
+// CHECK-FIXES: {{^}} unsigned const kMyConstLocalArray[] = {1,2,3};{{$}}
+
+ static unsigned MY_STATIC_array[] = {1,2,3};
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: invalid case style for static variable 'MY_STATIC_array'
+// CHECK-FIXES: {{^}} static unsigned s_myStaticArray[] = {1,2,3};{{$}}
+
+ static unsigned const MyConstStatic_array[] = {1,2,3};
+// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: invalid case style for static constant 'MyConstStatic_array'
+// CHECK-FIXES: {{^}} static unsigned const MY_CONST_STATIC_ARRAY[] = {1,2,3};{{$}}
+
+ char MY_LOCAL_string[] = "123";
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: invalid case style for local variable 'MY_LOCAL_string'
+// CHECK-FIXES: {{^}} char my_local_string[] = "123";{{$}}
+
+ char const MyConstLocal_string[] = "123";
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: invalid case style for local constant 'MyConstLocal_string'
+// CHECK-FIXES: {{^}} char const kMyConstLocalString[] = "123";{{$}}
+
+ static char MY_STATIC_string[] = "123";
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: invalid case style for static variable 'MY_STATIC_string'
+// CHECK-FIXES: {{^}} static char s_myStaticString[] = "123";{{$}}
+
+ static char const MyConstStatic_string[] = "123";
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: invalid case style for static constant 'MyConstStatic_string'
+// CHECK-FIXES: {{^}} static char const MY_CONST_STATIC_STRING[] = "123";{{$}}
+}
+
+#define MY_TEST_Macro(X) X()
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for macro definition 'MY_TEST_Macro'
+// CHECK-FIXES: {{^}}#define MY_TEST_MACRO(X) X()
+
+void MY_TEST_Macro(function) {}
+// CHECK-FIXES: {{^}}void MY_TEST_MACRO(function) {}
+}
+}
+
+template <typename t_t> struct a {
+ typename t_t::template b<> c;
+
+ char const MY_ConstMember_string[4] = "123";
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: invalid case style for constant member 'MY_ConstMember_string'
+// CHECK-FIXES: {{^}} char const my_const_member_string[4] = "123";{{$}}
+
+ static char const MyConstClass_string[];
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: invalid case style for class constant 'MyConstClass_string'
+// CHECK-FIXES: {{^}} static char const kMyConstClassString[];{{$}}
+};
+
+template<typename t_t>
+char const a<t_t>::MyConstClass_string[] = "123";
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: invalid case style for class constant 'MyConstClass_string'
+// CHECK-FIXES: {{^}}char const a<t_t>::kMyConstClassString[] = "123";{{$}}
+
+template <template <typename> class A> struct b { A<int> c; };
+
+unsigned MY_GLOBAL_array[] = {1,2,3};
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: invalid case style for global variable 'MY_GLOBAL_array'
+// CHECK-FIXES: {{^}}unsigned g_my_global_array[] = {1,2,3};{{$}}
+
+unsigned const MyConstGlobal_array[] = {1,2,3};
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: invalid case style for global constant 'MyConstGlobal_array'
+// CHECK-FIXES: {{^}}unsigned const MY_CONST_GLOBAL_ARRAY[] = {1,2,3};{{$}}
+
+int * MyGlobal_Ptr;// -> ok
+int * const MyConstantGlobalPointer = nullptr;
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: invalid case style for global constant pointer 'MyConstantGlobalPointer'
+// CHECK-FIXES: {{^}}int * const MY_CONSTANT_GLOBAL_POINTER_Ptr = nullptr;{{$}}
+
+void MyPoiterFunction(int * p_normal_pointer, int * const constant_ptr){
+// CHECK-MESSAGES: :[[@LINE-1]]:59: warning: invalid case style for constant pointer parameter 'constant_ptr'
+// CHECK-FIXES: {{^}}void MyPoiterFunction(int * p_normal_pointer, int * const cp_ConstantPtr){{{$}}
+ int * l_PointerA;
+ int * const pointer_b = nullptr;
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for local constant pointer 'pointer_b'
+// CHECK-FIXES: {{^}} int * const lc_PointerB = nullptr;{{$}}
+}
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-implicit-bool-conversion-allow-in-conditions.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-implicit-bool-conversion-allow-in-conditions.cpp
new file mode 100644
index 0000000..c50b798
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-implicit-bool-conversion-allow-in-conditions.cpp
@@ -0,0 +1,72 @@
+// RUN: %check_clang_tidy %s readability-implicit-bool-conversion %t \
+// RUN: -config='{CheckOptions: \
+// RUN: [{key: readability-implicit-bool-conversion.AllowIntegerConditions, value: 1}, \
+// RUN: {key: readability-implicit-bool-conversion.AllowPointerConditions, value: 1}]}' \
+// RUN: -- -std=c++11
+
+template<typename T>
+void functionTaking(T);
+
+int functionReturningInt();
+int* functionReturningPointer();
+
+struct Struct {
+ int member;
+ unsigned bitfield : 1;
+};
+
+
+void regularImplicitConversionIntegerToBoolIsNotIgnored() {
+ int integer = 0;
+ functionTaking<bool>(integer);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool [readability-implicit-bool-conversion]
+ // CHECK-FIXES: functionTaking<bool>(integer != 0);
+}
+
+void implicitConversionIntegerToBoolInConditionalsIsAllowed() {
+ Struct s = {};
+ if (s.member) {}
+ if (!s.member) {}
+ if (s.bitfield) {}
+ if (!s.bitfield) {}
+ if (functionReturningInt()) {}
+ if (!functionReturningInt()) {}
+ if (functionReturningInt() && functionReturningPointer()) {}
+ if (!functionReturningInt() && !functionReturningPointer()) {}
+ for (; functionReturningInt(); ) {}
+ for (; functionReturningPointer(); ) {}
+ for (; functionReturningInt() && !functionReturningPointer() || (!functionReturningInt() && functionReturningPointer()); ) {}
+ while (functionReturningInt()) {}
+ while (functionReturningPointer()) {}
+ while (functionReturningInt() && !functionReturningPointer() || (!functionReturningInt() && functionReturningPointer())) {}
+ int value1 = functionReturningInt() ? 1 : 2;
+ int value2 = !functionReturningInt() ? 1 : 2;
+ int value3 = (functionReturningInt() && functionReturningPointer() || !functionReturningInt()) ? 1 : 2;
+ int value4 = functionReturningInt() ?: value3;
+ int *p1 = functionReturningPointer() ?: &value3;
+}
+
+void regularImplicitConversionPointerToBoolIsNotIgnored() {
+ int* pointer = nullptr;
+ functionTaking<bool>(pointer);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int *' -> bool
+ // CHECK-FIXES: functionTaking<bool>(pointer != nullptr);
+
+ int Struct::* memberPointer = &Struct::member;
+ functionTaking<bool>(memberPointer);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int Struct::*' -> bool
+ // CHECK-FIXES: functionTaking<bool>(memberPointer != nullptr);
+}
+
+void implicitConversionPointerToBoolInConditionalsIsAllowed() {
+ if (functionReturningPointer()) {}
+ if (not functionReturningPointer()) {}
+ int value1 = functionReturningPointer() ? 1 : 2;
+ int value2 = (not functionReturningPointer()) ? 1 : 2;
+
+ int Struct::* memberPointer = &Struct::member;
+ if (memberPointer) {}
+ if (memberPointer) {}
+ int value3 = memberPointer ? 1 : 2;
+ int value4 = (not memberPointer) ? 1 : 2;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-implicit-bool-conversion-cxx98.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-implicit-bool-conversion-cxx98.cpp
new file mode 100644
index 0000000..587f7e2
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-implicit-bool-conversion-cxx98.cpp
@@ -0,0 +1,45 @@
+// RUN: %check_clang_tidy %s readability-implicit-bool-conversion %t -- -- -std=c++98
+
+// We need NULL macro, but some buildbots don't like including <cstddef> header
+// This is a portable way of getting it to work
+#undef NULL
+#define NULL 0L
+
+template<typename T>
+void functionTaking(T);
+
+struct Struct {
+ int member;
+};
+
+void useOldNullMacroInReplacements() {
+ int* pointer = NULL;
+ functionTaking<bool>(pointer);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int *' -> bool [readability-implicit-bool-conversion]
+ // CHECK-FIXES: functionTaking<bool>(pointer != 0);
+
+ int Struct::* memberPointer = NULL;
+ functionTaking<bool>(!memberPointer);
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit conversion 'int Struct::*' -> bool
+ // CHECK-FIXES: functionTaking<bool>(memberPointer == 0);
+}
+
+void fixFalseLiteralConvertingToNullPointer() {
+ functionTaking<int*>(false);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion bool -> 'int *'
+ // CHECK-FIXES: functionTaking<int*>(0);
+
+ int* pointer = NULL;
+ if (pointer == false) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: implicit conversion bool -> 'int *'
+ // CHECK-FIXES: if (pointer == 0) {}
+
+ functionTaking<int Struct::*>(false);
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion bool -> 'int Struct::*'
+ // CHECK-FIXES: functionTaking<int Struct::*>(0);
+
+ int Struct::* memberPointer = NULL;
+ if (memberPointer != false) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion bool -> 'int Struct::*'
+ // CHECK-FIXES: if (memberPointer != 0) {}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-implicit-bool-conversion.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-implicit-bool-conversion.cpp
new file mode 100644
index 0000000..d5e9bee
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-implicit-bool-conversion.cpp
@@ -0,0 +1,473 @@
+// RUN: %check_clang_tidy %s readability-implicit-bool-conversion %t
+
+// We need NULL macro, but some buildbots don't like including <cstddef> header
+// This is a portable way of getting it to work
+#undef NULL
+#define NULL 0L
+
+template<typename T>
+void functionTaking(T);
+
+struct Struct {
+ int member;
+};
+
+
+////////// Implicit conversion from bool.
+
+void implicitConversionFromBoolSimpleCases() {
+ bool boolean = true;
+
+ functionTaking<bool>(boolean);
+
+ functionTaking<int>(boolean);
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit conversion bool -> 'int' [readability-implicit-bool-conversion]
+ // CHECK-FIXES: functionTaking<int>(static_cast<int>(boolean));
+
+ functionTaking<unsigned long>(boolean);
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion bool -> 'unsigned long'
+ // CHECK-FIXES: functionTaking<unsigned long>(static_cast<unsigned long>(boolean));
+
+ functionTaking<char>(boolean);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion bool -> 'char'
+ // CHECK-FIXES: functionTaking<char>(static_cast<char>(boolean));
+
+ functionTaking<float>(boolean);
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit conversion bool -> 'float'
+ // CHECK-FIXES: functionTaking<float>(static_cast<float>(boolean));
+
+ functionTaking<double>(boolean);
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: implicit conversion bool -> 'double'
+ // CHECK-FIXES: functionTaking<double>(static_cast<double>(boolean));
+}
+
+float implicitConversionFromBoolInReturnValue() {
+ bool boolean = false;
+ return boolean;
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion bool -> 'float'
+ // CHECK-FIXES: return static_cast<float>(boolean);
+}
+
+void implicitConversionFromBoolInSingleBoolExpressions(bool b1, bool b2) {
+ bool boolean = true;
+ boolean = b1 ^ b2;
+ boolean = b1 && b2;
+ boolean |= !b1 || !b2;
+ boolean &= b1;
+ boolean = b1 == true;
+ boolean = b2 != false;
+
+ int integer = boolean - 3;
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit conversion bool -> 'int'
+ // CHECK-FIXES: int integer = static_cast<int>(boolean) - 3;
+
+ float floating = boolean / 0.3f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit conversion bool -> 'float'
+ // CHECK-FIXES: float floating = static_cast<float>(boolean) / 0.3f;
+
+ char character = boolean;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit conversion bool -> 'char'
+ // CHECK-FIXES: char character = static_cast<char>(boolean);
+}
+
+void implicitConversionFromBoollInComplexBoolExpressions() {
+ bool boolean = true;
+ bool anotherBoolean = false;
+
+ int integer = boolean && anotherBoolean;
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit conversion bool -> 'int'
+ // CHECK-FIXES: int integer = static_cast<int>(boolean && anotherBoolean);
+
+ unsigned long unsignedLong = (! boolean) + 4ul;
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: implicit conversion bool -> 'unsigned long'
+ // CHECK-FIXES: unsigned long unsignedLong = static_cast<unsigned long>(! boolean) + 4ul;
+
+ float floating = (boolean || anotherBoolean) * 0.3f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit conversion bool -> 'float'
+ // CHECK-FIXES: float floating = static_cast<float>(boolean || anotherBoolean) * 0.3f;
+
+ double doubleFloating = (boolean && (anotherBoolean || boolean)) * 0.3;
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: implicit conversion bool -> 'double'
+ // CHECK-FIXES: double doubleFloating = static_cast<double>(boolean && (anotherBoolean || boolean)) * 0.3;
+}
+
+void implicitConversionFromBoolLiterals() {
+ functionTaking<int>(true);
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit conversion bool -> 'int'
+ // CHECK-FIXES: functionTaking<int>(1);
+
+ functionTaking<unsigned long>(false);
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion bool -> 'unsigned long'
+ // CHECK-FIXES: functionTaking<unsigned long>(0u);
+
+ functionTaking<signed char>(true);
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: implicit conversion bool -> 'signed char'
+ // CHECK-FIXES: functionTaking<signed char>(1);
+
+ functionTaking<float>(false);
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit conversion bool -> 'float'
+ // CHECK-FIXES: functionTaking<float>(0.0f);
+
+ functionTaking<double>(true);
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: implicit conversion bool -> 'double'
+ // CHECK-FIXES: functionTaking<double>(1.0);
+}
+
+void implicitConversionFromBoolInComparisons() {
+ bool boolean = true;
+ int integer = 0;
+
+ functionTaking<bool>(boolean == integer);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion bool -> 'int'
+ // CHECK-FIXES: functionTaking<bool>(static_cast<int>(boolean) == integer);
+
+ functionTaking<bool>(integer != boolean);
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: implicit conversion bool -> 'int'
+ // CHECK-FIXES: functionTaking<bool>(integer != static_cast<int>(boolean));
+}
+
+void ignoreBoolComparisons() {
+ bool boolean = true;
+ bool anotherBoolean = false;
+
+ functionTaking<bool>(boolean == anotherBoolean);
+ functionTaking<bool>(boolean != anotherBoolean);
+}
+
+void ignoreExplicitCastsFromBool() {
+ bool boolean = true;
+
+ int integer = static_cast<int>(boolean) + 3;
+ float floating = static_cast<float>(boolean) * 0.3f;
+ char character = static_cast<char>(boolean);
+}
+
+void ignoreImplicitConversionFromBoolInMacroExpansions() {
+ bool boolean = true;
+
+ #define CAST_FROM_BOOL_IN_MACRO_BODY boolean + 3
+ int integerFromMacroBody = CAST_FROM_BOOL_IN_MACRO_BODY;
+
+ #define CAST_FROM_BOOL_IN_MACRO_ARGUMENT(x) x + 3
+ int integerFromMacroArgument = CAST_FROM_BOOL_IN_MACRO_ARGUMENT(boolean);
+}
+
+namespace ignoreImplicitConversionFromBoolInTemplateInstantiations {
+
+template<typename T>
+void templateFunction() {
+ bool boolean = true;
+ T uknownType = boolean + 3;
+}
+
+void useOfTemplateFunction() {
+ templateFunction<int>();
+}
+
+} // namespace ignoreImplicitConversionFromBoolInTemplateInstantiations
+
+////////// Implicit conversions to bool.
+
+void implicitConversionToBoolSimpleCases() {
+ int integer = 10;
+ functionTaking<bool>(integer);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool
+ // CHECK-FIXES: functionTaking<bool>(integer != 0);
+
+ unsigned long unsignedLong = 10;
+ functionTaking<bool>(unsignedLong);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'unsigned long' -> bool
+ // CHECK-FIXES: functionTaking<bool>(unsignedLong != 0u);
+
+ float floating = 0.0f;
+ functionTaking<bool>(floating);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'float' -> bool
+ // CHECK-FIXES: functionTaking<bool>(floating != 0.0f);
+
+ double doubleFloating = 1.0f;
+ functionTaking<bool>(doubleFloating);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'double' -> bool
+ // CHECK-FIXES: functionTaking<bool>(doubleFloating != 0.0);
+
+ signed char character = 'a';
+ functionTaking<bool>(character);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'signed char' -> bool
+ // CHECK-FIXES: functionTaking<bool>(character != 0);
+
+ int* pointer = nullptr;
+ functionTaking<bool>(pointer);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int *' -> bool
+ // CHECK-FIXES: functionTaking<bool>(pointer != nullptr);
+
+ auto pointerToMember = &Struct::member;
+ functionTaking<bool>(pointerToMember);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int Struct::*' -> bool
+ // CHECK-FIXES: functionTaking<bool>(pointerToMember != nullptr);
+}
+
+void implicitConversionToBoolInSingleExpressions() {
+ int integer = 10;
+ bool boolComingFromInt = integer;
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: implicit conversion 'int' -> bool
+ // CHECK-FIXES: bool boolComingFromInt = integer != 0;
+
+ float floating = 10.0f;
+ bool boolComingFromFloat = floating;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: implicit conversion 'float' -> bool
+ // CHECK-FIXES: bool boolComingFromFloat = floating != 0.0f;
+
+ signed char character = 'a';
+ bool boolComingFromChar = character;
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: implicit conversion 'signed char' -> bool
+ // CHECK-FIXES: bool boolComingFromChar = character != 0;
+
+ int* pointer = nullptr;
+ bool boolComingFromPointer = pointer;
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: implicit conversion 'int *' -> bool
+ // CHECK-FIXES: bool boolComingFromPointer = pointer != nullptr;
+}
+
+void implicitConversionToBoolInComplexExpressions() {
+ bool boolean = true;
+
+ int integer = 10;
+ int anotherInteger = 20;
+ bool boolComingFromInteger = integer + anotherInteger;
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: implicit conversion 'int' -> bool
+ // CHECK-FIXES: bool boolComingFromInteger = (integer + anotherInteger) != 0;
+
+ float floating = 0.2f;
+ bool boolComingFromFloating = floating - 0.3f || boolean;
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion 'float' -> bool
+ // CHECK-FIXES: bool boolComingFromFloating = ((floating - 0.3f) != 0.0f) || boolean;
+
+ double doubleFloating = 0.3;
+ bool boolComingFromDoubleFloating = (doubleFloating - 0.4) && boolean;
+ // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: implicit conversion 'double' -> bool
+ // CHECK-FIXES: bool boolComingFromDoubleFloating = ((doubleFloating - 0.4) != 0.0) && boolean;
+}
+
+void implicitConversionInNegationExpressions() {
+ int integer = 10;
+ bool boolComingFromNegatedInt = !integer;
+ // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: implicit conversion 'int' -> bool
+ // CHECK-FIXES: bool boolComingFromNegatedInt = integer == 0;
+
+ float floating = 10.0f;
+ bool boolComingFromNegatedFloat = ! floating;
+ // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: implicit conversion 'float' -> bool
+ // CHECK-FIXES: bool boolComingFromNegatedFloat = floating == 0.0f;
+
+ signed char character = 'a';
+ bool boolComingFromNegatedChar = (! character);
+ // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: implicit conversion 'signed char' -> bool
+ // CHECK-FIXES: bool boolComingFromNegatedChar = (character == 0);
+
+ int* pointer = nullptr;
+ bool boolComingFromNegatedPointer = not pointer;
+ // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: implicit conversion 'int *' -> bool
+ // CHECK-FIXES: bool boolComingFromNegatedPointer = pointer == nullptr;
+}
+
+void implicitConversionToBoolInControlStatements() {
+ int integer = 10;
+ if (integer) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: implicit conversion 'int' -> bool
+ // CHECK-FIXES: if (integer != 0) {}
+
+ long int longInteger = 0.2f;
+ for (;longInteger;) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicit conversion 'long' -> bool
+ // CHECK-FIXES: for (;longInteger != 0;) {}
+
+ float floating = 0.3f;
+ while (floating) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion 'float' -> bool
+ // CHECK-FIXES: while (floating != 0.0f) {}
+
+ double doubleFloating = 0.4;
+ do {} while (doubleFloating);
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: implicit conversion 'double' -> bool
+ // CHECK-FIXES: do {} while (doubleFloating != 0.0);
+}
+
+bool implicitConversionToBoolInReturnValue() {
+ float floating = 1.0f;
+ return floating;
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion 'float' -> bool
+ // CHECK-FIXES: return floating != 0.0f;
+}
+
+void implicitConversionToBoolFromLiterals() {
+ functionTaking<bool>(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool
+ // CHECK-FIXES: functionTaking<bool>(false);
+
+ functionTaking<bool>(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool
+ // CHECK-FIXES: functionTaking<bool>(true);
+
+ functionTaking<bool>(2ul);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'unsigned long' -> bool
+ // CHECK-FIXES: functionTaking<bool>(true);
+
+
+ functionTaking<bool>(0.0f);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'float' -> bool
+ // CHECK-FIXES: functionTaking<bool>(false);
+
+ functionTaking<bool>(1.0f);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'float' -> bool
+ // CHECK-FIXES: functionTaking<bool>(true);
+
+ functionTaking<bool>(2.0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'double' -> bool
+ // CHECK-FIXES: functionTaking<bool>(true);
+
+
+ functionTaking<bool>('\0');
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'char' -> bool
+ // CHECK-FIXES: functionTaking<bool>(false);
+
+ functionTaking<bool>('a');
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'char' -> bool
+ // CHECK-FIXES: functionTaking<bool>(true);
+
+
+ functionTaking<bool>("");
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'const char *' -> bool
+ // CHECK-FIXES: functionTaking<bool>(true);
+
+ functionTaking<bool>("abc");
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'const char *' -> bool
+ // CHECK-FIXES: functionTaking<bool>(true);
+
+ functionTaking<bool>(NULL);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'long' -> bool
+ // CHECK-FIXES: functionTaking<bool>(false);
+}
+
+void implicitConversionToBoolFromUnaryMinusAndZeroLiterals() {
+ functionTaking<bool>(-0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool
+ // CHECK-FIXES: functionTaking<bool>((-0) != 0);
+
+ functionTaking<bool>(-0.0f);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'float' -> bool
+ // CHECK-FIXES: functionTaking<bool>((-0.0f) != 0.0f);
+
+ functionTaking<bool>(-0.0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'double' -> bool
+ // CHECK-FIXES: functionTaking<bool>((-0.0) != 0.0);
+}
+
+void implicitConversionToBoolInWithOverloadedOperators() {
+ struct UserStruct {
+ int operator()(int x) { return x; }
+ int operator+(int y) { return y; }
+ };
+
+ UserStruct s;
+
+ functionTaking<bool>(s(0));
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool
+ // CHECK-FIXES: functionTaking<bool>(s(0) != 0);
+
+ functionTaking<bool>(s + 2);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool
+ // CHECK-FIXES: functionTaking<bool>((s + 2) != 0);
+}
+
+int functionReturningInt();
+int* functionReturningPointer();
+
+void ignoreImplicitConversionToBoolWhenDeclaringVariableInControlStatements() {
+ if (int integer = functionReturningInt()) {}
+
+ while (int* pointer = functionReturningPointer()) {}
+}
+
+void ignoreExplicitCastsToBool() {
+ int integer = 10;
+ bool boolComingFromInt = static_cast<bool>(integer);
+
+ float floating = 10.0f;
+ bool boolComingFromFloat = static_cast<bool>(floating);
+
+ char character = 'a';
+ bool boolComingFromChar = static_cast<bool>(character);
+
+ int* pointer = nullptr;
+ bool booleanComingFromPointer = static_cast<bool>(pointer);
+}
+
+void ignoreImplicitConversionToBoolInMacroExpansions() {
+ int integer = 3;
+
+ #define CAST_TO_BOOL_IN_MACRO_BODY integer && false
+ bool boolFromMacroBody = CAST_TO_BOOL_IN_MACRO_BODY;
+
+ #define CAST_TO_BOOL_IN_MACRO_ARGUMENT(x) x || true
+ bool boolFromMacroArgument = CAST_TO_BOOL_IN_MACRO_ARGUMENT(integer);
+}
+
+namespace ignoreImplicitConversionToBoolInTemplateInstantiations {
+
+template<typename T>
+void templateFunction() {
+ T unknownType = 0;
+ bool boolean = unknownType;
+}
+
+void useOfTemplateFunction() {
+ templateFunction<int>();
+}
+
+} // namespace ignoreImplicitConversionToBoolInTemplateInstantiations
+
+namespace ignoreUserDefinedConversionOperator {
+
+struct StructWithUserConversion {
+ operator bool();
+};
+
+void useOfUserConversion() {
+ StructWithUserConversion structure;
+ functionTaking<bool>(structure);
+}
+
+} // namespace ignoreUserDefinedConversionOperator
+
+namespace ignore_1bit_bitfields {
+
+struct S {
+ int a;
+ int b : 1;
+ int c : 2;
+
+ S(bool a, bool b, bool c) : a(a), b(b), c(c) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion bool -> 'int'
+ // CHECK-MESSAGES: :[[@LINE-2]]:45: warning: implicit conversion bool -> 'int'
+ // CHECK-FIXES: S(bool a, bool b, bool c) : a(static_cast<int>(a)), b(b), c(static_cast<int>(c)) {}
+};
+
+bool f(S& s) {
+ functionTaking<bool>(s.a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool
+ // CHECK-FIXES: functionTaking<bool>(s.a != 0);
+ functionTaking<bool>(s.b);
+ // CHECK-FIXES: functionTaking<bool>(s.b);
+ s.a = true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicit conversion bool -> 'int'
+ // CHECK-FIXES: s.a = 1;
+ s.b = true;
+ // CHECK-FIXES: s.b = true;
+ s.c = true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicit conversion bool -> 'int'
+ // CHECK-FIXES: s.c = 1;
+ functionTaking<bool>(s.c);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool
+ // CHECK-FIXES: functionTaking<bool>(s.c != 0);
+}
+
+} // namespace ignore_1bit_bitfields
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-inconsistent-declaration-parameter-name-macros.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-inconsistent-declaration-parameter-name-macros.cpp
new file mode 100644
index 0000000..ed05fac
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-inconsistent-declaration-parameter-name-macros.cpp
@@ -0,0 +1,47 @@
+// RUN: %check_clang_tidy %s readability-inconsistent-declaration-parameter-name %t -- \
+// RUN: -config="{CheckOptions: [{key: readability-inconsistent-declaration-parameter-name.IgnoreMacros, value: 0}]}" \
+// RUN: -- -std=c++11
+
+#define MACRO() \
+ void f(int x)
+
+struct S1 {
+ MACRO();
+ // CHECK-NOTES: :[[@LINE-1]]:3: warning: function 'S1::f' has a definition with different parameter names
+ // CHECK-NOTES: :[[@LINE-5]]:8: note: expanded from macro 'MACRO'
+ // CHECK-NOTES: :[[@LINE+4]]:10: note: the definition seen here
+ // CHECK-NOTES: :[[@LINE-4]]:3: note: differing parameters are named here: ('x'), in definition: ('y')
+ // CHECK-NOTES: :[[@LINE-8]]:8: note: expanded from macro 'MACRO'
+};
+void S1::f(int y) {}
+
+struct S2 {
+ int g() const;
+ void set_g(int g);
+ // CHECK-NOTES: :[[@LINE-1]]:8: warning: function 'S2::set_g' has a definition with different parameter names
+ // CHECK-NOTES: :[[@LINE+14]]:1: note: the definition seen here
+ // CHECK-NOTES: :[[@LINE+9]]:12: note: expanded from macro 'DEFINITION'
+ // This one is unfortunate, but the location this points to is in a scratch
+ // space, so it's not helpful to the user.
+ // CHECK-NOTES: {{^}}note: expanded from here{{$}}
+ // CHECK-NOTES: :[[@LINE-7]]:8: note: differing parameters are named here: ('g'), in definition: ('w')
+};
+
+#define DEFINITION(name, parameter) \
+ int S2::name() const { return 0; } \
+ void S2::set_##name(int parameter) { \
+ (void)parameter; \
+ }
+
+DEFINITION(g, w)
+
+//////////////////////////////////////////////////////
+
+#define DECLARE_FUNCTION_WITH_PARAM_NAME(function_name, param_name) \
+ void function_name(int param_name)
+
+// CHECK-NOTES: :[[@LINE+1]]:34: warning: function 'macroFunction' has 1 other declaration with different parameter names [readability-inconsistent-declaration-parameter-name]
+DECLARE_FUNCTION_WITH_PARAM_NAME(macroFunction, a);
+// CHECK-NOTES: :[[@LINE+2]]:34: note: the 1st inconsistent declaration seen here
+// CHECK-NOTES: :[[@LINE+1]]:34: note: differing parameters are named here: ('b'), in the other declaration: ('a')
+DECLARE_FUNCTION_WITH_PARAM_NAME(macroFunction, b);
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-inconsistent-declaration-parameter-name-strict.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-inconsistent-declaration-parameter-name-strict.cpp
new file mode 100644
index 0000000..90ac45f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-inconsistent-declaration-parameter-name-strict.cpp
@@ -0,0 +1,11 @@
+// RUN: %check_clang_tidy %s readability-inconsistent-declaration-parameter-name %t -- \
+// RUN: -config="{CheckOptions: [{key: readability-inconsistent-declaration-parameter-name.Strict, value: 1}]}" \
+// RUN: -- -std=c++11
+
+void inconsistentFunction(int a, int b, int c);
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'inconsistentFunction' has 1 other declaration with different parameter names
+void inconsistentFunction(int prefixA, int b, int cSuffix);
+// CHECK-MESSAGES: :[[@LINE-1]]:6: note: the 1st inconsistent declaration seen here
+// CHECK-MESSAGES: :[[@LINE-2]]:6: note: differing parameters are named here: ('prefixA', 'cSuffix'), in the other declaration: ('a', 'c')
+void inconsistentFunction(int a, int b, int c);
+void inconsistentFunction(int /*c*/, int /*c*/, int /*c*/);
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-inconsistent-declaration-parameter-name.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-inconsistent-declaration-parameter-name.cpp
new file mode 100644
index 0000000..c98258b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-inconsistent-declaration-parameter-name.cpp
@@ -0,0 +1,193 @@
+// RUN: %check_clang_tidy %s readability-inconsistent-declaration-parameter-name %t -- -- -std=c++11 -fno-delayed-template-parsing
+
+void consistentFunction(int a, int b, int c);
+void consistentFunction(int a, int b, int c);
+void consistentFunction(int prefixA, int b, int cSuffix);
+void consistentFunction(int a, int b, int c);
+void consistentFunction(int a, int b, int /*c*/);
+void consistentFunction(int /*c*/, int /*c*/, int /*c*/);
+
+//////////////////////////////////////////////////////
+
+// CHECK-MESSAGES: :[[@LINE+1]]:6: warning: function 'inconsistentFunction' has 2 other declarations with different parameter names [readability-inconsistent-declaration-parameter-name]
+void inconsistentFunction(int a, int b, int c);
+// CHECK-MESSAGES: :[[@LINE+2]]:6: note: the 1st inconsistent declaration seen here
+// CHECK-MESSAGES: :[[@LINE+1]]:6: note: differing parameters are named here: ('d', 'e', 'f'), in the other declaration: ('a', 'b', 'c')
+void inconsistentFunction(int d, int e, int f);
+// CHECK-MESSAGES: :[[@LINE+2]]:6: note: the 2nd inconsistent declaration seen here
+// CHECK-MESSAGES: :[[@LINE+1]]:6: note: differing parameters are named here: ('x', 'y', 'z'), in the other declaration: ('a', 'b', 'c')
+void inconsistentFunction(int x, int y, int z);
+
+//////////////////////////////////////////////////////
+
+// CHECK-MESSAGES: :[[@LINE+4]]:6: warning: function 'inconsistentFunctionWithVisibleDefinition' has a definition with different parameter names [readability-inconsistent-declaration-parameter-name]
+// CHECK-MESSAGES: :[[@LINE+9]]:6: note: the definition seen here
+// CHECK-MESSAGES: :[[@LINE+2]]:6: note: differing parameters are named here: ('a'), in definition: ('c')
+// CHECK-FIXES: void inconsistentFunctionWithVisibleDefinition(int c);
+void inconsistentFunctionWithVisibleDefinition(int a);
+// CHECK-MESSAGES: :[[@LINE+4]]:6: warning: function 'inconsistentFunctionWithVisibleDefinition' has a definition
+// CHECK-MESSAGES: :[[@LINE+4]]:6: note: the definition seen here
+// CHECK-MESSAGES: :[[@LINE+2]]:6: note: differing parameters are named here: ('b'), in definition: ('c')
+// CHECK-FIXES: void inconsistentFunctionWithVisibleDefinition(int c);
+void inconsistentFunctionWithVisibleDefinition(int b);
+void inconsistentFunctionWithVisibleDefinition(int c) { c; }
+
+// CHECK-MESSAGES: :[[@LINE+3]]:6: warning: function 'inconsidentFunctionWithUnreferencedParameterInDefinition' has a definition
+// CHECK-MESSAGES: :[[@LINE+3]]:6: note: the definition seen here
+// CHECK-MESSAGES: :[[@LINE+1]]:6: note: differing parameters are named here: ('a'), in definition: ('b')
+void inconsidentFunctionWithUnreferencedParameterInDefinition(int a);
+void inconsidentFunctionWithUnreferencedParameterInDefinition(int b) {}
+
+//////////////////////////////////////////////////////
+
+struct Struct {
+// CHECK-MESSAGES: :[[@LINE+4]]:8: warning: function 'Struct::inconsistentFunction' has a definition
+// CHECK-MESSAGES: :[[@LINE+6]]:14: note: the definition seen here
+// CHECK-MESSAGES: :[[@LINE+2]]:8: note: differing parameters are named here: ('a'), in definition: ('b')
+// CHECK-FIXES: void inconsistentFunction(int b);
+ void inconsistentFunction(int a);
+};
+
+void Struct::inconsistentFunction(int b) { b = 0; }
+
+//////////////////////////////////////////////////////
+
+struct SpecialFunctions {
+// CHECK-MESSAGES: :[[@LINE+4]]:3: warning: function 'SpecialFunctions::SpecialFunctions' has a definition
+// CHECK-MESSAGES: :[[@LINE+12]]:19: note: the definition seen here
+// CHECK-MESSAGES: :[[@LINE+2]]:3: note: differing parameters are named here: ('a'), in definition: ('b')
+// CHECK-FIXES: SpecialFunctions(int b);
+ SpecialFunctions(int a);
+
+// CHECK-MESSAGES: :[[@LINE+4]]:21: warning: function 'SpecialFunctions::operator=' has a definition
+// CHECK-MESSAGES: :[[@LINE+8]]:37: note: the definition seen here
+// CHECK-MESSAGES: :[[@LINE+2]]:21: note: differing parameters are named here: ('a'), in definition: ('b')
+// CHECK-FIXES: SpecialFunctions& operator=(const SpecialFunctions& b);
+ SpecialFunctions& operator=(const SpecialFunctions& a);
+};
+
+SpecialFunctions::SpecialFunctions(int b) { b; }
+
+SpecialFunctions& SpecialFunctions::operator=(const SpecialFunctions& b) { b; return *this; }
+
+//////////////////////////////////////////////////////
+
+// CHECK-MESSAGES: :[[@LINE+5]]:6: warning: function 'templateFunctionWithSeparateDeclarationAndDefinition' has a definition
+// CHECK-MESSAGES: :[[@LINE+7]]:6: note: the definition seen here
+// CHECK-MESSAGES: :[[@LINE+3]]:6: note: differing parameters are named here: ('a'), in definition: ('b')
+// CHECK-FIXES: void templateFunctionWithSeparateDeclarationAndDefinition(T b);
+template<typename T>
+void templateFunctionWithSeparateDeclarationAndDefinition(T a);
+
+template<typename T>
+void templateFunctionWithSeparateDeclarationAndDefinition(T b) { b; }
+
+//////////////////////////////////////////////////////
+
+template<typename T>
+void templateFunctionWithSpecializations(T a) { a; }
+
+template<>
+// CHECK-MESSAGES: :[[@LINE+3]]:6: warning: function template specialization 'templateFunctionWithSpecializations<int>' has a primary template declaration with different parameter names [readability-inconsistent-declaration-parameter-name]
+// CHECK-MESSAGES: :[[@LINE-4]]:6: note: the primary template declaration seen here
+// CHECK-MESSAGES: :[[@LINE+1]]:6: note: differing parameters are named here: ('b'), in primary template declaration: ('a')
+void templateFunctionWithSpecializations(int b) { b; }
+
+template<>
+// CHECK-MESSAGES: :[[@LINE+3]]:6: warning: function template specialization 'templateFunctionWithSpecializations<float>' has a primary template
+// CHECK-MESSAGES: :[[@LINE-10]]:6: note: the primary template declaration seen here
+// CHECK-MESSAGES: :[[@LINE+1]]:6: note: differing parameters are named here: ('c'), in primary template declaration: ('a')
+void templateFunctionWithSpecializations(float c) { c; }
+
+//////////////////////////////////////////////////////
+
+template<typename T>
+void templateFunctionWithoutDefinitionButWithSpecialization(T a);
+
+template<>
+// CHECK-MESSAGES: :[[@LINE+3]]:6: warning: function template specialization 'templateFunctionWithoutDefinitionButWithSpecialization<int>' has a primary template
+// CHECK-MESSAGES: :[[@LINE-4]]:6: note: the primary template declaration seen here
+// CHECK-MESSAGES: :[[@LINE+1]]:6: note: differing parameters are named here: ('b'), in primary template declaration: ('a')
+void templateFunctionWithoutDefinitionButWithSpecialization(int b) { b; }
+
+//////////////////////////////////////////////////////
+
+template<typename T>
+void templateFunctionWithSeparateSpecializationDeclarationAndDefinition(T a);
+
+template<>
+// CHECK-MESSAGES: :[[@LINE+3]]:6: warning: function template specialization 'templateFunctionWithSeparateSpecializationDeclarationAndDefinition<int>' has a primary template
+// CHECK-MESSAGES: :[[@LINE-4]]:6: note: the primary template declaration seen here
+// CHECK-MESSAGES: :[[@LINE+1]]:6: note: differing parameters are named here: ('b'), in primary template declaration: ('a')
+void templateFunctionWithSeparateSpecializationDeclarationAndDefinition(int b);
+
+template<>
+// CHECK-MESSAGES: :[[@LINE+3]]:6: warning: function template specialization 'templateFunctionWithSeparateSpecializationDeclarationAndDefinition<int>' has a primary template
+// CHECK-MESSAGES: :[[@LINE-10]]:6: note: the primary template declaration seen here
+// CHECK-MESSAGES: :[[@LINE+1]]:6: note: differing parameters are named here: ('c'), in primary template declaration: ('a')
+void templateFunctionWithSeparateSpecializationDeclarationAndDefinition(int c) { c; }
+
+//////////////////////////////////////////////////////
+
+template<typename T>
+class ClassTemplate
+{
+public:
+// CHECK-MESSAGES: :[[@LINE+4]]:10: warning: function 'ClassTemplate::functionInClassTemplateWithSeparateDeclarationAndDefinition' has a definition
+// CHECK-MESSAGES: :[[@LINE+7]]:24: note: the definition seen here
+// CHECK-MESSAGES: :[[@LINE+2]]:10: note: differing parameters are named here: ('a'), in definition: ('b')
+// CHECK-FIXES: void functionInClassTemplateWithSeparateDeclarationAndDefinition(int b);
+ void functionInClassTemplateWithSeparateDeclarationAndDefinition(int a);
+};
+
+template<typename T>
+void ClassTemplate<T>::functionInClassTemplateWithSeparateDeclarationAndDefinition(int b) { b; }
+
+//////////////////////////////////////////////////////
+
+class Class
+{
+public:
+ template<typename T>
+// CHECK-MESSAGES: :[[@LINE+4]]:8: warning: function 'Class::memberFunctionTemplateWithSeparateDeclarationAndDefinition' has a definition
+// CHECK-MESSAGES: :[[@LINE+12]]:13: note: the definition seen here
+// CHECK-MESSAGES: :[[@LINE+2]]:8: note: differing parameters are named here: ('a'), in definition: ('b')
+// CHECK-FIXES: void memberFunctionTemplateWithSeparateDeclarationAndDefinition(T b);
+ void memberFunctionTemplateWithSeparateDeclarationAndDefinition(T a);
+
+ template<typename T>
+ void memberFunctionTemplateWithSpecializations(T a) { a; }
+};
+
+//////////////////////////////////////////////////////
+
+template<typename T>
+void Class::memberFunctionTemplateWithSeparateDeclarationAndDefinition(T b) { b; }
+
+//////////////////////////////////////////////////////
+
+template<>
+// CHECK-MESSAGES: :[[@LINE+3]]:13: warning: function template specialization 'Class::memberFunctionTemplateWithSpecializations<int>' has a primary template
+// CHECK-MESSAGES: :[[@LINE-12]]:8: note: the primary template declaration seen here
+// CHECK-MESSAGES: :[[@LINE+1]]:13: note: differing parameters are named here: ('b'), in primary template declaration: ('a')
+void Class::memberFunctionTemplateWithSpecializations(int b) { b; }
+
+template<>
+// CHECK-MESSAGES: :[[@LINE+3]]:13: warning: function template specialization 'Class::memberFunctionTemplateWithSpecializations<float>' has a primary template
+// CHECK-MESSAGES: :[[@LINE-18]]:8: note: the primary template declaration seen here
+// CHECK-MESSAGES: :[[@LINE+1]]:13: note: differing parameters are named here: ('c'), in primary template declaration: ('a')
+void Class::memberFunctionTemplateWithSpecializations(float c) { c; }
+
+//////////////////////////////////////////////////////
+
+// This resulted in a warning by default.
+#define MACRO() \
+ void f(int x);
+
+struct S {
+ MACRO();
+};
+
+void S::f(int y)
+{
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-isolate-declaration-cxx17.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-isolate-declaration-cxx17.cpp
new file mode 100644
index 0000000..623eafe
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-isolate-declaration-cxx17.cpp
@@ -0,0 +1,103 @@
+// RUN: %check_clang_tidy %s readability-isolate-declaration %t -- -- -std=c++17
+
+template <typename T1, typename T2>
+struct pair {
+ T1 first;
+ T2 second;
+ pair(T1 v1, T2 v2) : first(v1), second(v2) {}
+
+ template <int N>
+ decltype(auto) get() const {
+ if constexpr (N == 0)
+ return first;
+ else if constexpr (N == 1)
+ return second;
+ }
+};
+
+void forbidden_transformations() {
+ if (int i = 42, j = i; i == j)
+ ;
+ switch (int i = 12, j = 14; i)
+ ;
+
+ auto [i, j] = pair<int, int>(42, 42);
+}
+
+struct SomeClass {
+ SomeClass() = default;
+ SomeClass(int value);
+};
+
+namespace std {
+template <typename T>
+class initializer_list {};
+
+template <typename T>
+class vector {
+public:
+ vector() = default;
+ vector(initializer_list<T> init) {}
+};
+
+class string {
+public:
+ string() = default;
+ string(const char *) {}
+};
+
+namespace string_literals {
+string operator""s(const char *, decltype(sizeof(int))) {
+ return string();
+}
+} // namespace string_literals
+} // namespace std
+
+namespace Types {
+typedef int MyType;
+} // namespace Types
+
+int touch1, touch2;
+
+void modern() {
+ auto autoInt1 = 3, autoInt2 = 4;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: auto autoInt1 = 3;
+ // CHECK-FIXES: {{^ }}auto autoInt2 = 4;
+
+ decltype(int()) declnottouch = 4;
+ decltype(int()) declint1 = 5, declint2 = 3;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: decltype(int()) declint1 = 5;
+ // CHECK-FIXES: {{^ }}decltype(int()) declint2 = 3;
+
+ std::vector<int> vectorA = {1, 2}, vectorB = {1, 2, 3}, vectorC({1, 1, 1});
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: std::vector<int> vectorA = {1, 2};
+ // CHECK-FIXES: {{^ }}std::vector<int> vectorB = {1, 2, 3};
+ // CHECK-FIXES: {{^ }}std::vector<int> vectorC({1, 1, 1});
+
+ using uType = int;
+ uType utype1, utype2;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: uType utype1;
+ // CHECK-FIXES: {{^ }}uType utype2;
+
+ Types::MyType mytype1, mytype2, mytype3 = 3;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: Types::MyType mytype1;
+ // CHECK-FIXES: {{^ }}Types::MyType mytype2;
+ // CHECK-FIXES: {{^ }}Types::MyType mytype3 = 3;
+
+ {
+ using namespace std::string_literals;
+
+ std::vector<std::string> s{"foo"s, "bar"s}, t{"foo"s}, u, a({"hey", "you"}), bb = {"h", "a"};
+ // CHECK-MESSAGES: [[@LINE-1]]:5: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: std::vector<std::string> s{"foo"s, "bar"s};
+ // CHECK-FIXES: {{^ }}std::vector<std::string> t{"foo"s};
+ // CHECK-FIXES: {{^ }}std::vector<std::string> u;
+ // CHECK-FIXES: {{^ }}std::vector<std::string> a({"hey", "you"});
+ // CHECK-FIXES: {{^ }}std::vector<std::string> bb = {"h", "a"};
+ }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-isolate-declaration-fixing.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-isolate-declaration-fixing.cpp
new file mode 100644
index 0000000..3bd1982
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-isolate-declaration-fixing.cpp
@@ -0,0 +1,64 @@
+// RUN: %check_clang_tidy %s readability-isolate-declaration %t
+// XFAIL: *
+
+struct S {
+ int a;
+ const int b;
+ void f() {}
+};
+
+void member_pointers() {
+ // FIXME: Memberpointers are transformed incorrect. Emit only a warning
+ // for now.
+ int S::*p = &S::a, S::*const q = &S::a;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: int S::*p = &S::a;
+ // CHECK-FIXES: {{^ }}int S::*const q = &S::a;
+
+ int /* :: */ S::*pp2 = &S::a, var1 = 0;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: int /* :: */ S::*pp2 = &S::a;
+ // CHECK-FIXES: {{^ }}int var1 = 0;
+
+ const int S::*r = &S::b, S::*t;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: const int S::*r = &S::b;
+ // CHECK-FIXES: {{^ }}const int S::*t;
+
+ {
+ int S::*mdpa1[2] = {&S::a, &S::a}, var1 = 0;
+ // CHECK-MESSAGES: [[@LINE-1]]:5: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: int S::*mdpa1[2] = {&S::a, &S::a};
+ // CHECK-FIXES: {{^ }}int var1 = 0;
+
+ int S ::**mdpa2[2] = {&p, &pp2}, var2 = 0;
+ // CHECK-MESSAGES: [[@LINE-1]]:5: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: int S ::**mdpa2[2] = {&p, &pp2};
+ // CHECK-FIXES: {{^ }}int var2 = 0;
+
+ void (S::*mdfp1)() = &S::f, (S::*mdfp2)() = &S::f;
+ // CHECK-MESSAGES: [[@LINE-1]]:5: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: void (S::*mdfp1)() = &S::f;
+ // CHECK-FIXES: {{^ }}void (S::*mdfp2)() = &S::f;
+
+ void (S::*mdfpa1[2])() = {&S::f, &S::f}, (S::*mdfpa2)() = &S::f;
+ // CHECK-MESSAGES: [[@LINE-1]]:5: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: void (S::*mdfpa1[2])() = {&S::f, &S::f};
+ // CHECK-FIXES: {{^ }}void (S::*mdfpa2)() = &S::f;
+
+ void (S::* * mdfpa3[2])() = {&mdfpa1[0], &mdfpa1[1]}, (S::*mdfpa4)() = &S::f;
+ // CHECK-MESSAGES: [[@LINE-1]]:5: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: void (S::* * mdfpa3[2])() = {&mdfpa1[0], &mdfpa1[1]};
+ // CHECK-FIXES: {{^ }}void (S::*mdfpa4)() = &S::f;
+ }
+
+ class CS {
+ public:
+ int a;
+ const int b;
+ };
+ int const CS ::*pp = &CS::a, CS::*const qq = &CS::a;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: int const CS ::*pp = &CS::a;
+ // CHECK-FIXES: {{^ }}int const CS::*const qq = &CS::a;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-isolate-declaration.c b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-isolate-declaration.c
new file mode 100644
index 0000000..e09a581
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-isolate-declaration.c
@@ -0,0 +1,13 @@
+// RUN: %check_clang_tidy %s readability-isolate-declaration %t
+
+void c_specific() {
+ void (*signal(int sig, void (*func)(int)))(int);
+ int i = sizeof(struct S { int i; });
+ int j = sizeof(struct T { int i; }), k;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: int j = sizeof(struct T { int i; });
+ // CHECK-FIXES: {{^ }}int k;
+
+ void g(struct U { int i; } s); // One decl
+ void h(struct V { int i; } s), m(int i, ...); // Two decls
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-isolate-declaration.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-isolate-declaration.cpp
new file mode 100644
index 0000000..7489d5d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-isolate-declaration.cpp
@@ -0,0 +1,412 @@
+// RUN: %check_clang_tidy %s readability-isolate-declaration %t -- -- -fexceptions
+
+void f() {
+ int i;
+}
+
+void f2() {
+ int i, j, *k, lala = 42;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: int i;
+ // CHECK-FIXES: {{^ }}int j;
+ // CHECK-FIXES: {{^ }}int *k;
+ // CHECK-FIXES: {{^ }}int lala = 42;
+
+ int normal, weird = /* comment */ 42;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: int normal;
+ // CHECK-FIXES: {{^ }}int weird = /* comment */ 42;
+
+ int /* here is a comment */ v1,
+ // another comment
+ v2 = 42 // Ok, more comments
+ ;
+ // CHECK-MESSAGES: [[@LINE-4]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: int /* here is a comment */ v1;
+ // CHECK-FIXES: {{^ }}int /* here is a comment */ // another comment
+ // CHECK-FIXES: {{^ }}v2 = 42 // Ok, more comments
+ // CHECK-FIXES: {{^ }};
+
+ auto int1 = 42, int2 = 0, int3 = 43;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: auto int1 = 42;
+ // CHECK-FIXES: {{^ }}auto int2 = 0;
+ // CHECK-FIXES: {{^ }}auto int3 = 43;
+
+ decltype(auto) ptr1 = &int1, ptr2 = &int1;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: decltype(auto) ptr1 = &int1;
+ // CHECK-FIXES: {{^ }}decltype(auto) ptr2 = &int1;
+
+ decltype(k) ptr3 = &int1, ptr4 = &int1;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: decltype(k) ptr3 = &int1;
+ // CHECK-FIXES: {{^ }}decltype(k) ptr4 = &int1;
+}
+
+void f3() {
+ int i, *pointer1;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: int i;
+ // CHECK-FIXES: {{^ }}int *pointer1;
+ //
+ int *pointer2 = nullptr, *pointer3 = &i;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: int *pointer2 = nullptr;
+ // CHECK-FIXES: {{^ }}int *pointer3 = &i;
+
+ int *(i_ptr) = nullptr, *((i_ptr2));
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: int *(i_ptr) = nullptr;
+ // CHECK-FIXES: {{^ }}int *((i_ptr2));
+
+ float(*f_ptr)[42], (((f_value))) = 42;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: float (*f_ptr)[42];
+ // CHECK-FIXES: {{^ }}float (((f_value))) = 42;
+
+ float(((*f_ptr2)))[42], ((*f_ptr3)), f_value2 = 42.f;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: float (((*f_ptr2)))[42];
+ // CHECK-FIXES: {{^ }}float ((*f_ptr3));
+ // CHECK-FIXES: {{^ }}float f_value2 = 42.f;
+
+ float(((*f_ptr4)))[42], *f_ptr5, ((f_value3));
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: float (((*f_ptr4)))[42];
+ // CHECK-FIXES: {{^ }}float *f_ptr5;
+ // CHECK-FIXES: {{^ }}float ((f_value3));
+
+ void(((*f2))(int)), (*g2)(int, float);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: void (((*f2))(int));
+ // CHECK-FIXES: {{^ }}void (*g2)(int, float);
+
+ float(*(*(*f_ptr6)))[42], (*f_ptr7);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: float (*(*(*f_ptr6)))[42];
+ // CHECK-FIXES: {{^ }}float (*f_ptr7);
+}
+
+void f4() {
+ double d = 42. /* foo */, z = 43., /* hi */ y, c /* */ /* */, l = 2.;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: double d = 42. /* foo */;
+ // CHECK-FIXES: {{^ }}double z = 43.;
+ // CHECK-FIXES: {{^ }}double /* hi */ y;
+ // CHECK-FIXES: {{^ }}double c /* */ /* */;
+ // CHECK-FIXES: {{^ }}double l = 2.;
+}
+
+struct SomeClass {
+ SomeClass() = default;
+ SomeClass(int value);
+};
+
+class Point {
+ double x;
+ double y;
+
+public:
+ Point(double x, double y) : x(x), y(y) {}
+};
+
+class Rectangle {
+ Point TopLeft;
+ Point BottomRight;
+
+public:
+ Rectangle(Point TopLeft, Point BottomRight) : TopLeft(TopLeft), BottomRight(BottomRight) {}
+};
+
+void f5() {
+ SomeClass v1, v2(42), v3{42}, v4(42.5);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: SomeClass v1;
+ // CHECK-FIXES: {{^ }}SomeClass v2(42);
+ // CHECK-FIXES: {{^ }}SomeClass v3{42};
+ // CHECK-FIXES: {{^ }}SomeClass v4(42.5);
+
+ SomeClass v5 = 42, *p1 = nullptr;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: SomeClass v5 = 42;
+ // CHECK-FIXES: {{^ }}SomeClass *p1 = nullptr;
+
+ Point P1(0., 2.), P2{2., 0.};
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: Point P1(0., 2.);
+ // CHECK-FIXES: {{^ }}Point P2{2., 0.};
+
+ Rectangle R1({0., 0.}, {1., -2.}), R2{{0., 1.}, {1., 0.}}, R3(P1, P2), R4{P1, P2};
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: Rectangle R1({0., 0.}, {1., -2.});
+ // CHECK-FIXES: {{^ }}Rectangle R2{{[{][{]}}0., 1.}, {1., 0.{{[}][}]}};
+ // CHECK-FIXES: {{^ }}Rectangle R3(P1, P2);
+ // CHECK-FIXES: {{^ }}Rectangle R4{P1, P2};
+}
+
+void f6() {
+ int array1[] = {1, 2, 3, 4}, array2[] = {1, 2, 3}, value1, value2 = 42;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: int array1[] = {1, 2, 3, 4};
+ // CHECK-FIXES: {{^ }}int array2[] = {1, 2, 3};
+ // CHECK-FIXES: {{^ }}int value1;
+ // CHECK-FIXES: {{^ }}int value2 = 42;
+}
+
+template <typename T>
+struct TemplatedType {
+ TemplatedType() = default;
+ TemplatedType(T value);
+};
+
+void f7() {
+ TemplatedType<int> TT1(42), TT2{42}, TT3;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: TemplatedType<int> TT1(42);
+ // CHECK-FIXES: {{^ }}TemplatedType<int> TT2{42};
+ // CHECK-FIXES: {{^ }}TemplatedType<int> TT3;
+ //
+ TemplatedType<int *> *TT4(nullptr), TT5, **TT6 = nullptr, *const *const TT7{nullptr};
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: TemplatedType<int *> *TT4(nullptr);
+ // CHECK-FIXES: {{^ }}TemplatedType<int *> TT5;
+ // CHECK-FIXES: {{^ }}TemplatedType<int *> **TT6 = nullptr;
+ // CHECK-FIXES: {{^ }}TemplatedType<int *> *const *const TT7{nullptr};
+
+ TemplatedType<int &> **TT8(nullptr), *TT9;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: TemplatedType<int &> **TT8(nullptr);
+ // CHECK-FIXES: {{^ }}TemplatedType<int &> *TT9;
+
+ TemplatedType<int *> TT10{nullptr}, *TT11(nullptr);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: TemplatedType<int *> TT10{nullptr};
+ // CHECK-FIXES: {{^ }}TemplatedType<int *> *TT11(nullptr);
+}
+
+void forbidden_transformations() {
+ for (int i = 0, j = 42; i < j; ++i)
+ ;
+}
+
+#define NULL 0
+#define MY_NICE_TYPE int **
+#define VAR_NAME(name) name##__LINE__
+#define A_BUNCH_OF_VARIABLES int m1 = 42, m2 = 43, m3 = 44;
+
+void macros() {
+ int *p1 = NULL, *p2 = NULL;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: int *p1 = NULL;
+ // CHECK-FIXES: {{^ }}int *p2 = NULL;
+
+ // Macros are involved, so there will be no transformation
+ MY_NICE_TYPE p3, v1, v2;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+
+ int VAR_NAME(v3),
+ VAR_NAME(v4),
+ VAR_NAME(v5);
+ // CHECK-MESSAGES: [[@LINE-3]]:3: warning: multiple declarations in a single statement reduces readability
+
+ A_BUNCH_OF_VARIABLES
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+
+ int Unconditional,
+ // Explanatory comment.
+#if CONFIGURATION
+ IfConfigured = 42,
+#else
+ IfConfigured = 0;
+#endif
+ // CHECK-MESSAGES: [[@LINE-7]]:3: warning: multiple declarations in a single statement reduces readability
+}
+
+void dontTouchParameter(int param1, int param2) {}
+
+struct StructOne {
+ StructOne() {}
+ StructOne(int b) {}
+
+ int member1, member2;
+ // TODO: Handle FieldDecl's as well
+};
+
+using PointerType = int;
+
+struct {
+ int i;
+} AS1, AS2;
+struct TemT {
+ template <typename T>
+ T *getAs() {
+ return nullptr;
+ }
+} TT1, TT2;
+
+void complex_typedefs() {
+ typedef int *IntPtr;
+ typedef int ArrayType[2];
+ typedef int FunType(void);
+
+ IntPtr intptr1, intptr2 = nullptr, intptr3;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: IntPtr intptr1;
+ // CHECK-FIXES: {{^ }}IntPtr intptr2 = nullptr;
+ // CHECK-FIXES: {{^ }}IntPtr intptr3;
+
+ IntPtr *DoublePtr1 = nullptr, **TriplePtr, SinglePtr = nullptr;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: IntPtr *DoublePtr1 = nullptr;
+ // CHECK-FIXES: {{^ }}IntPtr **TriplePtr;
+ // CHECK-FIXES: {{^ }}IntPtr SinglePtr = nullptr;
+
+ IntPtr intptr_array1[2], intptr_array2[4] = {nullptr, nullptr, nullptr, nullptr};
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: IntPtr intptr_array1[2];
+ // CHECK-FIXES: {{^ }}IntPtr intptr_array2[4] = {nullptr, nullptr, nullptr, nullptr};
+
+ ArrayType arraytype1, arraytype2 = {1}, arraytype3;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: ArrayType arraytype1;
+ // CHECK-FIXES: {{^ }}ArrayType arraytype2 = {1};
+ // CHECK-FIXES: {{^ }}ArrayType arraytype3;
+
+ // Don't touch function declarations.
+ FunType funtype1, funtype2, functype3;
+
+ for (int index1 = 0, index2 = 0;;) {
+ int localFor1 = 1, localFor2 = 2;
+ // CHECK-MESSAGES: [[@LINE-1]]:5: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: int localFor1 = 1;
+ // CHECK-FIXES: {{^ }}int localFor2 = 2;
+ }
+
+ StructOne s1, s2(23), s3, s4(3), *sptr = new StructOne(2);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: StructOne s1;
+ // CHECK-FIXES: {{^ }}StructOne s2(23);
+ // CHECK-FIXES: {{^ }}StructOne s3;
+ // CHECK-FIXES: {{^ }}StructOne s4(3);
+ // CHECK-FIXES: {{^ }}StructOne *sptr = new StructOne(2);
+
+ struct StructOne cs1, cs2(42);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: struct StructOne cs1;
+ // CHECK-FIXES: {{^ }}struct StructOne cs2(42);
+
+ int *ptrArray[3], dummy, **ptrArray2[5], twoDim[2][3], *twoDimPtr[2][3];
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: int *ptrArray[3];
+ // CHECK-FIXES: {{^ }}int dummy;
+ // CHECK-FIXES: {{^ }}int **ptrArray2[5];
+ // CHECK-FIXES: {{^ }}int twoDim[2][3];
+ // CHECK-FIXES: {{^ }}int *twoDimPtr[2][3];
+
+ {
+ void f1(int), g1(int, float);
+ }
+
+ {
+ void gg(int, float);
+
+ void (*f2)(int), (*g2)(int, float) = gg;
+ // CHECK-MESSAGES: [[@LINE-1]]:5: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: void (*f2)(int);
+ // CHECK-FIXES: {{^ }}void (*g2)(int, float) = gg;
+
+ void /*(*/ (/*(*/ *f3)(int), (*g3)(int, float);
+ // CHECK-MESSAGES: [[@LINE-1]]:5: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: void /*(*/ (/*(*/ *f3)(int);
+ // CHECK-FIXES: {{^ }}void /*(*/ (*g3)(int, float);
+ }
+
+ // clang-format off
+ auto returner = []() { return int(32); };
+ int intfunction = returner(), intarray[] =
+ {
+ 1,
+ 2,
+ 3,
+ 4
+ }, bb = 4;
+ // CHECK-MESSAGES: [[@LINE-7]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: int intfunction = returner();
+ // CHECK-FIXES: {{^ }}int intarray[] =
+ // CHECK-FIXES: {{^ }}{
+ // CHECK-FIXES: {{^ }}1,
+ // CHECK-FIXES: {{^ }}2,
+ // CHECK-FIXES: {{^ }}3,
+ // CHECK-FIXES: {{^ }}4
+ // CHECK-FIXES: {{^ }}};
+ // CHECK-FIXES: {{^ }}int bb = 4;
+ // clang-format on
+
+ TemT *T1 = &TT1, *T2 = &TT2;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: TemT *T1 = &TT1;
+ // CHECK-FIXES: {{^ }}TemT *T2 = &TT2;
+
+ const PointerType *PT1 = T1->getAs<PointerType>(),
+ *PT2 = T2->getAs<PointerType>();
+ // CHECK-MESSAGES: [[@LINE-2]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: const PointerType *PT1 = T1->getAs<PointerType>();
+ // CHECK-FIXES: {{^ }}const PointerType *PT2 = T2->getAs<PointerType>();
+
+ const int *p1 = nullptr;
+ const int *p2 = nullptr;
+
+ const int *&pref1 = p1, *&pref2 = p2;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: const int *&pref1 = p1;
+ // CHECK-FIXES: {{^ }}const int *&pref2 = p2;
+
+ // clang-format off
+ const char *literal1 = "clang" "test"\
+ "one",
+ *literal2 = "empty", literal3[] = "three";
+ // CHECK-MESSAGES: [[@LINE-3]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: const char *literal1 = "clang" "test"\
+ // CHECK-FIXES: {{^ }}"one";
+ // CHECK-FIXES: {{^ }}const char *literal2 = "empty";
+ // CHECK-FIXES: {{^ }}const char literal3[] = "three";
+ // clang-format on
+}
+
+void g() try {
+ int i, j;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: int i;
+ // CHECK-FIXES: {{^ }}int j;
+} catch (...) {
+}
+
+struct S {
+ int a;
+ const int b;
+ void f() {}
+};
+
+void memberPointers() {
+ typedef const int S::*MemPtr;
+ MemPtr aaa = &S::a, bbb = &S::b;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: multiple declarations in a single statement reduces readability
+ // CHECK-FIXES: MemPtr aaa = &S::a;
+ // CHECK-FIXES: {{^ }}MemPtr bbb = &S::b;
+}
+
+typedef int *tptr, tbt;
+typedef int (&tfp)(int, long), tarr[10];
+typedef int tarr2[10], tct;
+
+template <typename A, typename B>
+void should_not_be_touched(A, B);
+
+int variable, function(void);
+
+int call_func_with_sideeffect();
+void bad_if_decl() {
+ if (true)
+ int i, j, k = call_func_with_sideeffect();
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-magic-numbers.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-magic-numbers.cpp
new file mode 100644
index 0000000..3cf9dc5
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-magic-numbers.cpp
@@ -0,0 +1,199 @@
+// RUN: %check_clang_tidy %s readability-magic-numbers %t \
+// RUN: -config='{CheckOptions: \
+// RUN: [{key: readability-magic-numbers.IgnoredIntegerValues, value: "0;1;2;10;100;"}, \
+// RUN: {key: readability-magic-numbers.IgnoredFloatingPointValues, value: "3.14;2.71828;9.81;10000.0;101.0;0x1.2p3"}, \
+// RUN: {key: readability-magic-numbers.IgnorePowersOf2IntegerValues, value: 1}]}' \
+// RUN: --
+
+template <typename T, int V>
+struct ValueBucket {
+ T value[V];
+};
+
+int BadGlobalInt = 5;
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 5 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+
+int IntSquarer(int param) {
+ return param * param;
+}
+
+void BuggyFunction() {
+ int BadLocalInt = 6;
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 6 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+
+ (void)IntSquarer(7);
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 7 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+
+ int LocalArray[15];
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 15 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+
+ for (int ii = 0; ii < 22; ++ii)
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: 22 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+ {
+ LocalArray[ii] = 3 * ii;
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 3 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+ }
+
+ ValueBucket<int, 66> Bucket;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 66 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+}
+
+class TwoIntContainer {
+public:
+ TwoIntContainer(int val) : anotherMember(val * val), yetAnotherMember(6), anotherConstant(val + val) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:73: warning: 6 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+
+ int getValue() const;
+
+private:
+ int oneMember = 9;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 9 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+
+ int anotherMember;
+
+ int yetAnotherMember;
+
+ const int oneConstant = 2;
+
+ const int anotherConstant;
+};
+
+int ValueArray[] = {3, 5};
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 3 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+// CHECK-MESSAGES: :[[@LINE-2]]:24: warning: 5 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+
+float FloatPiVariable = 3.1415926535f;
+// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: 3.1415926535f is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+double DoublePiVariable = 6.283185307;
+// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 6.283185307 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+
+float SomeFloats[] = {0.5, 0x1.2p4};
+// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 0.5 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+// CHECK-MESSAGES: :[[@LINE-2]]:28: warning: 0x1.2p4 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+
+int getAnswer() {
+ if (ValueArray[0] < ValueArray[1])
+ return ValueArray[1];
+
+ return -3; // FILENOTFOUND
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: 3 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+}
+
+/*
+ * Clean code
+ */
+
+#define INT_MACRO 5
+
+const int GoodGlobalIntConstant = 42;
+
+constexpr int AlsoGoodGlobalIntConstant = 42;
+
+int InitializedByMacro = INT_MACRO;
+
+void SolidFunction() {
+ const int GoodLocalIntConstant = 43;
+
+ (void)IntSquarer(GoodLocalIntConstant);
+
+ int LocalArray[INT_MACRO];
+
+ ValueBucket<int, INT_MACRO> Bucket;
+}
+
+const int ConstValueArray[] = {7, 9};
+
+const int ConstValueArray2D[2][2] = {{7, 9}, {13, 15}};
+
+/*
+ * no warnings for ignored values (specified in the configuration above)
+ */
+int GrandfatheredIntegerValues[] = {0, 1, 2, 10, 100, -1, -10, -100, 65536};
+
+float GrandfatheredFloatValues[] = {3.14f, 3.14, 2.71828, 2.71828f, -1.01E2, 1E4, 0x1.2p3};
+
+/*
+ * no warnings for enums
+ */
+enum Smorgasbord {
+ STARTER,
+ ALPHA = 3,
+ BETA = 1 << 5,
+};
+
+const float FloatPiConstant = 3.1415926535f;
+const double DoublePiConstant = 6.283185307;
+
+const float Angles[] = {45.0f, 90.0f, 135.0f};
+
+double DoubleZeroIsAccepted = 0.0;
+float FloatZeroIsAccepted = 0.0f;
+
+namespace geometry {
+
+template <typename T>
+struct Point {
+ T x;
+ T y;
+
+ explicit Point(T xval, T yval) noexcept : x{xval}, y{yval} {
+ }
+};
+
+template <typename T>
+struct Dimension {
+ T x;
+ T y;
+
+ explicit Dimension(T xval, T yval) noexcept : x{xval}, y{yval} {
+ }
+};
+
+template <typename T>
+struct Rectangle {
+ Point<T> origin;
+ Dimension<T> size;
+ T rotation; // angle of rotation around origin
+
+ Rectangle(Point<T> origin_, Dimension<T> size_, T rotation_ = 0) noexcept : origin{origin_}, size{size_}, rotation{rotation_} {
+ }
+
+ bool contains(Point<T> point) const;
+};
+
+} // namespace geometry
+
+const geometry::Rectangle<double> mandelbrotCanvas{geometry::Point<double>{-2.5, -1}, geometry::Dimension<double>{3.5, 2}};
+
+// Simulate the macro magic in Google Test internal headers
+class AssertionHelper {
+public:
+ AssertionHelper(const char *Message, int LineNumber) : Message(Message), LineNumber(LineNumber) {}
+
+private:
+ const char *Message;
+ int LineNumber;
+};
+
+#define ASSERTION_HELPER_AT(M, L) AssertionHelper(M, L)
+
+#define ASSERTION_HELPER(M) ASSERTION_HELPER_AT(M, __LINE__)
+
+void FunctionWithCompilerDefinedSymbol(void) {
+ ASSERTION_HELPER("here and now");
+}
+
+// prove that integer literals introduced by the compiler are accepted silently
+extern int ConsumeString(const char *Input);
+
+const char *SomeStrings[] = {"alpha", "beta", "gamma"};
+
+int TestCheckerOverreach() {
+ int Total = 0;
+
+ for (const auto *Str : SomeStrings) {
+ Total += ConsumeString(Str);
+ }
+
+ return Total;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-misleading-indentation.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-misleading-indentation.cpp
new file mode 100644
index 0000000..59d5f40
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-misleading-indentation.cpp
@@ -0,0 +1,111 @@
+// RUN: %check_clang_tidy %s readability-misleading-indentation %t
+
+void foo1();
+void foo2();
+
+#define BLOCK \
+ if (cond1) \
+ foo1(); \
+ foo2();
+
+int main()
+{
+ bool cond1 = true;
+ bool cond2 = true;
+
+ if (cond1)
+ if (cond2)
+ foo1();
+ else
+ foo2();
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: different indentation for 'if' and corresponding 'else' [readability-misleading-indentation]
+
+ if (cond1) {
+ if (cond2)
+ foo1();
+ }
+ else
+ foo2();
+
+ if (cond1)
+ if (cond2)
+ foo1();
+ else
+ foo2();
+
+ if (cond2)
+ foo1();
+ foo2();
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: misleading indentation: statement is indented too deeply [readability-misleading-indentation]
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: note: did you mean this line to be inside this 'if'
+ foo2(); // No redundant warning.
+
+ if (cond1)
+ {
+ foo1();
+ }
+ foo2();
+
+ if (cond1)
+ foo1();
+ foo2();
+
+ if (cond2)
+ if (cond1) foo1(); else foo2();
+
+ if (cond1) {
+ } else {
+ }
+
+ if (cond1) {
+ }
+ else {
+ }
+
+ if (cond1)
+ {
+ }
+ else
+ {
+ }
+
+ if (cond1)
+ {
+ }
+ else
+ {
+ }
+
+ if(cond1) {
+ }
+ else if (cond2) {
+ }
+ else {
+ }
+
+ if(cond1) {
+ }
+ else if (cond2) {
+ }
+ else {
+ }
+ // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: different indentation for 'if' and corresponding 'else' [readability-misleading-indentation]
+
+ if (cond1) {
+ if (cond1) {
+ }
+ else if (cond2) {
+ }
+ else {
+ }
+ if (cond1) {
+ } else if (cond2) {
+ } else if (!cond2) {
+ } else {
+ }
+ }
+ else if (cond2) {
+ }
+
+ BLOCK
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-misplaced-array-index.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-misplaced-array-index.cpp
new file mode 100644
index 0000000..43dd458
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-misplaced-array-index.cpp
@@ -0,0 +1,34 @@
+// RUN: %check_clang_tidy %s readability-misplaced-array-index %t
+
+#define ABC "abc"
+
+struct XY { int *X; int *Y; };
+
+void dostuff(int);
+
+void unusualSyntax(int *P1, struct XY *P2) {
+ 10[P1] = 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: confusing array subscript expression, usually the index is inside the []
+ // CHECK-FIXES: P1[10] = 0;
+
+ 10[P2->X] = 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: confusing array subscript expression
+ // CHECK-FIXES: P2->X[10] = 0;
+
+ dostuff(1["abc"]);
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: confusing array subscript expression
+ // CHECK-FIXES: dostuff("abc"[1]);
+
+ dostuff(1[ABC]);
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: confusing array subscript expression
+ // CHECK-FIXES: dostuff(ABC[1]);
+
+ dostuff(0[0 + ABC]);
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: confusing array subscript expression
+ // CHECK-FIXES: dostuff(0[0 + ABC]);
+ // No fixit. Probably the code should be ABC[0]
+}
+
+void normalSyntax(int *X) {
+ X[10] = 0;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-named-parameter.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-named-parameter.cpp
new file mode 100644
index 0000000..af2c195
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-named-parameter.cpp
@@ -0,0 +1,133 @@
+// RUN: %check_clang_tidy %s readability-named-parameter %t
+
+void Method(char *) { /* */ }
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: all parameters should be named in a function
+// CHECK-FIXES: void Method(char * /*unused*/) { /* */ }
+void Method2(char *) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: all parameters should be named in a function
+// CHECK-FIXES: void Method2(char * /*unused*/) {}
+void Method3(char *, void *) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: all parameters should be named in a function
+// CHECK-FIXES: void Method3(char * /*unused*/, void * /*unused*/) {}
+void Method4(char *, int /*unused*/) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: all parameters should be named in a function
+// CHECK-FIXES: void Method4(char * /*unused*/, int /*unused*/) {}
+void operator delete[](void *) throw() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: all parameters should be named in a function
+// CHECK-FIXES: void operator delete[](void * /*unused*/) throw() {}
+int Method5(int) { return 0; }
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: all parameters should be named in a function
+// CHECK-FIXES: int Method5(int /*unused*/) { return 0; }
+void Method6(void (*)(void *)) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: all parameters should be named in a function
+// CHECK-FIXES: void Method6(void (* /*unused*/)(void *)) {}
+template <typename T> void Method7(T) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: all parameters should be named in a function
+// CHECK-FIXES: template <typename T> void Method7(T /*unused*/) {}
+
+// Don't warn in macros.
+#define M void MethodM(int) {}
+M
+
+void operator delete(void *x) throw() {}
+void Method7(char * /*x*/) {}
+void Method8(char *x) {}
+typedef void (*TypeM)(int x);
+void operator delete[](void *x) throw();
+void operator delete[](void * /*x*/) throw();
+
+struct X {
+ X operator++(int) {}
+ X operator--(int) {}
+
+ X(X&) = delete;
+ X &operator=(X&) = default;
+
+ const int &i;
+};
+
+void (*Func1)(void *);
+void Func2(void (*func)(void *)) {}
+template <void Func(void *)> void Func3() {}
+
+template <typename T>
+struct Y {
+ void foo(T) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: all parameters should be named in a function
+// CHECK-FIXES: void foo(T /*unused*/) {}
+};
+
+Y<int> y;
+Y<float> z;
+
+struct Base {
+ virtual void foo(bool notThisOne);
+ virtual void foo(int argname);
+};
+
+struct Derived : public Base {
+ void foo(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: all parameters should be named in a function
+// CHECK-FIXES: void foo(int /*argname*/);
+};
+
+void FDef(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: all parameters should be named in a function
+// CHECK-FIXES: void FDef(int /*n*/);
+void FDef(int n) {}
+
+void FDef2(int, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: all parameters should be named in a function
+// CHECK-FIXES: void FDef2(int /*n*/, int /*unused*/);
+void FDef2(int n, int) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: all parameters should be named in a function
+// CHECK-FIXES: void FDef2(int n, int /*unused*/) {}
+
+void FNoDef(int);
+
+class Z {};
+
+Z &operator++(Z&) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: all parameters should be named in a function
+// CHECK-FIXES: Z &operator++(Z& /*unused*/) {}
+
+Z &operator++(Z&, int) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: all parameters should be named in a function
+// CHECK-FIXES: Z &operator++(Z& /*unused*/, int) {}
+
+Z &operator--(Z&) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: all parameters should be named in a function
+// CHECK-FIXES: Z &operator--(Z& /*unused*/) {}
+
+Z &operator--(Z&, int) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: all parameters should be named in a function
+// CHECK-FIXES: Z &operator--(Z& /*unused*/, int) {}
+
+namespace testing {
+namespace internal {
+class IgnoredValue {
+ public:
+ template <typename T>
+ IgnoredValue(const T& /* ignored */) {}
+};
+}
+typedef internal::IgnoredValue Unused;
+}
+
+using ::testing::Unused;
+
+void MockFunction(Unused, int q, Unused) {
+ ++q;
+ ++q;
+ ++q;
+}
+
+namespace std {
+typedef decltype(nullptr) nullptr_t;
+}
+
+void f(std::nullptr_t) {}
+
+typedef void (F)(int);
+F f;
+void f(int x) {}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-non-const-parameter.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-non-const-parameter.cpp
new file mode 100644
index 0000000..6cd1f91
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-non-const-parameter.cpp
@@ -0,0 +1,289 @@
+// RUN: %check_clang_tidy %s readability-non-const-parameter %t
+
+// Currently the checker only warns about pointer arguments.
+//
+// It can be defined both that the data is const and that the pointer is const,
+// the checker only checks if the data can be const-specified.
+//
+// It does not warn about pointers to records or function pointers.
+
+// Some external function where first argument is nonconst and second is const.
+char *strcpy1(char *dest, const char *src);
+unsigned my_strcpy(char *buf, const char *s);
+unsigned my_strlen(const char *buf);
+
+// CHECK-MESSAGES: :[[@LINE+1]]:29: warning: pointer parameter 'last' can be pointer to const [readability-non-const-parameter]
+void warn1(int *first, int *last) {
+ // CHECK-FIXES: {{^}}void warn1(int *first, const int *last) {{{$}}
+ *first = 0;
+ if (first < last) {
+ } // <- last can be const
+}
+
+// TODO: warning should be written here
+void warn2(char *p) {
+ char buf[10];
+ strcpy1(buf, p);
+}
+
+// CHECK-MESSAGES: :[[@LINE+1]]:19: warning: pointer parameter 'p' can be
+void assign1(int *p) {
+ // CHECK-FIXES: {{^}}void assign1(const int *p) {{{$}}
+ const int *q;
+ q = p;
+}
+
+// CHECK-MESSAGES: :[[@LINE+1]]:19: warning: pointer parameter 'p' can be
+void assign2(int *p) {
+ // CHECK-FIXES: {{^}}void assign2(const int *p) {{{$}}
+ const int *q;
+ q = p + 1;
+}
+
+void assign3(int *p) {
+ *p = 0;
+}
+
+void assign4(int *p) {
+ *p += 2;
+}
+
+void assign5(char *p) {
+ p[0] = 0;
+}
+
+void assign6(int *p) {
+ int *q;
+ q = p++;
+}
+
+void assign7(char *p) {
+ char *a, *b;
+ a = b = p;
+}
+
+void assign8(char *a, char *b) {
+ char *x;
+ x = (a ? a : b);
+}
+
+void assign9(unsigned char *str, const unsigned int i) {
+ unsigned char *p;
+ for (p = str + i; *p;) {
+ }
+}
+
+void assign10(int *buf) {
+ int i, *p;
+ for (i = 0, p = buf; i < 10; i++, p++) {
+ *p = 1;
+ }
+}
+
+// CHECK-MESSAGES: :[[@LINE+1]]:17: warning: pointer parameter 'p' can be
+void init1(int *p) {
+ // CHECK-FIXES: {{^}}void init1(const int *p) {{{$}}
+ const int *q = p;
+}
+
+// CHECK-MESSAGES: :[[@LINE+1]]:17: warning: pointer parameter 'p' can be
+void init2(int *p) {
+ // CHECK-FIXES: {{^}}void init2(const int *p) {{{$}}
+ const int *q = p + 1;
+}
+
+void init3(int *p) {
+ int *q = p;
+}
+
+void init4(float *p) {
+ int *q = (int *)p;
+}
+
+void init5(int *p) {
+ int *i = p ? p : 0;
+}
+
+void init6(int *p) {
+ int *a[] = {p, p, 0};
+}
+
+void init7(int *p, int x) {
+ for (int *q = p + x - 1; 0; q++)
+ ;
+}
+
+// CHECK-MESSAGES: :[[@LINE+1]]:18: warning: pointer parameter 'p' can be
+int return1(int *p) {
+ // CHECK-FIXES: {{^}}int return1(const int *p) {{{$}}
+ return *p;
+}
+
+// CHECK-MESSAGES: :[[@LINE+1]]:25: warning: pointer parameter 'p' can be
+const int *return2(int *p) {
+ // CHECK-FIXES: {{^}}const int *return2(const int *p) {{{$}}
+ return p;
+}
+
+// CHECK-MESSAGES: :[[@LINE+1]]:25: warning: pointer parameter 'p' can be
+const int *return3(int *p) {
+ // CHECK-FIXES: {{^}}const int *return3(const int *p) {{{$}}
+ return p + 1;
+}
+
+// CHECK-MESSAGES: :[[@LINE+1]]:27: warning: pointer parameter 'p' can be
+const char *return4(char *p) {
+ // CHECK-FIXES: {{^}}const char *return4(const char *p) {{{$}}
+ return p ? p : "";
+}
+
+char *return5(char *s) {
+ return s;
+}
+
+char *return6(char *s) {
+ return s + 1;
+}
+
+char *return7(char *a, char *b) {
+ return a ? a : b;
+}
+
+char return8(int *p) {
+ return ++(*p);
+}
+
+void dontwarn1(int *p) {
+ ++(*p);
+}
+
+void dontwarn2(int *p) {
+ (*p)++;
+}
+
+int dontwarn3(_Atomic(int) * p) {
+ return *p;
+}
+
+void callFunction1(char *p) {
+ strcpy1(p, "abc");
+}
+
+void callFunction2(char *p) {
+ strcpy1(&p[0], "abc");
+}
+
+void callFunction3(char *p) {
+ strcpy1(p + 2, "abc");
+}
+
+char *callFunction4(char *p) {
+ return strcpy1(p, "abc");
+}
+
+unsigned callFunction5(char *buf) {
+ unsigned len = my_strlen(buf);
+ return len + my_strcpy(buf, "abc");
+}
+
+void f6(int **p);
+void callFunction6(int *p) { f6(&p); }
+
+typedef union { void *v; } t;
+void f7(t obj);
+void callFunction7(int *p) {
+ f7((t){p});
+}
+
+void f8(int &x);
+void callFunction8(int *p) {
+ f8(*p);
+}
+
+// Don't warn about nonconst function pointers that can be const.
+void functionpointer(double f(double), int x) {
+ f(x);
+}
+
+// TODO: This is a false positive.
+// CHECK-MESSAGES: :[[@LINE+1]]:27: warning: pointer parameter 'p' can be
+int functionpointer2(int *p) {
+ return *p;
+}
+void use_functionpointer2() {
+ int (*fp)(int *) = functionpointer2; // <- the parameter 'p' can't be const
+}
+
+// Don't warn about nonconst record pointers that can be const.
+struct XY {
+ int *x;
+ int *y;
+};
+void recordpointer(struct XY *xy) {
+ *(xy->x) = 0;
+}
+
+class C {
+public:
+ C(int *p) : p(p) {}
+
+private:
+ int *p;
+};
+
+class C2 {
+public:
+ // CHECK-MESSAGES: :[[@LINE+1]]:11: warning: pointer parameter 'p' can be
+ C2(int *p) : p(p) {}
+ // CHECK-FIXES: {{^}} C2(const int *p) : p(p) {}{{$}}
+
+private:
+ const int *p;
+};
+
+void tempObject(int *p) {
+ C c(p);
+}
+
+// avoid fp for const pointer array
+void constPointerArray(const char *remapped[][2]) {
+ const char *name = remapped[0][0];
+}
+
+class Warn {
+public:
+ // CHECK-MESSAGES: :[[@LINE+1]]:21: warning: pointer parameter 'p' can be
+ void doStuff(int *p) {
+ // CHECK-FIXES: {{^}} void doStuff(const int *p) {{{$}}
+ x = *p;
+ }
+
+private:
+ int x;
+};
+
+class Base {
+public:
+ // Ensure there is no false positive for this method. It is virtual.
+ virtual void doStuff(int *p) {
+ int x = *p;
+ }
+};
+
+class Derived : public Base {
+public:
+ // Ensure there is no false positive for this method. It overrides a method.
+ void doStuff(int *p) override {
+ int x = *p;
+ }
+};
+
+extern char foo(char *s); // 1
+// CHECK-FIXES: {{^}}extern char foo(const char *s); // 1{{$}}
+// CHECK-MESSAGES: :[[@LINE+1]]:16: warning: pointer parameter 's' can be
+char foo(char *s) {
+ // CHECK-FIXES: {{^}}char foo(const char *s) {{{$}}
+ return *s;
+}
+char foo(char *s); // 2
+// CHECK-FIXES: {{^}}char foo(const char *s); // 2{{$}}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-control-flow.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-control-flow.cpp
new file mode 100644
index 0000000..0352e3a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-control-flow.cpp
@@ -0,0 +1,224 @@
+// RUN: %check_clang_tidy %s readability-redundant-control-flow %t
+
+void g(int i);
+void j();
+
+void f() {
+ return;
+}
+// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: redundant return statement at the end of a function with a void return type [readability-redundant-control-flow]
+// CHECK-FIXES: {{^}}void f() {{{$}}
+// CHECK-FIXES-NEXT: {{^ *}$}}
+
+void g() {
+ f();
+ return;
+}
+// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: redundant return statement
+// CHECK-FIXES: {{^ }}f();{{$}}
+// CHECK-FIXES-NEXT: {{^ *}$}}
+
+void g(int i) {
+ if (i < 0) {
+ return;
+ }
+ if (i < 10) {
+ f();
+ }
+}
+
+int h() {
+ return 1;
+}
+
+void j() {
+}
+
+void k() {
+ for (int i = 0; i < 10; ++i) {
+ continue;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: redundant continue statement at the end of loop statement
+// CHECK-FIXES: {{^}} for (int i = 0; i < 10; ++i) {{{$}}
+// CHECK-FIXES-NEXT: {{^ *}$}}
+
+void k2() {
+ int v[10] = { 0 };
+ for (auto i : v) {
+ continue;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: redundant continue statement
+// CHECK-FIXES: {{^}} for (auto i : v) {{{$}}
+// CHECK-FIXES-NEXT: {{^ *}$}}
+
+void m() {
+ int i = 0;
+ do {
+ ++i;
+ continue;
+ } while (i < 10);
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: redundant continue statement
+// CHECK-FIXES: {{^ do {$}}
+// CHECK-FIXES-NEXT: {{^}} ++i;{{$}}
+// CHECK-FIXES-NEXT: {{^ *}}} while (i < 10);{{$}}
+
+void p() {
+ int i = 0;
+ while (i < 10) {
+ ++i;
+ continue;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: redundant continue statement
+// CHECK-FIXES: {{^}} while (i < 10) {{{$}}
+// CHECK-FIXES-NEXT: {{^}} ++i;{{$}}
+// CHECK-FIXES-NEXT: {{^ *}$}}
+
+void im_not_dead(int i) {
+ if (i > 0) {
+ return;
+ }
+ g();
+}
+
+void im_still_not_dead(int i) {
+ for (int j = 0; j < 10; ++j) {
+ if (i < 10) {
+ continue;
+ }
+ g();
+ }
+}
+
+void im_dead(int i) {
+ if (i > 0) {
+ return;
+ g();
+ }
+ g();
+}
+
+void im_still_dead(int i) {
+ for (int j = 0; j < 10; ++j) {
+ if (i < 10) {
+ continue;
+ g();
+ }
+ g();
+ }
+}
+
+void void_return() {
+ return g();
+}
+
+void nested_return_unmolested() {
+ g();
+ {
+ g();
+ return;
+ }
+}
+
+void nested_continue_unmolested() {
+ for (int i = 0; i < 10; ++i) {
+ if (i < 5) {
+ continue;
+ }
+ }
+}
+
+#define MACRO_RETURN_UNMOLESTED(fn_) \
+ (fn_)(); \
+ return
+
+#define MACRO_CONTINUE_UNMOLESTED(x_) \
+ do { \
+ for (int i = 0; i < (x_); ++i) { \
+ continue; \
+ } \
+ } while (false)
+
+void macro_return() {
+ MACRO_RETURN_UNMOLESTED(g);
+}
+
+void macro_continue() {
+ MACRO_CONTINUE_UNMOLESTED(10);
+}
+
+#define MACRO_RETURN_ARG(stmt_) \
+ stmt_
+
+#define MACRO_CONTINUE_ARG(stmt_) \
+ do { \
+ for (int i = 0; i < 10; ++i) { \
+ stmt_; \
+ } \
+ } while (false)
+
+void macro_arg_return() {
+ MACRO_RETURN_ARG(return);
+}
+
+void macro_arg_continue() {
+ MACRO_CONTINUE_ARG(continue);
+}
+
+template <typename T>
+void template_return(T check) {
+ if (check < T(0)) {
+ return;
+ }
+ return;
+}
+// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: redundant return statement
+// CHECK-FIXES: {{^}} if (check < T(0)) {{{$}}
+// CHECK-FIXES-NEXT: {{^ return;$}}
+// CHECK-FIXES-NEXT: {{^ *}$}}
+// CHECK-FIXES-NEXT: {{^ *}$}}
+
+template <>
+void template_return(int check) {
+ if (check < 0) {
+ return;
+ }
+ return;
+}
+// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: redundant return statement
+// CHECK-FIXES: {{^}} if (check < 0) {{{$}}
+// CHECK-FIXES-NEXT: {{^ return;$}}
+// CHECK-FIXES-NEXT: {{^ *}$}}
+// CHECK-FIXES-NEXT: {{^ *}$}}
+
+template <typename T>
+void template_loop(T end) {
+ for (T i = 0; i < end; ++i) {
+ continue;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: redundant continue statement
+// CHECK-FIXES: {{^}} for (T i = 0; i < end; ++i) {{{$}}
+// CHECK-FIXES-NEXT: {{^ *}$}}
+
+template <>
+void template_loop(int end) {
+ for (int i = 0; i < end; ++i) {
+ continue;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: redundant continue statement
+// CHECK-FIXES: {{^}} for (int i = 0; i < end; ++i) {{{$}}
+// CHECK-FIXES-NEXT: {{^ *}$}}
+
+void call_templates() {
+ template_return(10);
+ template_return(10.0f);
+ template_return(10.0);
+ template_loop(10);
+ template_loop(10L);
+ template_loop(10U);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-declaration-ignore-macros.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-declaration-ignore-macros.cpp
new file mode 100644
index 0000000..2dc8618
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-declaration-ignore-macros.cpp
@@ -0,0 +1,22 @@
+// RUN: %check_clang_tidy %s readability-redundant-declaration %t -- \
+// RUN: -config="{CheckOptions: \
+// RUN: [{key: readability-redundant-declaration.IgnoreMacros, \
+// RUN: value: 1}]}" \
+// RUN: -- -std=c++11
+
+extern int Xyz;
+extern int Xyz; // Xyz
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant 'Xyz' declaration [readability-redundant-declaration]
+// CHECK-FIXES: {{^}}// Xyz{{$}}
+
+namespace macros {
+#define DECLARE(x) extern int x
+#define DEFINE(x) extern int x; int x = 42
+DECLARE(test);
+DEFINE(test);
+// CHECK-FIXES: {{^}}#define DECLARE(x) extern int x{{$}}
+// CHECK-FIXES: {{^}}#define DEFINE(x) extern int x; int x = 42{{$}}
+// CHECK-FIXES: {{^}}DECLARE(test);{{$}}
+// CHECK-FIXES: {{^}}DEFINE(test);{{$}}
+
+} // namespace macros
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-declaration.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-declaration.cpp
new file mode 100644
index 0000000..83d1b5b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-declaration.cpp
@@ -0,0 +1,70 @@
+// RUN: %check_clang_tidy %s readability-redundant-declaration %t -- \
+// RUN: -config="{CheckOptions: \
+// RUN: [{key: readability-redundant-declaration.IgnoreMacros, \
+// RUN: value: 0}]}" \
+// RUN: -- -std=c++11
+
+extern int Xyz;
+extern int Xyz; // Xyz
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant 'Xyz' declaration [readability-redundant-declaration]
+// CHECK-FIXES: {{^}}// Xyz{{$}}
+int Xyz = 123;
+
+extern int A;
+extern int A, B;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant 'A' declaration
+// CHECK-FIXES: {{^}}extern int A, B;{{$}}
+
+extern int Buf[10];
+extern int Buf[10]; // Buf[10]
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant 'Buf' declaration
+// CHECK-FIXES: {{^}}// Buf[10]{{$}}
+
+static int f();
+static int f(); // f
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant 'f' declaration
+// CHECK-FIXES: {{^}}// f{{$}}
+static int f() {}
+
+// Original check crashed for the code below.
+namespace std {
+typedef decltype(sizeof(0)) size_t;
+}
+void *operator new(std::size_t) __attribute__((__externally_visible__));
+void *operator new[](std::size_t) __attribute__((__externally_visible__));
+
+// Don't warn about static member definition.
+struct C {
+ static int I;
+};
+int C::I;
+
+template <class T>
+struct C2 {
+ C2();
+};
+
+template <class T>
+C2<T>::C2() = default;
+
+void best_friend();
+
+struct Friendly {
+ friend void best_friend();
+ friend void enemy();
+};
+
+void enemy();
+
+namespace macros {
+#define DECLARE(x) extern int x
+#define DEFINE(x) extern int x; int x = 42
+DECLARE(test);
+DEFINE(test);
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant 'test' declaration
+// CHECK-FIXES: {{^}}#define DECLARE(x) extern int x{{$}}
+// CHECK-FIXES: {{^}}#define DEFINE(x) extern int x; int x = 42{{$}}
+// CHECK-FIXES: {{^}}DECLARE(test);{{$}}
+// CHECK-FIXES: {{^}}DEFINE(test);{{$}}
+
+} // namespace macros
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-function-ptr-dereference.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-function-ptr-dereference.cpp
new file mode 100644
index 0000000..2b34ce1
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-function-ptr-dereference.cpp
@@ -0,0 +1,45 @@
+// RUN: %check_clang_tidy %s readability-redundant-function-ptr-dereference %t
+
+void f(int i);
+
+void positive() {
+ void (*p)(int) = f;
+
+ (**p)(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: redundant repeated dereference of function pointer [readability-redundant-function-ptr-dereference]
+ // CHECK-FIXES: (*p)(1);
+ (*****p)(2);
+ // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: redundant repeated
+ // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: redundant repeated
+ // CHECK-MESSAGES: :[[@LINE-3]]:6: warning: redundant repeated
+ // CHECK-MESSAGES: :[[@LINE-4]]:7: warning: redundant repeated
+ // CHECK-FIXES: (*p)(2);
+}
+
+template<typename T>
+void invoke(const T& fn) {
+ fn(0); // 1
+ (*fn)(0); // 2
+ // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: redundant repeated
+ // CHECK-FIXES: fn(0); // 1
+ // CHECK-FIXES: (fn)(0); // 2
+ // FIXME: Remove unnecessary parentheses.
+}
+
+void f1(int);
+void f2(double);
+void f3(char);
+
+void instantiate() {
+ invoke(f1);
+ invoke(f2);
+ invoke(f3);
+ invoke([](unsigned) {});
+}
+
+void negative() {
+ void (*q)(int) = &f;
+
+ q(1);
+ (*q)(2);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-member-init.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-member-init.cpp
new file mode 100644
index 0000000..90b52fd
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-member-init.cpp
@@ -0,0 +1,219 @@
+// RUN: %check_clang_tidy %s readability-redundant-member-init %t
+
+struct S {
+ S() = default;
+ S(int i) : i(i) {}
+ int i = 1;
+};
+
+struct T {
+ T(int i = 1) : i(i) {}
+ int i;
+};
+
+struct U {
+ int i;
+};
+
+union V {
+ int i;
+ double f;
+};
+
+// Initializer calls default constructor
+struct F1 {
+ F1() : f() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for member 'f' is redundant
+ // CHECK-FIXES: F1() {}
+ S f;
+};
+
+// Initializer calls default constructor with default argument
+struct F2 {
+ F2() : f() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for member 'f' is redundant
+ // CHECK-FIXES: F2() {}
+ T f;
+};
+
+// Multiple redundant initializers for same constructor
+struct F3 {
+ F3() : f(), g(1), h() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for member 'f' is redundant
+ // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: initializer for member 'h' is redundant
+ // CHECK-FIXES: F3() : g(1) {}
+ S f, g, h;
+};
+
+// Templated class independent type
+template <class V>
+struct F4 {
+ F4() : f() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for member 'f' is redundant
+ // CHECK-FIXES: F4() {}
+ S f;
+};
+F4<int> f4i;
+F4<S> f4s;
+
+// Base class
+struct F5 : S {
+ F5() : S() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for base class 'S' is redundant
+ // CHECK-FIXES: F5() {}
+};
+
+// Constructor call requires cleanup
+struct Cleanup {
+ ~Cleanup() {}
+};
+
+struct UsesCleanup {
+ UsesCleanup(const Cleanup &c = Cleanup()) {}
+};
+
+struct F6 {
+ F6() : uc() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for member 'uc' is redundant
+ // CHECK-FIXES: F6() {}
+ UsesCleanup uc;
+};
+
+// Multiple inheritance
+struct F7 : S, T {
+ F7() : S(), T() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for base class 'S' is redundant
+ // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: initializer for base class 'T' is redundant
+ // CHECK-FIXES: F7() {}
+};
+
+namespace Foo {
+inline namespace Bar {
+template <int N>
+struct Template {
+ Template() = default;
+ int i = N;
+};
+}
+}
+
+enum { N_THINGS = 5 };
+
+struct F8 : Foo::Template<N_THINGS> {
+ F8() : Template() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for base class 'Foo::Template<N_THINGS>' is redundant
+ // CHECK-FIXES: F8() {}
+};
+
+// Anonymous struct
+struct F9 {
+ F9() : s1() {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for member 's1' is redundant
+ // CHECK-FIXES: F9() {}
+ struct {
+ S s1;
+ S s2;
+ };
+};
+
+// Initializer not written
+struct NF1 {
+ NF1() {}
+ S f;
+};
+
+// Initializer doesn't call default constructor
+struct NF2 {
+ NF2() : f(1) {}
+ S f;
+};
+
+// Initializer calls default constructor without using default argument
+struct NF3 {
+ NF3() : f(1) {}
+ T f;
+};
+
+// Initializer calls default constructor without using default argument
+struct NF4 {
+ NF4() : f(2) {}
+ T f;
+};
+
+// Initializer is zero-initialization
+struct NF5 {
+ NF5() : i() {}
+ int i;
+};
+
+// Initializer is direct-initialization
+struct NF6 {
+ NF6() : i(1) {}
+ int i;
+};
+
+// Initializer is aggregate initialization of struct
+struct NF7 {
+ NF7() : f{} {}
+ U f;
+};
+
+// Initializer is zero-initialization of struct
+struct NF7b {
+ NF7b() : f() {}
+ U f;
+};
+
+// Initializer is aggregate initialization of array
+struct NF8 {
+ NF8() : f{} {}
+ int f[2];
+};
+
+struct NF9 {
+ NF9() : f{} {}
+ S f[2];
+};
+
+// Initializing member of union
+union NF10 {
+ NF10() : s() {}
+ int i;
+ S s;
+};
+
+// Templated class dependent type
+template <class V>
+struct NF11 {
+ NF11() : f() {}
+ V f;
+};
+NF11<int> nf11i;
+NF11<S> nf11s;
+
+// Delegating constructor
+class NF12 {
+ NF12() = default;
+ NF12(int) : NF12() {}
+};
+
+// Const member
+struct NF13 {
+ NF13() : f() {}
+ const S f;
+};
+
+// Union member
+struct NF14 {
+ NF14() : f() {}
+ V f;
+};
+
+// Anonymous union member
+struct NF15 {
+ NF15() : s1() {}
+ union {
+ S s1;
+ S s2;
+ };
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-preprocessor-ifdef.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-preprocessor-ifdef.cpp
new file mode 100644
index 0000000..72b608b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-preprocessor-ifdef.cpp
@@ -0,0 +1,36 @@
+// RUN: %check_clang_tidy %s readability-redundant-preprocessor %t -- -- -DFOO
+
+// Positive testing.
+#ifdef FOO
+// CHECK-NOTES: [[@LINE+1]]:2: warning: nested redundant #ifdef; consider removing it [readability-redundant-preprocessor]
+#ifdef FOO
+// CHECK-NOTES: [[@LINE-3]]:2: note: previous #ifdef was here
+void f();
+#endif
+#endif
+
+// Positive testing of inverted condition.
+#ifdef FOO
+// CHECK-NOTES: [[@LINE+1]]:2: warning: nested redundant #ifndef; consider removing it [readability-redundant-preprocessor]
+#ifndef FOO
+// CHECK-NOTES: [[@LINE-3]]:2: note: previous #ifdef was here
+void f2();
+#endif
+#endif
+
+// Negative testing.
+#ifdef BAR
+void g();
+#endif
+
+#ifdef FOO
+#ifdef BAR
+void h();
+#endif
+#endif
+
+#ifdef FOO
+#ifndef BAR
+void i();
+#endif
+#endif
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-preprocessor.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-preprocessor.cpp
new file mode 100644
index 0000000..6cffd8f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-preprocessor.cpp
@@ -0,0 +1,84 @@
+// RUN: %check_clang_tidy %s readability-redundant-preprocessor %t -- -- -I %S
+
+// Positive testing.
+#ifndef FOO
+// CHECK-NOTES: [[@LINE+1]]:2: warning: nested redundant #ifndef; consider removing it [readability-redundant-preprocessor]
+#ifndef FOO
+// CHECK-NOTES: [[@LINE-3]]:2: note: previous #ifndef was here
+void f();
+#endif
+#endif
+
+// Positive testing of inverted condition.
+#ifndef FOO
+// CHECK-NOTES: [[@LINE+1]]:2: warning: nested redundant #ifdef; consider removing it [readability-redundant-preprocessor]
+#ifdef FOO
+// CHECK-NOTES: [[@LINE-3]]:2: note: previous #ifndef was here
+void f2();
+#endif
+#endif
+
+// Negative testing.
+#include "readability-redundant-preprocessor.h"
+
+#ifndef BAR
+void g();
+#endif
+
+#ifndef FOO
+#ifndef BAR
+void h();
+#endif
+#endif
+
+#ifndef FOO
+#ifdef BAR
+void i();
+#endif
+#endif
+
+// Positive #if testing.
+#define FOO 4
+
+#if FOO == 4
+// CHECK-NOTES: [[@LINE+1]]:2: warning: nested redundant #if; consider removing it [readability-redundant-preprocessor]
+#if FOO == 4
+// CHECK-NOTES: [[@LINE-3]]:2: note: previous #if was here
+void j();
+#endif
+#endif
+
+#if FOO == 3 + 1
+// CHECK-NOTES: [[@LINE+1]]:2: warning: nested redundant #if; consider removing it [readability-redundant-preprocessor]
+#if FOO == 3 + 1
+// CHECK-NOTES: [[@LINE-3]]:2: note: previous #if was here
+void j();
+#endif
+#endif
+
+#if FOO == \
+ 4
+// CHECK-NOTES: [[@LINE+1]]:2: warning: nested redundant #if; consider removing it [readability-redundant-preprocessor]
+#if FOO == \
+ 4
+// CHECK-NOTES: [[@LINE-5]]:2: note: previous #if was here
+void j();
+#endif
+#endif
+
+// Negative #if testing.
+#define BAR 4
+
+#if FOO == 4
+#if BAR == 4
+void k();
+#endif
+#endif
+
+#if FOO == \
+ 4
+#if BAR == \
+ 5
+void k();
+#endif
+#endif
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-preprocessor.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-preprocessor.h
new file mode 100644
index 0000000..dfe5f97
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-preprocessor.h
@@ -0,0 +1,5 @@
+#ifndef FOO
+#ifndef FOO // this would warn, but not in a header
+void f();
+#endif
+#endif
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-smartptr-get-macros.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-smartptr-get-macros.cpp
new file mode 100644
index 0000000..79e4d92
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-smartptr-get-macros.cpp
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s readability-redundant-smartptr-get %t -- \
+// RUN: -config="{CheckOptions: [{key: readability-redundant-smartptr-get.IgnoreMacros, value: 0}]}" \
+// RUN: -- -std=c++11
+
+namespace std {
+
+template <typename T>
+struct shared_ptr {
+ T &operator*() const;
+ T *operator->() const;
+ T *get() const;
+ explicit operator bool() const noexcept;
+};
+
+} // namespace std
+
+#define MACRO(p) p.get()
+
+void Positive() {
+ std::shared_ptr<int> x;
+ if (MACRO(x) == nullptr)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:13: warning: redundant get() call on smart pointer
+};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-smartptr-get.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-smartptr-get.cpp
new file mode 100644
index 0000000..51d9879
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-smartptr-get.cpp
@@ -0,0 +1,201 @@
+// RUN: %check_clang_tidy %s readability-redundant-smartptr-get %t
+
+#define NULL __null
+
+namespace std {
+
+template <typename T>
+struct unique_ptr {
+ T& operator*() const;
+ T* operator->() const;
+ T* get() const;
+ explicit operator bool() const noexcept;
+};
+
+template <typename T>
+struct shared_ptr {
+ T& operator*() const;
+ T* operator->() const;
+ T* get() const;
+ explicit operator bool() const noexcept;
+};
+
+} // namespace std
+
+struct Bar {
+ void Do();
+ void ConstDo() const;
+};
+struct BarPtr {
+ Bar* operator->();
+ Bar& operator*();
+ Bar* get();
+ explicit operator bool() const;
+};
+struct int_ptr {
+ int* get();
+ int* operator->();
+ int& operator*();
+};
+
+struct Fail1 {
+ Bar* get();
+};
+struct Fail2 {
+ Bar* get();
+ int* operator->();
+ int& operator*();
+};
+
+struct PointerWithOverloadedGet {
+ int* get();
+ template <typename T>
+ T* get();
+ int* operator->();
+ int& operator*();
+};
+
+void Positive() {
+ BarPtr u;
+ // CHECK-FIXES: BarPtr u;
+ BarPtr().get()->Do();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant get() call on smart pointer [readability-redundant-smartptr-get]
+ // CHECK-MESSAGES: BarPtr().get()->Do();
+ // CHECK-FIXES: BarPtr()->Do();
+
+ u.get()->ConstDo();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant get() call
+ // CHECK-MESSAGES: u.get()->ConstDo();
+ // CHECK-FIXES: u->ConstDo();
+
+ Bar& b = *BarPtr().get();
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant get() call
+ // CHECK-MESSAGES: Bar& b = *BarPtr().get();
+ // CHECK-FIXES: Bar& b = *BarPtr();
+
+ Bar& b2 = *std::unique_ptr<Bar>().get();
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant get() call
+ // CHECK-MESSAGES: Bar& b2 = *std::unique_ptr<Bar>().get();
+ // CHECK-FIXES: Bar& b2 = *std::unique_ptr<Bar>();
+
+ (*BarPtr().get()).ConstDo();
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant get() call
+ // CHECK-MESSAGES: (*BarPtr().get()).ConstDo();
+ // CHECK-FIXES: (*BarPtr()).ConstDo();
+
+ (*std::unique_ptr<Bar>().get()).ConstDo();
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant get() call
+ // CHECK-MESSAGES: (*std::unique_ptr<Bar>().get()).ConstDo();
+ // CHECK-FIXES: (*std::unique_ptr<Bar>()).ConstDo();
+
+ std::unique_ptr<Bar>* up;
+ (*up->get()).Do();
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant get() call
+ // CHECK-MESSAGES: (*up->get()).Do();
+ // CHECK-FIXES: (**up).Do();
+
+ int_ptr ip;
+ int i = *ip.get();
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant get() call
+ // CHECK-MESSAGES: int i = *ip.get();
+ // CHECK-FIXES: int i = *ip;
+
+ auto ip2 = ip;
+ i = *ip2.get();
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call
+ // CHECK-MESSAGES: i = *ip2.get();
+ // CHECK-FIXES: i = *ip2;
+
+ std::unique_ptr<int> uu;
+ std::shared_ptr<double> *ss;
+ bool bb = uu.get() == nullptr;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant get() call
+ // CHECK-MESSAGES: uu.get() == nullptr;
+ // CHECK-FIXES: bool bb = uu == nullptr;
+
+ if (up->get());
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant get() call
+ // CHECK-MESSAGES: if (up->get());
+ // CHECK-FIXES: if (*up);
+ if ((uu.get()));
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call
+ // CHECK-MESSAGES: if ((uu.get()));
+ // CHECK-FIXES: if ((uu));
+ bb = !ss->get();
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: redundant get() call
+ // CHECK-MESSAGES: bb = !ss->get();
+ // CHECK-FIXES: bb = !*ss;
+ bb = u.get() ? true : false;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call
+ // CHECK-MESSAGES: bb = u.get() ? true : false;
+ // CHECK-FIXES: bb = u ? true : false;
+
+ bb = nullptr != ss->get();
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: redundant get() call
+ // CHECK-MESSAGES: nullptr != ss->get();
+ // CHECK-FIXES: bb = nullptr != *ss;
+
+ i = *PointerWithOverloadedGet().get();
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call
+ // CHECK-MESSAGES: i = *PointerWithOverloadedGet().get();
+ // CHECK-FIXES: i = *PointerWithOverloadedGet();
+
+ bb = std::unique_ptr<int>().get() == NULL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call
+ // CHECK-MESSAGES: bb = std::unique_ptr<int>().get() == NULL;
+ // CHECK-FIXES: bb = std::unique_ptr<int>() == NULL;
+ bb = ss->get() == NULL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call
+ // CHECK-MESSAGES: bb = ss->get() == NULL;
+ // CHECK-FIXES: bb = *ss == NULL;
+
+ std::unique_ptr<int> x, y;
+ if (x.get() == nullptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant get() call
+ // CHECK-MESSAGES: if (x.get() == nullptr);
+ // CHECK-FIXES: if (x == nullptr);
+ if (nullptr == y.get());
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: redundant get() call
+ // CHECK-MESSAGES: if (nullptr == y.get());
+ // CHECK-FIXES: if (nullptr == y);
+ if (x.get() == NULL);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant get() call
+ // CHECK-MESSAGES: if (x.get() == NULL);
+ // CHECK-FIXES: if (x == NULL);
+ if (NULL == x.get());
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: redundant get() call
+ // CHECK-MESSAGES: if (NULL == x.get());
+ // CHECK-FIXES: if (NULL == x);
+}
+
+#define MACRO(p) p.get()
+
+void Negative() {
+ struct NegPtr {
+ int* get();
+ int* operator->() {
+ return &*this->get();
+ }
+ int& operator*() {
+ return *get();
+ }
+ };
+
+ long l = *PointerWithOverloadedGet().get<long>();
+
+ std::unique_ptr<Bar>* u;
+ u->get()->Do();
+
+ Fail1().get()->Do();
+ Fail2().get()->Do();
+ const Bar& b = *Fail1().get();
+ (*Fail2().get()).Do();
+
+ int_ptr ip;
+ bool bb = ip.get() == nullptr;
+ bb = !ip.get();
+ bb = ip.get() ? true : false;
+ std::unique_ptr<int> x;
+ if (MACRO(x) == nullptr)
+ ;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-string-cstr-msvc.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-string-cstr-msvc.cpp
new file mode 100644
index 0000000..a6b6b20
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-string-cstr-msvc.cpp
@@ -0,0 +1,47 @@
+// RUN: %check_clang_tidy %s readability-redundant-string-cstr %t
+
+namespace std {
+template <typename T>
+class allocator {};
+template <typename T>
+class char_traits {};
+template <typename C, typename T, typename A>
+struct basic_string {
+ basic_string();
+ // MSVC headers define two constructors instead of using optional arguments.
+ basic_string(const C *p);
+ basic_string(const C *p, const A &a);
+ const C *c_str() const;
+ const C *data() const;
+};
+typedef basic_string<char, std::char_traits<char>, std::allocator<char>> string;
+}
+namespace llvm {
+struct StringRef {
+ StringRef(const char *p);
+ StringRef(const std::string &);
+};
+}
+
+void f1(const std::string &s) {
+ f1(s.c_str());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to 'c_str' [readability-redundant-string-cstr]
+ // CHECK-FIXES: {{^ }}f1(s);{{$}}
+ f1(s.data());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to 'data' [readability-redundant-string-cstr]
+ // CHECK-FIXES: {{^ }}f1(s);{{$}}
+}
+void f2(const llvm::StringRef r) {
+ std::string s;
+ f2(s.c_str());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call {{.*}}
+ // CHECK-FIXES: {{^ }}std::string s;{{$}}
+ // CHECK-FIXES-NEXT: {{^ }}f2(s);{{$}}
+}
+void f3(const llvm::StringRef &r) {
+ std::string s;
+ f3(s.c_str());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call {{.*}}
+ // CHECK-FIXES: {{^ }}std::string s;{{$}}
+ // CHECK-FIXES-NEXT: {{^ }}f3(s);{{$}}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-string-cstr.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-string-cstr.cpp
new file mode 100644
index 0000000..976a54f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-string-cstr.cpp
@@ -0,0 +1,207 @@
+// RUN: %check_clang_tidy %s readability-redundant-string-cstr %t -- -- -std=c++11
+
+typedef unsigned __INT16_TYPE__ char16;
+typedef unsigned __INT32_TYPE__ char32;
+typedef __SIZE_TYPE__ size;
+
+namespace std {
+template <typename T>
+class allocator {};
+template <typename T>
+class char_traits {};
+template <typename C, typename T, typename A>
+struct basic_string {
+ typedef basic_string<C, T, A> _Type;
+ basic_string();
+ basic_string(const C *p, const A &a = A());
+
+ const C *c_str() const;
+ const C *data() const;
+
+ _Type& append(const C *s);
+ _Type& append(const C *s, size n);
+ _Type& assign(const C *s);
+ _Type& assign(const C *s, size n);
+
+ int compare(const _Type&) const;
+ int compare(const C* s) const;
+ int compare(size pos, size len, const _Type&) const;
+ int compare(size pos, size len, const C* s) const;
+
+ size find(const _Type& str, size pos = 0) const;
+ size find(const C* s, size pos = 0) const;
+ size find(const C* s, size pos, size n) const;
+
+ _Type& insert(size pos, const _Type& str);
+ _Type& insert(size pos, const C* s);
+ _Type& insert(size pos, const C* s, size n);
+
+ _Type& operator+=(const _Type& str);
+ _Type& operator+=(const C* s);
+ _Type& operator=(const _Type& str);
+ _Type& operator=(const C* s);
+};
+
+typedef basic_string<char, std::char_traits<char>, std::allocator<char>> string;
+typedef basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t>> wstring;
+typedef basic_string<char16, std::char_traits<char16>, std::allocator<char16>> u16string;
+typedef basic_string<char32, std::char_traits<char32>, std::allocator<char32>> u32string;
+}
+
+std::string operator+(const std::string&, const std::string&);
+std::string operator+(const std::string&, const char*);
+std::string operator+(const char*, const std::string&);
+
+bool operator==(const std::string&, const std::string&);
+bool operator==(const std::string&, const char*);
+bool operator==(const char*, const std::string&);
+
+namespace llvm {
+struct StringRef {
+ StringRef(const char *p);
+ StringRef(const std::string &);
+};
+}
+
+// Tests for std::string.
+
+void f1(const std::string &s) {
+ f1(s.c_str());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to 'c_str' [readability-redundant-string-cstr]
+ // CHECK-FIXES: {{^ }}f1(s);{{$}}
+ f1(s.data());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to 'data' [readability-redundant-string-cstr]
+ // CHECK-FIXES: {{^ }}f1(s);{{$}}
+}
+void f2(const llvm::StringRef r) {
+ std::string s;
+ f2(s.c_str());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call {{.*}}
+ // CHECK-FIXES: {{^ }}std::string s;{{$}}
+ // CHECK-FIXES-NEXT: {{^ }}f2(s);{{$}}
+}
+void f3(const llvm::StringRef &r) {
+ std::string s;
+ f3(s.c_str());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call {{.*}}
+ // CHECK-FIXES: {{^ }}std::string s;{{$}}
+ // CHECK-FIXES-NEXT: {{^ }}f3(s);{{$}}
+}
+void f4(const std::string &s) {
+ const std::string* ptr = &s;
+ f1(ptr->c_str());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to 'c_str' [readability-redundant-string-cstr]
+ // CHECK-FIXES: {{^ }}f1(*ptr);{{$}}
+}
+void f5(const std::string &s) {
+ std::string tmp;
+ tmp.append(s.c_str());
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant call {{.*}}
+ // CHECK-FIXES: {{^ }}tmp.append(s);{{$}}
+ tmp.assign(s.c_str());
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant call {{.*}}
+ // CHECK-FIXES: {{^ }}tmp.assign(s);{{$}}
+
+ if (tmp.compare(s.c_str()) == 0) return;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: redundant call {{.*}}
+ // CHECK-FIXES: {{^ }}if (tmp.compare(s) == 0) return;{{$}}
+
+ if (tmp.compare(1, 2, s.c_str()) == 0) return;
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: redundant call {{.*}}
+ // CHECK-FIXES: {{^ }}if (tmp.compare(1, 2, s) == 0) return;{{$}}
+
+ if (tmp.find(s.c_str()) == 0) return;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: redundant call {{.*}}
+ // CHECK-FIXES: {{^ }}if (tmp.find(s) == 0) return;{{$}}
+
+ if (tmp.find(s.c_str(), 2) == 0) return;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: redundant call {{.*}}
+ // CHECK-FIXES: {{^ }}if (tmp.find(s, 2) == 0) return;{{$}}
+
+ if (tmp.find(s.c_str(), 2) == 0) return;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: redundant call {{.*}}
+ // CHECK-FIXES: {{^ }}if (tmp.find(s, 2) == 0) return;{{$}}
+
+ tmp.insert(1, s.c_str());
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: redundant call {{.*}}
+ // CHECK-FIXES: {{^ }}tmp.insert(1, s);{{$}}
+
+ tmp = s.c_str();
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: redundant call {{.*}}
+ // CHECK-FIXES: {{^ }}tmp = s;{{$}}
+
+ tmp += s.c_str();
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: redundant call {{.*}}
+ // CHECK-FIXES: {{^ }}tmp += s;{{$}}
+
+ if (tmp == s.c_str()) return;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant call {{.*}}
+ // CHECK-FIXES: {{^ }}if (tmp == s) return;{{$}}
+
+ tmp = s + s.c_str();
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant call {{.*}}
+ // CHECK-FIXES: {{^ }}tmp = s + s;{{$}}
+
+ tmp = s.c_str() + s;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: redundant call {{.*}}
+ // CHECK-FIXES: {{^ }}tmp = s + s;{{$}}
+}
+void f6(const std::string &s) {
+ std::string tmp;
+ tmp.append(s.c_str(), 2);
+ tmp.assign(s.c_str(), 2);
+
+ if (tmp.compare(s) == 0) return;
+ if (tmp.compare(1, 2, s) == 0) return;
+
+ tmp = s;
+ tmp += s;
+
+ if (tmp == s)
+ return;
+
+ tmp = s + s;
+
+ if (tmp.find(s.c_str(), 2, 4) == 0) return;
+
+ tmp.insert(1, s);
+ tmp.insert(1, s.c_str(), 2);
+}
+
+// Tests for std::wstring.
+
+void g1(const std::wstring &s) {
+ g1(s.c_str());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to 'c_str' [readability-redundant-string-cstr]
+ // CHECK-FIXES: {{^ }}g1(s);{{$}}
+}
+
+// Tests for std::u16string.
+
+void h1(const std::u16string &s) {
+ h1(s.c_str());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to 'c_str' [readability-redundant-string-cstr]
+ // CHECK-FIXES: {{^ }}h1(s);{{$}}
+}
+
+// Tests for std::u32string.
+
+void k1(const std::u32string &s) {
+ k1(s.c_str());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to 'c_str' [readability-redundant-string-cstr]
+ // CHECK-FIXES: {{^ }}k1(s);{{$}}
+}
+
+// Tests on similar classes that aren't good candidates for this checker.
+
+struct NotAString {
+ NotAString();
+ NotAString(const NotAString&);
+ const char *c_str() const;
+};
+
+void dummy(const char*) {}
+
+void invalid(const NotAString &s) {
+ dummy(s.c_str());
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-string-init-msvc.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-string-init-msvc.cpp
new file mode 100644
index 0000000..0299519
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-string-init-msvc.cpp
@@ -0,0 +1,61 @@
+// RUN: %check_clang_tidy %s readability-redundant-string-init %t
+
+namespace std {
+template <typename T>
+class allocator {};
+template <typename T>
+class char_traits {};
+template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C>>
+struct basic_string {
+ basic_string();
+ basic_string(const basic_string&);
+ // MSVC headers define two constructors instead of using optional arguments.
+ basic_string(const C *);
+ basic_string(const C *, const A &);
+ ~basic_string();
+};
+typedef basic_string<char> string;
+typedef basic_string<wchar_t> wstring;
+}
+
+void f() {
+ std::string a = "";
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization [readability-redundant-string-init]
+ // CHECK-FIXES: std::string a;
+ std::string b("");
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+ // CHECK-FIXES: std::string b;
+ std::string c = R"()";
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+ // CHECK-FIXES: std::string c;
+ std::string d(R"()");
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+ // CHECK-FIXES: std::string d;
+
+ std::string u = "u";
+ std::string w("w");
+ std::string x = R"(x)";
+ std::string y(R"(y)");
+ std::string z;
+}
+
+void g() {
+ std::wstring a = L"";
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+ // CHECK-FIXES: std::wstring a;
+ std::wstring b(L"");
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+ // CHECK-FIXES: std::wstring b;
+ std::wstring c = LR"()";
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+ // CHECK-FIXES: std::wstring c;
+ std::wstring d(LR"()");
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+ // CHECK-FIXES: std::wstring d;
+
+ std::wstring u = L"u";
+ std::wstring w(L"w");
+ std::wstring x = LR"(x)";
+ std::wstring y(LR"(y)");
+ std::wstring z;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-string-init.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-string-init.cpp
new file mode 100644
index 0000000..4455ad4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-redundant-string-init.cpp
@@ -0,0 +1,140 @@
+// RUN: %check_clang_tidy %s readability-redundant-string-init %t
+
+namespace std {
+template <typename T>
+class allocator {};
+template <typename T>
+class char_traits {};
+template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C>>
+struct basic_string {
+ basic_string();
+ basic_string(const basic_string&);
+ basic_string(const C *, const A &a = A());
+ ~basic_string();
+};
+typedef basic_string<char> string;
+typedef basic_string<wchar_t> wstring;
+}
+
+void f() {
+ std::string a = "";
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization [readability-redundant-string-init]
+ // CHECK-FIXES: std::string a;
+ std::string b("");
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+ // CHECK-FIXES: std::string b;
+ std::string c = R"()";
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+ // CHECK-FIXES: std::string c;
+ std::string d(R"()");
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+ // CHECK-FIXES: std::string d;
+
+ std::string u = "u";
+ std::string w("w");
+ std::string x = R"(x)";
+ std::string y(R"(y)");
+ std::string z;
+}
+
+void g() {
+ std::wstring a = L"";
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+ // CHECK-FIXES: std::wstring a;
+ std::wstring b(L"");
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+ // CHECK-FIXES: std::wstring b;
+ std::wstring c = LR"()";
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+ // CHECK-FIXES: std::wstring c;
+ std::wstring d(LR"()");
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+ // CHECK-FIXES: std::wstring d;
+
+ std::wstring u = L"u";
+ std::wstring w(L"w");
+ std::wstring x = LR"(x)";
+ std::wstring y(LR"(y)");
+ std::wstring z;
+}
+
+template <typename T>
+void templ() {
+ std::string s = "";
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+ // CHECK-FIXES: std::string s;
+}
+
+#define M(x) x
+#define N { std::string s = ""; }
+// CHECK-FIXES: #define N { std::string s = ""; }
+
+void h() {
+ templ<int>();
+ templ<double>();
+
+ M({ std::string s = ""; })
+ // CHECK-MESSAGES: [[@LINE-1]]:19: warning: redundant string initialization
+ // CHECK-FIXES: M({ std::string s; })
+
+ N
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: redundant string initialization
+ // CHECK-FIXES: N
+ N
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: redundant string initialization
+ // CHECK-FIXES: N
+}
+
+typedef std::string MyString;
+#define STRING MyString
+#define DECL_STRING(name, val) STRING name = val
+
+void i() {
+ MyString a = "";
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant string initialization
+ // CHECK-FIXES: MyString a;
+ STRING b = "";
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: redundant string initialization
+ // CHECK-FIXES: STRING b;
+ MyString c = "" "" "";
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant string initialization
+ // CHECK-FIXES: MyString c;
+ STRING d = "" "" "";
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: redundant string initialization
+ // CHECK-FIXES: STRING d;
+ DECL_STRING(e, "");
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+
+ MyString f = "u";
+ STRING g = "u";
+ DECL_STRING(h, "u");
+}
+
+#define EMPTY_STR ""
+void j() {
+ std::string a(EMPTY_STR);
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+ // CHECK-FIXES: std::string a;
+ std::string b = (EMPTY_STR);
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+ // CHECK-FIXES: std::string b;
+
+ std::string c(EMPTY_STR "u" EMPTY_STR);
+}
+
+void k() {
+ std::string a = "", b = "", c = "";
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+ // CHECK-MESSAGES: [[@LINE-2]]:23: warning: redundant string initialization
+ // CHECK-MESSAGES: [[@LINE-3]]:31: warning: redundant string initialization
+ // CHECK-FIXES: std::string a, b, c;
+
+ std::string d = "u", e = "u", f = "u";
+}
+
+// These cases should not generate warnings.
+extern void Param1(std::string param = "");
+extern void Param2(const std::string& param = "");
+void Param3(std::string param = "") {}
+void Param4(STRING param = "") {}
+
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-simplify-bool-expr-chained-conditional-assignment.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-simplify-bool-expr-chained-conditional-assignment.cpp
new file mode 100644
index 0000000..65b86c3
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-simplify-bool-expr-chained-conditional-assignment.cpp
@@ -0,0 +1,34 @@
+// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t -- -config="{CheckOptions: [{key: "readability-simplify-boolean-expr.ChainedConditionalAssignment", value: 1}]}" --
+
+void chained_conditional_compound_assignment(int i) {
+ bool b;
+ if (i < 0) {
+ b = true;
+ } else if (i < 10) {
+ b = false;
+ } else if (i > 20) {
+ b = true;
+ } else {
+ b = false;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:9: warning: redundant boolean literal in conditional assignment [readability-simplify-boolean-expr]
+ // CHECK-FIXES: {{^}} } else if (i < 10) {{{$}}
+ // CHECK-FIXES-NEXT: {{^}} b = false;{{$}}
+ // CHECK-FIXES-NEXT: {{^}} } else b = i > 20;{{$}}
+}
+
+void chained_conditional_assignment(int i) {
+ bool b;
+ if (i < 0)
+ b = true;
+ else if (i < 10)
+ b = false;
+ else if (i > 20)
+ b = true;
+ else
+ b = false;
+ // CHECK-MESSAGES: :[[@LINE-3]]:9: warning: {{.*}} in conditional assignment
+ // CHECK-FIXES: {{^}} else if (i < 10)
+ // CHECK-FIXES-NEXT: {{^}} b = false;
+ // CHECK-FIXES-NEXT: {{^}} else b = i > 20;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-simplify-bool-expr-chained-conditional-return.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-simplify-bool-expr-chained-conditional-return.cpp
new file mode 100644
index 0000000..fb8759c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-simplify-bool-expr-chained-conditional-return.cpp
@@ -0,0 +1,94 @@
+// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t -- -config="{CheckOptions: [{key: "readability-simplify-boolean-expr.ChainedConditionalReturn", value: 1}]}" --
+
+bool chained_conditional_compound_return(int i) {
+ if (i < 0) {
+ return true;
+ } else if (i < 10) {
+ return false;
+ } else if (i > 20) {
+ return true;
+ } else {
+ return false;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:12: warning: redundant boolean literal in conditional return statement [readability-simplify-boolean-expr]
+ // CHECK-FIXES: {{^}} } else if (i < 10) {{{$}}
+ // CHECK-FIXES-NEXT: {{^}} return false;{{$}}
+ // CHECK-FIXES-NEXT: {{^}} } else return i > 20;{{$}}
+}
+
+bool chained_conditional_return(int i) {
+ if (i < 0)
+ return true;
+ else if (i < 10)
+ return false;
+ else if (i > 20)
+ return true;
+ else
+ return false;
+ // CHECK-MESSAGES: :[[@LINE-3]]:12: warning: {{.*}} in conditional return statement
+ // CHECK-FIXES: {{^}} else if (i < 10)
+ // CHECK-FIXES-NEXT: {{^}} return false;
+ // CHECK-FIXES-NEXT: {{^}} else return i > 20;
+}
+
+bool chained_simple_if_return(int i) {
+ if (i < 5)
+ return true;
+ if (i > 10)
+ return true;
+ return false;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}}bool chained_simple_if_return(int i) {{{$}}
+// CHECK-FIXES: {{^}} if (i < 5){{$}}
+// CHECK-FIXES: {{^ return true;$}}
+// CHECK-FIXES: {{^ return i > 10;$}}
+// CHECK-FIXES: {{^}$}}
+
+bool chained_simple_if_return_negated(int i) {
+ if (i < 5)
+ return false;
+ if (i > 10)
+ return false;
+ return true;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}}bool chained_simple_if_return_negated(int i) {{{$}}
+// CHECK-FIXES: {{^}} if (i < 5){{$}}
+// CHECK-FIXES: {{^ return false;$}}
+// CHECK-FIXES: {{^ return i <= 10;$}}
+// CHECK-FIXES: {{^}$}}
+
+bool complex_chained_if_return_return(int i) {
+ if (i < 5) {
+ return true;
+ }
+ if (i > 10) {
+ return true;
+ }
+ return false;
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}}bool complex_chained_if_return_return(int i) {{{$}}
+// CHECK-FIXES: {{^}} if (i < 5) {{{$}}
+// CHECK-FIXES: {{^}} return true;{{$}}
+// CHECK-FIXES: {{^}} }{{$}}
+// CHECK-FIXES: {{^ return i > 10;$}}
+// CHECK-FIXES: {{^}$}}
+
+bool complex_chained_if_return_return_negated(int i) {
+ if (i < 5) {
+ return false;
+ }
+ if (i > 10) {
+ return false;
+ }
+ return true;
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}}bool complex_chained_if_return_return_negated(int i) {{{$}}
+// CHECK-FIXES: {{^}} if (i < 5) {{{$}}
+// CHECK-FIXES: {{^}} return false;{{$}}
+// CHECK-FIXES: {{^}} }{{$}}
+// CHECK-FIXES: {{^ return i <= 10;$}}
+// CHECK-FIXES: {{^}$}}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-simplify-bool-expr.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-simplify-bool-expr.cpp
new file mode 100644
index 0000000..cd93c5d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-simplify-bool-expr.cpp
@@ -0,0 +1,950 @@
+// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t
+
+bool a1 = false;
+
+//=-=-=-=-=-=-= operator ==
+bool aa = false == a1;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant boolean literal supplied to boolean operator [readability-simplify-boolean-expr]
+// CHECK-FIXES: {{^bool aa = !a1;$}}
+bool ab = true == a1;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator
+// CHECK-FIXES: {{^bool ab = a1;$}}
+bool a2 = a1 == false;
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator
+// CHECK-FIXES: {{^bool a2 = !a1;$}}
+bool a3 = a1 == true;
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator
+// CHECK-FIXES: {{^bool a3 = a1;$}}
+
+//=-=-=-=-=-=-= operator !=
+bool n1 = a1 != false;
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator
+// CHECK-FIXES: {{^bool n1 = a1;$}}
+bool n2 = a1 != true;
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator
+// CHECK-FIXES: {{^bool n2 = !a1;$}}
+bool n3 = false != a1;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator
+// CHECK-FIXES: {{^bool n3 = a1;$}}
+bool n4 = true != a1;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator
+// CHECK-FIXES: {{^bool n4 = !a1;$}}
+
+//=-=-=-=-=-=-= operator ||
+bool a4 = a1 || false;
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator
+// CHECK-FIXES: {{^bool a4 = a1;$}}
+bool a5 = a1 || true;
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator
+// CHECK-FIXES: {{^bool a5 = true;$}}
+bool a6 = false || a1;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator
+// CHECK-FIXES: {{^bool a6 = a1;$}}
+bool a7 = true || a1;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator
+// CHECK-FIXES: {{^bool a7 = true;$}}
+
+//=-=-=-=-=-=-= operator &&
+bool a8 = a1 && false;
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator
+// CHECK-FIXES: {{^bool a8 = false;$}}
+bool a9 = a1 && true;
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator
+// CHECK-FIXES: {{^bool a9 = a1;$}}
+bool ac = false && a1;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator
+// CHECK-FIXES: {{^bool ac = false;$}}
+bool ad = true && a1;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} to boolean operator
+// CHECK-FIXES: {{^bool ad = a1;$}}
+
+void if_with_bool_literal_condition() {
+ int i = 0;
+ if (false) {
+ i = 1;
+ } else {
+ i = 2;
+ }
+ i = 3;
+ // CHECK-MESSAGES: :[[@LINE-6]]:7: warning: {{.*}} in if statement condition
+ // CHECK-FIXES: {{^ int i = 0;$}}
+ // CHECK-FIXES-NEXT: {{^ {$}}
+ // CHECK-FIXES-NEXT: {{^ i = 2;$}}
+ // CHECK-FIXES-NEXT: {{^ }$}}
+ // CHECK-FIXES-NEXT: {{^ i = 3;$}}
+
+ i = 4;
+ if (true) {
+ i = 5;
+ } else {
+ i = 6;
+ }
+ i = 7;
+ // CHECK-MESSAGES: :[[@LINE-6]]:7: warning: {{.*}} in if statement condition
+ // CHECK-FIXES: {{^ i = 4;$}}
+ // CHECK-FIXES-NEXT: {{^ {$}}
+ // CHECK-FIXES-NEXT: {{^ i = 5;$}}
+ // CHECK-FIXES-NEXT: {{^ }$}}
+ // CHECK-FIXES-NEXT: {{^ i = 7;$}}
+
+ i = 8;
+ if (false) {
+ i = 9;
+ }
+ i = 11;
+ // CHECK-MESSAGES: :[[@LINE-4]]:7: warning: {{.*}} in if statement condition
+ // CHECK-FIXES: {{^ i = 8;$}}
+ // CHECK-FIXES-NEXT: {{^ $}}
+ // CHECK-FIXES-NEXT: {{^ i = 11;$}}
+}
+
+void operator_equals() {
+ int i = 0;
+ bool b1 = (i > 2);
+ if (b1 == true) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} to boolean operator
+ // CHECK-FIXES: {{^ if \(b1\) {$}}
+ i = 5;
+ } else {
+ i = 6;
+ }
+ bool b2 = (i > 4);
+ if (b2 == false) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} to boolean operator
+ // CHECK-FIXES: {{^ if \(!b2\) {$}}
+ i = 7;
+ } else {
+ i = 9;
+ }
+ bool b3 = (i > 6);
+ if (true == b3) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator
+ // CHECK-FIXES: {{^ if \(b3\) {$}}
+ i = 10;
+ } else {
+ i = 11;
+ }
+ bool b4 = (i > 8);
+ if (false == b4) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator
+ // CHECK-FIXES: {{^ if \(!b4\) {$}}
+ i = 12;
+ } else {
+ i = 13;
+ }
+}
+
+void operator_or() {
+ int i = 0;
+ bool b5 = (i > 10);
+ if (b5 || false) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} to boolean operator
+ // CHECK-FIXES: {{^ if \(b5\) {$}}
+ i = 14;
+ } else {
+ i = 15;
+ }
+ bool b6 = (i > 10);
+ if (b6 || true) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} to boolean operator
+ // CHECK-FIXES: {{^ if \(true\) {$}}
+ i = 16;
+ } else {
+ i = 17;
+ }
+ bool b7 = (i > 10);
+ if (false || b7) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator
+ // CHECK-FIXES: {{^ if \(b7\) {$}}
+ i = 18;
+ } else {
+ i = 19;
+ }
+ bool b8 = (i > 10);
+ if (true || b8) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator
+ // CHECK-FIXES: {{^ if \(true\) {$}}
+ i = 20;
+ } else {
+ i = 21;
+ }
+}
+
+void operator_and() {
+ int i = 0;
+ bool b9 = (i > 20);
+ if (b9 && false) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} to boolean operator
+ // CHECK-FIXES: {{^ if \(false\) {$}}
+ i = 22;
+ } else {
+ i = 23;
+ }
+ bool ba = (i > 20);
+ if (ba && true) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} to boolean operator
+ // CHECK-FIXES: {{^ if \(ba\) {$}}
+ i = 24;
+ } else {
+ i = 25;
+ }
+ bool bb = (i > 20);
+ if (false && bb) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator
+ // CHECK-FIXES: {{^ if \(false\) {$}}
+ i = 26;
+ } else {
+ i = 27;
+ }
+ bool bc = (i > 20);
+ if (true && bc) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator
+ // CHECK-FIXES: {{^ if \(bc\) {$}}
+ i = 28;
+ } else {
+ i = 29;
+ }
+}
+
+void ternary_operator() {
+ int i = 0;
+ bool bd = (i > 20) ? true : false;
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: {{.*}} in ternary expression result
+ // CHECK-FIXES: {{^ bool bd = i > 20;$}}
+
+ bool be = (i > 20) ? false : true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: {{.*}} in ternary expression result
+ // CHECK-FIXES: {{^ bool be = i <= 20;$}}
+
+ bool bf = ((i > 20)) ? false : true;
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: {{.*}} in ternary expression result
+ // CHECK-FIXES: {{^ bool bf = i <= 20;$}}
+}
+
+void operator_not_equal() {
+ int i = 0;
+ bool bf = (i > 20);
+ if (false != bf) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator
+ // CHECK-FIXES: {{^ if \(bf\) {$}}
+ i = 30;
+ } else {
+ i = 31;
+ }
+ bool bg = (i > 20);
+ if (true != bg) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator
+ // CHECK-FIXES: {{^ if \(!bg\) {$}}
+ i = 32;
+ } else {
+ i = 33;
+ }
+ bool bh = (i > 20);
+ if (bh != false) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} to boolean operator
+ // CHECK-FIXES: {{^ if \(bh\) {$}}
+ i = 34;
+ } else {
+ i = 35;
+ }
+ bool bi = (i > 20);
+ if (bi != true) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} to boolean operator
+ // CHECK-FIXES: {{^ if \(!bi\) {$}}
+ i = 36;
+ } else {
+ i = 37;
+ }
+}
+
+void nested_booleans() {
+ if (false || (true || false)) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator
+ // CHECK-FIXES: {{^ if \(false \|\| \(true\)\) {$}}
+ }
+ if (true && (true || false)) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} to boolean operator
+ // CHECK-FIXES: {{^ if \(true && \(true\)\) {$}}
+ }
+ if (false || (true && false)) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} to boolean operator
+ // CHECK-FIXES: {{^ if \(false \|\| \(false\)\) {$}}
+ }
+ if (true && (true && false)) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} to boolean operator
+ // CHECK-FIXES: {{^ if \(true && \(false\)\) {$}}
+ }
+}
+
+static constexpr bool truthy() {
+ return true;
+}
+
+#define HAS_XYZ_FEATURE true
+#define M1(what) M2(true, what)
+#define M2(condition, what) if (condition) what
+
+void macros_and_constexprs(int i = 0) {
+ bool b = (i == 1);
+ if (b && truthy()) {
+ // leave this alone; if you want it simplified, then you should
+ // inline the constexpr function first.
+ i = 1;
+ }
+ i = 2;
+ if (b && HAS_XYZ_FEATURE) {
+ // leave this alone; if you want it simplified, then you should
+ // inline the macro first.
+ i = 3;
+ }
+ if (HAS_XYZ_FEATURE) {
+ i = 5;
+ }
+ i = 4;
+ M1(i = 7);
+}
+
+#undef HAS_XYZ_FEATURE
+
+bool conditional_return_statements(int i) {
+ if (i == 0) return true; else return false;
+}
+// CHECK-MESSAGES: :[[@LINE-2]]:22: warning: {{.*}} in conditional return statement
+// CHECK-FIXES: {{^}} return i == 0;{{$}}
+// CHECK-FIXES-NEXT: {{^}$}}
+
+bool conditional_return_statements_then_expr(int i, int j) {
+ if (i == j) return (i == 0); else return false;
+}
+
+bool conditional_return_statements_else_expr(int i, int j) {
+ if (i == j) return true; else return (i == 0);
+}
+
+bool negated_conditional_return_statements(int i) {
+ if (i == 0) return false; else return true;
+}
+// CHECK-MESSAGES: :[[@LINE-2]]:22: warning: {{.*}} in conditional return statement
+// CHECK-FIXES: {{^}} return i != 0;{{$}}
+// CHECK-FIXES-NEXT: {{^}$}}
+
+bool negative_condition_conditional_return_statement(int i) {
+ if (!(i == 0)) return false; else return true;
+}
+// CHECK-MESSAGES: :[[@LINE-2]]:25: warning: {{.*}} in conditional return statement
+// CHECK-FIXES: {{^}} return i == 0;{{$}}
+// CHECK-FIXES-NEXT: {{^}$}}
+
+bool conditional_compound_return_statements(int i) {
+ if (i == 1) {
+ return true;
+ } else {
+ return false;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return statement
+// CHECK-FIXES: {{^}}bool conditional_compound_return_statements(int i) {{{$}}
+// CHECK-FIXES-NEXT: {{^}} return i == 1;{{$}}
+// CHECK-FIXES-NEXT: {{^}$}}
+
+bool negated_conditional_compound_return_statements(int i) {
+ if (i == 1) {
+ return false;
+ } else {
+ return true;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return statement
+// CHECK-FIXES: {{^}}bool negated_conditional_compound_return_statements(int i) {{{$}}
+// CHECK-FIXES-NEXT: {{^}} return i != 1;{{$}}
+// CHECK-FIXES-NEXT: {{^}$}}
+
+bool conditional_return_statements_side_effects_then(int i) {
+ if (i == 2) {
+ macros_and_constexprs();
+ return true;
+ } else
+ return false;
+}
+
+bool negated_conditional_return_statements_side_effects_then(int i) {
+ if (i == 2) {
+ macros_and_constexprs();
+ return false;
+ } else
+ return true;
+}
+
+bool conditional_return_statements_side_effects_else(int i) {
+ if (i == 2)
+ return true;
+ else {
+ macros_and_constexprs();
+ return false;
+ }
+}
+
+bool negated_conditional_return_statements_side_effects_else(int i) {
+ if (i == 2)
+ return false;
+ else {
+ macros_and_constexprs();
+ return true;
+ }
+}
+
+void lambda_conditional_return_statements() {
+ auto lambda = [](int n) -> bool { if (n > 0) return true; else return false; };
+ // CHECK-MESSAGES: :[[@LINE-1]]:55: warning: {{.*}} in conditional return statement
+ // CHECK-FIXES: {{^}} auto lambda = [](int n) -> bool { return n > 0; };{{$}}
+
+ auto lambda2 = [](int n) -> bool {
+ if (n > 0) {
+ return true;
+ } else {
+ return false;
+ }
+ };
+ // CHECK-MESSAGES: :[[@LINE-5]]:16: warning: {{.*}} in conditional return statement
+ // CHECK-FIXES: {{^}} auto lambda2 = [](int n) -> bool {{{$}}
+ // CHECK-FIXES-NEXT: {{^}} return n > 0;{{$}}
+ // CHECK-FIXES-NEXT: {{^}} };{{$}}
+
+ auto lambda3 = [](int n) -> bool { if (n > 0) {macros_and_constexprs(); return true; } else return false; };
+
+ auto lambda4 = [](int n) -> bool {
+ if (n > 0)
+ return true;
+ else {
+ macros_and_constexprs();
+ return false;
+ }
+ };
+
+ auto lambda5 = [](int n) -> bool { if (n > 0) return false; else return true; };
+ // CHECK-MESSAGES: :[[@LINE-1]]:56: warning: {{.*}} in conditional return statement
+ // CHECK-FIXES: {{^}} auto lambda5 = [](int n) -> bool { return n <= 0; };{{$}}
+
+ auto lambda6 = [](int n) -> bool {
+ if (n > 0) {
+ return false;
+ } else {
+ return true;
+ }
+ };
+ // CHECK-MESSAGES: :[[@LINE-5]]:16: warning: {{.*}} in conditional return statement
+ // CHECK-FIXES: {{^}} auto lambda6 = [](int n) -> bool {{{$}}
+ // CHECK-FIXES-NEXT: {{^}} return n <= 0;{{$}}
+ // CHECK-FIXES-NEXT: {{^}} };{{$}}
+}
+
+void simple_conditional_assignment_statements(int i) {
+ bool b;
+ if (i > 10)
+ b = true;
+ else
+ b = false;
+ bool bb = false;
+ // CHECK-MESSAGES: :[[@LINE-4]]:9: warning: {{.*}} in conditional assignment
+ // CHECK-FIXES: bool b;
+ // CHECK-FIXES: {{^ }}b = i > 10;{{$}}
+ // CHECK-FIXES: bool bb = false;
+
+ bool c;
+ if (i > 20)
+ c = false;
+ else
+ c = true;
+ bool c2 = false;
+ // CHECK-MESSAGES: :[[@LINE-4]]:9: warning: {{.*}} in conditional assignment
+ // CHECK-FIXES: bool c;
+ // CHECK-FIXES: {{^ }}c = i <= 20;{{$}}
+ // CHECK-FIXES: bool c2 = false;
+
+ // Unchanged: different variables.
+ bool b2;
+ if (i > 12)
+ b = true;
+ else
+ b2 = false;
+
+ // Unchanged: no else statement.
+ bool b3;
+ if (i > 15)
+ b3 = true;
+
+ // Unchanged: not boolean assignment.
+ int j;
+ if (i > 17)
+ j = 10;
+ else
+ j = 20;
+
+ // Unchanged: different variables assigned.
+ int k = 0;
+ bool b4 = false;
+ if (i > 10)
+ b4 = true;
+ else
+ k = 10;
+}
+
+void complex_conditional_assignment_statements(int i) {
+ bool d;
+ if (i > 30) {
+ d = true;
+ } else {
+ d = false;
+ }
+ d = false;
+ // CHECK-MESSAGES: :[[@LINE-5]]:9: warning: {{.*}} in conditional assignment
+ // CHECK-FIXES: bool d;
+ // CHECK-FIXES: {{^ }}d = i > 30;{{$}}
+ // CHECK-FIXES: d = false;
+
+ bool e;
+ if (i > 40) {
+ e = false;
+ } else {
+ e = true;
+ }
+ e = false;
+ // CHECK-MESSAGES: :[[@LINE-5]]:9: warning: {{.*}} in conditional assignment
+ // CHECK-FIXES: bool e;
+ // CHECK-FIXES: {{^ }}e = i <= 40;{{$}}
+ // CHECK-FIXES: e = false;
+
+ // Unchanged: no else statement.
+ bool b3;
+ if (i > 15) {
+ b3 = true;
+ }
+
+ // Unchanged: not a boolean assignment.
+ int j;
+ if (i > 17) {
+ j = 10;
+ } else {
+ j = 20;
+ }
+
+ // Unchanged: multiple statements.
+ bool f;
+ if (j > 10) {
+ j = 10;
+ f = true;
+ } else {
+ j = 20;
+ f = false;
+ }
+
+ // Unchanged: multiple statements.
+ bool g;
+ if (j > 10)
+ f = true;
+ else {
+ j = 20;
+ f = false;
+ }
+
+ // Unchanged: multiple statements.
+ bool h;
+ if (j > 10) {
+ j = 10;
+ f = true;
+ } else
+ f = false;
+}
+
+// Unchanged: chained return statements, but ChainedConditionalReturn not set.
+bool chained_conditional_compound_return(int i) {
+ if (i < 0) {
+ return true;
+ } else if (i < 10) {
+ return false;
+ } else if (i > 20) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+// Unchanged: chained return statements, but ChainedConditionalReturn not set.
+bool chained_conditional_return(int i) {
+ if (i < 0)
+ return true;
+ else if (i < 10)
+ return false;
+ else if (i > 20)
+ return true;
+ else
+ return false;
+}
+
+// Unchanged: chained assignments, but ChainedConditionalAssignment not set.
+void chained_conditional_compound_assignment(int i) {
+ bool b;
+ if (i < 0) {
+ b = true;
+ } else if (i < 10) {
+ b = false;
+ } else if (i > 20) {
+ b = true;
+ } else {
+ b = false;
+ }
+}
+
+// Unchanged: chained return statements, but ChainedConditionalReturn not set.
+void chained_conditional_assignment(int i) {
+ bool b;
+ if (i < 0)
+ b = true;
+ else if (i < 10)
+ b = false;
+ else if (i > 20)
+ b = true;
+ else
+ b = false;
+}
+
+// Unchanged: chained return statements, but ChainedConditionalReturn not set.
+bool chained_simple_if_return_negated(int i) {
+ if (i < 5)
+ return false;
+ if (i > 10)
+ return false;
+ return true;
+}
+
+// Unchanged: chained return statements, but ChainedConditionalReturn not set.
+bool complex_chained_if_return_return(int i) {
+ if (i < 5) {
+ return true;
+ }
+ if (i > 10) {
+ return true;
+ }
+ return false;
+}
+
+// Unchanged: chained return statements, but ChainedConditionalReturn not set.
+bool complex_chained_if_return_return_negated(int i) {
+ if (i < 5) {
+ return false;
+ }
+ if (i > 10) {
+ return false;
+ }
+ return true;
+}
+
+// Unchanged: chained return statements, but ChainedConditionalReturn not set.
+bool chained_simple_if_return(int i) {
+ if (i < 5)
+ return true;
+ if (i > 10)
+ return true;
+ return false;
+}
+
+bool simple_if_return_return(int i) {
+ if (i > 10)
+ return true;
+ return false;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}}bool simple_if_return_return(int i) {{{$}}
+// CHECK-FIXES: {{^ return i > 10;$}}
+// CHECK-FIXES: {{^}$}}
+
+bool simple_if_return_return_negated(int i) {
+ if (i > 10)
+ return false;
+ return true;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}}bool simple_if_return_return_negated(int i) {{{$}}
+// CHECK-FIXES: {{^ return i <= 10;$}}
+// CHECK-FIXES: {{^}$}}
+
+bool complex_if_return_return(int i) {
+ if (i > 10) {
+ return true;
+ }
+ return false;
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}}bool complex_if_return_return(int i) {{{$}}
+// CHECK-FIXES: {{^ return i > 10;$}}
+// CHECK-FIXES: {{^}$}}
+
+bool complex_if_return_return_negated(int i) {
+ if (i > 10) {
+ return false;
+ }
+ return true;
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}}bool complex_if_return_return_negated(int i) {{{$}}
+// CHECK-FIXES: {{^ return i <= 10;$}}
+// CHECK-FIXES: {{^}$}}
+
+bool if_implicit_bool_expr(int i) {
+ if (i & 1) {
+ return true;
+ } else {
+ return false;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}} return (i & 1) != 0;{{$}}
+
+bool negated_if_implicit_bool_expr(int i) {
+ if (i - 1) {
+ return false;
+ } else {
+ return true;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}} return (i - 1) == 0;{{$}}
+
+bool implicit_int(int i) {
+ if (i) {
+ return true;
+ } else {
+ return false;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}} return i != 0;{{$}}
+
+bool explicit_bool(bool b) {
+ if (b) {
+ return true;
+ } else {
+ return false;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}} return b;{{$}}
+
+class Implicit {
+public:
+ operator bool() {
+ return true;
+ }
+};
+
+bool object_bool_implicit_conversion(Implicit O) {
+ if (O) {
+ return true;
+ } else {
+ return false;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}} return O;{{$}}
+
+bool negated_explicit_bool(bool b) {
+ if (!b) {
+ return true;
+ } else {
+ return false;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}} return !b;{{$}}
+
+bool bitwise_complement_conversion(int i) {
+ if (~i) {
+ return true;
+ } else {
+ return false;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}} return ~i != 0;{{$}}
+
+bool logical_or(bool a, bool b) {
+ if (a || b) {
+ return true;
+ } else {
+ return false;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}} return a || b;{{$}}
+
+bool logical_and(bool a, bool b) {
+ if (a && b) {
+ return true;
+ } else {
+ return false;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}} return a && b;{{$}}
+
+class Comparable
+{
+public:
+ bool operator==(Comparable const &rhs) { return true; }
+ bool operator!=(Comparable const &rhs) { return false; }
+};
+
+bool comparable_objects() {
+ Comparable c;
+ Comparable d;
+ if (c == d) {
+ return true;
+ } else {
+ return false;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}} return c == d;{{$}}
+
+bool negated_comparable_objects() {
+ Comparable c;
+ Comparable d;
+ if (c == d) {
+ return false;
+ } else {
+ return true;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}} return c != d;{{$}}
+
+struct X {
+ explicit operator bool();
+};
+
+void explicit_conversion_assignment(X x) {
+ bool y;
+ if (x) {
+ y = true;
+ } else {
+ y = false;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:9: warning: {{.*}} in conditional assignment
+// CHECK-FIXES: {{^ bool y;$}}
+// CHECK-FIXES: {{^}} y = static_cast<bool>(x);{{$}}
+
+void ternary_integer_condition(int i) {
+ bool b = i ? true : false;
+}
+// CHECK-MESSAGES: :[[@LINE-2]]:16: warning: {{.*}} in ternary expression result
+// CHECK-FIXES: bool b = i != 0;{{$}}
+
+bool non_null_pointer_condition(int *p1) {
+ if (p1) {
+ return true;
+ } else {
+ return false;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: return p1 != nullptr;{{$}}
+
+bool null_pointer_condition(int *p2) {
+ if (!p2) {
+ return true;
+ } else {
+ return false;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: return p2 == nullptr;{{$}}
+
+bool negated_non_null_pointer_condition(int *p3) {
+ if (p3) {
+ return false;
+ } else {
+ return true;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: return p3 == nullptr;{{$}}
+
+bool negated_null_pointer_condition(int *p4) {
+ if (!p4) {
+ return false;
+ } else {
+ return true;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: return p4 != nullptr;{{$}}
+
+bool comments_in_the_middle(bool b) {
+ if (b) {
+ return true;
+ } else {
+ // something wicked this way comes
+ return false;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-6]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}} if (b) {
+// CHECK-FIXES: // something wicked this way comes{{$}}
+
+bool preprocessor_in_the_middle(bool b) {
+ if (b) {
+ return true;
+ } else {
+#define SOMETHING_WICKED false
+ return false;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-6]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}} if (b) {
+// CHECK-FIXES: {{^}}#define SOMETHING_WICKED false
+
+bool integer_not_zero(int i) {
+ if (i) {
+ return false;
+ } else {
+ return true;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: {{^}} return i == 0;{{$}}
+
+class A {
+public:
+ int m;
+};
+
+bool member_pointer_nullptr(int A::*p) {
+ if (p) {
+ return true;
+ } else {
+ return false;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: return p != nullptr;{{$}}
+
+bool integer_member_implicit_cast(A *p) {
+ if (p->m) {
+ return true;
+ } else {
+ return false;
+ }
+}
+// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: return p->m != 0;{{$}}
+
+bool operator!=(const A&, const A&) { return false; }
+bool expr_with_cleanups(A &S) {
+ if (S != (A)S)
+ return false;
+
+ return true;
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:12: warning: {{.*}} in conditional return
+// CHECK-FIXES: S == (A)S;{{$}}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-simplify-subscript-expr.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-simplify-subscript-expr.cpp
new file mode 100644
index 0000000..16197dc
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-simplify-subscript-expr.cpp
@@ -0,0 +1,108 @@
+// RUN: %check_clang_tidy %s readability-simplify-subscript-expr %t \
+// RUN: -config="{CheckOptions: \
+// RUN: [{key: readability-simplify-subscript-expr.Types, \
+// RUN: value: '::std::basic_string;::std::basic_string_view;MyVector'}]}" --
+
+namespace std {
+
+template <class T>
+class basic_string {
+ public:
+ using size_type = unsigned;
+ using value_type = T;
+ using reference = value_type&;
+ using const_reference = const value_type&;
+
+ reference operator[](size_type);
+ const_reference operator[](size_type) const;
+ T* data();
+ const T* data() const;
+};
+
+using string = basic_string<char>;
+
+template <class T>
+class basic_string_view {
+ public:
+ using size_type = unsigned;
+ using const_reference = const T&;
+ using const_pointer = const T*;
+
+ constexpr const_reference operator[](size_type) const;
+ constexpr const_pointer data() const noexcept;
+};
+
+using string_view = basic_string_view<char>;
+
+}
+
+template <class T>
+class MyVector {
+ public:
+ using size_type = unsigned;
+ using const_reference = const T&;
+ using const_pointer = const T*;
+
+ const_reference operator[](size_type) const;
+ const T* data() const noexcept;
+};
+
+#define DO(x) do { x; } while (false)
+#define ACCESS(x) (x)
+#define GET(x, i) (x).data()[i]
+
+template <class T>
+class Foo {
+ public:
+ char bar(int i) {
+ return x.data()[i];
+ }
+ private:
+ T x;
+};
+
+void f(int i) {
+ MyVector<int> v;
+ int x = v.data()[i];
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: accessing an element of the container does not require a call to 'data()'; did you mean to use 'operator[]'? [readability-simplify-subscript-expr]
+ // CHECK-FIXES: int x = v[i];
+
+ std::string s;
+ char c1 = s.data()[i];
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: accessing an element
+ // CHECK-FIXES: char c1 = s[i];
+
+ std::string_view sv;
+ char c2 = sv.data()[i];
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: accessing an element
+ // CHECK-FIXES: char c2 = sv[i];
+
+ std::string* ps = &s;
+ char c3 = ps->data()[i];
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: accessing an element
+ // CHECK-FIXES: char c3 = (*ps)[i];
+
+ char c4 = (*ps).data()[i];
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: accessing an element
+ // CHECK-FIXES: char c4 = (*ps)[i];
+
+ DO(char c5 = s.data()[i]);
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: accessing an element
+ // CHECK-FIXES: DO(char c5 = s[i]);
+
+ char c6 = ACCESS(s).data()[i];
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: accessing an element
+ // CHECK-FIXES: char c6 = ACCESS(s)[i];
+
+ char c7 = ACCESS(s.data())[i];
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: accessing an element
+ // CHECK-FIXES: char c7 = ACCESS(s)[i];
+
+ char c8 = ACCESS(s.data()[i]);
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: accessing an element
+ // CHECK-FIXES: char c8 = ACCESS(s[i]);
+
+ char c9 = GET(s, i);
+
+ char c10 = Foo<std::string>{}.bar(i);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-static-accessed-through-instance-nesting-threshold.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-static-accessed-through-instance-nesting-threshold.cpp
new file mode 100644
index 0000000..0375249
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-static-accessed-through-instance-nesting-threshold.cpp
@@ -0,0 +1,33 @@
+// RUN: %check_clang_tidy %s readability-static-accessed-through-instance %t -- -config="{CheckOptions: [{key: readability-static-accessed-through-instance.NameSpecifierNestingThreshold, value: 4}]}" --
+
+// Nested specifiers
+namespace M {
+namespace N {
+struct V {
+ static int v;
+ struct T {
+ static int t;
+ struct U {
+ static int u;
+ };
+ };
+};
+}
+}
+
+void f(M::N::V::T::U u) {
+ M::N::V v;
+ v.v = 12;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member
+ // CHECK-FIXES: {{^}} M::N::V::v = 12;{{$}}
+
+ M::N::V::T w;
+ w.t = 12;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member
+ // CHECK-FIXES: {{^}} M::N::V::T::t = 12;{{$}}
+
+ // u.u is not changed, because the nesting level is over 4
+ u.u = 12;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member
+ // CHECK-FIXES: {{^}} u.u = 12;{{$}}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-static-accessed-through-instance.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-static-accessed-through-instance.cpp
new file mode 100644
index 0000000..fc42a1d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-static-accessed-through-instance.cpp
@@ -0,0 +1,222 @@
+// RUN: %check_clang_tidy %s readability-static-accessed-through-instance %t
+
+struct C {
+ static void foo();
+ static int x;
+ int nsx;
+ void mf() {
+ (void)&x; // OK, x is accessed inside the struct.
+ (void)&C::x; // OK, x is accessed using a qualified-id.
+ foo(); // OK, foo() is accessed inside the struct.
+ }
+ void ns() const;
+};
+
+int C::x = 0;
+
+struct CC {
+ void foo();
+ int x;
+};
+
+template <typename T> struct CT {
+ static T foo();
+ static T x;
+ int nsx;
+ void mf() {
+ (void)&x; // OK, x is accessed inside the struct.
+ (void)&C::x; // OK, x is accessed using a qualified-id.
+ foo(); // OK, foo() is accessed inside the struct.
+ }
+};
+
+// Expressions with side effects
+C &f(int, int, int, int);
+void g() {
+ f(1, 2, 3, 4).x;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member accessed through instance [readability-static-accessed-through-instance]
+ // CHECK-FIXES: {{^}} f(1, 2, 3, 4).x;{{$}}
+}
+
+int i(int &);
+void j(int);
+C h();
+bool a();
+int k(bool);
+
+void f(C c) {
+ j(i(h().x));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: static member
+ // CHECK-FIXES: {{^}} j(i(h().x));{{$}}
+
+ // The execution of h() depends on the return value of a().
+ j(k(a() && h().x));
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: static member
+ // CHECK-FIXES: {{^}} j(k(a() && h().x));{{$}}
+
+ if ([c]() {
+ c.ns();
+ return c;
+ }().x == 15)
+ ;
+ // CHECK-MESSAGES: :[[@LINE-5]]:7: warning: static member
+ // CHECK-FIXES: {{^}} if ([c]() {{{$}}
+}
+
+// Nested specifiers
+namespace N {
+struct V {
+ static int v;
+ struct T {
+ static int t;
+ struct U {
+ static int u;
+ };
+ };
+};
+}
+
+void f(N::V::T::U u) {
+ N::V v;
+ v.v = 12;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member
+ // CHECK-FIXES: {{^}} N::V::v = 12;{{$}}
+
+ N::V::T w;
+ w.t = 12;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member
+ // CHECK-FIXES: {{^}} N::V::T::t = 12;{{$}}
+
+ // u.u is not changed to N::V::T::U::u; because the nesting level is over 3.
+ u.u = 12;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member
+ // CHECK-FIXES: {{^}} u.u = 12;{{$}}
+
+ using B = N::V::T::U;
+ B b;
+ b.u;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member
+ // CHECK-FIXES: {{^}} B::u;{{$}}
+}
+
+// Templates
+template <typename T> T CT<T>::x;
+
+template <typename T> struct CCT {
+ T foo();
+ T x;
+};
+
+typedef C D;
+
+using E = D;
+
+#define FOO(c) c.foo()
+#define X(c) c.x
+
+template <typename T> void f(T t, C c) {
+ t.x; // OK, t is a template parameter.
+ c.x;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member
+ // CHECK-FIXES: {{^}} C::x;{{$}}
+}
+
+template <int N> struct S { static int x; };
+
+template <> struct S<0> { int x; };
+
+template <int N> void h() {
+ S<N> sN;
+ sN.x; // OK, value of N affects whether x is static or not.
+
+ S<2> s2;
+ s2.x;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member
+ // CHECK-FIXES: {{^}} S<2>::x;{{$}}
+}
+
+void static_through_instance() {
+ C *c1 = new C();
+ c1->foo(); // 1
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member
+ // CHECK-FIXES: {{^}} C::foo(); // 1{{$}}
+ c1->x; // 2
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member
+ // CHECK-FIXES: {{^}} C::x; // 2{{$}}
+ c1->nsx; // OK, nsx is a non-static member.
+
+ const C *c2 = new C();
+ c2->foo(); // 2
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member
+ // CHECK-FIXES: {{^}} C::foo(); // 2{{$}}
+
+ C::foo(); // OK, foo() is accessed using a qualified-id.
+ C::x; // OK, x is accessed using a qualified-id.
+
+ D d;
+ d.foo();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member
+ // CHECK-FIXES: {{^}} D::foo();{{$}}
+ d.x;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member
+ // CHECK-FIXES: {{^}} D::x;{{$}}
+
+ E e;
+ e.foo();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member
+ // CHECK-FIXES: {{^}} E::foo();{{$}}
+ e.x;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member
+ // CHECK-FIXES: {{^}} E::x;{{$}}
+
+ CC *cc = new CC;
+
+ f(*c1, *c1);
+ f(*cc, *c1);
+
+ // Macros: OK, macros are not checked.
+ FOO((*c1));
+ X((*c1));
+ FOO((*cc));
+ X((*cc));
+
+ // Templates
+ CT<int> ct;
+ ct.foo();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member
+ // CHECK-FIXES: {{^}} CT<int>::foo();{{$}}
+ ct.x;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member
+ // CHECK-FIXES: {{^}} CT<int>::x;{{$}}
+ ct.nsx; // OK, nsx is a non-static member
+
+ CCT<int> cct;
+ cct.foo(); // OK, CCT has no static members.
+ cct.x; // OK, CCT has no static members.
+
+ h<4>();
+}
+
+// Overloaded member access operator
+struct Q {
+ static int K;
+ int y = 0;
+};
+
+int Q::K = 0;
+
+struct Qptr {
+ Q *q;
+
+ explicit Qptr(Q *qq) : q(qq) {}
+
+ Q *operator->() {
+ ++q->y;
+ return q;
+ }
+};
+
+int func(Qptr qp) {
+ qp->y = 10; // OK, the overloaded operator might have side-effects.
+ qp->K = 10; //
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-static-definition-in-anonymous-namespace.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-static-definition-in-anonymous-namespace.cpp
new file mode 100644
index 0000000..5c3c8c1
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-static-definition-in-anonymous-namespace.cpp
@@ -0,0 +1,49 @@
+// RUN: %check_clang_tidy %s readability-static-definition-in-anonymous-namespace %t
+
+namespace {
+
+int a = 1;
+const int b = 1;
+static int c = 1;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: 'c' is a static definition in anonymous namespace; static is redundant here [readability-static-definition-in-anonymous-namespace]
+// CHECK-FIXES: {{^}}int c = 1;
+static const int d = 1;
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'd' is a static definition in anonymous namespace
+// CHECK-FIXES: {{^}}const int d = 1;
+const static int e = 1;
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'e' is a static definition in anonymous namespace
+// CHECK-FIXES: {{^}}const int e = 1;
+
+void f() {
+ int a = 1;
+ static int b = 1;
+}
+
+static int g() {
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: 'g' is a static definition in anonymous namespace
+// CHECK-FIXES: {{^}}int g() {
+ return 1;
+}
+
+#define DEFINE_STATIC static
+// CHECK-FIXES: {{^}}#define DEFINE_STATIC static
+DEFINE_STATIC int h = 1;
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 'h' is a static definition in anonymous namespace
+// CHECK-FIXES: {{^}}DEFINE_STATIC int h = 1;
+
+#define DEFINE_STATIC_VAR(x) static int x = 2
+// CHECK-FIXES: {{^}}#define DEFINE_STATIC_VAR(x) static int x = 2
+DEFINE_STATIC_VAR(i);
+// CHECK-FIXES: {{^}}DEFINE_STATIC_VAR(i);
+
+} // namespace
+
+namespace N {
+
+int a = 1;
+const int b = 1;
+static int c = 1;
+static const int d = 1;
+const static int e = 1;
+
+} // namespace N
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-string-compare.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-string-compare.cpp
new file mode 100644
index 0000000..9bd11da
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-string-compare.cpp
@@ -0,0 +1,119 @@
+// RUN: %check_clang_tidy %s readability-string-compare %t -- -- -std=c++11
+
+namespace std {
+template <typename T>
+class allocator {};
+template <typename T>
+class char_traits {};
+template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C>>
+class basic_string {
+public:
+ basic_string();
+ basic_string(const C *, unsigned int size);
+ int compare(const basic_string<char> &str) const;
+ int compare(const C *) const;
+ int compare(int, int, const basic_string<char> &str) const;
+ bool empty();
+};
+bool operator==(const basic_string<char> &lhs, const basic_string<char> &rhs);
+bool operator!=(const basic_string<char> &lhs, const basic_string<char> &rhs);
+bool operator==(const basic_string<char> &lhs, const char *&rhs);
+typedef basic_string<char> string;
+}
+
+void func(bool b);
+
+std::string comp() {
+ std::string str("a", 1);
+ return str;
+}
+
+void Test() {
+ std::string str1("a", 1);
+ std::string str2("b", 1);
+
+ if (str1.compare(str2)) {
+ }
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: do not use 'compare' to test equality of strings; use the string equality operator instead [readability-string-compare]
+ if (!str1.compare(str2)) {
+ }
+ // CHECK-MESSAGES: [[@LINE-2]]:8: warning: do not use 'compare' to test equality of strings; use the string equality operator instead [readability-string-compare]
+ if (str1.compare(str2) == 0) {
+ }
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: do not use 'compare' to test equality of strings;
+ // CHECK-FIXES: if (str1 == str2) {
+ if (str1.compare(str2) != 0) {
+ }
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: do not use 'compare' to test equality of strings;
+ // CHECK-FIXES: if (str1 != str2) {
+ if (str1.compare("foo") == 0) {
+ }
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: do not use 'compare' to test equality of strings;
+ // CHECK-FIXES: if (str1 == "foo") {
+ if (0 == str1.compare(str2)) {
+ }
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: do not use 'compare' to test equality of strings;
+ // CHECK-FIXES: if (str2 == str1) {
+ if (0 != str1.compare(str2)) {
+ }
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: do not use 'compare' to test equality of strings;
+ // CHECK-FIXES: if (str2 != str1) {
+ func(str1.compare(str2));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: do not use 'compare' to test equality of strings;
+ if (str2.empty() || str1.compare(str2) != 0) {
+ }
+ // CHECK-MESSAGES: [[@LINE-2]]:23: warning: do not use 'compare' to test equality of strings;
+ // CHECK-FIXES: if (str2.empty() || str1 != str2) {
+ std::string *str3 = &str1;
+ if (str3->compare(str2)) {
+ }
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: do not use 'compare' to test equality of strings;
+ if (str3->compare(str2) == 0) {
+ }
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: do not use 'compare' to test equality of strings;
+ // CHECK-FIXES: if (*str3 == str2) {
+ if (str2.compare(*str3) == 0) {
+ }
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: do not use 'compare' to test equality of strings;
+ // CHECK-FIXES: if (str2 == *str3) {
+ if (comp().compare(str1) == 0) {
+ }
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: do not use 'compare' to test equality of strings;
+ // CHECK-FIXES: if (comp() == str1) {
+ if (str1.compare(comp()) == 0) {
+ }
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: do not use 'compare' to test equality of strings;
+ // CHECK-FIXES: if (str1 == comp()) {
+ if (str1.compare(comp())) {
+ }
+ // CHECK-MESSAGES: [[@LINE-2]]:7: warning: do not use 'compare' to test equality of strings;
+}
+
+void Valid() {
+ std::string str1("a", 1);
+ std::string str2("b", 1);
+ if (str1 == str2) {
+ }
+ if (str1 != str2) {
+ }
+ if (str1.compare(str2) == str1.compare(str2)) {
+ }
+ if (0 == 0) {
+ }
+ if (str1.compare(str2) > 0) {
+ }
+ if (str1.compare(1, 3, str2)) {
+ }
+ if (str1.compare(str2) > 0) {
+ }
+ if (str1.compare(str2) < 0) {
+ }
+ if (str1.compare(str2) == 2) {
+ }
+ if (str1.compare(str2) == -3) {
+ }
+ if (str1.compare(str2) == 1) {
+ }
+ if (str1.compare(str2) == -1) {
+ }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uniqueptr-delete-release.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uniqueptr-delete-release.cpp
new file mode 100644
index 0000000..bd51bc6
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uniqueptr-delete-release.cpp
@@ -0,0 +1,76 @@
+// RUN: %check_clang_tidy %s readability-uniqueptr-delete-release %t
+
+namespace std {
+template <typename T>
+struct default_delete {};
+
+template <typename T, typename D = default_delete<T>>
+class unique_ptr {
+ public:
+ unique_ptr();
+ ~unique_ptr();
+ explicit unique_ptr(T*);
+ template <typename U, typename E>
+ unique_ptr(unique_ptr<U, E>&&);
+ T* release();
+};
+} // namespace std
+
+std::unique_ptr<int>& ReturnsAUnique();
+
+void Positives() {
+ std::unique_ptr<int> P;
+ delete P.release();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer '= nullptr' to 'delete x.release()' to reset unique_ptr<> objects [readability-uniqueptr-delete-release]
+ // CHECK-FIXES: {{^}} P = nullptr;
+
+ auto P2 = P;
+ delete P2.release();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer '= nullptr' to 'delete x.release()' to reset unique_ptr<> objects [readability-uniqueptr-delete-release]
+ // CHECK-FIXES: {{^}} P2 = nullptr;
+
+ std::unique_ptr<int> Array[20];
+ delete Array[4].release();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer '= nullptr' to 'delete
+ // CHECK-FIXES: {{^}} Array[4] = nullptr;
+
+ delete ReturnsAUnique().release();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer '= nullptr' to 'delete
+ // CHECK-FIXES: {{^}} ReturnsAUnique() = nullptr;
+}
+
+struct NotDefaultDeleter {};
+
+struct NotUniquePtr {
+ int* release();
+};
+
+void Negatives() {
+ std::unique_ptr<int, NotDefaultDeleter> P;
+ delete P.release();
+
+ NotUniquePtr P2;
+ delete P2.release();
+}
+
+template <typename T, typename D>
+void NegativeDeleterT() {
+ // Ideally this would trigger a warning, but we have all dependent types
+ // disabled for now.
+ std::unique_ptr<T> P;
+ delete P.release();
+
+ // We ignore this one because the deleter is a template argument.
+ // Not all instantiations will use the default deleter.
+ std::unique_ptr<int, D> P2;
+ delete P2.release();
+}
+template void NegativeDeleterT<int, std::default_delete<int>>();
+
+// Test some macros
+
+#define DELETE_RELEASE(x) delete (x).release()
+void NegativesWithTemplate() {
+ std::unique_ptr<int> P;
+ DELETE_RELEASE(P);
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-float16.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-float16.cpp
new file mode 100644
index 0000000..b2b858f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-float16.cpp
@@ -0,0 +1,51 @@
+// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- -- -target aarch64-linux-gnu -I %S
+
+#include "readability-uppercase-literal-suffix.h"
+
+void float16_normal_literals() {
+ // _Float16
+
+ static constexpr auto v14 = 1.f16;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v14 = 1.f16;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}}
+ // CHECK-FIXES: static constexpr auto v14 = 1.F16;
+ static_assert(is_same<decltype(v14), const _Float16>::value, "");
+ static_assert(v14 == 1.F16, "");
+
+ static constexpr auto v15 = 1.e0f16;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v15 = 1.e0f16;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}}
+ // CHECK-FIXES: static constexpr auto v15 = 1.e0F16;
+ static_assert(is_same<decltype(v15), const _Float16>::value, "");
+ static_assert(v15 == 1.F16, "");
+
+ static constexpr auto v16 = 1.F16; // OK.
+ static_assert(is_same<decltype(v16), const _Float16>::value, "");
+ static_assert(v16 == 1.F16, "");
+
+ static constexpr auto v17 = 1.e0F16; // OK.
+ static_assert(is_same<decltype(v17), const _Float16>::value, "");
+ static_assert(v17 == 1.F16, "");
+}
+
+void float16_hexadecimal_literals() {
+// _Float16
+
+ static constexpr auto v13 = 0xfp0f16;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v13 = 0xfp0f16;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}}
+ // CHECK-FIXES: static constexpr auto v13 = 0xfp0F16;
+ static_assert(is_same<decltype(v13), const _Float16>::value, "");
+ static_assert(v13 == 0xfp0F16, "");
+
+ static constexpr auto v14 = 0xfp0F16; // OK.
+ static_assert(is_same<decltype(v14), const _Float16>::value, "");
+ static_assert(v14 == 0xfp0F16, "");
+
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-floating-point-opencl-half.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-floating-point-opencl-half.cpp
new file mode 100644
index 0000000..96d2eb0
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-floating-point-opencl-half.cpp
@@ -0,0 +1,30 @@
+// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- -- -target x86_64-pc-linux-gnu -I %S -std=cl2.0 -x cl
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
+// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -fix -- -target x86_64-pc-linux-gnu -I %S -std=cl2.0 -x cl
+// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -warnings-as-errors='-*,readability-uppercase-literal-suffix' -- -target x86_64-pc-linux-gnu -I %S -std=cl2.0 -x cl
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+
+void floating_point_half_suffix() {
+ static half v0 = 0x0p0; // no literal
+
+ // half
+
+ static half v2 = 1.h;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: floating point literal has suffix 'h', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static half v2 = 1.h;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}H{{$}}
+ // CHECK-HIXES: static half v2 = 1.H;
+
+ static half v3 = 1.e0h;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: floating point literal has suffix 'h', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static half v3 = 1.e0h;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}H{{$}}
+ // CHECK-HIXES: static half v3 = 1.e0H;
+
+ static half v4 = 1.H; // OK.
+
+ static half v5 = 1.e0H; // OK.
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp
new file mode 100644
index 0000000..50e75fa
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp
@@ -0,0 +1,170 @@
+// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- -- -target x86_64-pc-linux-gnu -I %S
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
+// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -fix -- -target x86_64-pc-linux-gnu -I %S
+// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -warnings-as-errors='-*,readability-uppercase-literal-suffix' -- -target x86_64-pc-linux-gnu -I %S
+
+#include "readability-uppercase-literal-suffix.h"
+
+void floating_point_suffix() {
+ static constexpr auto v0 = 1.; // no literal
+ static_assert(is_same<decltype(v0), const double>::value, "");
+ static_assert(v0 == 1., "");
+
+ static constexpr auto v1 = 1.e0; // no literal
+ static_assert(is_same<decltype(v1), const double>::value, "");
+ static_assert(v1 == 1., "");
+
+ // Float
+
+ static constexpr auto v2 = 1.f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'f', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v2 = 1.f;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}F{{$}}
+ // CHECK-FIXES: static constexpr auto v2 = 1.F;
+ static_assert(is_same<decltype(v2), const float>::value, "");
+ static_assert(v2 == 1.0F, "");
+
+ static constexpr auto v3 = 1.e0f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'f', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v3 = 1.e0f;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}F{{$}}
+ // CHECK-FIXES: static constexpr auto v3 = 1.e0F;
+ static_assert(is_same<decltype(v3), const float>::value, "");
+ static_assert(v3 == 1.0F, "");
+
+ static constexpr auto v4 = 1.F; // OK.
+ static_assert(is_same<decltype(v4), const float>::value, "");
+ static_assert(v4 == 1.0F, "");
+
+ static constexpr auto v5 = 1.e0F; // OK.
+ static_assert(is_same<decltype(v5), const float>::value, "");
+ static_assert(v5 == 1.0F, "");
+
+ // Long double
+
+ static constexpr auto v6 = 1.l;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'l', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v6 = 1.l;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}L{{$}}
+ // CHECK-FIXES: static constexpr auto v6 = 1.L;
+ static_assert(is_same<decltype(v6), const long double>::value, "");
+ static_assert(v6 == 1., "");
+
+ static constexpr auto v7 = 1.e0l;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'l', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v7 = 1.e0l;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}L{{$}}
+ // CHECK-FIXES: static constexpr auto v7 = 1.e0L;
+ static_assert(is_same<decltype(v7), const long double>::value, "");
+ static_assert(v7 == 1., "");
+
+ static constexpr auto v8 = 1.L; // OK.
+ static_assert(is_same<decltype(v8), const long double>::value, "");
+ static_assert(v8 == 1., "");
+
+ static constexpr auto v9 = 1.e0L; // OK.
+ static_assert(is_same<decltype(v9), const long double>::value, "");
+ static_assert(v9 == 1., "");
+
+ // __float128
+
+ static constexpr auto v10 = 1.q;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'q', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v10 = 1.q;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}Q{{$}}
+ // CHECK-FIXES: static constexpr auto v10 = 1.Q;
+ static_assert(is_same<decltype(v10), const __float128>::value, "");
+ static_assert(v10 == 1., "");
+
+ static constexpr auto v11 = 1.e0q;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'q', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v11 = 1.e0q;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}Q{{$}}
+ // CHECK-FIXES: static constexpr auto v11 = 1.e0Q;
+ static_assert(is_same<decltype(v11), const __float128>::value, "");
+ static_assert(v11 == 1., "");
+
+ static constexpr auto v12 = 1.Q; // OK.
+ static_assert(is_same<decltype(v12), const __float128>::value, "");
+ static_assert(v12 == 1., "");
+
+ static constexpr auto v13 = 1.e0Q; // OK.
+ static_assert(is_same<decltype(v13), const __float128>::value, "");
+ static_assert(v13 == 1., "");
+}
+
+void floating_point_complex_suffix() {
+ // _Complex, I
+
+ static constexpr auto v14 = 1.i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'i', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v14 = 1.i;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}I{{$}}
+ // CHECK-FIXES: static constexpr auto v14 = 1.I;
+ static_assert(is_same<decltype(v14), const _Complex double>::value, "");
+ static_assert(v14 == 1.I, "");
+
+ static constexpr auto v15 = 1.e0i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'i', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v15 = 1.e0i;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}I{{$}}
+ // CHECK-FIXES: static constexpr auto v15 = 1.e0I;
+ static_assert(is_same<decltype(v15), const _Complex double>::value, "");
+ static_assert(v15 == 1.I, "");
+
+ static constexpr auto v16 = 1.I; // OK.
+ static_assert(is_same<decltype(v16), const _Complex double>::value, "");
+ static_assert(v16 == 1.I, "");
+
+ static constexpr auto v17 = 1.e0I; // OK.
+ static_assert(is_same<decltype(v17), const _Complex double>::value, "");
+ static_assert(v17 == 1.I, "");
+
+ // _Complex, J
+
+ static constexpr auto v18 = 1.j;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'j', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v18 = 1.j;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}J{{$}}
+ // CHECK-FIXES: static constexpr auto v18 = 1.J;
+ static_assert(is_same<decltype(v18), const _Complex double>::value, "");
+ static_assert(v18 == 1.J, "");
+
+ static constexpr auto v19 = 1.e0j;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'j', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v19 = 1.e0j;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}J{{$}}
+ // CHECK-FIXES: static constexpr auto v19 = 1.e0J;
+ static_assert(is_same<decltype(v19), const _Complex double>::value, "");
+ static_assert(v19 == 1.J, "");
+
+ static constexpr auto v20 = 1.J; // OK.
+ static_assert(is_same<decltype(v20), const _Complex double>::value, "");
+ static_assert(v20 == 1.J, "");
+
+ static constexpr auto v21 = 1.e0J; // OK.
+ static_assert(is_same<decltype(v21), const _Complex double>::value, "");
+ static_assert(v21 == 1.J, "");
+}
+
+void macros() {
+#define PASSTHROUGH(X) X
+ static constexpr auto m0 = PASSTHROUGH(1.f);
+ // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: floating point literal has suffix 'f', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto m0 = PASSTHROUGH(1.f);
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}F{{$}}
+ // CHECK-FIXES: static constexpr auto m0 = PASSTHROUGH(1.F);
+ static_assert(is_same<decltype(m0), const float>::value, "");
+ static_assert(m0 == 1.0F, "");
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp
new file mode 100644
index 0000000..415c6d8
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp
@@ -0,0 +1,140 @@
+// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- -- -target x86_64-pc-linux-gnu -I %S
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
+// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -fix -- -target x86_64-pc-linux-gnu -I %S
+// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -warnings-as-errors='-*,readability-uppercase-literal-suffix' -- -target x86_64-pc-linux-gnu -I %S
+
+#include "readability-uppercase-literal-suffix.h"
+
+void floating_point_suffix() {
+ static constexpr auto v0 = 0x0p0; // no literal
+ static_assert(is_same<decltype(v0), const double>::value, "");
+ static_assert(v0 == 0, "");
+
+ // Float
+
+ static constexpr auto v1 = 0xfp0f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'f', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v1 = 0xfp0f;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}F{{$}}
+ // CHECK-FIXES: static constexpr auto v1 = 0xfp0F;
+ static_assert(is_same<decltype(v1), const float>::value, "");
+ static_assert(v1 == 15, "");
+
+ static constexpr auto v2 = 0xfp0F; // OK
+ static_assert(is_same<decltype(v2), const float>::value, "");
+ static_assert(v2 == 15, "");
+
+ static constexpr auto v3 = 0xfP0f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'f', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v3 = 0xfP0f;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}F{{$}}
+ // CHECK-FIXES: static constexpr auto v3 = 0xfP0F;
+ static_assert(is_same<decltype(v3), const float>::value, "");
+ static_assert(v3 == 15, "");
+
+ static constexpr auto v4 = 0xfP0F; // OK
+ static_assert(is_same<decltype(v4), const float>::value, "");
+ static_assert(v4 == 15, "");
+
+ static constexpr auto v5 = 0xFP0f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'f', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v5 = 0xFP0f;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}F{{$}}
+ // CHECK-FIXES: static constexpr auto v5 = 0xFP0F;
+ static_assert(is_same<decltype(v5), const float>::value, "");
+ static_assert(v5 == 15, "");
+
+ static constexpr auto v6 = 0xFP0F; // OK
+ static_assert(is_same<decltype(v6), const float>::value, "");
+ static_assert(v6 == 15, "");
+
+ static constexpr auto v7 = 0xFp0f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'f', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v7 = 0xFp0f;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}F{{$}}
+ // CHECK-FIXES: static constexpr auto v7 = 0xFp0F;
+ static_assert(is_same<decltype(v7), const float>::value, "");
+ static_assert(v7 == 15, "");
+
+ static constexpr auto v8 = 0xFp0F; // OK
+ static_assert(is_same<decltype(v8), const float>::value, "");
+ static_assert(v8 == 15, "");
+
+ // long double
+
+ static constexpr auto v9 = 0xfp0l;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'l', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v9 = 0xfp0l;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}L{{$}}
+ // CHECK-FIXES: static constexpr auto v9 = 0xfp0L;
+ static_assert(is_same<decltype(v9), const long double>::value, "");
+ static_assert(v9 == 0xfp0, "");
+
+ static constexpr auto v10 = 0xfp0L; // OK.
+ static_assert(is_same<decltype(v10), const long double>::value, "");
+ static_assert(v10 == 0xfp0, "");
+
+ // __float128
+
+ static constexpr auto v11 = 0xfp0q;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'q', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v11 = 0xfp0q;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}Q{{$}}
+ // CHECK-FIXES: static constexpr auto v11 = 0xfp0Q;
+ static_assert(is_same<decltype(v11), const __float128>::value, "");
+ static_assert(v11 == 0xfp0, "");
+
+ static constexpr auto v12 = 0xfp0Q; // OK.
+ static_assert(is_same<decltype(v12), const __float128>::value, "");
+ static_assert(v12 == 0xfp0, "");
+}
+
+void floating_point_complex_suffix() {
+ // _Complex, I
+
+ static constexpr auto v14 = 0xfp0i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'i', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v14 = 0xfp0i;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}I{{$}}
+ // CHECK-FIXES: static constexpr auto v14 = 0xfp0I;
+ static_assert(is_same<decltype(v14), const _Complex double>::value, "");
+ static_assert(v14 == 0xfp0I, "");
+
+ static constexpr auto v16 = 0xfp0I; // OK.
+ static_assert(is_same<decltype(v16), const _Complex double>::value, "");
+ static_assert(v16 == 0xfp0I, "");
+
+ // _Complex, J
+
+ static constexpr auto v18 = 0xfp0j;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'j', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v18 = 0xfp0j;
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}J{{$}}
+ // CHECK-FIXES: static constexpr auto v18 = 0xfp0J;
+ static_assert(is_same<decltype(v18), const _Complex double>::value, "");
+ static_assert(v18 == 0xfp0J, "");
+
+ static constexpr auto v20 = 0xfp0J; // OK.
+ static_assert(is_same<decltype(v20), const _Complex double>::value, "");
+ static_assert(v20 == 0xfp0J, "");
+}
+
+void macros() {
+#define PASSTHROUGH(X) X
+ static constexpr auto m0 = PASSTHROUGH(0x0p0f);
+ // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: floating point literal has suffix 'f', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto m0 = PASSTHROUGH(0x0p0f);
+ // CHECK-MESSAGES-NEXT: ^ ~
+ // CHECK-MESSAGES-NEXT: {{^ *}}F{{$}}
+ // CHECK-FIXES: static constexpr auto m0 = PASSTHROUGH(0x0p0F);
+ static_assert(is_same<decltype(m0), const float>::value, "");
+ static_assert(m0 == 0x0p0F, "");
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-integer-custom-list.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-integer-custom-list.cpp
new file mode 100644
index 0000000..ff67a33
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-integer-custom-list.cpp
@@ -0,0 +1,130 @@
+// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- -config="{CheckOptions: [{key: readability-uppercase-literal-suffix.NewSuffixes, value: 'L;uL'}]}" -- -I %S
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
+// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -fix -config="{CheckOptions: [{key: readability-uppercase-literal-suffix.NewSuffixes, value: 'L;uL'}]}" -- -I %S
+// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -warnings-as-errors='-*,readability-uppercase-literal-suffix' -config="{CheckOptions: [{key: readability-uppercase-literal-suffix.NewSuffixes, value: 'L;uL'}]}" -- -I %S
+
+#include "readability-uppercase-literal-suffix.h"
+
+void integer_suffix() {
+ // Unsigned
+
+ static constexpr auto v3 = 1u; // OK.
+ static_assert(is_same<decltype(v3), const unsigned int>::value, "");
+ static_assert(v3 == 1, "");
+
+ static constexpr auto v4 = 1U; // OK.
+ static_assert(is_same<decltype(v4), const unsigned int>::value, "");
+ static_assert(v4 == 1, "");
+
+ // Long
+
+ static constexpr auto v5 = 1l;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'l', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v5 = 1l;
+ // CHECK-MESSAGES-NEXT: ^~
+ // CHECK-MESSAGES-NEXT: {{^ *}}L{{$}}
+ // CHECK-FIXES: static constexpr auto v5 = 1L;
+ static_assert(is_same<decltype(v5), const long>::value, "");
+ static_assert(v5 == 1, "");
+
+ static constexpr auto v6 = 1L; // OK.
+ static_assert(is_same<decltype(v6), const long>::value, "");
+ static_assert(v6 == 1, "");
+
+ // Long Long
+
+ static constexpr auto v7 = 1ll; // OK.
+ static_assert(is_same<decltype(v7), const long long>::value, "");
+ static_assert(v7 == 1, "");
+
+ static constexpr auto v8 = 1LL; // OK.
+ static_assert(is_same<decltype(v8), const long long>::value, "");
+ static_assert(v8 == 1, "");
+
+ // Unsigned Long
+
+ static constexpr auto v9 = 1ul;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'ul', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v9 = 1ul;
+ // CHECK-MESSAGES-NEXT: ^~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}uL{{$}}
+ // CHECK-FIXES: static constexpr auto v9 = 1uL;
+ static_assert(is_same<decltype(v9), const unsigned long>::value, "");
+ static_assert(v9 == 1, "");
+
+ static constexpr auto v10 = 1uL; // OK.
+ static_assert(is_same<decltype(v10), const unsigned long>::value, "");
+ static_assert(v10 == 1, "");
+
+ static constexpr auto v11 = 1Ul;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'Ul', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v11 = 1Ul;
+ // CHECK-MESSAGES-NEXT: ^~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}uL{{$}}
+ // CHECK-FIXES: static constexpr auto v11 = 1uL;
+ static_assert(is_same<decltype(v11), const unsigned long>::value, "");
+ static_assert(v11 == 1, "");
+
+ static constexpr auto v12 = 1UL; // OK.
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'UL', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v12 = 1UL;
+ // CHECK-MESSAGES-NEXT: ^~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}uL{{$}}
+ // CHECK-FIXES: static constexpr auto v12 = 1uL;
+ static_assert(is_same<decltype(v12), const unsigned long>::value, "");
+ static_assert(v12 == 1, "");
+
+ // Long Unsigned
+
+ static constexpr auto v13 = 1lu; // OK.
+ static_assert(is_same<decltype(v13), const unsigned long>::value, "");
+ static_assert(v13 == 1, "");
+
+ static constexpr auto v14 = 1Lu; // OK.
+ static_assert(is_same<decltype(v14), const unsigned long>::value, "");
+ static_assert(v14 == 1, "");
+
+ static constexpr auto v15 = 1lU; // OK.
+ static_assert(is_same<decltype(v15), const unsigned long>::value, "");
+ static_assert(v15 == 1, "");
+
+ static constexpr auto v16 = 1LU; // OK.
+ static_assert(is_same<decltype(v16), const unsigned long>::value, "");
+ static_assert(v16 == 1, "");
+
+ // Unsigned Long Long
+
+ static constexpr auto v17 = 1ull; // OK.
+ static_assert(is_same<decltype(v17), const unsigned long long>::value, "");
+ static_assert(v17 == 1, "");
+
+ static constexpr auto v18 = 1uLL; // OK.
+ static_assert(is_same<decltype(v18), const unsigned long long>::value, "");
+ static_assert(v18 == 1, "");
+
+ static constexpr auto v19 = 1Ull; // OK.
+ static_assert(is_same<decltype(v19), const unsigned long long>::value, "");
+ static_assert(v19 == 1, "");
+
+ static constexpr auto v20 = 1ULL; // OK.
+ static_assert(is_same<decltype(v20), const unsigned long long>::value, "");
+ static_assert(v20 == 1, "");
+
+ // Long Long Unsigned
+
+ static constexpr auto v21 = 1llu; // OK.
+ static_assert(is_same<decltype(v21), const unsigned long long>::value, "");
+ static_assert(v21 == 1, "");
+
+ static constexpr auto v22 = 1LLu; // OK.
+ static_assert(is_same<decltype(v22), const unsigned long long>::value, "");
+ static_assert(v22 == 1, "");
+
+ static constexpr auto v23 = 1llU; // OK.
+ static_assert(is_same<decltype(v23), const unsigned long long>::value, "");
+ static_assert(v23 == 1, "");
+
+ static constexpr auto v24 = 1LLU; // OK.
+ static_assert(is_same<decltype(v24), const unsigned long long>::value, "");
+ static_assert(v24 == 1, "");
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-integer-macro.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-integer-macro.cpp
new file mode 100644
index 0000000..40a9c26
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-integer-macro.cpp
@@ -0,0 +1,27 @@
+// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- \
+// RUN: -config="{CheckOptions: [{key: readability-uppercase-literal-suffix.IgnoreMacros, value: 0}]}" \
+// RUN: -- -I %S
+
+void macros() {
+#define INMACRO(X) 1.f
+ static constexpr auto m1 = INMACRO();
+ // CHECK-NOTES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'f', which is not uppercase
+ // CHECK-NOTES: :[[@LINE-3]]:20: note: expanded from macro 'INMACRO'
+ // CHECK-FIXES: #define INMACRO(X) 1.f
+ // CHECK-FIXES: static constexpr auto m1 = INMACRO();
+ // ^ so no fix-its here.
+}
+
+void horrible_macros() {
+#define MAKE_UNSIGNED(x) x##u
+#define ONE MAKE_UNSIGNED(1)
+ static constexpr auto hm0 = ONE;
+ // CHECK-NOTES: :[[@LINE-1]]:31: warning: integer literal has suffix 'u', which is not uppercase
+ // CHECK-NOTES: :[[@LINE-3]]:13: note: expanded from macro 'ONE'
+ // CHECK-NOTES: :[[@LINE-5]]:26: note: expanded from macro 'MAKE_UNSIGNED'
+ // CHECK-NOTES: note: expanded from here
+ // CHECK-FIXES: #define MAKE_UNSIGNED(x) x##u
+ // CHECK-FIXES: #define ONE MAKE_UNSIGNED(1)
+ // CHECK-FIXES: static constexpr auto hm0 = ONE;
+ // Certainly no fix-its.
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-integer-ms.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-integer-ms.cpp
new file mode 100644
index 0000000..1ec3211
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-integer-ms.cpp
@@ -0,0 +1,77 @@
+// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- -- -target x86_64-pc-linux-gnu -I %S -fms-extensions
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
+// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -fix -- -target x86_64-pc-linux-gnu -I %S -fms-extensions
+// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -warnings-as-errors='-*,readability-uppercase-literal-suffix' -- -target x86_64-pc-linux-gnu -I %S -fms-extensions
+
+#include "readability-uppercase-literal-suffix.h"
+
+void integer_suffix() {
+ static constexpr auto v0 = __LINE__; // synthetic
+ static_assert(v0 == 9 || v0 == 5, "");
+
+ static constexpr auto v1 = __cplusplus; // synthetic, long
+
+ static constexpr auto v2 = 1; // no literal
+ static_assert(is_same<decltype(v2), const int>::value, "");
+ static_assert(v2 == 1, "");
+
+ // i32
+
+ static constexpr auto v3 = 1i32;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'i32', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v3 = 1i32;
+ // CHECK-MESSAGES-NEXT: ^~
+ // CHECK-MESSAGES-NEXT: {{^ *}}I32{{$}}
+ // CHECK-FIXES: static constexpr auto v3 = 1I32;
+ static_assert(is_same<decltype(v3), const int>::value, "");
+ static_assert(v3 == 1I32, "");
+
+ static constexpr auto v4 = 1I32; // OK.
+ static_assert(is_same<decltype(v4), const int>::value, "");
+ static_assert(v4 == 1I32, "");
+
+ // i64
+
+ static constexpr auto v5 = 1i64;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'i64', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v5 = 1i64;
+ // CHECK-MESSAGES-NEXT: ^~
+ // CHECK-MESSAGES-NEXT: {{^ *}}I64{{$}}
+ // CHECK-FIXES: static constexpr auto v5 = 1I64;
+ static_assert(is_same<decltype(v5), const long int>::value, "");
+ static_assert(v5 == 1I64, "");
+
+ static constexpr auto v6 = 1I64; // OK.
+ static_assert(is_same<decltype(v6), const long int>::value, "");
+ static_assert(v6 == 1I64, "");
+
+ // i16
+
+ static constexpr auto v7 = 1i16;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'i16', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v7 = 1i16;
+ // CHECK-MESSAGES-NEXT: ^~
+ // CHECK-MESSAGES-NEXT: {{^ *}}I16{{$}}
+ // CHECK-FIXES: static constexpr auto v7 = 1I16;
+ static_assert(is_same<decltype(v7), const short>::value, "");
+ static_assert(v7 == 1I16, "");
+
+ static constexpr auto v8 = 1I16; // OK.
+ static_assert(is_same<decltype(v8), const short>::value, "");
+ static_assert(v8 == 1I16, "");
+
+ // i8
+
+ static constexpr auto v9 = 1i8;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'i8', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v9 = 1i8;
+ // CHECK-MESSAGES-NEXT: ^~
+ // CHECK-MESSAGES-NEXT: {{^ *}}I8{{$}}
+ // CHECK-FIXES: static constexpr auto v9 = 1I8;
+ static_assert(is_same<decltype(v9), const char>::value, "");
+ static_assert(v9 == 1I8, "");
+
+ static constexpr auto v10 = 1I8; // OK.
+ static_assert(is_same<decltype(v10), const char>::value, "");
+ static_assert(v10 == 1I8, "");
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-integer.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-integer.cpp
new file mode 100644
index 0000000..a6f38a8
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-integer.cpp
@@ -0,0 +1,272 @@
+// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- -- -I %S
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
+// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -fix -- -I %S
+// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -warnings-as-errors='-*,readability-uppercase-literal-suffix' -- -I %S
+
+#include "readability-uppercase-literal-suffix.h"
+
+void integer_suffix() {
+ static constexpr auto v0 = __LINE__; // synthetic
+ static_assert(v0 == 9 || v0 == 5, "");
+
+ static constexpr auto v1 = __cplusplus; // synthetic, long
+
+ static constexpr auto v2 = 1; // no literal
+ static_assert(is_same<decltype(v2), const int>::value, "");
+ static_assert(v2 == 1, "");
+
+ // Unsigned
+
+ static constexpr auto v3 = 1u;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'u', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v3 = 1u;
+ // CHECK-MESSAGES-NEXT: ^~
+ // CHECK-MESSAGES-NEXT: {{^ *}}U{{$}}
+ // CHECK-FIXES: static constexpr auto v3 = 1U;
+ static_assert(is_same<decltype(v3), const unsigned int>::value, "");
+ static_assert(v3 == 1, "");
+
+ static constexpr auto v4 = 1U; // OK.
+ static_assert(is_same<decltype(v4), const unsigned int>::value, "");
+ static_assert(v4 == 1, "");
+
+ // Long
+
+ static constexpr auto v5 = 1l;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'l', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v5 = 1l;
+ // CHECK-MESSAGES-NEXT: ^~
+ // CHECK-MESSAGES-NEXT: {{^ *}}L{{$}}
+ // CHECK-FIXES: static constexpr auto v5 = 1L;
+ static_assert(is_same<decltype(v5), const long>::value, "");
+ static_assert(v5 == 1, "");
+
+ static constexpr auto v6 = 1L; // OK.
+ static_assert(is_same<decltype(v6), const long>::value, "");
+ static_assert(v6 == 1, "");
+
+ // Long Long
+
+ static constexpr auto v7 = 1ll;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'll', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v7 = 1ll;
+ // CHECK-MESSAGES-NEXT: ^~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}LL{{$}}
+ // CHECK-FIXES: static constexpr auto v7 = 1LL;
+ static_assert(is_same<decltype(v7), const long long>::value, "");
+ static_assert(v7 == 1, "");
+
+ static constexpr auto v8 = 1LL; // OK.
+ static_assert(is_same<decltype(v8), const long long>::value, "");
+ static_assert(v8 == 1, "");
+
+ // Unsigned Long
+
+ static constexpr auto v9 = 1ul;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'ul', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v9 = 1ul;
+ // CHECK-MESSAGES-NEXT: ^~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}UL{{$}}
+ // CHECK-FIXES: static constexpr auto v9 = 1UL;
+ static_assert(is_same<decltype(v9), const unsigned long>::value, "");
+ static_assert(v9 == 1, "");
+
+ static constexpr auto v10 = 1uL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'uL', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v10 = 1uL;
+ // CHECK-MESSAGES-NEXT: ^~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}UL{{$}}
+ // CHECK-FIXES: static constexpr auto v10 = 1UL;
+ static_assert(is_same<decltype(v10), const unsigned long>::value, "");
+ static_assert(v10 == 1, "");
+
+ static constexpr auto v11 = 1Ul;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'Ul', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v11 = 1Ul;
+ // CHECK-MESSAGES-NEXT: ^~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}UL{{$}}
+ // CHECK-FIXES: static constexpr auto v11 = 1UL;
+ static_assert(is_same<decltype(v11), const unsigned long>::value, "");
+ static_assert(v11 == 1, "");
+
+ static constexpr auto v12 = 1UL; // OK.
+ static_assert(is_same<decltype(v12), const unsigned long>::value, "");
+ static_assert(v12 == 1, "");
+
+ // Long Unsigned
+
+ static constexpr auto v13 = 1lu;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'lu', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v13 = 1lu;
+ // CHECK-MESSAGES-NEXT: ^~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}}
+ // CHECK-FIXES: static constexpr auto v13 = 1LU;
+ static_assert(is_same<decltype(v13), const unsigned long>::value, "");
+ static_assert(v13 == 1, "");
+
+ static constexpr auto v14 = 1Lu;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'Lu', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v14 = 1Lu;
+ // CHECK-MESSAGES-NEXT: ^~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}}
+ // CHECK-FIXES: static constexpr auto v14 = 1LU;
+ static_assert(is_same<decltype(v14), const unsigned long>::value, "");
+ static_assert(v14 == 1, "");
+
+ static constexpr auto v15 = 1lU;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'lU', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v15 = 1lU;
+ // CHECK-MESSAGES-NEXT: ^~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}}
+ // CHECK-FIXES: static constexpr auto v15 = 1LU;
+ static_assert(is_same<decltype(v15), const unsigned long>::value, "");
+ static_assert(v15 == 1, "");
+
+ static constexpr auto v16 = 1LU; // OK.
+ static_assert(is_same<decltype(v16), const unsigned long>::value, "");
+ static_assert(v16 == 1, "");
+
+ // Unsigned Long Long
+
+ static constexpr auto v17 = 1ull;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'ull', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v17 = 1ull;
+ // CHECK-MESSAGES-NEXT: ^~~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}ULL{{$}}
+ // CHECK-FIXES: static constexpr auto v17 = 1ULL;
+ static_assert(is_same<decltype(v17), const unsigned long long>::value, "");
+ static_assert(v17 == 1, "");
+
+ static constexpr auto v18 = 1uLL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'uLL', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v18 = 1uLL;
+ // CHECK-MESSAGES-NEXT: ^~~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}ULL{{$}}
+ // CHECK-FIXES: static constexpr auto v18 = 1ULL;
+ static_assert(is_same<decltype(v18), const unsigned long long>::value, "");
+ static_assert(v18 == 1, "");
+
+ static constexpr auto v19 = 1Ull;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'Ull', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v19 = 1Ull;
+ // CHECK-MESSAGES-NEXT: ^~~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}ULL{{$}}
+ // CHECK-FIXES: static constexpr auto v19 = 1ULL;
+ static_assert(is_same<decltype(v19), const unsigned long long>::value, "");
+ static_assert(v19 == 1, "");
+
+ static constexpr auto v20 = 1ULL; // OK.
+ static_assert(is_same<decltype(v20), const unsigned long long>::value, "");
+ static_assert(v20 == 1, "");
+
+ // Long Long Unsigned
+
+ static constexpr auto v21 = 1llu;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'llu', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v21 = 1llu;
+ // CHECK-MESSAGES-NEXT: ^~~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}LLU{{$}}
+ // CHECK-FIXES: static constexpr auto v21 = 1LLU;
+ static_assert(is_same<decltype(v21), const unsigned long long>::value, "");
+ static_assert(v21 == 1, "");
+
+ static constexpr auto v22 = 1LLu;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'LLu', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v22 = 1LLu;
+ // CHECK-MESSAGES-NEXT: ^~~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}LLU{{$}}
+ // CHECK-FIXES: static constexpr auto v22 = 1LLU;
+ static_assert(is_same<decltype(v22), const unsigned long long>::value, "");
+ static_assert(v22 == 1, "");
+
+ static constexpr auto v23 = 1llU;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'llU', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v23 = 1llU;
+ // CHECK-MESSAGES-NEXT: ^~~~
+ // CHECK-MESSAGES-NEXT: {{^ *}}LLU{{$}}
+ // CHECK-FIXES: static constexpr auto v23 = 1LLU;
+ static_assert(is_same<decltype(v23), const unsigned long long>::value, "");
+ static_assert(v23 == 1, "");
+
+ static constexpr auto v24 = 1LLU; // OK.
+ static_assert(is_same<decltype(v24), const unsigned long long>::value, "");
+ static_assert(v24 == 1, "");
+}
+
+void integer_complex_suffix() {
+ // _Complex, I
+
+ static constexpr auto v25 = 1i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'i', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v25 = 1i;
+ // CHECK-MESSAGES-NEXT: ^~
+ // CHECK-MESSAGES-NEXT: {{^ *}}I{{$}}
+ // CHECK-FIXES: static constexpr auto v25 = 1I;
+ static_assert(is_same<decltype(v25), const _Complex int>::value, "");
+ static_assert(v25 == 1I, "");
+
+ static constexpr auto v26 = 1I; // OK.
+ static_assert(is_same<decltype(v26), const _Complex int>::value, "");
+ static_assert(v26 == 1I, "");
+
+ // _Complex, J
+
+ static constexpr auto v27 = 1j;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'j', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto v27 = 1j;
+ // CHECK-MESSAGES-NEXT: ^~
+ // CHECK-MESSAGES-NEXT: {{^ *}}J{{$}}
+ // CHECK-FIXES: static constexpr auto v27 = 1J;
+ static_assert(is_same<decltype(v27), const _Complex int>::value, "");
+ static_assert(v27 == 1J, "");
+
+ static constexpr auto v28 = 1J; // OK.
+ static_assert(is_same<decltype(v28), const _Complex int>::value, "");
+ static_assert(v28 == 1J, "");
+}
+
+void macros() {
+#define PASSTHROUGH(X) X
+ static constexpr auto m0 = PASSTHROUGH(1u);
+ // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: integer literal has suffix 'u', which is not uppercase
+ // CHECK-MESSAGES-NEXT: static constexpr auto m0 = PASSTHROUGH(1u);
+ // CHECK-MESSAGES-NEXT: ^~
+ // CHECK-MESSAGES-NEXT: {{^ *}}U{{$}}
+ // CHECK-FIXES: static constexpr auto m0 = PASSTHROUGH(1U);
+ static_assert(is_same<decltype(m0), const unsigned int>::value, "");
+ static_assert(m0 == 1, "");
+
+ // This location is inside a macro, no warning on that by default.
+#define MACRO 1u
+ int foo = MACRO;
+}
+
+// Check that user-defined literals do not cause any diags.
+
+unsigned long long int operator"" _ull(unsigned long long int);
+void user_defined_literals() {
+ 1_ull;
+}
+
+template <unsigned alignment>
+void template_test() {
+ static_assert(alignment, "");
+}
+void actual_template_test() {
+ template_test<4>();
+}
+
+const int table[6] = {};
+void read_test() {
+ for (auto i : table) {
+ }
+}
+
+namespace {
+enum a { b };
+constexpr bool operator&(a, a) { return int(); }
+template <a l>
+void c() { l &a(); }
+void d();
+void d() { c<b>(); }
+} // namespace
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix.h b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix.h
new file mode 100644
index 0000000..680321e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix.h
@@ -0,0 +1,16 @@
+template <class T, T v>
+struct integral_constant {
+ static constexpr T value = v;
+ typedef T value_type;
+ typedef integral_constant type; // using injected-class-name
+ constexpr operator value_type() const noexcept { return value; }
+};
+
+using false_type = integral_constant<bool, false>;
+using true_type = integral_constant<bool, true>;
+
+template <class T, class U>
+struct is_same : false_type {};
+
+template <class T>
+struct is_same<T, T> : true_type {};
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/run-clang-tidy.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/run-clang-tidy.cpp
new file mode 100644
index 0000000..2207e43
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/run-clang-tidy.cpp
@@ -0,0 +1,17 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: echo "[{\"directory\":\".\",\"command\":\"clang++ -c %/t/test.cpp\",\"file\":\"%/t/test.cpp\"}]" | sed -e 's/\\/\\\\/g' > %t/compile_commands.json
+// RUN: echo "Checks: '-*,modernize-use-auto'" > %t/.clang-tidy
+// RUN: echo "WarningsAsErrors: '*'" >> %t/.clang-tidy
+// RUN: echo "CheckOptions:" >> %t/.clang-tidy
+// RUN: echo " - key: modernize-use-auto.MinTypeNameLength" >> %t/.clang-tidy
+// RUN: echo " value: '0'" >> %t/.clang-tidy
+// RUN: cp "%s" "%t/test.cpp"
+// RUN: cd "%t"
+// RUN: not %run_clang_tidy "%t/test.cpp"
+
+int main()
+{
+ int* x = new int();
+ delete x;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/select-checks.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/select-checks.cpp
new file mode 100644
index 0000000..791def7
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/select-checks.cpp
@@ -0,0 +1,11 @@
+// RUN: clang-tidy %s -checks='-*,llvm-namespace-*' -- 2>&1 | FileCheck -implicit-check-not='{{warning:|error:}}' %s
+// RUN: not clang-tidy %s -checks='-*,an-unknown-check' -- 2>&1 | FileCheck -implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK2 %s
+
+// CHECK2: Error: no checks enabled.
+
+namespace i {
+}
+// CHECK: :[[@LINE-1]]:2: warning: namespace 'i' not terminated with a closing comment [llvm-namespace-comment]
+
+// Expect no warnings from the google-explicit-constructor check:
+class A { A(int i); };
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/serialize-diagnostics.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/serialize-diagnostics.cpp
new file mode 100644
index 0000000..8b0895a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/serialize-diagnostics.cpp
@@ -0,0 +1,3 @@
+// RUN: not clang-tidy -checks=-*,llvm-namespace-comment %s -- -serialize-diagnostics %t | FileCheck %s
+// CHECK: :[[@LINE+1]]:12: error: expected ';' after struct [clang-diagnostic-error]
+struct A {}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/static-analyzer-config.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/static-analyzer-config.cpp
new file mode 100644
index 0000000..9ca87cf
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/static-analyzer-config.cpp
@@ -0,0 +1,20 @@
+// REQUIRES: static-analyzer
+// RUN: clang-tidy %s -checks='-*,clang-analyzer-unix.Malloc' -config='{CheckOptions: [{ key: "clang-analyzer-unix.Malloc:Optimistic", value: true}]}' -- | FileCheck %s
+typedef __typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+void free(void *);
+void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
+void __attribute((ownership_takes(malloc, 1))) my_free(void *);
+
+void f1() {
+ void *p = malloc(12);
+ return;
+ // CHECK: warning: Potential leak of memory pointed to by 'p' [clang-analyzer-unix.Malloc]
+}
+
+void af2() {
+ void *p = my_malloc(12);
+ my_free(p);
+ free(p);
+ // CHECK: warning: Attempt to free released memory [clang-analyzer-unix.Malloc]
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/static-analyzer.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/static-analyzer.cpp
new file mode 100644
index 0000000..af9693a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/static-analyzer.cpp
@@ -0,0 +1,18 @@
+// REQUIRES: static-analyzer
+// RUN: clang-tidy %s -checks='-*,clang-analyzer-*' -- | FileCheck %s
+extern void *malloc(unsigned long);
+extern void free(void *);
+
+void f() {
+ int *p = new int(42);
+ delete p;
+ delete p;
+ // CHECK: warning: Attempt to free released memory [clang-analyzer-cplusplus.NewDelete]
+}
+
+void g() {
+ void *q = malloc(132);
+ free(q);
+ free(q);
+ // CHECK: warning: Attempt to free released memory [clang-analyzer-unix.Malloc]
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/temporaries.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/temporaries.cpp
new file mode 100644
index 0000000..0aa60ed
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/temporaries.cpp
@@ -0,0 +1,25 @@
+// REQUIRES: static-analyzer
+// RUN: clang-tidy -checks='-*,clang-analyzer-core.NullDereference' %s -- | FileCheck %s
+
+struct NoReturnDtor {
+ ~NoReturnDtor() __attribute__((noreturn));
+};
+
+extern bool check(const NoReturnDtor &);
+
+// CHECK-NOT: warning
+void testNullPointerDereferencePositive() {
+ int *value = 0;
+ // CHECK: [[@LINE+1]]:10: warning: Dereference of null pointer (loaded from variable 'value') [clang-analyzer-core.NullDereference]
+ *value = 1;
+}
+
+// CHECK-NOT: warning
+void testNullPointerDereference() {
+ int *value = 0;
+ if (check(NoReturnDtor())) {
+ // This unreachable code causes a warning if analysis of temporary
+ // destructors is not enabled.
+ *value = 1;
+ }
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/validate-check-names.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/validate-check-names.cpp
new file mode 100644
index 0000000..35bfb09
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/validate-check-names.cpp
@@ -0,0 +1,2 @@
+// Check names may only contain alphanumeric characters, '-', '_', and '.'.
+// RUN: clang-tidy -checks=* -list-checks | grep '^ ' | cut -b5- | not grep -v '^[a-zA-Z0-9_.\-]\+$'
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/vfsoverlay.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/vfsoverlay.cpp
new file mode 100644
index 0000000..5704b71
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/vfsoverlay.cpp
@@ -0,0 +1,8 @@
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs/vfsoverlay:g" -e "s:OUT_DIR:%t:g" %S/Inputs/vfsoverlay/vfsoverlay.yaml > %t.yaml
+// RUN: clang-tidy %s -checks='-*,modernize-use-nullptr' -vfsoverlay %t.yaml -- -I %t | FileCheck %s
+// REQUIRES: shell
+
+#include "not_real.h"
+
+X *ptr = 0;
+// CHECK: warning: use nullptr [modernize-use-nullptr]
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/warnings-as-errors-diagnostics.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/warnings-as-errors-diagnostics.cpp
new file mode 100644
index 0000000..9f90b62
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/warnings-as-errors-diagnostics.cpp
@@ -0,0 +1,18 @@
+// RUN: clang-tidy %s -checks='-*,llvm-namespace-comment,clang-diagnostic*' \
+// RUN: -- -Wunused-variable 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-WARN -implicit-check-not='{{warning|error}}:'
+// RUN: not clang-tidy %s -checks='-*,llvm-namespace-comment,clang-diagnostic*' \
+// RUN: -warnings-as-errors='clang-diagnostic*' -- -Wunused-variable 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-WERR -implicit-check-not='{{warning|error}}:'
+// RUN: not clang-tidy %s -checks='-*,llvm-namespace-comment,clang-diagnostic*' \
+// RUN: -warnings-as-errors='clang-diagnostic*' -quiet -- -Wunused-variable 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-WERR-QUIET -implicit-check-not='{{warning|error}}:'
+
+void f() { int i; }
+// CHECK-WARN: warning: unused variable 'i' [clang-diagnostic-unused-variable]
+// CHECK-WERR: error: unused variable 'i' [clang-diagnostic-unused-variable,-warnings-as-errors]
+// CHECK-WERR-QUIET: error: unused variable 'i' [clang-diagnostic-unused-variable,-warnings-as-errors]
+
+// CHECK-WARN-NOT: treated as
+// CHECK-WERR: 1 warning treated as error
+// CHECK-WERR-QUIET-NOT: treated as
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/warnings-as-errors-plural.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/warnings-as-errors-plural.cpp
new file mode 100644
index 0000000..a14759d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/warnings-as-errors-plural.cpp
@@ -0,0 +1,24 @@
+// RUN: clang-tidy %s -checks='-*,llvm-namespace-comment,clang-diagnostic*' -- 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-WARN -implicit-check-not='{{warning|error}}:'
+// RUN: not clang-tidy %s -checks='-*,llvm-namespace-comment,clang-diagnostic*' \
+// RUN: -warnings-as-errors='llvm-namespace-comment' -- 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-WERR -implicit-check-not='{{warning|error}}:'
+// RUN: not clang-tidy %s -checks='-*,llvm-namespace-comment,clang-diagnostic*' \
+// RUN: -warnings-as-errors='llvm-namespace-comment' -quiet -- 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-WERR-QUIET -implicit-check-not='{{warning|error}}:'
+
+namespace j {
+}
+// CHECK-WARN: warning: namespace 'j' not terminated with a closing comment [llvm-namespace-comment]
+// CHECK-WERR: error: namespace 'j' not terminated with a closing comment [llvm-namespace-comment,-warnings-as-errors]
+// CHECK-WERR-QUIET: error: namespace 'j' not terminated with a closing comment [llvm-namespace-comment,-warnings-as-errors]
+
+namespace k {
+}
+// CHECK-WARN: warning: namespace 'k' not terminated with a closing comment [llvm-namespace-comment]
+// CHECK-WERR: error: namespace 'k' not terminated with a closing comment [llvm-namespace-comment,-warnings-as-errors]
+// CHECK-WERR-QUIET: error: namespace 'k' not terminated with a closing comment [llvm-namespace-comment,-warnings-as-errors]
+
+// CHECK-WARN-NOT: treated as
+// CHECK-WERR: 2 warnings treated as errors
+// CHECK-WERR-QUIET-NOT: treated as
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/warnings-as-errors.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/warnings-as-errors.cpp
new file mode 100644
index 0000000..44afb83
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/warnings-as-errors.cpp
@@ -0,0 +1,13 @@
+// RUN: clang-tidy %s -checks='-*,llvm-namespace-comment' -- 2>&1 | FileCheck %s --check-prefix=CHECK-WARN -implicit-check-not='{{warning|error}}:'
+// RUN: not clang-tidy %s -checks='-*,llvm-namespace-comment' -warnings-as-errors='llvm-namespace-comment' -- 2>&1 | FileCheck %s --check-prefix=CHECK-WERR -implicit-check-not='{{warning|error}}:'
+// RUN: not clang-tidy %s -checks='-*,llvm-namespace-comment' -warnings-as-errors='llvm-namespace-comment' -quiet -- 2>&1 | FileCheck %s --check-prefix=CHECK-WERR-QUIET -implicit-check-not='{{warning|error}}:'
+
+namespace i {
+}
+// CHECK-WARN: warning: namespace 'i' not terminated with a closing comment [llvm-namespace-comment]
+// CHECK-WERR: error: namespace 'i' not terminated with a closing comment [llvm-namespace-comment,-warnings-as-errors]
+// CHECK-WERR-QUIET: error: namespace 'i' not terminated with a closing comment [llvm-namespace-comment,-warnings-as-errors]
+
+// CHECK-WARN-NOT: treated as
+// CHECK-WERR: 1 warning treated as error
+// CHECK-WERR-QUIET-NOT: treated as
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/zircon-temporary-objects.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/zircon-temporary-objects.cpp
new file mode 100644
index 0000000..b29b482
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/zircon-temporary-objects.cpp
@@ -0,0 +1,109 @@
+// RUN: %check_clang_tidy %s zircon-temporary-objects %t -- \
+// RUN: -config="{CheckOptions: [{key: zircon-temporary-objects.Names, value: 'Foo;NS::Bar'}]}" \
+// RUN: -header-filter=.* \
+// RUN: -- -std=c++11
+
+// Should flag instances of Foo, NS::Bar.
+
+class Foo {
+public:
+ Foo() = default;
+ Foo(int Val) : Val(Val){};
+
+private:
+ int Val;
+};
+
+namespace NS {
+
+class Bar {
+public:
+ Bar() = default;
+ Bar(int Val) : Val(Val){};
+
+private:
+ int Val;
+};
+
+} // namespace NS
+
+class Bar {
+public:
+ Bar() = default;
+ Bar(int Val) : Val(Val){};
+
+private:
+ int Val;
+};
+
+int func(Foo F) { return 1; };
+
+int main() {
+ Foo F;
+ Foo *F2 = new Foo();
+ new Foo();
+ Foo();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: creating a temporary object of type 'Foo' is prohibited
+ Foo F3 = Foo();
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: creating a temporary object of type 'Foo' is prohibited
+
+ Bar();
+ NS::Bar();
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: creating a temporary object of type 'NS::Bar' is prohibited
+
+ int A = func(Foo());
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: creating a temporary object of type 'Foo' is prohibited
+
+ Foo F4(0);
+ Foo *F5 = new Foo(0);
+ new Foo(0);
+ Foo(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: creating a temporary object of type 'Foo' is prohibited
+ Foo F6 = Foo(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: creating a temporary object of type 'Foo' is prohibited
+
+ Bar(0);
+ NS::Bar(0);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: creating a temporary object of type 'NS::Bar' is prohibited
+
+ int B = func(Foo(0));
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: creating a temporary object of type 'Foo' is prohibited
+}
+
+namespace NS {
+
+void f() {
+ Bar();
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: creating a temporary object of type 'NS::Bar' is prohibited
+ Bar(0);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: creating a temporary object of type 'NS::Bar' is prohibited
+}
+
+} // namespace NS
+
+template <typename Ty>
+Ty make_ty() { return Ty(); }
+// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: creating a temporary object of type 'Foo' is prohibited
+// CHECK-MESSAGES: :[[@LINE-2]]:23: warning: creating a temporary object of type 'NS::Bar' is prohibited
+
+void ty_func() {
+ make_ty<Bar>();
+ make_ty<NS::Bar>();
+ make_ty<Foo>();
+}
+
+// Inheriting the disallowed class does not trigger the check.
+
+class Bingo : NS::Bar {}; // Not explicitly disallowed
+
+void f2() {
+ Bingo();
+}
+
+template <typename Ty>
+class Quux : Ty {};
+
+void f3() {
+ Quux<NS::Bar>();
+ Quux<Bar>();
+}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/Inputs/BenchmarkHeader.h b/src/llvm-project/clang-tools-extra/test/clangd/Inputs/BenchmarkHeader.h
new file mode 100644
index 0000000..3b7620a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/Inputs/BenchmarkHeader.h
@@ -0,0 +1,19 @@
+namespace clang {
+namespace clangd {
+namespace dex {
+class Dex;
+} // namespace dex
+} // namespace clangd
+} // namespace clang
+
+namespace llvm {
+namespace sys {
+
+int getHostNumPhysicalCores();
+
+} // namespace sys
+} // namespace llvm
+
+namespace {
+int Variable;
+} // namespace
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/Inputs/BenchmarkSource.cpp b/src/llvm-project/clang-tools-extra/test/clangd/Inputs/BenchmarkSource.cpp
new file mode 100644
index 0000000..1924df9
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/Inputs/BenchmarkSource.cpp
@@ -0,0 +1 @@
+#include "BenchmarkHeader.h"
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/Inputs/background-index/compile_commands.json b/src/llvm-project/clang-tools-extra/test/clangd/Inputs/background-index/compile_commands.json
new file mode 100644
index 0000000..1bb835f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/Inputs/background-index/compile_commands.json
@@ -0,0 +1,5 @@
+[{
+ "directory": "DIRECTORY",
+ "command": "clang foo.cpp",
+ "file": "DIRECTORY/foo.cpp"
+}]
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/Inputs/background-index/definition.jsonrpc b/src/llvm-project/clang-tools-extra/test/clangd/Inputs/background-index/definition.jsonrpc
new file mode 100644
index 0000000..89d5048
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/Inputs/background-index/definition.jsonrpc
@@ -0,0 +1,51 @@
+{
+ "jsonrpc": "2.0",
+ "id": 0,
+ "method": "initialize",
+ "params": {
+ "processId": 123,
+ "rootPath": "clangd",
+ "capabilities": {},
+ "trace": "off"
+ }
+}
+---
+{
+ "jsonrpc": "2.0",
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file://DIRECTORY/bar.cpp",
+ "languageId": "cpp",
+ "version": 1,
+ "text": "#include \"foo.h\"\nint main(){\nreturn foo();\n}"
+ }
+ }
+}
+---
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "sync",
+ "params": null
+}
+---
+{
+ "jsonrpc": "2.0",
+ "id": 2,
+ "method": "textDocument/definition",
+ "params": {
+ "textDocument": {
+ "uri": "file://DIRECTORY/bar.cpp"
+ },
+ "position": {
+ "line": 2,
+ "character": 8
+ }
+ }
+}
+# CHECK: "uri": "file://DIRECTORY/foo.cpp"
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/Inputs/background-index/foo.cpp b/src/llvm-project/clang-tools-extra/test/clangd/Inputs/background-index/foo.cpp
new file mode 100644
index 0000000..c42ca4d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/Inputs/background-index/foo.cpp
@@ -0,0 +1,2 @@
+#include "foo.h"
+int foo() { return 42; }
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/Inputs/background-index/foo.h b/src/llvm-project/clang-tools-extra/test/clangd/Inputs/background-index/foo.h
new file mode 100644
index 0000000..9539f1d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/Inputs/background-index/foo.h
@@ -0,0 +1,4 @@
+#ifndef FOO_H
+#define FOO_H
+int foo();
+#endif
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/Inputs/requests.json b/src/llvm-project/clang-tools-extra/test/clangd/Inputs/requests.json
new file mode 100644
index 0000000..ee91cf2
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/Inputs/requests.json
@@ -0,0 +1,7 @@
+[{"Limit":100,"ProximityPaths":["/usr/home/user/clang-tools-extra/clangd/benchmarks/IndexBenchmark.cpp"],"Query":"OMP","RestrictForCodeCompletion":true,"Scopes":["clang::"], "AnyScope":false},
+{"Limit":100,"ProximityPaths":[],"Query":"s","RestrictForCodeCompletion":true,"Scopes":["llvm::", ""], "AnyScope":false},
+{"Limit":100,"ProximityPaths":[],"Query":"sy","RestrictForCodeCompletion":true,"Scopes":["llvm::", ""], "AnyScope":false},
+{"Limit":100,"ProximityPaths":[],"Query":"sys","RestrictForCodeCompletion":true,"Scopes":["llvm::", ""], "AnyScope":false},
+{"Limit":100,"ProximityPaths":[],"Query":"sys","RestrictForCodeCompletion":true,"Scopes":["llvm::", ""], "AnyScope":false},
+{"Limit":100,"ProximityPaths":[],"Query":"Dex","RestrictForCodeCompletion":true,"Scopes":["clang::clangd::", "clang::", "clang::clangd::dex::"],"AnyScope":false},
+{"Limit":100,"ProximityPaths":[],"Query":"Variable","RestrictForCodeCompletion":true,"Scopes":[""], "AnyScope":false}]
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/Inputs/symbols.test.yaml b/src/llvm-project/clang-tools-extra/test/clangd/Inputs/symbols.test.yaml
new file mode 100644
index 0000000..40068e3
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/Inputs/symbols.test.yaml
@@ -0,0 +1,17 @@
+---
+!Symbol
+ID: 057557CEBF6E6B2D
+Name: 'vector'
+Scope: 'std::'
+SymInfo:
+ Kind: Class
+ Lang: Cpp
+CanonicalDeclaration:
+ FileURI: 'file:///vector.h'
+ Start:
+ Line: 215
+ Column: 10
+ End:
+ Line: 215
+ Column: 16
+...
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/background-index.test b/src/llvm-project/clang-tools-extra/test/clangd/background-index.test
new file mode 100644
index 0000000..1d11736
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/background-index.test
@@ -0,0 +1,20 @@
+# We need to splice paths into file:// URIs for this test.
+# UNSUPPORTED: win32
+
+# Use a copy of inputs, as we'll mutate it (as will the background index).
+# RUN: rm -rf %t
+# RUN: cp -r %S/Inputs/background-index %t
+# Need to embed the correct temp path in the actual JSON-RPC requests.
+# RUN: sed -i -e "s|DIRECTORY|%t|" %t/*
+
+# We're editing bar.cpp, which includes foo.h.
+# foo() is declared in foo.h and defined in foo.cpp.
+# The background index should allow us to go-to-definition on foo().
+# RUN: clangd -background-index -background-index-rebuild-period=0 -lit-test < %t/definition.jsonrpc | FileCheck %t/definition.jsonrpc
+
+# Test that the index is writing files in the expected location.
+# RUN: ls %t/.clangd/index/foo.cpp.*.idx
+
+# Test the index is read from disk: delete code and restart clangd.
+# RUN: rm %t/foo.cpp
+# RUN: clangd -background-index -lit-test < %t/definition.jsonrpc | FileCheck %t/definition.jsonrpc
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/compile-commands-path-in-initialize.test b/src/llvm-project/clang-tools-extra/test/clangd/compile-commands-path-in-initialize.test
new file mode 100644
index 0000000..87086e3
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/compile-commands-path-in-initialize.test
@@ -0,0 +1,28 @@
+# Test that we can set choose a configuration/build directly in the initialize
+# request.
+
+# RUN: rm -rf %t.dir/* && mkdir -p %t.dir
+# RUN: mkdir %t.dir/build-1
+# RUN: echo '[{"directory": "%/t.dir", "command": "c++ the-file.cpp", "file": "the-file.cpp"}]' > %t.dir/compile_commands.json
+# RUN: echo '[{"directory": "%/t.dir/build-1", "command": "c++ -DMACRO=1 the-file.cpp", "file": "../the-file.cpp"}]' > %t.dir/build-1/compile_commands.json
+
+# RUN: sed -e "s|INPUT_DIR|%/t.dir|g" %s > %t.test.1
+
+# On Windows, we need the URI in didOpen to look like "uri":"file:///C:/..."
+# (with the extra slash in the front), so we add it here.
+# RUN: sed -e "s|file://\([A-Z]\):/|file:///\1:/|g" %t.test.1 > %t.test
+
+# RUN: clangd -lit-test < %t.test | FileCheck -strict-whitespace %t.test
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"initializationOptions":{"compilationDatabasePath":"INPUT_DIR/build-1"}}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file://INPUT_DIR/the-file.cpp","languageId":"cpp","version":1,"text":"#if !defined(MACRO)\n#pragma message (\"MACRO is not defined\")\n#elif MACRO == 1\n#pragma message (\"MACRO is one\")\n#else\n#pragma message (\"woops\")\n#endif\nint main() {}\n"}}}
+# CHECK: "method": "textDocument/publishDiagnostics",
+# CHECK-NEXT: "params": {
+# CHECK-NEXT: "diagnostics": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "message": "MACRO is one",
+---
+{"jsonrpc":"2.0","id":10000,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/completion-auto-trigger.test b/src/llvm-project/clang-tools-extra/test/clangd/completion-auto-trigger.test
new file mode 100644
index 0000000..db3cc53
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/completion-auto-trigger.test
@@ -0,0 +1,106 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"namespace ns { int ns_member; } struct vector { int size; static int default_capacity; };\nvoid test(vector *a, vector *b) {\n if (a > b) {} \n a->size = 10;\n\n a ? a : b;\n ns::ns_member = 10;\n}"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":9},"context":{"triggerKind":2,"triggerCharacter":">"}}}
+# CHECK: "error": {
+# CHECK-NEXT: "code": -32001,
+# CHECK-NEXT: "message": "ignored auto-triggered completion, preceding char did not match"
+# CHECK-NEXT: },
+# CHECK-NEXT: "id": 1,
+---
+{"jsonrpc":"2.0","id":2,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":3,"character":5},"context":{"triggerKind":2,"triggerCharacter":">"}}}
+# CHECK: "id": 2,
+# CHECK-NEXT: "jsonrpc": "2.0"
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "isIncomplete": false,
+# CHECK-NEXT: "items": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "detail": "int",
+# CHECK-NEXT: "filterText": "size",
+# CHECK-NEXT: "insertText": "size",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 5,
+# CHECK-NEXT: "label": " size",
+# CHECK-NEXT: "sortText": "3eacccccsize",
+# CHECK-NEXT: "textEdit": {
+# CHECK-NEXT: "newText": "size",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 5,
+# CHECK-NEXT: "line": 3
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 5,
+# CHECK-NEXT: "line": 3
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "detail": "int",
+# CHECK-NEXT: "filterText": "default_capacity",
+# CHECK-NEXT: "insertText": "default_capacity",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 10,
+# CHECK-NEXT: "label": " default_capacity",
+# CHECK-NEXT: "sortText": "3fd70a3ddefault_capacity",
+# CHECK-NEXT: "textEdit": {
+# CHECK-NEXT: "newText": "default_capacity",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 5,
+# CHECK-NEXT: "line": 3
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 5,
+# CHECK-NEXT: "line": 3
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+---
+{"jsonrpc":"2.0","id":3,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":5,"character":9},"context":{"triggerKind":2,"triggerCharacter":":"}}}
+# CHECK: "error": {
+# CHECK-NEXT: "code": -32001,
+# CHECK-NEXT: "message": "ignored auto-triggered completion, preceding char did not match"
+# CHECK-NEXT: },
+# CHECK-NEXT: "id": 3,
+---
+{"jsonrpc":"2.0","id":4,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":6,"character":6},"context":{"triggerKind":2,"triggerCharacter":":"}}}
+---
+# CHECK: "id": 4,
+# CHECK-NEXT: "jsonrpc": "2.0"
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "isIncomplete": false,
+# CHECK-NEXT: "items": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "detail": "int",
+# CHECK-NEXT: "filterText": "ns_member",
+# CHECK-NEXT: "insertText": "ns_member",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 6,
+# CHECK-NEXT: "label": " ns_member",
+# CHECK-NEXT: "sortText": "3f2cccccns_member",
+# CHECK-NEXT: "textEdit": {
+# CHECK-NEXT: "newText": "ns_member",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 6,
+# CHECK-NEXT: "line": 6
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 6,
+# CHECK-NEXT: "line": 6
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+{"jsonrpc":"2.0","id":5,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/completion-snippets.test b/src/llvm-project/clang-tools-extra/test/clangd/completion-snippets.test
new file mode 100644
index 0000000..22cd082
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/completion-snippets.test
@@ -0,0 +1,56 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+# RUN: clangd -lit-test -pch-storage=memory < %s | FileCheck -strict-whitespace %s
+{
+ "jsonrpc": "2.0",
+ "id": 0,
+ "method": "initialize",
+ "params": {
+ "processId": 123,
+ "rootPath": "clangd",
+ "capabilities": {
+ "textDocument": {
+ "completion": {
+ "completionItem": {
+ "snippetSupport": true
+ }
+ }
+ }
+ },
+ "trace": "off"
+ }
+}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"int func_with_args(int a, int b);\nint main() {\nfunc_with\n}"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":7}}}
+# CHECK: "id": 1
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "isIncomplete": {{.*}}
+# CHECK-NEXT: "items": [
+# CHECK: "filterText": "func_with_args",
+# CHECK-NEXT: "insertText": "func_with_args(${1:int a}, ${2:int b})",
+# CHECK-NEXT: "insertTextFormat": 2,
+# CHECK-NEXT: "kind": 3,
+# CHECK-NEXT: "label": " func_with_args(int a, int b)",
+# CHECK-NEXT: "sortText": "{{.*}}func_with_args"
+# CHECK-NEXT: "textEdit": {
+# CHECK-NEXT: "newText": "func_with_args(${1:int a}, ${2:int b})",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 7,
+# CHECK-NEXT: "line": 2
+# CHECK-NEXT: }
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 0,
+# CHECK-NEXT: "line": 2
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+---
+{"jsonrpc":"2.0","id":4,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/completion.test b/src/llvm-project/clang-tools-extra/test/clangd/completion.test
new file mode 100644
index 0000000..0094d47
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/completion.test
@@ -0,0 +1,72 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+# RUN: clangd -lit-test -pch-storage=memory < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"struct S { int a; };\nint main() {\nS().\n}"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":4}}}
+# CHECK: "id": 1
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "isIncomplete": false,
+# CHECK-NEXT: "items": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "detail": "int",
+# CHECK-NEXT: "filterText": "a",
+# CHECK-NEXT: "insertText": "a",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 5,
+# CHECK-NEXT: "label": " a",
+# CHECK-NEXT: "sortText": "{{.*}}a"
+# CHECK-NEXT: "textEdit": {
+# CHECK-NEXT: "newText": "a",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 4,
+# CHECK-NEXT: "line": 2
+# CHECK-NEXT: }
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 4,
+# CHECK-NEXT: "line": 2
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+---
+# Update the source file and check for completions again.
+{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"test:///main.cpp","version":2},"contentChanges":[{"text":"struct S { int b; };\nint main() {\nS().\n}"}]}}
+---
+{"jsonrpc":"2.0","id":3,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":4}}}
+# CHECK: "id": 3,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "isIncomplete": false,
+# CHECK-NEXT: "items": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "detail": "int",
+# CHECK-NEXT: "filterText": "b",
+# CHECK-NEXT: "insertText": "b",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 5,
+# CHECK-NEXT: "label": " b",
+# CHECK-NEXT: "sortText": "{{.*}}b"
+# CHECK-NEXT: "textEdit": {
+# CHECK-NEXT: "newText": "b",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 4,
+# CHECK-NEXT: "line": 2
+# CHECK-NEXT: }
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 4,
+# CHECK-NEXT: "line": 2
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+---
+{"jsonrpc":"2.0","id":4,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/crash-non-added-files.test b/src/llvm-project/clang-tools-extra/test/clangd/crash-non-added-files.test
new file mode 100644
index 0000000..d86f7d2
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/crash-non-added-files.test
@@ -0,0 +1,34 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":104,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"using the result of an assignment as a condition without parentheses"},{"range":{"start": {"line": 0, "character": 34}, "end": {"line": 0, "character": 35}},"severity":3,"message":"place parentheses around the assignment to silence this warning"},{"range":{"start": {"line": 0, "character": 34}, "end": {"line": 0, "character": 35}},"severity":3,"message":"use '==' to turn this assignment into an equality comparison"}]}}}
+# CHECK: "error": {
+# CHECK-NEXT: "code": -32602
+# CHECK-NEXT: "message": "onCodeAction called for non-added file"
+# CHECK-NEXT: },
+# CHECK-NEXT: "id": 2,
+---
+{"jsonrpc":"2.0","id":3,"method":"textDocument/rangeFormatting","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":1,"character":4},"end":{"line":1,"character":12}},"options":{"tabSize":4,"insertSpaces":true}}}
+# CHECK: "error": {
+# CHECK-NEXT: "code": -32602
+# CHECK-NEXT: "message": "onDocumentRangeFormatting called for non-added file"
+# CHECK-NEXT: },
+# CHECK-NEXT: "id": 3,
+---
+{"jsonrpc":"2.0","id":4,"method":"textDocument/formatting","params":{"textDocument":{"uri":"test:///foo.c"},"options":{"tabSize":4,"insertSpaces":true}}}
+# CHECK: "error": {
+# CHECK-NEXT: "code": -32602
+# CHECK-NEXT: "message": "onDocumentFormatting called for non-added file"
+# CHECK-NEXT: },
+# CHECK-NEXT: "id": 4,
+---
+{"jsonrpc":"2.0","id":5,"method":"textDocument/onTypeFormatting","params":{"textDocument":{"uri":"test:///foo.c"},"position":{"line":3,"character":1},"ch":"}","options":{"tabSize":4,"insertSpaces":true}}}
+# CHECK: "error": {
+# CHECK-NEXT: "code": -32602
+# CHECK-NEXT: "message": "onDocumentOnTypeFormatting called for non-added file"
+# CHECK-NEXT: },
+# CHECK-NEXT: "id": 5,
+---
+{"jsonrpc":"2.0","id":6,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/delimited-input-comment-at-the-end.test b/src/llvm-project/clang-tools-extra/test/clangd/delimited-input-comment-at-the-end.test
new file mode 100644
index 0000000..34a248d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/delimited-input-comment-at-the-end.test
@@ -0,0 +1,11 @@
+# RUN: clangd -input-style=delimited -run-synchronously -input-mirror-file %t < %s
+# RUN: grep '{"jsonrpc":"2.0","id":3,"method":"exit"}' %t
+#
+# RUN: clangd -lit-test -input-mirror-file %t < %s
+# RUN: grep '{"jsonrpc":"2.0","id":3,"method":"exit"}' %t
+#
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/diagnostic-category.test b/src/llvm-project/clang-tools-extra/test/clangd/diagnostic-category.test
new file mode 100644
index 0000000..440afbb
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/diagnostic-category.test
@@ -0,0 +1,43 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{"textDocument":{"publishDiagnostics":{"categorySupport":true}}},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"struct Point {}; union Point p;"}}}
+# CHECK: "method": "textDocument/publishDiagnostics",
+# CHECK-NEXT: "params": {
+# CHECK-NEXT: "diagnostics": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "category": "Semantic Issue",
+# CHECK-NEXT: "message": "Use of 'Point' with tag type that does not match previous declaration\n\nfoo.c:1:8: note: previous use is here",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 22,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 17,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "severity": 1
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "message": "Previous use is here\n\nfoo.c:1:18: error: use of 'Point' with tag type that does not match previous declaration",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 12,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 7,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "severity": 3
+# CHECK-NEXT: }
+# CHECK-NEXT: ],
+# CHECK-NEXT: "uri": "file://{{.*}}/foo.c"
+# CHECK-NEXT: }
+---
+{"jsonrpc":"2.0","id":4,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/diagnostics.test b/src/llvm-project/clang-tools-extra/test/clangd/diagnostics.test
new file mode 100644
index 0000000..a191c08
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/diagnostics.test
@@ -0,0 +1,28 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"void main() {}"}}}
+# CHECK: "method": "textDocument/publishDiagnostics",
+# CHECK-NEXT: "params": {
+# CHECK-NEXT: "diagnostics": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "message": "Return type of 'main' is not 'int'",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 4,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 0,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "severity": 2
+# CHECK-NEXT: }
+# CHECK-NEXT: ],
+# CHECK-NEXT: "uri": "file://{{.*}}/foo.c"
+# CHECK-NEXT: }
+---
+{"jsonrpc":"2.0","id":5,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/did-change-configuration-params.test b/src/llvm-project/clang-tools-extra/test/clangd/did-change-configuration-params.test
new file mode 100644
index 0000000..51b4a87
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/did-change-configuration-params.test
@@ -0,0 +1,52 @@
+# RUN: clangd -compile_args_from=lsp -lit-test < %s 2> %t | FileCheck -strict-whitespace %s
+# RUN: cat %t | FileCheck --check-prefix=ERR %s
+# UNSUPPORTED: windows-gnu,windows-msvc
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"compilationDatabaseChanges":{"/clangd-test/foo.c": {"workingDirectory":"/clangd-test", "compilationCommand": ["clang", "-c", "foo.c"]}}}}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"int main() { int i; return i; }"}}}
+# CHECK: "method": "textDocument/publishDiagnostics",
+# CHECK-NEXT: "params": {
+# CHECK-NEXT: "diagnostics": [],
+# CHECK-NEXT: "uri": "file://{{.*}}/foo.c"
+# CHECK-NEXT: }
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///bar.c","languageId":"c","version":1,"text":"int main() { int i; return i; }"}}}
+# CHECK: "method": "textDocument/publishDiagnostics",
+# CHECK-NEXT: "params": {
+# CHECK-NEXT: "diagnostics": [],
+# CHECK-NEXT: "uri": "file://{{.*}}/bar.c"
+# CHECK-NEXT: }
+---
+{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"compilationDatabaseChanges":{"/clangd-test/foo.c": {"workingDirectory":"/clangd-test2", "compilationCommand": ["clang", "-c", "foo.c", "-Wall", "-Werror"]}}}}}
+# CHECK: "method": "textDocument/publishDiagnostics",
+# CHECK-NEXT: "params": {
+# CHECK-NEXT: "diagnostics": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "message": "Variable 'i' is uninitialized when used here",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 28,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 27,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "severity": 1
+# CHECK-NEXT: }
+# CHECK-NEXT: ],
+# CHECK-NEXT: "uri": "file://{{.*}}/foo.c"
+# CHECK-NEXT: }
+#
+# ERR: Updating file {{.*}}foo.c with command [{{.*}}clangd-test2] clang -c foo.c -Wall -Werror
+# Don't reparse the second file:
+# ERR: Skipping rebuild of the AST for {{.*}}bar.c
+---
+{"jsonrpc":"2.0","id":5,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
+
+
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/execute-command.test b/src/llvm-project/clang-tools-extra/test/clangd/execute-command.test
new file mode 100644
index 0000000..85d4b9b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/execute-command.test
@@ -0,0 +1,66 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"int main(int i, char **a) { if (i = 2) {}}"}}}
+# CHECK: "method": "textDocument/publishDiagnostics",
+# CHECK-NEXT: "params": {
+# CHECK-NEXT: "diagnostics": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "message": "Using the result of an assignment as a condition without parentheses",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 37,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 32,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "severity": 2
+# CHECK-NEXT: }
+# CHECK-NEXT: ],
+# CHECK-NEXT: "uri": "file://{{.*}}/foo.c"
+# CHECK-NEXT: }
+---
+# No command name
+{"jsonrpc":"2.0","id":3,"method":"workspace/executeCommand","params":{}}
+---
+# Invalid, non-scalar command name
+{"jsonrpc":"2.0","id":4,"method":"workspace/executeCommand","params":{"command": {}}}
+---
+{"jsonrpc":"2.0","id":5,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","custom":"foo", "arguments":[{"changes":{"test:///foo.c":[{"range":{"start":{"line":0,"character":32},"end":{"line":0,"character":32}},"newText":"("},{"range":{"start":{"line":0,"character":37},"end":{"line":0,"character":37}},"newText":")"}]}}]}}
+---
+# Arguments not a sequence.
+{"jsonrpc":"2.0","id":6,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":"foo"}}
+---
+# Unknown command.
+{"jsonrpc":"2.0","id":7,"method":"workspace/executeCommand","params":{"command":"mycommand"}}
+---
+# ApplyFix argument not a mapping node.
+{"jsonrpc":"2.0","id":8,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","custom":"foo", "arguments":[""]}}
+---
+# Custom field in WorkspaceEdit
+{"jsonrpc":"2.0","id":9,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"custom":"foo", "changes":{"test:///foo.c":[{"range":{"start":{"line":0,"character":32},"end":{"line":0,"character":32}},"newText":"("},{"range":{"start":{"line":0,"character":37},"end":{"line":0,"character":37}},"newText":")"}]}}]}}
+---
+# changes in WorkspaceEdit with no mapping node
+{"jsonrpc":"2.0","id":10,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"changes":"foo"}]}}
+---
+# Custom field in WorkspaceEditChange
+{"jsonrpc":"2.0","id":11,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"changes":{"test:///foo.c":[{"range":{"start":{"line":0,"character":32},"end":{"line":0,"character":32}},"newText":"("},{"range":{"start":{"line":0,"character":37},"end":{"line":0,"character":37}},"newText":")"}], "custom":"foo"}}]}}
+---
+# No sequence node for TextEdits
+{"jsonrpc":"2.0","id":12,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"changes":{"test:///foo.c":"bar"}}]}}
+---
+# No mapping node for TextEdit
+{"jsonrpc":"2.0","id":13,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"changes":{"test:///foo.c":[""]}}]}}
+---
+# TextEdit not decoded
+{"jsonrpc":"2.0","id":14,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"changes":{"test:///foo.c":[{"range":{"start":{"line":0,"character":32},"end":{"line":0,"character":32}},"newText":"("},{"range":"","newText":")"}]}}]}}
+---
+# Command name after arguments
+{"jsonrpc":"2.0","id":9,"method":"workspace/executeCommand","params":{"arguments":[{"custom":"foo", "changes":{"test:///foo.c":[{"range":{"start":{"line":0,"character":32},"end":{"line":0,"character":32}},"newText":"("},{"range":{"start":{"line":0,"character":37},"end":{"line":0,"character":37}},"newText":")"}]}}],"command":"clangd.applyFix"}}
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/exit-with-shutdown.test b/src/llvm-project/clang-tools-extra/test/clangd/exit-with-shutdown.test
new file mode 100644
index 0000000..99e412c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/exit-with-shutdown.test
@@ -0,0 +1,6 @@
+# RUN: clangd -lit-test < %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/exit-without-shutdown.test b/src/llvm-project/clang-tools-extra/test/clangd/exit-without-shutdown.test
new file mode 100644
index 0000000..7b22d05
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/exit-without-shutdown.test
@@ -0,0 +1,4 @@
+# RUN: not clangd -lit-test < %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/filestatus.test b/src/llvm-project/clang-tools-extra/test/clangd/filestatus.test
new file mode 100644
index 0000000..c485939
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/filestatus.test
@@ -0,0 +1,13 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"initializationOptions":{"clangdFileStatus": true},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"int x; int y = x;"}}}
+# CHECK: "method": "textDocument/clangd.fileStatus",
+# CHECK-NEXT: "params": {
+# CHECK-NEXT: "state": "parsing includes",
+# CHECK-NEXT: "uri": "{{.*}}/main.cpp"
+# CHECK-NEXT: }
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/fixits-codeaction.test b/src/llvm-project/clang-tools-extra/test/clangd/fixits-codeaction.test
new file mode 100644
index 0000000..97dd4ff
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/fixits-codeaction.test
@@ -0,0 +1,126 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{"textDocument":{"codeAction":{"codeActionLiteralSupport":{}}}},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"int main(int i, char **a) { if (i = 2) {}}"}}}
+# CHECK: "method": "textDocument/publishDiagnostics",
+# CHECK-NEXT: "params": {
+# CHECK-NEXT: "diagnostics": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "message": "Using the result of an assignment as a condition without parentheses",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 37,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 32,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "severity": 2
+# CHECK-NEXT: }
+# CHECK-NEXT: ],
+# CHECK-NEXT: "uri": "file://{{.*}}/foo.c"
+# CHECK-NEXT: }
+---
+{"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":104,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses"}]}}}
+# CHECK: "id": 2,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "diagnostics": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "message": "Using the result of an assignment as a condition without parentheses",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 37,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 32,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "severity": 2
+# CHECK-NEXT: }
+# CHECK-NEXT: ],
+# CHECK-NEXT: "edit": {
+# CHECK-NEXT: "changes": {
+# CHECK-NEXT: "file://{{.*}}/foo.c": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": "(",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 32,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 32,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": ")",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 37,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 37,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "kind": "quickfix",
+# CHECK-NEXT: "title": "place parentheses around the assignment to silence this warning"
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "diagnostics": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "message": "Using the result of an assignment as a condition without parentheses",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 37,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 32,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "severity": 2
+# CHECK-NEXT: }
+# CHECK-NEXT: ],
+# CHECK-NEXT: "edit": {
+# CHECK-NEXT: "changes": {
+# CHECK-NEXT: "file://{{.*}}/foo.c": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": "==",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 35,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 34,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "kind": "quickfix",
+# CHECK-NEXT: "title": "use '==' to turn this assignment into an equality comparison"
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+---
+{"jsonrpc":"2.0","id":4,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
+
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/fixits-command.test b/src/llvm-project/clang-tools-extra/test/clangd/fixits-command.test
new file mode 100644
index 0000000..67f70db
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/fixits-command.test
@@ -0,0 +1,210 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"int main(int i, char **a) { if (i = 2) {}}"}}}
+# CHECK: "method": "textDocument/publishDiagnostics",
+# CHECK-NEXT: "params": {
+# CHECK-NEXT: "diagnostics": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "message": "Using the result of an assignment as a condition without parentheses",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 37,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 32,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "severity": 2
+# CHECK-NEXT: }
+# CHECK-NEXT: ],
+# CHECK-NEXT: "uri": "file://{{.*}}/foo.c"
+# CHECK-NEXT: }
+---
+{"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":104,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses"}]}}}
+# CHECK: "id": 2,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "arguments": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "changes": {
+# CHECK-NEXT: "file://{{.*}}/foo.c": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": "(",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 32,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 32,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": ")",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 37,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 37,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ],
+# CHECK-NEXT: "command": "clangd.applyFix",
+# CHECK-NEXT: "title": "Apply fix: place parentheses around the assignment to silence this warning"
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "arguments": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "changes": {
+# CHECK-NEXT: "file://{{.*}}/foo.c": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": "==",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 35,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 34,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ],
+# CHECK-NEXT: "command": "clangd.applyFix",
+# CHECK-NEXT: "title": "Apply fix: use '==' to turn this assignment into an equality comparison"
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+---
+{"jsonrpc":"2.0","id":3,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":104,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses"}]}}}
+# Make sure unused "code" and "source" fields ignored gracefully
+# CHECK: "id": 3,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "arguments": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "changes": {
+# CHECK-NEXT: "file://{{.*}}/foo.c": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": "(",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 32,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 32,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": ")",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 37,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 37,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ],
+# CHECK-NEXT: "command": "clangd.applyFix",
+# CHECK-NEXT: "title": "Apply fix: place parentheses around the assignment to silence this warning"
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "arguments": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "changes": {
+# CHECK-NEXT: "file://{{.*}}/foo.c": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": "==",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 35,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 34,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ],
+# CHECK-NEXT: "command": "clangd.applyFix",
+# CHECK-NEXT: "title": "Apply fix: use '==' to turn this assignment into an equality comparison"
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+---
+{"jsonrpc":"2.0","id":4,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"changes":{"test:///foo.c":[{"range":{"start":{"line":0,"character":32},"end":{"line":0,"character":32}},"newText":"("},{"range":{"start":{"line":0,"character":37},"end":{"line":0,"character":37}},"newText":")"}]}}]}}
+# CHECK: "id": 4,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": "Fix applied."
+#
+# CHECK: "id": 0,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "method": "workspace/applyEdit",
+# CHECK-NEXT: "params": {
+# CHECK-NEXT: "edit": {
+# CHECK-NEXT: "changes": {
+# CHECK-NEXT: "{{.*}}/foo.c": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": "(",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 32,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 32,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": ")",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 37,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 37,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+---
+{"jsonrpc":"2.0","id":4,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/fixits-embed-in-diagnostic.test b/src/llvm-project/clang-tools-extra/test/clangd/fixits-embed-in-diagnostic.test
new file mode 100644
index 0000000..f1aa1cf
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/fixits-embed-in-diagnostic.test
@@ -0,0 +1,67 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{"textDocument":{"publishDiagnostics":{"codeActionsInline":true}}},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"struct Point {}; union Point p;"}}}
+# CHECK: "method": "textDocument/publishDiagnostics",
+# CHECK-NEXT: "params": {
+# CHECK-NEXT: "diagnostics": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "codeActions": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "edit": {
+# CHECK-NEXT: "changes": {
+# CHECK-NEXT: "file://{{.*}}/foo.c": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": "struct",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 22,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 17,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "kind": "quickfix",
+# CHECK-NEXT: "title": "change 'union' to 'struct'"
+# CHECK-NEXT: }
+# CHECK-NEXT: ],
+# CHECK-NEXT: "message": "Use of 'Point' with tag type that does not match previous declaration\n\nfoo.c:1:8: note: previous use is here",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 22,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 17,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "severity": 1
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "message": "Previous use is here\n\nfoo.c:1:18: error: use of 'Point' with tag type that does not match previous declaration",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 12,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 7,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "severity": 3
+# CHECK-NEXT: }
+# CHECK-NEXT: ],
+# CHECK-NEXT: "uri": "file://{{.*}}/foo.c"
+# CHECK-NEXT: }
+---
+{"jsonrpc":"2.0","id":4,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/formatting.test b/src/llvm-project/clang-tools-extra/test/clangd/formatting.test
new file mode 100644
index 0000000..9f8f3db
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/formatting.test
@@ -0,0 +1,187 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"int foo ( int x ) {\n x = x+1;\n return x;\n }"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/rangeFormatting","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":1,"character":4},"end":{"line":1,"character":12}},"options":{"tabSize":4,"insertSpaces":true}}}
+# CHECK: "id": 1,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": "\n ",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 4,
+# CHECK-NEXT: "line": 1
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 19,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": " ",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 9,
+# CHECK-NEXT: "line": 1
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 9,
+# CHECK-NEXT: "line": 1
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": " ",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 10,
+# CHECK-NEXT: "line": 1
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 10,
+# CHECK-NEXT: "line": 1
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": "\n ",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 4,
+# CHECK-NEXT: "line": 2
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 12,
+# CHECK-NEXT: "line": 1
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+---
+{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"test:///foo.c","version":5},"contentChanges":[{"text":"int foo ( int x ) {\n x = x + 1;\n return x;\n }"}]}}
+#
+#
+---
+{"jsonrpc":"2.0","id":2,"method":"textDocument/rangeFormatting","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":1,"character":2},"end":{"line":1,"character":12}},"options":{"tabSize":4,"insertSpaces":true}}}
+# CHECK: "id": 2,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": []
+---
+{"jsonrpc":"2.0","id":3,"method":"textDocument/formatting","params":{"textDocument":{"uri":"test:///foo.c"},"options":{"tabSize":4,"insertSpaces":true}}}
+# CHECK: "id": 3,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": "",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 8,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 7,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": "",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 10,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 9,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": "",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 16,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 15,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": "\n",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 4,
+# CHECK-NEXT: "line": 3
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 11,
+# CHECK-NEXT: "line": 2
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+---
+{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"test:///foo.c","version":9},"contentChanges":[{"text":"int foo(int x) {\n x = x + 1;\n return x;\n}"}]}}
+---
+{"jsonrpc":"2.0","id":4,"method":"textDocument/formatting","params":{"textDocument":{"uri":"test:///foo.c"},"options":{"tabSize":4,"insertSpaces":true}}}
+# CHECK: "id": 4,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": []
+---
+{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"test:///foo.c","version":5},"contentChanges":[{"text":"int foo ( int x ) {\n x = x + 1;\n return x;\n}"}]}}
+---
+{"jsonrpc":"2.0","id":5,"method":"textDocument/onTypeFormatting","params":{"textDocument":{"uri":"test:///foo.c"},"position":{"line":3,"character":1},"ch":"}","options":{"tabSize":4,"insertSpaces":true}}}
+# CHECK: "id": 5,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": "",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 8,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 7,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": "",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 10,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 9,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": "",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 16,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 15,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+---
+{"jsonrpc":"2.0","id":6,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/hover.test b/src/llvm-project/clang-tools-extra/test/clangd/hover.test
new file mode 100644
index 0000000..8f1ead0
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/hover.test
@@ -0,0 +1,24 @@
+# RUN: clangd -lit-test < %s | FileCheck %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"void foo(); int main() { foo(); }\n"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":0,"character":27}}}
+# CHECK: "id": 1,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "contents": {
+# CHECK-NEXT: "kind": "plaintext",
+# CHECK-NEXT: "value": "Declared in global namespace\n\nvoid foo()"
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT:}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":0,"character":10}}}
+# CHECK: "id": 1,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": null
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/index-tools.test b/src/llvm-project/clang-tools-extra/test/clangd/index-tools.test
new file mode 100644
index 0000000..93cf56f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/index-tools.test
@@ -0,0 +1,6 @@
+# RUN: clangd-indexer %p/Inputs/BenchmarkSource.cpp -- -I%p/Inputs > %t.index
+# FIXME: By default, benchmarks are excluded from the list of default targets hence not built. Find a way to depend on benchmarks to run the next command.
+# REQUIRES: shell
+# RUN: if [ -f %clangd-benchmark-dir/IndexBenchmark ]; then %clangd-benchmark-dir/IndexBenchmark %t.index %p/Inputs/requests.json --benchmark_min_time=0.01 ; fi
+# Pass invalid JSON file and check that IndexBenchmark fails to parse it.
+# RUN: if [ -f %clangd-benchmark-dir/IndexBenchmark ]; then not %clangd-benchmark-dir/IndexBenchmark %t.index %t --benchmark_min_time=0.01 ; fi
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/initialize-params-invalid.test b/src/llvm-project/clang-tools-extra/test/clangd/initialize-params-invalid.test
new file mode 100644
index 0000000..f51a727
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/initialize-params-invalid.test
@@ -0,0 +1,12 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+# Test with invalid initialize request parameters
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":"","rootUri":"test:///workspace","capabilities":{},"trace":"off"}}
+# CHECK: "id": 0,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "capabilities": {
+# ...
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/initialize-params.test b/src/llvm-project/clang-tools-extra/test/clangd/initialize-params.test
new file mode 100644
index 0000000..62f7b41
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/initialize-params.test
@@ -0,0 +1,50 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+# Test initialize request parameters with rootUri
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootUri":"test:///workspace","capabilities":{},"trace":"off"}}
+# CHECK: "id": 0,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "capabilities": {
+# CHECK-NEXT: "codeActionProvider": true,
+# CHECK-NEXT: "completionProvider": {
+# CHECK-NEXT: "resolveProvider": false,
+# CHECK-NEXT: "triggerCharacters": [
+# CHECK-NEXT: ".",
+# CHECK-NEXT: ">",
+# CHECK-NEXT: ":"
+# CHECK-NEXT: ]
+# CHECK-NEXT: },
+# CHECK-NEXT: "definitionProvider": true,
+# CHECK-NEXT: "documentFormattingProvider": true,
+# CHECK-NEXT: "documentHighlightProvider": true,
+# CHECK-NEXT: "documentOnTypeFormattingProvider": {
+# CHECK-NEXT: "firstTriggerCharacter": "}",
+# CHECK-NEXT: "moreTriggerCharacter": []
+# CHECK-NEXT: },
+# CHECK-NEXT: "documentRangeFormattingProvider": true,
+# CHECK-NEXT: "documentSymbolProvider": true,
+# CHECK-NEXT: "executeCommandProvider": {
+# CHECK-NEXT: "commands": [
+# CHECK-NEXT: "clangd.applyFix"
+# CHECK-NEXT: ]
+# CHECK-NEXT: },
+# CHECK-NEXT: "hoverProvider": true,
+# CHECK-NEXT: "referencesProvider": true,
+# CHECK-NEXT: "renameProvider": true,
+# CHECK-NEXT: "signatureHelpProvider": {
+# CHECK-NEXT: "triggerCharacters": [
+# CHECK-NEXT: "(",
+# CHECK-NEXT: ","
+# CHECK-NEXT: ]
+# CHECK-NEXT: },
+# CHECK-NEXT: "textDocumentSync": 2,
+# CHECK-NEXT: "workspaceSymbolProvider": true
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+# CHECK: "id": 3,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": null
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/initialize-sequence.test b/src/llvm-project/clang-tools-extra/test/clangd/initialize-sequence.test
new file mode 100644
index 0000000..d1b8247
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/initialize-sequence.test
@@ -0,0 +1,21 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"workspace/symbol","params":{"query":"std::basic_ostringstream"}}
+# CHECK: "error": {
+# CHECK-NEXT: "code": -32002
+# CHECK-NEXT: "message": "server not initialized"
+# CHECK-NEXT: },
+# CHECK-NEXT: "id": 0,
+---
+{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","id":2,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+# CHECK: "error": {
+# CHECK-NEXT: "code": -32600
+# CHECK-NEXT: "message": "server already initialized"
+# CHECK-NEXT: },
+# CHECK-NEXT: "id": 2,
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
+
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/input-mirror.test b/src/llvm-project/clang-tools-extra/test/clangd/input-mirror.test
new file mode 100644
index 0000000..5284562
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/input-mirror.test
@@ -0,0 +1,17 @@
+# RUN: clangd -pretty -run-synchronously -input-mirror-file %t < %s
+# Note that we have to use '-b' as -input-mirror-file does not have a newline at the end of file.
+# RUN: diff -b %t %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+Content-Length: 172
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"int main() {\nint a;\na;\n}\n"}}}
+Content-Length: 44
+
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+Content-Length: 33
+
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/lit.local.cfg b/src/llvm-project/clang-tools-extra/test/clangd/lit.local.cfg
new file mode 100644
index 0000000..ef338c7
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/lit.local.cfg
@@ -0,0 +1,6 @@
+import re
+# We rely on the default -std being derived from the filetype.
+# PS4 sets a different -std, and many tests break.
+# FIXME: make our tests less brittle instead.
+if re.match(r'.*-scei-ps4', config.target_triple):
+ config.unsupported = True
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/protocol.test b/src/llvm-project/clang-tools-extra/test/clangd/protocol.test
new file mode 100644
index 0000000..c218763
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/protocol.test
@@ -0,0 +1,110 @@
+# RUN: not clangd -pretty -run-synchronously -enable-test-uri-scheme < %s | FileCheck -strict-whitespace %s
+# RUN: not clangd -pretty -run-synchronously -enable-test-uri-scheme < %s 2>&1 | FileCheck -check-prefix=STDERR %s
+# vim: fileformat=dos
+# It is absolutely vital that this file has CRLF line endings.
+#
+# Note that we invert the test because we intent to let clangd exit prematurely.
+#
+# Test protocol parsing
+Content-Length: 125
+Content-Type: application/vscode-jsonrpc; charset-utf-8
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+# Test message with Content-Type after Content-Length
+#
+# CHECK: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": {
+# CHECK: }
+Content-Length: 246
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"struct fake { int a, bb, ccc; int f(int i, const float f) const; };\nint main() {\n fake f;\n f.\n}\n"}}}
+
+Content-Length: 104
+
+{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"test:///main.cpp"}}}
+
+Content-Type: application/vscode-jsonrpc; charset-utf-8
+Content-Length: 146
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:/main.cpp"},"position":{"line":3,"character":5}}}
+# Test message with Content-Type before Content-Length
+#
+# CHECK: "id": 1,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "isIncomplete": false,
+# CHECK-NEXT: "items": [
+# CHECK: "filterText": "a",
+# CHECK-NEXT: "insertText": "a",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 5,
+# CHECK-NEXT: "label": " a",
+# CHECK-NEXT: "sortText": "{{.*}}"
+# CHECK: ]
+# CHECK-NEXT: }
+
+X-Test: Testing
+Content-Type: application/vscode-jsonrpc; charset-utf-8
+Content-Length: 146
+Content-Type: application/vscode-jsonrpc; charset-utf-8
+X-Testing: Test
+
+{"jsonrpc":"2.0","id":2,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:/main.cpp"},"position":{"line":3,"character":5}}}
+
+Content-Type: application/vscode-jsonrpc; charset-utf-8
+Content-Length: 10
+Content-Length: 146
+
+{"jsonrpc":"2.0","id":3,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:/main.cpp"},"position":{"line":3,"character":5}}}
+# Test message with duplicate Content-Length headers
+#
+# CHECK: "id": 3,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "isIncomplete": false,
+# CHECK-NEXT: "items": [
+# CHECK: "filterText": "a",
+# CHECK-NEXT: "insertText": "a",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 5,
+# CHECK-NEXT: "label": " a",
+# CHECK-NEXT: "sortText": "{{.*}}"
+# CHECK: ]
+# CHECK-NEXT: }
+# STDERR: Warning: Duplicate Content-Length header received. The previous value for this message (10) was ignored.
+
+Content-Type: application/vscode-jsonrpc; charset-utf-8
+Content-Length: 10
+
+{"jsonrpc":"2.0","id":4,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:/main.cpp"},"position":{"line":3,"character":5}}}
+# Test message with malformed Content-Length
+#
+# STDERR: JSON parse error
+# Ensure we recover by sending another (valid) message
+
+Content-Length: 146
+
+{"jsonrpc":"2.0","id":5,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:/main.cpp"},"position":{"line":3,"character":5}}}
+# Test message with Content-Type before Content-Length
+#
+# CHECK: "id": 5,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "isIncomplete": false,
+# CHECK-NEXT: "items": [
+# CHECK: "filterText": "a",
+# CHECK-NEXT: "insertText": "a",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 5,
+# CHECK-NEXT: "label": " a",
+# CHECK-NEXT: "sortText": "{{.*}}"
+# CHECK: ]
+# CHECK-NEXT: }
+Content-Length: 1024
+
+{"jsonrpc":"2.0","id":5,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:/main.cpp"},"position":{"line":3,"character":5}}}
+# Test message which reads beyond the end of the stream.
+#
+# Ensure this is the last test in the file!
+# STDERR: Input was aborted. Read only {{[0-9]+}} bytes of expected {{[0-9]+}}.
+
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/references.test b/src/llvm-project/clang-tools-extra/test/clangd/references.test
new file mode 100644
index 0000000..964f5e7
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/references.test
@@ -0,0 +1,40 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"int x; int y = x;"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/references","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":0,"character":4}}}
+# CHECK: "id": 1
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 5,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 4,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "uri": "{{.*}}/main.cpp"
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 16,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 15,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "uri": "{{.*}}/main.cpp"
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/rename.test b/src/llvm-project/clang-tools-extra/test/clangd/rename.test
new file mode 100644
index 0000000..caf8b20
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/rename.test
@@ -0,0 +1,39 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.cpp","languageId":"cpp","version":1,"text":"int foo;"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/rename","params":{"textDocument":{"uri":"test:///foo.cpp"},"position":{"line":0,"character":5},"newName":"bar"}}
+# CHECK: "id": 1,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "changes": {
+# CHECK-NEXT: "file://{{.*}}/foo.cpp": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "newText": "bar",
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 7
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 4
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+---
+{"jsonrpc":"2.0","id":2,"method":"textDocument/rename","params":{"textDocument":{"uri":"test:///foo.cpp"},"position":{"line":0,"character":2},"newName":"bar"}}
+# CHECK: "error": {
+# CHECK-NEXT: "code": -32001,
+# CHECK-NEXT: "message": "clang diagnostic"
+# CHECK-NEXT: },
+# CHECK-NEXT: "id": 2,
+# CHECK-NEXT: "jsonrpc": "2.0"
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/signature-help.test b/src/llvm-project/clang-tools-extra/test/clangd/signature-help.test
new file mode 100644
index 0000000..37b8b50
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/signature-help.test
@@ -0,0 +1,27 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+# Start a session.
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"void x(int);\nint main(){\nx("}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/signatureHelp","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":2}}}
+# CHECK: "id": 1,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "activeParameter": 0,
+# CHECK-NEXT: "activeSignature": 0,
+# CHECK-NEXT: "signatures": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "label": "x(int) -> void",
+# CHECK-NEXT: "parameters": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "label": "int"
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+---
+{"jsonrpc":"2.0","id":100000,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/spaces-in-delimited-input.test b/src/llvm-project/clang-tools-extra/test/clangd/spaces-in-delimited-input.test
new file mode 100644
index 0000000..9636425
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/spaces-in-delimited-input.test
@@ -0,0 +1,13 @@
+# RUN: clangd -input-style=delimited -run-synchronously < %s 2>&1 | FileCheck %s
+# RUN: clangd -lit-test -run-synchronously < %s 2>&1 | FileCheck %s
+#
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+---
+
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+
+---
+
+{"jsonrpc":"2.0","method":"exit"}
+# CHECK-NOT: JSON parse error
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/symbol-info.test b/src/llvm-project/clang-tools-extra/test/clangd/symbol-info.test
new file mode 100644
index 0000000..65094a4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/symbol-info.test
@@ -0,0 +1,14 @@
+# RUN: clangd -lit-test < %s | FileCheck %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///simple.cpp","languageId":"cpp","version":1,"text":"void foo(); int main() { foo(); }\n"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/symbolInfo","params":{"textDocument":{"uri":"test:///simple.cpp"},"position":{"line":0,"character":27}}}
+# CHECK: "containerName": null,
+# CHECK-NEXT: "id": "CA2EBE44A1D76D2A",
+# CHECK-NEXT: "name": "foo",
+# CHECK-NEXT: "usr": "c:@F@foo#"
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/symbols.test b/src/llvm-project/clang-tools-extra/test/clangd/symbols.test
new file mode 100644
index 0000000..a15d702
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/symbols.test
@@ -0,0 +1,84 @@
+# RUN: clangd --index-file=%S/Inputs/symbols.test.yaml -lit-test < %s | FileCheck %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{"workspace":{"symbol":{"symbolKind":{"valueSet": [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]}}}},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"void foo(); int main() { foo(); }\n"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"workspace/symbol","params":{"query":"vector"}}
+# CHECK: "id": 1,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "containerName": "std",
+# CHECK-NEXT: "kind": 5,
+# CHECK-NEXT: "location": {
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": {{.*}},
+# CHECK-NEXT: "line": {{.*}}
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": {{.*}},
+# CHECK-NEXT: "line": {{.*}}
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "uri": "file:///vector.h"
+# CHECK-NEXT: },
+# CHECK-NEXT: "name": "vector"
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT:}
+---
+{"jsonrpc":"2.0","id":2,"method":"textDocument/documentSymbol","params":{"textDocument":{"uri":"test:///main.cpp"}}}
+# CHECK: "id": 2,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "containerName": "",
+# CHECK-NEXT: "kind": 12,
+# CHECK-NEXT: "location": {
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": {{.*}},
+# CHECK-NEXT: "line": {{.*}}
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": {{.*}},
+# CHECK-NEXT: "line": {{.*}}
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "uri": "file://{{.*}}/main.cpp"
+# CHECK-NEXT: },
+# CHECK-NEXT: "name": "foo"
+# CHECK-NEXT: }
+# CHECK-NEXT: {
+# CHECK-NEXT: "containerName": "",
+# CHECK-NEXT: "kind": 12,
+# CHECK-NEXT: "location": {
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": {{.*}},
+# CHECK-NEXT: "line": {{.*}}
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": {{.*}},
+# CHECK-NEXT: "line": {{.*}}
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "uri": "file://{{.*}}/main.cpp"
+# CHECK-NEXT: },
+# CHECK-NEXT: "name": "main"
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT:}
+---
+{"jsonrpc":"2.0","id":3,"method":"textDocument/documentSymbol","params":{"textDocument":{"uri":"test:///foo.cpp"}}}
+# CHECK: "error": {
+# CHECK-NEXT: "code": -32602,
+# CHECK-NEXT: "message": "trying to get AST for non-added document"
+# CHECK-NEXT: },
+# CHECK-NEXT: "id": 3,
+# CHECK-NEXT: "jsonrpc": "2.0"
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/test-uri-posix.test b/src/llvm-project/clang-tools-extra/test/clangd/test-uri-posix.test
new file mode 100644
index 0000000..2b67fa0
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/test-uri-posix.test
@@ -0,0 +1,11 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+# UNSUPPORTED: windows-gnu,windows-msvc
+# Test authority-less URI
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"void main() {}"}}}
+# CHECK: "uri": "file:///clangd-test/foo.c"
+---
+{"jsonrpc":"2.0","id":5,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/test-uri-windows.test b/src/llvm-project/clang-tools-extra/test/clangd/test-uri-windows.test
new file mode 100644
index 0000000..381c48f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/test-uri-windows.test
@@ -0,0 +1,11 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+# REQUIRES: windows-gnu || windows-msvc
+# Test authority-less URI
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"void main() {}"}}}
+# CHECK: "uri": "file:///C:/clangd-test/foo.c"
+---
+{"jsonrpc":"2.0","id":5,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/textdocument-didchange-fail.test b/src/llvm-project/clang-tools-extra/test/clangd/textdocument-didchange-fail.test
new file mode 100644
index 0000000..33350c4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/textdocument-didchange-fail.test
@@ -0,0 +1,39 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+# RUN: clangd -lit-test -pch-storage=memory < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"int main() {}\n"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":0,"character":6}}}
+# CHECK: "id": 1,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 8,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 4,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "uri": "file://{{.*}}/clangd-test/main.cpp"
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+---
+{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"test:///main.cpp"},"contentChanges":[{"range":{"start":{"line":100,"character":0},"end":{"line":100,"character":0}},"text": "foo"}]}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":0,"character":6}}}
+# CHECK: "error": {
+# CHECK-NEXT: "code": -32602,
+# CHECK-NEXT: "message": "trying to get AST for non-added document"
+# CHECK-NEXT: },
+# CHECK-NEXT: "id": 1,
+# CHECK-NEXT: "jsonrpc": "2.0"
+# CHECK-NEXT:}
+---
+{"jsonrpc":"2.0","id":4,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/too_large.test b/src/llvm-project/clang-tools-extra/test/clangd/too_large.test
new file mode 100644
index 0000000..7b846c3
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/too_large.test
@@ -0,0 +1,7 @@
+# RUN: not clangd -run-synchronously < %s 2>&1 | FileCheck -check-prefix=STDERR %s
+# vim: fileformat=dos
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 2147483648
+
+# STDERR: Refusing to read message
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/trace.test b/src/llvm-project/clang-tools-extra/test/clangd/trace.test
new file mode 100644
index 0000000..83b040a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/trace.test
@@ -0,0 +1,25 @@
+# RUN: env CLANGD_TRACE=%t clangd -lit-test < %s && FileCheck %s < %t
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"void main() {}"}}}
+# These assertions are a bit loose, to avoid brittleness.
+# CHECK: {"displayTimeUnit":"ns","traceEvents":[
+# CHECK: {
+# CHECK: "args": {
+# CHECK: "File": "{{.*(/|\\)}}foo.c"
+# CHECK: },
+# CHECK: "name": "BuildPreamble",
+# CHECK: "ph": "X",
+# CHECK: }
+# CHECK: {
+# CHECK: "args": {
+# CHECK: "File": "{{.*(/|\\)}}foo.c"
+# CHECK: },
+# CHECK: "name": "BuildAST",
+# CHECK: "ph": "X",
+# CHECK: }
+# CHECK: },
+---
+{"jsonrpc":"2.0","id":5,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/unsupported-method.test b/src/llvm-project/clang-tools-extra/test/clangd/unsupported-method.test
new file mode 100644
index 0000000..9cdb12c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/unsupported-method.test
@@ -0,0 +1,16 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":""}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/jumpInTheAirLikeYouJustDontCare","params":{}}
+# CHECK: "error": {
+# CHECK-NEXT: "code": -32601,
+# CHECK-NEXT: "message": "method not found"
+# CHECK-NEXT: },
+# CHECK-NEXT: "id": 1,
+# CHECK-NEXT: "jsonrpc": "2.0"
+---
+{"jsonrpc":"2.0","id":2,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/xpc/initialize.test b/src/llvm-project/clang-tools-extra/test/clangd/xpc/initialize.test
new file mode 100644
index 0000000..44bef65
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/xpc/initialize.test
@@ -0,0 +1,10 @@
+# RUN: clangd-xpc-test-client < %s | FileCheck %s
+# REQUIRES: clangd-xpc-support
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootUri":"test:///workspace","capabilities":{},"trace":"off"}}
+# CHECK: {"id":0,"jsonrpc":"2.0","result":{"capabilities"
+
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+# CHECK: {"id":3,"jsonrpc":"2.0","result":null}
+
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/clangd/xrefs.test b/src/llvm-project/clang-tools-extra/test/clangd/xrefs.test
new file mode 100644
index 0000000..58ca44c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clangd/xrefs.test
@@ -0,0 +1,59 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"int x = 0;\nint y = x;"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":1,"character":8}}}
+# CHECK: "id": 1,
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 5,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 4,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "uri": "file://{{.*}}/{{([A-Z]:/)?}}main.cpp"
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":1,"character":8}}}
+# CHECK: "id": 1
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "kind": 1,
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 5,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 4,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "kind": 2,
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 9,
+# CHECK-NEXT: "line": 1
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 8,
+# CHECK-NEXT: "line": 1
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+---
+{"jsonrpc":"2.0","id":10000,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/src/llvm-project/clang-tools-extra/test/include-fixer/Inputs/database_template.json b/src/llvm-project/clang-tools-extra/test/include-fixer/Inputs/database_template.json
new file mode 100644
index 0000000..ec71c56
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/include-fixer/Inputs/database_template.json
@@ -0,0 +1,7 @@
+[
+{
+ "directory": "test_dir/build",
+ "command": "clang++ -I../include -o bar.o test_dir/src/bar.cpp",
+ "file": "test_dir/src/bar.cpp"
+}
+]
diff --git a/src/llvm-project/clang-tools-extra/test/include-fixer/Inputs/fake_yaml_db.yaml b/src/llvm-project/clang-tools-extra/test/include-fixer/Inputs/fake_yaml_db.yaml
new file mode 100644
index 0000000..b599005
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/include-fixer/Inputs/fake_yaml_db.yaml
@@ -0,0 +1,71 @@
+---
+Name: foo
+Contexts:
+ - ContextType: Namespace
+ ContextName: a
+ - ContextType: Namespace
+ ContextName: b
+FilePath: foo.h
+Type: Class
+Seen: 1
+Used: 0
+---
+Name: foo_bar
+Contexts:
+ - ContextType: Namespace
+ ContextName: a
+ - ContextType: Namespace
+ ContextName: b
+FilePath: foobar.h
+Type: Class
+Seen: 0
+Used: 0
+---
+Name: bar
+Contexts:
+ - ContextType: Namespace
+ ContextName: a
+ - ContextType: Namespace
+ ContextName: b
+FilePath: ../include/bar.h
+Type: Class
+Seen: 1
+Used: 0
+---
+Name: bar
+Contexts:
+ - ContextType: Namespace
+ ContextName: a
+ - ContextType: Namespace
+ ContextName: b
+FilePath: ../include/bar.h
+Type: Class
+Seen: 3
+Used: 0
+---
+Name: bar
+Contexts:
+ - ContextType: Namespace
+ ContextName: a
+ - ContextType: Namespace
+ ContextName: b
+FilePath: ../include/zbar.h
+Type: Class
+Seen: 3
+Used: 0
+---
+Name: b
+Contexts:
+FilePath: var.h
+Type: Variable
+Seen: 1
+Used: 0
+---
+Name: bar
+Contexts:
+ - ContextType: Namespace
+ ContextName: c
+FilePath: test/include-fixer/baz.h
+Type: Class
+Seen: 1
+Used: 0
diff --git a/src/llvm-project/clang-tools-extra/test/include-fixer/Inputs/merge/a.yaml b/src/llvm-project/clang-tools-extra/test/include-fixer/Inputs/merge/a.yaml
new file mode 100644
index 0000000..174db0e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/include-fixer/Inputs/merge/a.yaml
@@ -0,0 +1,20 @@
+---
+Name: foo
+Contexts:
+ - ContextType: Namespace
+ ContextName: a
+FilePath: foo.h
+Type: Class
+Seen: 1
+Used: 1
+...
+---
+Name: bar
+Contexts:
+ - ContextType: Namespace
+ ContextName: a
+FilePath: ../include/bar.h
+Type: Class
+Seen: 1
+Used: 2
+...
diff --git a/src/llvm-project/clang-tools-extra/test/include-fixer/Inputs/merge/b.yaml b/src/llvm-project/clang-tools-extra/test/include-fixer/Inputs/merge/b.yaml
new file mode 100644
index 0000000..8689320
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/include-fixer/Inputs/merge/b.yaml
@@ -0,0 +1,20 @@
+---
+Name: foo
+Contexts:
+ - ContextType: Namespace
+ ContextName: a
+FilePath: foo.h
+Type: Class
+Seen: 1
+Used: 2
+...
+---
+Name: bar
+Contexts:
+ - ContextType: Namespace
+ ContextName: a
+FilePath: ../include/barbar.h
+Type: Class
+Seen: 1
+Used: 0
+...
diff --git a/src/llvm-project/clang-tools-extra/test/include-fixer/commandline_options.cpp b/src/llvm-project/clang-tools-extra/test/include-fixer/commandline_options.cpp
new file mode 100644
index 0000000..3cc77b4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/include-fixer/commandline_options.cpp
@@ -0,0 +1,15 @@
+// RUN: echo "foo f;" > %t.cpp
+// RUN: clang-include-fixer -db=fixed -input='foo= "foo.h","bar.h"' -output-headers %t.cpp -- | FileCheck %s
+// RUN: cat %t.cpp | clang-include-fixer -stdin -insert-header='{FilePath: "%/t.cpp", QuerySymbolInfos: [{RawIdentifier: foo, Range: {Offset: 0, Length: 3}}], HeaderInfos: [{Header: "\"foo.h\"", QualifiedName: "foo"}]}' %t.cpp | FileCheck %s -check-prefix=CHECK-CODE
+// RUN: cat %t.cpp | not clang-include-fixer -stdin -insert-header='{FilePath: "%/t.cpp", QuerySymbolInfos: [{RawIdentifier: foo, Range: {Offset: 0, Length: 3}}], HeaderInfos: [{Header: "\"foo.h\"", QualifiedName: "foo"},{Header: "\"foo2.h\"", QualifiedName: "foo"}]}' %t.cpp
+// RUN: cat %t.cpp | clang-include-fixer -stdin -insert-header='{FilePath: "%/t.cpp", QuerySymbolInfos: [{RawIdentifier: foo, Range: {Offset: 0, Length: 3}}], HeaderInfos: [{Header: "\"foo.h\"", QualifiedName: "a:foo"},{Header: "\"foo.h\"", QualifiedName: "b:foo"}]}' %t.cpp
+//
+// CHECK: "HeaderInfos": [
+// CHECK-NEXT: {"Header": "\"foo.h\"",
+// CHECK-NEXT: "QualifiedName": "foo"},
+// CHECK-NEXT: {"Header": "\"bar.h\"",
+// CHECK-NEXT: "QualifiedName": "foo"}
+// CHECK-NEXT:]
+//
+// CHECK-CODE: #include "foo.h"
+// CHECK-CODE: foo f;
diff --git a/src/llvm-project/clang-tools-extra/test/include-fixer/exit_on_fatal.cpp b/src/llvm-project/clang-tools-extra/test/include-fixer/exit_on_fatal.cpp
new file mode 100644
index 0000000..fc8c95a
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/include-fixer/exit_on_fatal.cpp
@@ -0,0 +1,10 @@
+// RUN: sed -e 's#//.*$##' %s > %t.cpp
+// RUN: not clang-include-fixer -db=fixed -input='foo= "foo.h"' %t.cpp --
+// RUN: FileCheck %s -input-file=%t.cpp
+
+// CHECK-NOT: #include
+// CHECK: #include "doesnotexist.h"
+// CHECK-NEXT: foo f;
+
+#include "doesnotexist.h"
+foo f;
diff --git a/src/llvm-project/clang-tools-extra/test/include-fixer/fixeddb.cpp b/src/llvm-project/clang-tools-extra/test/include-fixer/fixeddb.cpp
new file mode 100644
index 0000000..90068db
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/include-fixer/fixeddb.cpp
@@ -0,0 +1,8 @@
+// RUN: sed -e 's#//.*$##' %s > %t.cpp
+// RUN: clang-include-fixer -db=fixed -input='foo= "foo.h","bar.h"' %t.cpp --
+// RUN: FileCheck %s -input-file=%t.cpp
+
+// CHECK: #include "foo.h"
+// CHECK: foo f;
+
+foo f;
diff --git a/src/llvm-project/clang-tools-extra/test/include-fixer/include_path.cpp b/src/llvm-project/clang-tools-extra/test/include-fixer/include_path.cpp
new file mode 100644
index 0000000..28b6ace
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/include-fixer/include_path.cpp
@@ -0,0 +1,19 @@
+// RUN: mkdir -p %T/include-fixer/include
+// RUN: mkdir -p %T/include-fixer/symbols
+// RUN: mkdir -p %T/include-fixer/build
+// RUN: mkdir -p %T/include-fixer/src
+// RUN: sed 's|test_dir|%/T/include-fixer|g' %S/Inputs/database_template.json > %T/include-fixer/build/compile_commands.json
+// RUN: echo -e '#include "bar.h"\nb::a::bar f;' > %T/include-fixer/src/bar.cpp
+// RUN: echo 'namespace b { namespace a { class bar {}; } }' > %T/include-fixer/include/bar.h
+// RUN: cd %T/include-fixer/build
+// RUN: find-all-symbols -output-dir=%T/include-fixer/symbols -p=. %T/include-fixer/src/bar.cpp
+// RUN: find-all-symbols -merge-dir=%T/include-fixer/symbols %T/include-fixer/build/find_all_symbols.yaml
+// RUN: FileCheck -input-file=%T/include-fixer/build/find_all_symbols.yaml -check-prefix=CHECK-YAML %s
+//
+// RUN: echo 'b::a::bar f;' > %T/include-fixer/src/bar.cpp
+// RUN: clang-include-fixer -db=yaml -input=%T/include-fixer/build/find_all_symbols.yaml -minimize-paths=true -p=. %T/include-fixer/src/bar.cpp
+// RUN: FileCheck -input-file=%T/include-fixer/src/bar.cpp %s
+
+// CHECK-YAML: ..{{[/\\]}}include{{[/\\]}}bar.h
+// CHECK: #include "bar.h"
+// CHECK: b::a::bar f;
diff --git a/src/llvm-project/clang-tools-extra/test/include-fixer/merge.test b/src/llvm-project/clang-tools-extra/test/include-fixer/merge.test
new file mode 100644
index 0000000..230d38d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/include-fixer/merge.test
@@ -0,0 +1,33 @@
+# RUN: find-all-symbols -merge-dir=%S/Inputs/merge %t.merged
+# RUN: sed '/^#/d' %s > %t.golden
+# RUN: diff -u %t.golden %t.merged
+---
+Name: bar
+Contexts:
+ - ContextType: Namespace
+ ContextName: a
+FilePath: '../include/bar.h'
+Type: Class
+Seen: 1
+Used: 1
+...
+---
+Name: bar
+Contexts:
+ - ContextType: Namespace
+ ContextName: a
+FilePath: '../include/barbar.h'
+Type: Class
+Seen: 1
+Used: 0
+...
+---
+Name: foo
+Contexts:
+ - ContextType: Namespace
+ ContextName: a
+FilePath: foo.h
+Type: Class
+Seen: 2
+Used: 2
+...
diff --git a/src/llvm-project/clang-tools-extra/test/include-fixer/multiple_fixes.cpp b/src/llvm-project/clang-tools-extra/test/include-fixer/multiple_fixes.cpp
new file mode 100644
index 0000000..35a73b4
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/include-fixer/multiple_fixes.cpp
@@ -0,0 +1,13 @@
+// REQUIRES: shell
+// RUN: sed -e 's#//.*$##' %s > %t.cpp
+// RUN: mkdir -p %T/include-fixer/multiple-fixes
+// RUN: echo 'foo f;' > %T/include-fixer/multiple-fixes/foo.cpp
+// RUN: echo 'bar b;' > %T/include-fixer/multiple-fixes/bar.cpp
+// RUN: clang-include-fixer -db=fixed -input='foo= "foo.h";bar= "bar.h"' %T/include-fixer/multiple-fixes/*.cpp --
+// RUN: FileCheck -input-file=%T/include-fixer/multiple-fixes/bar.cpp %s -check-prefix=CHECK-BAR
+// RUN: FileCheck -input-file=%T/include-fixer/multiple-fixes/foo.cpp %s -check-prefix=CHECK-FOO
+//
+// CHECK-FOO: #include "foo.h"
+// CHECK-FOO: foo f;
+// CHECK-BAR: #include "bar.h"
+// CHECK-BAR: bar b;
diff --git a/src/llvm-project/clang-tools-extra/test/include-fixer/prefix_variable.cpp b/src/llvm-project/clang-tools-extra/test/include-fixer/prefix_variable.cpp
new file mode 100644
index 0000000..b39cdb8
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/include-fixer/prefix_variable.cpp
@@ -0,0 +1,10 @@
+// RUN: sed -e 's#//.*$##' %s > %t.cpp
+// RUN: clang-include-fixer -db=yaml -input=%p/Inputs/fake_yaml_db.yaml %t.cpp --
+// RUN: FileCheck %s -input-file=%t.cpp
+
+// CHECK-NOT: #include
+// CHECK: doesnotexist f;
+
+namespace b {
+doesnotexist f;
+}
diff --git a/src/llvm-project/clang-tools-extra/test/include-fixer/query_symbol.cpp b/src/llvm-project/clang-tools-extra/test/include-fixer/query_symbol.cpp
new file mode 100644
index 0000000..84c3a23
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/include-fixer/query_symbol.cpp
@@ -0,0 +1,13 @@
+// RUN: clang-include-fixer -db=fixed -input='foo= "foo.h","bar.h"' -query-symbol="foo" test.cpp -- | FileCheck %s
+
+// CHECK: "FilePath": "test.cpp",
+// CHECK-NEXT:"QuerySymbolInfos": [
+// CHECK-NEXT: {"RawIdentifier": "foo",
+// CHECK-NEXT: "Range":{"Offset":0,"Length":0}}
+// CHECK-NEXT:],
+// CHECK-NEXT:"HeaderInfos": [
+// CHECK-NEXT: {"Header": "\"foo.h\"",
+// CHECK-NEXT: "QualifiedName": "foo"},
+// CHECK-NEXT: {"Header": "\"bar.h\"",
+// CHECK-NEXT: "QualifiedName": "foo"}
+// CHECK-NEXT:]
diff --git a/src/llvm-project/clang-tools-extra/test/include-fixer/ranking.cpp b/src/llvm-project/clang-tools-extra/test/include-fixer/ranking.cpp
new file mode 100644
index 0000000..2dabe16
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/include-fixer/ranking.cpp
@@ -0,0 +1,13 @@
+// RUN: clang-include-fixer -db=yaml -input=%S/Inputs/fake_yaml_db.yaml -output-headers %s -- | FileCheck %s
+// RUN: clang-include-fixer -query-symbol bar -db=yaml -input=%S/Inputs/fake_yaml_db.yaml -output-headers %s -- | FileCheck %s
+
+// CHECK: "HeaderInfos": [
+// CHECK-NEXT: {"Header": "\"test/include-fixer/baz.h\"",
+// CHECK-NEXT: "QualifiedName": "c::bar"},
+// CHECK-NEXT: {"Header": "\"../include/bar.h\"",
+// CHECK-NEXT: "QualifiedName": "b::a::bar"},
+// CHECK-NEXT: {"Header": "\"../include/zbar.h\"",
+// CHECK-NEXT: "QualifiedName": "b::a::bar"}
+// CHECK-NEXT:]
+
+bar b;
diff --git a/src/llvm-project/clang-tools-extra/test/include-fixer/yaml_fuzzy.cpp b/src/llvm-project/clang-tools-extra/test/include-fixer/yaml_fuzzy.cpp
new file mode 100644
index 0000000..705542d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/include-fixer/yaml_fuzzy.cpp
@@ -0,0 +1,9 @@
+// RUN: sed -e 's#//.*$##' %s > %t.cpp
+// RUN: clang-include-fixer -db=fuzzyYaml -input=%p/Inputs/fake_yaml_db.yaml %t.cpp --
+// RUN: FileCheck %s -input-file=%t.cpp
+
+// include-fixer will add the include, but doesn't complete the symbol.
+// CHECK: #include "foobar.h"
+// CHECK: fba f;
+
+b::a::fba f;
diff --git a/src/llvm-project/clang-tools-extra/test/include-fixer/yamldb.cpp b/src/llvm-project/clang-tools-extra/test/include-fixer/yamldb.cpp
new file mode 100644
index 0000000..d17b414
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/include-fixer/yamldb.cpp
@@ -0,0 +1,8 @@
+// RUN: sed -e 's#//.*$##' %s > %t.cpp
+// RUN: clang-include-fixer -db=yaml -input=%p/Inputs/fake_yaml_db.yaml %t.cpp --
+// RUN: FileCheck %s -input-file=%t.cpp
+
+// CHECK: #include "foo.h"
+// CHECK: b::a::foo f;
+
+b::a::foo f;
diff --git a/src/llvm-project/clang-tools-extra/test/include-fixer/yamldb_autodetect.cpp b/src/llvm-project/clang-tools-extra/test/include-fixer/yamldb_autodetect.cpp
new file mode 100644
index 0000000..1997390
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/include-fixer/yamldb_autodetect.cpp
@@ -0,0 +1,11 @@
+// RUN: mkdir -p %T/foo/bar
+// RUN: cp %p/Inputs/fake_yaml_db.yaml %T/find_all_symbols_db.yaml
+// RUN: cd %T/foo
+// RUN: sed -e 's#//.*$##' %s > bar/test.cpp
+// RUN: clang-include-fixer -db=yaml bar/test.cpp --
+// RUN: FileCheck %s -input-file=bar/test.cpp
+
+// CHECK: #include "foo.h"
+// CHECK: b::a::foo f;
+
+b::a::foo f;
diff --git a/src/llvm-project/clang-tools-extra/test/lit.cfg b/src/llvm-project/clang-tools-extra/test/lit.cfg
new file mode 100644
index 0000000..7fe56f7
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/lit.cfg
@@ -0,0 +1,147 @@
+# -*- Python -*-
+
+import os
+import platform
+import re
+import subprocess
+
+import lit.formats
+import lit.util
+
+# Configuration file for the 'lit' test runner.
+
+# name: The name of this test suite.
+config.name = 'Clang Tools'
+
+# Tweak PATH for Win32
+if platform.system() == 'Windows':
+ # Seek sane tools in directories and set to $PATH.
+ path = getattr(config, 'lit_tools_dir', None)
+ path = lit_config.getToolsPath(path,
+ config.environment['PATH'],
+ ['cmp.exe', 'grep.exe', 'sed.exe'])
+ if path is not None:
+ path = os.path.pathsep.join((path,
+ config.environment['PATH']))
+ config.environment['PATH'] = path
+
+# Choose between lit's internal shell pipeline runner and a real shell. If
+# LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override.
+use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL")
+if use_lit_shell:
+ # 0 is external, "" is default, and everything else is internal.
+ execute_external = (use_lit_shell == "0")
+else:
+ # Otherwise we default to internal on Windows and external elsewhere, as
+ # bash on Windows is usually very slow.
+ execute_external = (not sys.platform in ['win32'])
+
+# testFormat: The test format to use to interpret tests.
+#
+# For now we require '&&' between commands, until they get globally killed and
+# the test runner updated.
+config.test_format = lit.formats.ShTest(execute_external)
+
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes = ['.c', '.cpp', '.hpp', '.m', '.mm', '.cu', '.ll', '.cl', '.s',
+ '.modularize', '.module-map-checker', '.test']
+
+# Test-time dependencies located in directories called 'Inputs' are excluded
+# from test suites; there won't be any lit tests within them.
+config.excludes = ['Inputs']
+
+# test_source_root: The root path where tests are located.
+config.test_source_root = os.path.dirname(__file__)
+
+# test_exec_root: The root path where tests should be run.
+config.test_exec_root = os.path.join(config.clang_tools_binary_dir, 'test')
+
+# Clear some environment variables that might affect Clang.
+#
+# This first set of vars are read by Clang, but shouldn't affect tests
+# that aren't specifically looking for these features, or are required
+# simply to run the tests at all.
+#
+# FIXME: Should we have a tool that enforces this?
+
+# safe_env_vars = ('TMPDIR', 'TEMP', 'TMP', 'USERPROFILE', 'PWD',
+# 'MACOSX_DEPLOYMENT_TARGET', 'IPHONEOS_DEPLOYMENT_TARGET',
+# 'IOS_SIMULATOR_DEPLOYMENT_TARGET',
+# 'VCINSTALLDIR', 'VC100COMNTOOLS', 'VC90COMNTOOLS',
+# 'VC80COMNTOOLS')
+possibly_dangerous_env_vars = ['COMPILER_PATH', 'RC_DEBUG_OPTIONS',
+ 'CINDEXTEST_PREAMBLE_FILE', 'LIBRARY_PATH',
+ 'CPATH', 'C_INCLUDE_PATH', 'CPLUS_INCLUDE_PATH',
+ 'OBJC_INCLUDE_PATH', 'OBJCPLUS_INCLUDE_PATH',
+ 'LIBCLANG_TIMING', 'LIBCLANG_OBJTRACKING',
+ 'LIBCLANG_LOGGING', 'LIBCLANG_BGPRIO_INDEX',
+ 'LIBCLANG_BGPRIO_EDIT', 'LIBCLANG_NOTHREADS',
+ 'LIBCLANG_RESOURCE_USAGE',
+ 'LIBCLANG_CODE_COMPLETION_LOGGING']
+# Clang/Win32 may refer to %INCLUDE%. vsvarsall.bat sets it.
+if platform.system() != 'Windows':
+ possibly_dangerous_env_vars.append('INCLUDE')
+for name in possibly_dangerous_env_vars:
+ if name in config.environment:
+ del config.environment[name]
+
+# Tweak the PATH to include the tools dir and the scripts dir.
+path = os.path.pathsep.join((
+ config.clang_tools_dir, config.llvm_tools_dir, config.environment['PATH']))
+config.environment['PATH'] = path
+
+path = os.path.pathsep.join((config.clang_libs_dir, config.llvm_libs_dir,
+ config.environment.get('LD_LIBRARY_PATH','')))
+config.environment['LD_LIBRARY_PATH'] = path
+
+# When running under valgrind, we mangle '-vg' onto the end of the triple so we
+# can check it with XFAIL and XTARGET.
+if lit_config.useValgrind:
+ config.target_triple += '-vg'
+
+# Set available features we allow tests to conditionalize on.
+#
+# As of 2011.08, crash-recovery tests still do not pass on FreeBSD.
+if platform.system() not in ['FreeBSD']:
+ config.available_features.add('crash-recovery')
+
+# Shell execution
+if execute_external:
+ config.available_features.add('shell')
+
+# Exclude MSYS due to transforming '/' to 'X:/mingwroot/'.
+if not platform.system() in ['Windows'] or not execute_external:
+ config.available_features.add('shell-preserves-root')
+
+# ANSI escape sequences in non-dumb terminal
+if platform.system() not in ['Windows']:
+ config.available_features.add('ansi-escape-sequences')
+
+# XPC support for Clangd.
+if config.clangd_xpc_support:
+ config.available_features.add('clangd-xpc-support')
+
+if config.clang_staticanalyzer:
+ config.available_features.add('static-analyzer')
+
+check_clang_tidy = os.path.join(
+ config.test_source_root, "clang-tidy", "check_clang_tidy.py")
+config.substitutions.append(
+ ('%check_clang_tidy',
+ '%s %s' % (config.python_executable, check_clang_tidy)) )
+clang_tidy_diff = os.path.join(
+ config.test_source_root, "..", "clang-tidy", "tool", "clang-tidy-diff.py")
+config.substitutions.append(
+ ('%clang_tidy_diff',
+ '%s %s' % (config.python_executable, clang_tidy_diff)) )
+run_clang_tidy = os.path.join(
+ config.test_source_root, "..", "clang-tidy", "tool", "run-clang-tidy.py")
+config.substitutions.append(
+ ('%run_clang_tidy',
+ '%s %s' % (config.python_executable, run_clang_tidy)) )
+
+clangd_benchmarks_dir = os.path.join(os.path.dirname(config.clang_tools_dir),
+ "tools", "clang", "tools", "extra",
+ "clangd", "benchmarks")
+config.substitutions.append(('%clangd-benchmark-dir',
+ '%s' % (clangd_benchmarks_dir)))
diff --git a/src/llvm-project/clang-tools-extra/test/lit.site.cfg.in b/src/llvm-project/clang-tools-extra/test/lit.site.cfg.in
new file mode 100644
index 0000000..d71ca18
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/lit.site.cfg.in
@@ -0,0 +1,31 @@
+@LIT_SITE_CFG_IN_HEADER@
+
+import sys
+
+config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
+config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
+config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
+config.clang_tools_binary_dir = "@CLANG_TOOLS_BINARY_DIR@"
+config.clang_tools_dir = "@CLANG_TOOLS_DIR@"
+config.clang_libs_dir = "@SHLIBDIR@"
+config.python_executable = "@PYTHON_EXECUTABLE@"
+config.target_triple = "@TARGET_TRIPLE@"
+config.clang_staticanalyzer = @CLANG_ENABLE_STATIC_ANALYZER@
+config.clangd_xpc_support = @CLANGD_BUILD_XPC_SUPPORT@
+
+# Support substitution of the tools and libs dirs with user parameters. This is
+# used when we can't determine the tool dir at configuration time.
+try:
+ config.clang_tools_dir = config.clang_tools_dir % lit_config.params
+ config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params
+ config.llvm_libs_dir = config.llvm_libs_dir % lit_config.params
+except KeyError:
+ e = sys.exc_info()[1]
+ key, = e.args
+ lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
+
+import lit.llvm
+lit.llvm.initialize(lit_config, config)
+
+# Let the main config do the real work.
+lit_config.load_config(config, "@CLANG_TOOLS_SOURCE_DIR@/test/lit.cfg")
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/Anonymous.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/Anonymous.h
new file mode 100644
index 0000000..8388eca
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/Anonymous.h
@@ -0,0 +1,11 @@
+// Exercise some anonymous type issues.
+
+// Anonymous enum.
+enum {
+ Tag1
+};
+
+// Anonymous enum typedef.
+typedef enum {
+ Tag2
+} AnonymousEnum;
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CompileError/HasError.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CompileError/HasError.h
new file mode 100644
index 0000000..4395cb1
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CompileError/HasError.h
@@ -0,0 +1,2 @@
+typedef WithoutDep BadType;
+
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CompileError/Level1A.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CompileError/Level1A.h
new file mode 100644
index 0000000..10eef67
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CompileError/Level1A.h
@@ -0,0 +1 @@
+#define MACRO_1A 1
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CompileError/module.modulemap b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CompileError/module.modulemap
new file mode 100644
index 0000000..fbb8e7d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CompileError/module.modulemap
@@ -0,0 +1,10 @@
+// module.map
+
+module Level1A {
+ header "Level1A.h"
+ export *
+}
+module HasError {
+ header "HasError.h"
+ export *
+}
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageNoProblems/Includes1/.hidden/DontFindMe.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageNoProblems/Includes1/.hidden/DontFindMe.h
new file mode 100644
index 0000000..f60b66c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageNoProblems/Includes1/.hidden/DontFindMe.h
@@ -0,0 +1,3 @@
+#error DontFindMe.h shouldn't be found.
+
+
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageNoProblems/Includes1/Level1A.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageNoProblems/Includes1/Level1A.h
new file mode 100644
index 0000000..10eef67
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageNoProblems/Includes1/Level1A.h
@@ -0,0 +1 @@
+#define MACRO_1A 1
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageNoProblems/Includes2/Level2A.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageNoProblems/Includes2/Level2A.h
new file mode 100644
index 0000000..9a355df
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageNoProblems/Includes2/Level2A.h
@@ -0,0 +1 @@
+#define MACRO_2A 1
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageNoProblems/NonIncludes/Level3A.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageNoProblems/NonIncludes/Level3A.h
new file mode 100644
index 0000000..594e284
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageNoProblems/NonIncludes/Level3A.h
@@ -0,0 +1 @@
+#define MACRO_3A 1
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageNoProblems/module.modulemap b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageNoProblems/module.modulemap
new file mode 100644
index 0000000..d2b0957
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageNoProblems/module.modulemap
@@ -0,0 +1,10 @@
+// module.map
+
+module Level1A {
+ header "Includes1/Level1A.h"
+ export *
+}
+module Level2A {
+ header "Includes2/Level2A.h"
+ export *
+}
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Level1A.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Level1A.h
new file mode 100644
index 0000000..165efc7
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Level1A.h
@@ -0,0 +1,2 @@
+#include "Level2A.h"
+#define MACRO_1A 1
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Level1B.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Level1B.h
new file mode 100644
index 0000000..1e60798
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Level1B.h
@@ -0,0 +1,2 @@
+#include "Level2B.h"
+#define MACRO_1B 1
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Level2A.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Level2A.h
new file mode 100644
index 0000000..9a355df
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Level2A.h
@@ -0,0 +1 @@
+#define MACRO_2A 1
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Level2B.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Level2B.h
new file mode 100644
index 0000000..25b7017
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Level2B.h
@@ -0,0 +1 @@
+#define MACRO_2B 1
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Level3A.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Level3A.h
new file mode 100644
index 0000000..1699061
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Level3A.h
@@ -0,0 +1,2 @@
+#include "Sub/Level3B.h"
+#define MACRO_3A 1
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Level3B b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Level3B
new file mode 100644
index 0000000..e1eee7e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Level3B
@@ -0,0 +1 @@
+#define MACRO_3B 1
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Sub/Level3B.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Sub/Level3B.h
new file mode 100644
index 0000000..e1eee7e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/Sub/Level3B.h
@@ -0,0 +1 @@
+#define MACRO_3B 1
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/UmbrellaFile.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/UmbrellaFile.h
new file mode 100644
index 0000000..5417a42
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/UmbrellaFile.h
@@ -0,0 +1,3 @@
+#define UMBRELLA_HEADER 1
+#include "UmbrellaInclude1.h"
+#include "UmbrellaInclude2.h"
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/UmbrellaInclude1.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/UmbrellaInclude1.h
new file mode 100644
index 0000000..adf82cb
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/UmbrellaInclude1.h
@@ -0,0 +1 @@
+#define UMBRELLA_INCLUDE_1 1
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/UmbrellaInclude2.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/UmbrellaInclude2.h
new file mode 100644
index 0000000..a3875ab
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/UmbrellaInclude2.h
@@ -0,0 +1 @@
+#define UMBRELLA_INCLUDE_2 1
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/UmbrellaSub/Umbrell1.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/UmbrellaSub/Umbrell1.h
new file mode 100644
index 0000000..719c223
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/UmbrellaSub/Umbrell1.h
@@ -0,0 +1 @@
+#define UMBRELLA_1 1
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/UmbrellaSub/Umbrell2.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/UmbrellaSub/Umbrell2.h
new file mode 100644
index 0000000..8efec99
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/UmbrellaSub/Umbrell2.h
@@ -0,0 +1 @@
+#define UMBRELLA_2 1
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/module.modulemap b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/module.modulemap
new file mode 100644
index 0000000..dbe0bb8
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/CoverageProblems/module.modulemap
@@ -0,0 +1,30 @@
+// module.map
+
+module Level1A {
+ header "Level1A.h"
+ export *
+}
+module Level1B {
+ header "Level1B.h"
+ export *
+ module Level2B {
+ header "Level2B.h"
+ export *
+ }
+}
+module Level2A {
+ header "Level2A.h"
+ export *
+}
+module UmbrellaDirectoryModule {
+ umbrella "UmbrellaSub"
+}
+module UmbrellaHeaderModule {
+ umbrella header "UmbrellaFile.h"
+}
+/*
+module NoHeader {
+ header "NoHeader.h"
+ export *
+}
+*/
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/DuplicateHeader1.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/DuplicateHeader1.h
new file mode 100644
index 0000000..2936b08
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/DuplicateHeader1.h
@@ -0,0 +1,2 @@
+// Same decl as in DuplicateHeader2.h.
+typedef int TypeInt;
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/DuplicateHeader2.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/DuplicateHeader2.h
new file mode 100644
index 0000000..cef0ffe
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/DuplicateHeader2.h
@@ -0,0 +1,2 @@
+// Same decl as in DuplicateHeader1.h.
+typedef int TypeInt;
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/Empty.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/Empty.h
new file mode 100644
index 0000000..d74d27d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/Empty.h
@@ -0,0 +1 @@
+// Empty header for testing #include directives in blocks.
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/HeaderGuard.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/HeaderGuard.h
new file mode 100644
index 0000000..64d7476
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/HeaderGuard.h
@@ -0,0 +1,6 @@
+#ifndef _HEADERGUARD_H_
+#define _HEADERGUARD_H_
+#include "HeaderGuardSub1.h"
+#include "HeaderGuardSub2.h"
+#include "HeaderGuardSubSub.h"
+#endif // _HEADERGUARD_H_
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/HeaderGuardSub1.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/HeaderGuardSub1.h
new file mode 100644
index 0000000..36ad80c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/HeaderGuardSub1.h
@@ -0,0 +1,5 @@
+#ifndef _HEADERGUARDSUB1_H_
+#define _HEADERGUARDSUB1_H_
+#include "HeaderGuardSubSub.h"
+#include "HeaderGuardSubSubDefined.h"
+#endif // _HEADERGUARDSUB1_H_
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/HeaderGuardSub2.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/HeaderGuardSub2.h
new file mode 100644
index 0000000..4098c8e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/HeaderGuardSub2.h
@@ -0,0 +1,5 @@
+#ifndef _HEADERGUARDSUB2_H_
+#define _HEADERGUARDSUB2_H_
+#include "HeaderGuardSubSub.h"
+#include "HeaderGuardSubSubDefined.h"
+#endif // _HEADERGUARDSUB2_H_
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/HeaderGuardSubSub.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/HeaderGuardSubSub.h
new file mode 100644
index 0000000..3f230d2
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/HeaderGuardSubSub.h
@@ -0,0 +1,9 @@
+#ifndef _HEADERGUARDSUBSUB_H_
+#define _HEADERGUARDSUBSUB_H_
+
+#define SOMETHING 1
+
+// Nest include. Header guard should not confuse modularize.
+#include "HeaderGuard.h"
+
+#endif // _HEADERGUARDSUBSUB_H_
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/HeaderGuardSubSubDefined.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/HeaderGuardSubSubDefined.h
new file mode 100644
index 0000000..5f0cc62
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/HeaderGuardSubSubDefined.h
@@ -0,0 +1,9 @@
+#if !defined(_HEADERGUARDSUBSUBDEFINED_H_)
+#define _HEADERGUARDSUBSUBDEFINED_H_
+
+#define SOMETHING_OTHER 1
+
+// Nest include. Header guard should not confuse modularize.
+#include "HeaderGuard.h"
+
+#endif // _HEADERGUARDSUBSUBDEFINED_H_
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/IncludeInExtern.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/IncludeInExtern.h
new file mode 100644
index 0000000..da7de8f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/IncludeInExtern.h
@@ -0,0 +1,3 @@
+extern "C" {
+ #include "Empty.h"
+}
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/IncludeInNamespace.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/IncludeInNamespace.h
new file mode 100644
index 0000000..2122528
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/IncludeInNamespace.h
@@ -0,0 +1,3 @@
+namespace MyNamespace {
+ #include "Empty.h"
+}
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/InconsistentHeader1.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/InconsistentHeader1.h
new file mode 100644
index 0000000..7dfcca9
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/InconsistentHeader1.h
@@ -0,0 +1,4 @@
+// Define symbol such that a declaration exists when this header
+// is included, but not when InconsistentHeader2.h is included.
+#define SYMBOL1 1
+#include "InconsistentSubHeader.h"
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/InconsistentHeader2.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/InconsistentHeader2.h
new file mode 100644
index 0000000..a2bcae1
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/InconsistentHeader2.h
@@ -0,0 +1,3 @@
+// Set up so the declaration in InconsistentSubHeader.h is not defined.
+#define SYMBOL2 1
+#include "InconsistentSubHeader.h"
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/InconsistentSubHeader.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/InconsistentSubHeader.h
new file mode 100644
index 0000000..f87ea65
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/InconsistentSubHeader.h
@@ -0,0 +1,18 @@
+// Set up so TypeInt only defined during InconsistentHeader1.h include.
+#ifdef SYMBOL1
+#define SYMBOL 1
+#define FUNC_STYLE(a, b) a||b
+#endif
+#ifdef SYMBOL2
+#define SYMBOL 2
+#define FUNC_STYLE(a, b) a&&b
+#endif
+
+#if SYMBOL == 1
+typedef int TypeInt;
+#endif
+
+int var = FUNC_STYLE(1, 0);
+
+#if defined(SYMBOL1)
+#endif
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/IsDependent.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/IsDependent.h
new file mode 100644
index 0000000..4928110
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/IsDependent.h
@@ -0,0 +1,4 @@
+// This header depends on SomeTypes.h for the TypeInt typedef.
+
+typedef TypeInt NewTypeInt;
+typedef OtherTypeInt OtherNewTypeInt;
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/MissingHeader/Level1A.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/MissingHeader/Level1A.h
new file mode 100644
index 0000000..10eef67
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/MissingHeader/Level1A.h
@@ -0,0 +1 @@
+#define MACRO_1A 1
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/MissingHeader/module.modulemap b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/MissingHeader/module.modulemap
new file mode 100644
index 0000000..daa06fc
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/MissingHeader/module.modulemap
@@ -0,0 +1,10 @@
+// module.map
+
+module Level1A {
+ header "Level1A.h"
+ export *
+}
+module Missing {
+ header "Missing.h"
+ export *
+}
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/NamespaceClasses.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/NamespaceClasses.h
new file mode 100644
index 0000000..57e6091
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/NamespaceClasses.h
@@ -0,0 +1,20 @@
+// Define same class name in different namespaces.
+
+namespace Namespace1 {
+ class NamespaceClass {
+ public:
+ NamespaceClass() : Member(0) {}
+ private:
+ int Member;
+ };
+}
+
+namespace Namespace2 {
+ class NamespaceClass {
+ public:
+ NamespaceClass() : Member(0) {}
+ private:
+ int Member;
+ };
+}
+
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/NestedMacro.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/NestedMacro.h
new file mode 100644
index 0000000..2cfc92c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/NestedMacro.h
@@ -0,0 +1,5 @@
+// Verification of fix for nested macro.
+
+#define FUNCMACROINNER(a) a
+#define FUNCMACROOUTER(b, c) FUNCMACROINNER(b) + FUNCMACROINNER(c)
+int FuncMacroValue = FUNCMACROOUTER(1, 2);
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/NoProblems.modulemap b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/NoProblems.modulemap
new file mode 100644
index 0000000..82029c1
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/NoProblems.modulemap
@@ -0,0 +1,9 @@
+// NoProblems.modulemap
+module SomeTypes {
+ header "SomeTypes.h"
+ export *
+}
+module SomeDecls {
+ header "SomeDecls.h"
+ export *
+}
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/ProblemsDuplicate.modulemap b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/ProblemsDuplicate.modulemap
new file mode 100644
index 0000000..ff1d2f5
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/ProblemsDuplicate.modulemap
@@ -0,0 +1,9 @@
+// ProblemsDuplicate.modulemap
+module DuplicateHeader1 {
+ header "DuplicateHeader1.h"
+ export *
+}
+module DuplicateHeader2 {
+ header "DuplicateHeader2.h"
+ export *
+}
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SomeDecls.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SomeDecls.h
new file mode 100644
index 0000000..8892b65
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SomeDecls.h
@@ -0,0 +1,16 @@
+// Declare a couple of functions - no modules problems.
+
+void FuncOne();
+
+int FuncTwo(int arg);
+
+void FuncOverload(int arg) {}
+void FuncOverload(char *arg) {}
+
+namespace Namespace1 {
+ void FuncNameSpace() {}
+}
+
+namespace Namespace2 {
+ void FuncNameSpace() {}
+}
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SomeOtherTypes.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SomeOtherTypes.h
new file mode 100644
index 0000000..288faff
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SomeOtherTypes.h
@@ -0,0 +1,4 @@
+// Declare another type for the dependency check.
+// This file dependent on SomeTypes.h being included first.
+
+typedef TypeInt OtherTypeInt;
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SomeTypes.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SomeTypes.h
new file mode 100644
index 0000000..46c4316
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SomeTypes.h
@@ -0,0 +1,16 @@
+// Define a few different kinds of types - no modules problems.
+
+typedef int TypeInt;
+
+typedef TypeInt NestedTypeInt;
+
+struct TypeStruct {
+ int Member;
+};
+
+class TypeClass {
+public:
+ TypeClass() : Member(0) {}
+private:
+ int Member;
+};
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SubModule1/Header1.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SubModule1/Header1.h
new file mode 100644
index 0000000..ea89f0f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SubModule1/Header1.h
@@ -0,0 +1 @@
+// Header1.h - Empty.
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SubModule1/Header2.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SubModule1/Header2.h
new file mode 100644
index 0000000..7c71e98
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SubModule1/Header2.h
@@ -0,0 +1 @@
+// Header2.h - Empty.
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SubModule2/Header3.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SubModule2/Header3.h
new file mode 100644
index 0000000..bb56afa
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SubModule2/Header3.h
@@ -0,0 +1 @@
+// Header3.h - Empty.
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SubModule2/Header4.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SubModule2/Header4.h
new file mode 100644
index 0000000..07ec951
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/SubModule2/Header4.h
@@ -0,0 +1 @@
+// Header4.h - Empty.
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/Inputs/TemplateClasses.h b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/TemplateClasses.h
new file mode 100644
index 0000000..3eab6d9
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/Inputs/TemplateClasses.h
@@ -0,0 +1,15 @@
+// Exercise some template issues. Should not produce errors.
+
+// Forward declaration.
+template<class T> class TemplateClass;
+
+// Full declaration.
+template<class T>class TemplateClass {
+public:
+ TemplateClass() {}
+private:
+ T Member;
+};
+
+// Template alias.
+template<class T> using TemplateClassAlias = TemplateClass<T>;
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/NoProblems.modularize b/src/llvm-project/clang-tools-extra/test/modularize/NoProblems.modularize
new file mode 100644
index 0000000..b3cc36b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/NoProblems.modularize
@@ -0,0 +1,6 @@
+# RUN: modularize %s -x c++
+# RUN: modularize -prefix=%p %s -x c++
+# RUN: modularize -no-coverage-check %S/Inputs/NoProblems.modulemap -x c++
+
+Inputs/SomeTypes.h
+Inputs/SomeDecls.h
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsAnonymous.modularize b/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsAnonymous.modularize
new file mode 100644
index 0000000..20b1898
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsAnonymous.modularize
@@ -0,0 +1,3 @@
+# RUN: modularize %s -x c++
+
+Inputs/Anonymous.h
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsAssistant.modularize b/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsAssistant.modularize
new file mode 100644
index 0000000..7ddc726
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsAssistant.modularize
@@ -0,0 +1,50 @@
+# RUN: modularize -module-map-path=Output/NoProblemsAssistant.txt -root-module=Root -prefix=%S/Input %s
+# RUN: FileCheck --input-file=%T/NoProblemsAssistant.txt %s
+
+SomeTypes.h
+SomeDecls.h
+SubModule1/Header1.h
+SubModule1/Header2.h
+SubModule2/Header3.h
+SubModule2/Header4.h
+SubModule2/Header5-dash.dot.h
+SubModule2.h
+
+# CHECK: // Output/NoProblemsAssistant.txt
+# CHECK-NEXT: // Generated by: modularize -module-map-path=Output/NoProblemsAssistant.txt -root-module=Root -prefix={{.*}}{{[/\\]}}{{.*}} {{.*}}{{[/\\]}}NoProblemsAssistant.modularize
+# CHECK: module Root {
+# CHECK-NEXT: module SomeTypes {
+# CHECK-NEXT: header "SomeTypes.h"
+# CHECK-NEXT: export *
+# CHECK-NEXT: }
+# CHECK-NEXT: module SomeDecls {
+# CHECK-NEXT: header "SomeDecls.h"
+# CHECK-NEXT: export *
+# CHECK-NEXT: }
+# CHECK-NEXT: module SubModule1 {
+# CHECK-NEXT: module Header1 {
+# CHECK-NEXT: header "SubModule1/Header1.h"
+# CHECK-NEXT: export *
+# CHECK-NEXT: }
+# CHECK-NEXT: module Header2 {
+# CHECK-NEXT: header "SubModule1/Header2.h"
+# CHECK-NEXT: export *
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: module SubModule2 {
+# CHECK-NEXT: module Header3 {
+# CHECK-NEXT: header "SubModule2/Header3.h"
+# CHECK-NEXT: export *
+# CHECK-NEXT: }
+# CHECK-NEXT: module Header4 {
+# CHECK-NEXT: header "SubModule2/Header4.h"
+# CHECK-NEXT: export *
+# CHECK-NEXT: }
+# CHECK-NEXT: module Header5_dash_dot {
+# CHECK-NEXT: header "SubModule2/Header5-dash.dot.h"
+# CHECK-NEXT: export *
+# CHECK-NEXT: }
+# CHECK-NEXT: header "SubModule2.h"
+# CHECK-NEXT: export *
+# CHECK-NEXT: }
+# CHECK-NEXT: }
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsCoverage.modularize b/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsCoverage.modularize
new file mode 100644
index 0000000..bcb06f8
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsCoverage.modularize
@@ -0,0 +1 @@
+# RUN: modularize -I Includes1 -I Includes2 %S/Inputs/CoverageNoProblems/module.modulemap
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsDependencies.modularize b/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsDependencies.modularize
new file mode 100644
index 0000000..bd5292b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsDependencies.modularize
@@ -0,0 +1,3 @@
+# RUN: modularize %s -x c++
+
+Inputs/IsDependent.h: Inputs/SomeTypes.h Inputs/SomeOtherTypes.h
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsGuard.modularize b/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsGuard.modularize
new file mode 100644
index 0000000..a5a80f0
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsGuard.modularize
@@ -0,0 +1,5 @@
+# RUN: modularize %s -x c++
+
+Inputs/HeaderGuardSub1.h
+Inputs/HeaderGuardSub2.h
+Inputs/HeaderGuard.h
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsList.modularize b/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsList.modularize
new file mode 100644
index 0000000..39261ce
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsList.modularize
@@ -0,0 +1,2 @@
+# RUN: modularize %S/NoProblems.modularize,%S/NoProblemsAnonymous.modularize -x c++
+# RUN: modularize -prefix=%p %S/NoProblems.modularize,%S/NoProblemsAnonymous.modularize -x c++
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsNamespace.modularize b/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsNamespace.modularize
new file mode 100644
index 0000000..93a4fea
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsNamespace.modularize
@@ -0,0 +1,3 @@
+# RUN: modularize -block-check-header-list-only %s
+
+Inputs/IncludeInNamespace.h
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsNamespaceClasses.modularize b/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsNamespaceClasses.modularize
new file mode 100644
index 0000000..1d02c78
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsNamespaceClasses.modularize
@@ -0,0 +1,3 @@
+# RUN: modularize %s -x c++
+
+Inputs/NamespaceClasses.h
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsNestedMacro.modularize b/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsNestedMacro.modularize
new file mode 100644
index 0000000..a1c627d
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsNestedMacro.modularize
@@ -0,0 +1,3 @@
+# RUN: modularize %s -x c++
+
+Inputs/NestedMacro.h
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsTemplateClasses.modularize b/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsTemplateClasses.modularize
new file mode 100644
index 0000000..d41c43c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/NoProblemsTemplateClasses.modularize
@@ -0,0 +1,3 @@
+# RUN: modularize %s -x c++
+
+Inputs/TemplateClasses.h
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/ProblemsCompileError.modularize b/src/llvm-project/clang-tools-extra/test/modularize/ProblemsCompileError.modularize
new file mode 100644
index 0000000..a7ad298
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/ProblemsCompileError.modularize
@@ -0,0 +1,3 @@
+# RUN: not modularize %S/Inputs/CompileError/module.modulemap 2>&1 | FileCheck %s
+
+# CHECK: {{.*}}{{[/\\]}}Inputs{{[/\\]}}CompileError{{[/\\]}}HasError.h:1:9: error: unknown type name 'WithoutDep'
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/ProblemsCoverage.modularize b/src/llvm-project/clang-tools-extra/test/modularize/ProblemsCoverage.modularize
new file mode 100644
index 0000000..5a1c348
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/ProblemsCoverage.modularize
@@ -0,0 +1,5 @@
+# RUN: not modularize %S/Inputs/CoverageProblems/module.modulemap 2>&1 | FileCheck %s
+
+# CHECK: warning: {{.*}}{{[/\\]}}Inputs/CoverageProblems/module.modulemap does not account for file: {{.*}}{{[/\\]}}Inputs/CoverageProblems/Level3A.h
+# CHECK-NEXT: warning: {{.*}}{{[/\\]}}Inputs/CoverageProblems/module.modulemap does not account for file: {{.*}}{{[/\\]}}Inputs/CoverageProblems/Level3B
+# CHECK-NEXT: warning: {{.*}}{{[/\\]}}Inputs/CoverageProblems/module.modulemap does not account for file: {{.*}}{{[/\\]}}Inputs/CoverageProblems/Sub/Level3B.h
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/ProblemsDisplayLists.modularize b/src/llvm-project/clang-tools-extra/test/modularize/ProblemsDisplayLists.modularize
new file mode 100644
index 0000000..31be95c
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/ProblemsDisplayLists.modularize
@@ -0,0 +1,16 @@
+# RUN: not modularize -display-file-lists %S/Inputs/CompileError/module.modulemap 2>&1 | FileCheck %s
+
+# CHECK: {{.*}}{{[/\\]}}Inputs{{[/\\]}}CompileError{{[/\\]}}HasError.h:1:9: error: unknown type name 'WithoutDep'
+
+# CHECK: These are the files with possible errors:
+
+# CHECK: Inputs/CompileError/HasError.h
+
+# CHECK: These are the files with no detected errors:
+
+# CHECK: Inputs/CompileError/Level1A.h
+
+# CHECK: These are the combined files, with problem files preceded by #:
+
+# CHECK: {{.*}}Inputs/CompileError/HasError.h
+# CHECK: Inputs/CompileError/Level1A.h
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/ProblemsDuplicate.modularize b/src/llvm-project/clang-tools-extra/test/modularize/ProblemsDuplicate.modularize
new file mode 100644
index 0000000..301c9cc
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/ProblemsDuplicate.modularize
@@ -0,0 +1,9 @@
+# RUN: not modularize %s -x c++ 2>&1 | FileCheck %s
+# RUN: not modularize %S/Inputs/ProblemsDuplicate.modulemap -x c++ 2>&1 | FileCheck %s
+
+Inputs/DuplicateHeader1.h
+Inputs/DuplicateHeader2.h
+
+# CHECK: error: value 'TypeInt' defined at multiple locations:
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}DuplicateHeader1.h:2:13
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}DuplicateHeader2.h:2:13
\ No newline at end of file
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/ProblemsExternC.modularize b/src/llvm-project/clang-tools-extra/test/modularize/ProblemsExternC.modularize
new file mode 100644
index 0000000..b91d7e5
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/ProblemsExternC.modularize
@@ -0,0 +1,12 @@
+# RUN: not modularize %s -x c++ 2>&1 | FileCheck %s
+
+Inputs/IncludeInExtern.h
+
+# CHECK: {{.*}}{{[/\\]}}Inputs{{[/\\]}}IncludeInExtern.h:2:3:
+# CHECK-NEXT: #include "Empty.h"
+# CHECK-NEXT: ^
+# CHECK-NEXT: error: Include directive within extern "C" {}.
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}IncludeInExtern.h:1:1:
+# CHECK-NEXT: extern "C" {
+# CHECK-NEXT: ^
+# CHECK-NEXT: The "extern "C" {}" block is here.
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/ProblemsInconsistent.modularize b/src/llvm-project/clang-tools-extra/test/modularize/ProblemsInconsistent.modularize
new file mode 100644
index 0000000..04d0b01
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/ProblemsInconsistent.modularize
@@ -0,0 +1,108 @@
+# RUN: not modularize %s -x c++ 2>&1 | FileCheck %s
+
+Inputs/InconsistentHeader1.h
+Inputs/InconsistentHeader2.h
+
+# CHECK: error: macro 'SYMBOL' defined at multiple locations:
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:3:9
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:7:9
+# CHECK-NEXT: error: macro 'FUNC_STYLE' defined at multiple locations:
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:4:9
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:8:9
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:15:11:
+# CHECK-NEXT: int var = FUNC_STYLE(1, 0);
+# CHECK-NEXT: ^
+# CHECK-NEXT: error: Macro instance 'FUNC_STYLE(1, 0);' has different values in this header, depending on how it was included.
+# CHECK-NEXT: 'FUNC_STYLE(1, 0);' expanded to: '1||0' with respect to these inclusion paths:
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader1.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:4:9:
+# CHECK-NEXT: #define FUNC_STYLE(a, b) a||b
+# CHECK-NEXT: ^
+# CHECK-NEXT: Macro defined here.
+# CHECK-NEXT: 'FUNC_STYLE(1, 0);' expanded to: '1&&0' with respect to these inclusion paths:
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader2.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:8:9:
+# CHECK-NEXT: #define FUNC_STYLE(a, b) a&&b
+# CHECK-NEXT: ^
+# CHECK-NEXT: Macro defined here.
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:11:5:
+# CHECK-NEXT: #if SYMBOL == 1
+# CHECK-NEXT: ^
+# CHECK-NEXT: error: Macro instance 'SYMBOL' has different values in this header, depending on how it was included.
+# CHECK-NEXT: 'SYMBOL' expanded to: '1' with respect to these inclusion paths:
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader1.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:3:9:
+# CHECK-NEXT: #define SYMBOL 1
+# CHECK-NEXT: ^
+# CHECK-NEXT: Macro defined here.
+# CHECK-NEXT: 'SYMBOL' expanded to: '2' with respect to these inclusion paths:
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader2.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:7:9:
+# CHECK-NEXT: #define SYMBOL 2
+# CHECK-NEXT: ^
+# CHECK-NEXT: Macro defined here.
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:17:5:
+# CHECK-NEXT: #if defined(SYMBOL1)
+# CHECK-NEXT: ^
+# CHECK-NEXT: error: Macro instance 'defined(SYMBOL1)' has different values in this header, depending on how it was included.
+# CHECK-NEXT: 'defined(SYMBOL1)' expanded to: 'true' with respect to these inclusion paths:
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader1.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader1.h:3:9:
+# CHECK-NEXT: #define SYMBOL1 1
+# CHECK-NEXT: ^
+# CHECK-NEXT: Macro defined here.
+# CHECK-NEXT: 'defined(SYMBOL1)' expanded to: 'false' with respect to these inclusion paths:
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader2.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h
+# CHECK-NEXT: (no macro definition)
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:11:2
+# CHECK-NEXT: #if SYMBOL == 1
+# CHECK-NEXT: ^
+# CHECK-NEXT: error: Conditional expression instance 'SYMBOL == 1' has different values in this header, depending on how it was included.
+# CHECK-NEXT: 'SYMBOL == 1' expanded to: 'true' with respect to these inclusion paths:
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader1.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h
+# CHECK-NEXT: 'SYMBOL == 1' expanded to: 'false' with respect to these inclusion paths:
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader2.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:2:2
+# CHECK-NEXT: #ifdef SYMBOL1
+# CHECK-NEXT: ^
+# CHECK-NEXT: error: Conditional expression instance 'SYMBOL1' has different values in this header, depending on how it was included.
+# CHECK-NEXT: 'SYMBOL1' expanded to: 'true' with respect to these inclusion paths:
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader1.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h
+# CHECK-NEXT: 'SYMBOL1' expanded to: 'false' with respect to these inclusion paths:
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader2.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:6:2
+# CHECK-NEXT: #ifdef SYMBOL2
+# CHECK-NEXT: ^
+# CHECK-NEXT: error: Conditional expression instance 'SYMBOL2' has different values in this header, depending on how it was included.
+# CHECK-NEXT: 'SYMBOL2' expanded to: 'false' with respect to these inclusion paths:
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader1.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h
+# CHECK-NEXT: 'SYMBOL2' expanded to: 'true' with respect to these inclusion paths:
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader2.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:17:2
+# CHECK-NEXT: #if defined(SYMBOL1)
+# CHECK-NEXT: ^
+# CHECK-NEXT: error: Conditional expression instance 'defined(SYMBOL1)' has different values in this header, depending on how it was included.
+# CHECK-NEXT: 'defined(SYMBOL1)' expanded to: 'true' with respect to these inclusion paths:
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader1.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h
+# CHECK-NEXT: 'defined(SYMBOL1)' expanded to: 'false' with respect to these inclusion paths:
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader2.h
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h
+# CHECK-NEXT: error: header '{{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h' has different contents depending on how it was included.
+# CHECK-NEXT: note: 'SYMBOL' in {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h at 3:9 not always provided
+# CHECK-NEXT: note: 'FUNC_STYLE' in {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h at 4:9 not always provided
+# CHECK-NEXT: note: 'SYMBOL' in {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h at 7:9 not always provided
+# CHECK-NEXT: note: 'FUNC_STYLE' in {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h at 8:9 not always provided
+# CHECK-NEXT: note: 'TypeInt' in {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h at 12:13 not always provided
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/ProblemsMissingHeader.modularize b/src/llvm-project/clang-tools-extra/test/modularize/ProblemsMissingHeader.modularize
new file mode 100644
index 0000000..bc731fb
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/ProblemsMissingHeader.modularize
@@ -0,0 +1,3 @@
+# RUN: not modularize %S/Inputs/MissingHeader/module.modulemap 2>&1 | FileCheck %s
+
+# CHECK: {{.*}}{{[/\\]}}Inputs/MissingHeader/module.modulemap:8:10: error : Header not found: Missing.h
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/ProblemsNamespace.modularize b/src/llvm-project/clang-tools-extra/test/modularize/ProblemsNamespace.modularize
new file mode 100644
index 0000000..d4bc353
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/ProblemsNamespace.modularize
@@ -0,0 +1,12 @@
+# RUN: not modularize %s -x c++ 2>&1 | FileCheck %s
+
+Inputs/IncludeInNamespace.h
+
+# CHECK: {{.*}}{{[/\\]}}Inputs{{[/\\]}}IncludeInNamespace.h:2:3:
+# CHECK-NEXT: #include "Empty.h"
+# CHECK-NEXT: ^
+# CHECK-NEXT: error: Include directive within namespace MyNamespace {}.
+# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}IncludeInNamespace.h:1:1:
+# CHECK-NEXT: namespace MyNamespace {
+# CHECK-NEXT: ^
+# CHECK-NEXT: The "namespace MyNamespace {}" block is here.
diff --git a/src/llvm-project/clang-tools-extra/test/modularize/SubModule2.h b/src/llvm-project/clang-tools-extra/test/modularize/SubModule2.h
new file mode 100644
index 0000000..70d711b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/modularize/SubModule2.h
@@ -0,0 +1,3 @@
+// SubModule2.h - Master header with same name as directory.
+#include "SubModule2/Header3.h"
+#include "SubModule2/Header4.h"
diff --git a/src/llvm-project/clang-tools-extra/test/pp-trace/Inputs/Level1A.h b/src/llvm-project/clang-tools-extra/test/pp-trace/Inputs/Level1A.h
new file mode 100644
index 0000000..165efc7
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/pp-trace/Inputs/Level1A.h
@@ -0,0 +1,2 @@
+#include "Level2A.h"
+#define MACRO_1A 1
diff --git a/src/llvm-project/clang-tools-extra/test/pp-trace/Inputs/Level1B.h b/src/llvm-project/clang-tools-extra/test/pp-trace/Inputs/Level1B.h
new file mode 100644
index 0000000..1e60798
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/pp-trace/Inputs/Level1B.h
@@ -0,0 +1,2 @@
+#include "Level2B.h"
+#define MACRO_1B 1
diff --git a/src/llvm-project/clang-tools-extra/test/pp-trace/Inputs/Level2A.h b/src/llvm-project/clang-tools-extra/test/pp-trace/Inputs/Level2A.h
new file mode 100644
index 0000000..9a355df
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/pp-trace/Inputs/Level2A.h
@@ -0,0 +1 @@
+#define MACRO_2A 1
diff --git a/src/llvm-project/clang-tools-extra/test/pp-trace/Inputs/Level2B.h b/src/llvm-project/clang-tools-extra/test/pp-trace/Inputs/Level2B.h
new file mode 100644
index 0000000..25b7017
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/pp-trace/Inputs/Level2B.h
@@ -0,0 +1 @@
+#define MACRO_2B 1
diff --git a/src/llvm-project/clang-tools-extra/test/pp-trace/Inputs/ModularizeList.txt b/src/llvm-project/clang-tools-extra/test/pp-trace/Inputs/ModularizeList.txt
new file mode 100644
index 0000000..8193db6
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/pp-trace/Inputs/ModularizeList.txt
@@ -0,0 +1,4 @@
+Level1A.h
+Level1B.h
+Level2A.h
+Level2B.h
diff --git a/src/llvm-project/clang-tools-extra/test/pp-trace/Inputs/module.map b/src/llvm-project/clang-tools-extra/test/pp-trace/Inputs/module.map
new file mode 100644
index 0000000..31f33c5
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/pp-trace/Inputs/module.map
@@ -0,0 +1,18 @@
+// module.map
+
+module Level1A {
+ header "Level1A.h"
+ export *
+}
+module Level1B {
+ header "Level1B.h"
+ export *
+ module Level2B {
+ header "Level2B.h"
+ export *
+ }
+}
+module Level2A {
+ header "Level2A.h"
+ export *
+}
diff --git a/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-conditional.cpp b/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-conditional.cpp
new file mode 100644
index 0000000..ac5d3b3
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-conditional.cpp
@@ -0,0 +1,304 @@
+// RUN: pp-trace -ignore FileChanged %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s
+
+#if 1
+#endif
+
+#if 0
+#endif
+
+#if 1
+#else
+#endif
+
+#if 0
+#else
+#endif
+
+#if 1
+#elif 1
+#endif
+#if 1
+#elif 0
+#endif
+
+#if 0
+#elif 1
+#endif
+#if 0
+#elif 0
+#endif
+#if 1
+#elif 1
+#endif
+#if 1
+#elif 0
+#endif
+
+#if 0
+#elif 1
+#else
+#endif
+#if 0
+#elif 0
+#else
+#endif
+#if 1
+#elif 1
+#else
+#endif
+#if 1
+#elif 0
+#else
+#endif
+
+#define MACRO 1
+#ifdef MACRO
+#endif
+#ifdef NO_MACRO
+#endif
+#ifndef MACRO
+#endif
+#ifndef NO_MACRO
+#endif
+
+// CHECK: ---
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK: MacroNameTok: __STDC__
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK: MacroNameTok: __STDC_HOSTED__
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK: MacroNameTok: __cplusplus
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK: MacroNameTok: __STDC_UTF_16__
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK: MacroNameTok: __STDC_UTF_32__
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK: - Callback: If
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:3:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:3:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:4:1"]
+// CHECK-NEXT: ConditionValue: CVK_True
+// CHECK-NEXT: - Callback: Endif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:4:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:3:2"
+// CHECK-NEXT: - Callback: If
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:6:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:6:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:7:1"]
+// CHECK-NEXT: ConditionValue: CVK_False
+// CHECK-NEXT: - Callback: Endif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:7:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:6:2"
+// CHECK-NEXT: - Callback: SourceRangeSkipped
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:6:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:7:2"]
+// CHECK-NEXT: - Callback: If
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:9:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:9:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:10:1"]
+// CHECK-NEXT: ConditionValue: CVK_True
+// CHECK-NEXT: - Callback: Else
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:10:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:9:2"
+// CHECK-NEXT: - Callback: Endif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:11:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:9:2"
+// CHECK-NEXT: - Callback: SourceRangeSkipped
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:10:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:11:2"]
+// CHECK-NEXT: - Callback: If
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:13:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:13:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:14:1"]
+// CHECK-NEXT: ConditionValue: CVK_False
+// CHECK-NEXT: - Callback: Else
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:14:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:13:2"
+// CHECK-NEXT: - Callback: SourceRangeSkipped
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:13:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:14:2"]
+// CHECK-NEXT: - Callback: Endif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:15:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:13:2"
+// CHECK-NEXT: - Callback: If
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:17:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:17:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:18:1"]
+// CHECK-NEXT: ConditionValue: CVK_True
+// CHECK-NEXT: - Callback: Elif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:18:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:18:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:19:1"]
+// CHECK-NEXT: ConditionValue: CVK_NotEvaluated
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:17:2"
+// CHECK-NEXT: - Callback: Endif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:19:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:17:2"
+// CHECK-NEXT: - Callback: SourceRangeSkipped
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:18:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:19:2"]
+// CHECK-NEXT: - Callback: If
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:20:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:20:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:21:1"]
+// CHECK-NEXT: ConditionValue: CVK_True
+// CHECK-NEXT: - Callback: Elif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:21:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:21:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:22:1"]
+// CHECK-NEXT: ConditionValue: CVK_NotEvaluated
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:20:2"
+// CHECK-NEXT: - Callback: Endif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:22:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:20:2"
+// CHECK-NEXT: - Callback: SourceRangeSkipped
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:21:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:22:2"]
+// CHECK-NEXT: - Callback: If
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:24:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:24:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:25:1"]
+// CHECK-NEXT: ConditionValue: CVK_False
+// CHECK-NEXT: - Callback: Elif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:25:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:25:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:26:1"]
+// CHECK-NEXT: ConditionValue: CVK_True
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:24:2"
+// CHECK-NEXT: - Callback: SourceRangeSkipped
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:24:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:25:2"]
+// CHECK-NEXT: - Callback: Endif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:26:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:24:2"
+// CHECK-NEXT: - Callback: If
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:27:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:27:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:28:1"]
+// CHECK-NEXT: ConditionValue: CVK_False
+// CHECK-NEXT: - Callback: Elif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:28:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:28:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:29:1"]
+// CHECK-NEXT: ConditionValue: CVK_False
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:27:2"
+// CHECK-NEXT: - Callback: Endif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:29:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:27:2"
+// CHECK-NEXT: - Callback: SourceRangeSkipped
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:27:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:29:2"]
+// CHECK-NEXT: - Callback: If
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:30:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:30:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:31:1"]
+// CHECK-NEXT: ConditionValue: CVK_True
+// CHECK-NEXT: - Callback: Elif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:31:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:31:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:32:1"]
+// CHECK-NEXT: ConditionValue: CVK_NotEvaluated
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:30:2"
+// CHECK-NEXT: - Callback: Endif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:32:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:30:2"
+// CHECK-NEXT: - Callback: SourceRangeSkipped
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:31:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:32:2"]
+// CHECK-NEXT: - Callback: If
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:33:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:33:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:34:1"]
+// CHECK-NEXT: ConditionValue: CVK_True
+// CHECK-NEXT: - Callback: Elif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:34:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:34:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:35:1"]
+// CHECK-NEXT: ConditionValue: CVK_NotEvaluated
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:33:2"
+// CHECK-NEXT: - Callback: Endif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:35:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:33:2"
+// CHECK-NEXT: - Callback: SourceRangeSkipped
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:34:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:35:2"]
+// CHECK-NEXT: - Callback: If
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:37:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:37:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:38:1"]
+// CHECK-NEXT: ConditionValue: CVK_False
+// CHECK-NEXT: - Callback: Elif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:38:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:38:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:39:1"]
+// CHECK-NEXT: ConditionValue: CVK_True
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:37:2"
+// CHECK-NEXT: - Callback: SourceRangeSkipped
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:37:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:38:2"]
+// CHECK-NEXT: - Callback: Else
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:39:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:37:2"
+// CHECK-NEXT: - Callback: Endif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:40:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:37:2"
+// CHECK-NEXT: - Callback: SourceRangeSkipped
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:39:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:40:2"]
+// CHECK-NEXT: - Callback: If
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:41:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:41:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:42:1"]
+// CHECK-NEXT: ConditionValue: CVK_False
+// CHECK-NEXT: - Callback: Elif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:42:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:42:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:43:1"]
+// CHECK-NEXT: ConditionValue: CVK_False
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:41:2"
+// CHECK-NEXT: - Callback: Else
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:43:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:41:2"
+// CHECK-NEXT: - Callback: SourceRangeSkipped
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:41:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:43:2"]
+// CHECK-NEXT: - Callback: Endif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:44:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:41:2"
+// CHECK-NEXT: - Callback: If
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:45:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:45:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:46:1"]
+// CHECK-NEXT: ConditionValue: CVK_True
+// CHECK-NEXT: - Callback: Elif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:46:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:46:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:47:1"]
+// CHECK-NEXT: ConditionValue: CVK_NotEvaluated
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:45:2"
+// CHECK-NEXT: - Callback: Endif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:48:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:45:2"
+// CHECK-NEXT: - Callback: SourceRangeSkipped
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:46:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:48:2"]
+// CHECK-NEXT: - Callback: If
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:49:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:49:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:50:1"]
+// CHECK-NEXT: ConditionValue: CVK_True
+// CHECK-NEXT: - Callback: Elif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:50:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:50:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:51:1"]
+// CHECK-NEXT: ConditionValue: CVK_NotEvaluated
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:49:2"
+// CHECK-NEXT: - Callback: Endif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:52:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:49:2"
+// CHECK-NEXT: - Callback: SourceRangeSkipped
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:50:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:52:2"]
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK-NEXT: MacroNameTok: MACRO
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: Ifdef
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:55:2"
+// CHECK-NEXT: MacroNameTok: MACRO
+// CHECK-NEXT: MacroDefinition: [(local)]
+// CHECK-NEXT: - Callback: Endif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:56:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:55:2"
+// CHECK-NEXT: - Callback: Ifdef
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:57:2"
+// CHECK-NEXT: MacroNameTok: NO_MACRO
+// CHECK-NEXT: MacroDefinition: []
+// CHECK-NEXT: - Callback: Endif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:58:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:57:2"
+// CHECK-NEXT: - Callback: SourceRangeSkipped
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:57:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:58:2"]
+// CHECK-NEXT: - Callback: Ifndef
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:59:2"
+// CHECK-NEXT: MacroNameTok: MACRO
+// CHECK-NEXT: MacroDefinition: [(local)]
+// CHECK-NEXT: - Callback: Endif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:60:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:59:2"
+// CHECK-NEXT: - Callback: SourceRangeSkipped
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:59:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:60:2"]
+// CHECK-NEXT: - Callback: Ifndef
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:61:2"
+// CHECK-NEXT: MacroNameTok: NO_MACRO
+// CHECK-NEXT: MacroDefinition: []
+// CHECK-NEXT: - Callback: Endif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:62:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:61:2"
+// CHECK-NEXT: - Callback: EndOfMainFile
+// CHECK-NEXT: ...
diff --git a/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-ident.cpp b/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-ident.cpp
new file mode 100644
index 0000000..9981c39
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-ident.cpp
@@ -0,0 +1,10 @@
+// RUN: pp-trace -ignore FileChanged,MacroDefined %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s
+
+#ident "$Id$"
+
+// CHECK: ---
+// CHECK-NEXT: - Callback: Ident
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-ident.cpp:3:2"
+// CHECK-NEXT: Str: "$Id$"
+// CHECK-NEXT: - Callback: EndOfMainFile
+// CHECK-NEXT: ...
diff --git a/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-include.cpp b/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-include.cpp
new file mode 100644
index 0000000..7d925d8
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-include.cpp
@@ -0,0 +1,141 @@
+// RUN: pp-trace %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s
+
+#include "Inputs/Level1A.h"
+#include "Inputs/Level1B.h"
+
+// CHECK: ---
+// CHECK-NEXT: - Callback: FileChanged
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-include.cpp:1:1"
+// CHECK-NEXT: Reason: EnterFile
+// CHECK-NEXT: FileType: C_User
+// CHECK-NEXT: PrevFID: (invalid)
+// CHECK-NEXT: - Callback: FileChanged
+// CHECK-NEXT: Loc: "<built-in>:1:1"
+// CHECK-NEXT: Reason: EnterFile
+// CHECK-NEXT: FileType: C_User
+// CHECK-NEXT: PrevFID: (invalid)
+// CHECK-NEXT: - Callback: FileChanged
+// CHECK-NEXT: Loc: "<built-in>:1:1"
+// CHECK-NEXT: Reason: RenameFile
+// CHECK-NEXT: FileType: C_System
+// CHECK-NEXT: PrevFID: (invalid)
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK: MacroNameTok: __STDC__
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK: MacroNameTok: __STDC_HOSTED__
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK: MacroNameTok: __cplusplus
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK: MacroNameTok: __STDC_UTF_16__
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK: MacroNameTok: __STDC_UTF_32__
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK: - Callback: FileChanged
+// CHECK-NEXT: Loc: "<command line>:1:1"
+// CHECK-NEXT: Reason: EnterFile
+// CHECK-NEXT: FileType: C_User
+// CHECK-NEXT: PrevFID: (invalid)
+// CHECK-NEXT: - Callback: FileChanged
+// CHECK-NEXT: Loc: "<built-in>:1:1"
+// CHECK-NEXT: Reason: ExitFile
+// CHECK-NEXT: FileType: C_User
+// CHECK-NEXT: PrevFID: (invalid)
+// CHECK-NEXT: - Callback: FileChanged
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-include.cpp:1:1"
+// CHECK-NEXT: Reason: ExitFile
+// CHECK-NEXT: FileType: C_User
+// CHECK-NEXT: PrevFID: (getFileEntryForID failed)
+// CHECK-NEXT: - Callback: InclusionDirective
+// CHECK-NEXT: IncludeTok: include
+// CHECK-NEXT: FileName: "Inputs/Level1A.h"
+// CHECK-NEXT: IsAngled: false
+// CHECK-NEXT: FilenameRange: "Inputs/Level1A.h"
+// CHECK-NEXT: File: "{{.*}}{{[/\\]}}Inputs/Level1A.h"
+// CHECK-NEXT: SearchPath: "{{.*}}{{[/\\]}}pp-trace"
+// CHECK-NEXT: RelativePath: "Inputs/Level1A.h"
+// CHECK-NEXT: Imported: (null)
+// CHECK-NEXT: - Callback: FileChanged
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}Inputs/Level1A.h:1:1"
+// CHECK-NEXT: Reason: EnterFile
+// CHECK-NEXT: FileType: C_User
+// CHECK-NEXT: PrevFID: (invalid)
+// CHECK-NEXT: - Callback: InclusionDirective
+// CHECK-NEXT: IncludeTok: include
+// CHECK-NEXT: FileName: "Level2A.h"
+// CHECK-NEXT: IsAngled: false
+// CHECK-NEXT: FilenameRange: "Level2A.h"
+// CHECK-NEXT: File: "{{.*}}{{[/\\]}}Inputs/Level2A.h"
+// CHECK-NEXT: SearchPath: "{{.*}}{{[/\\]}}Inputs"
+// CHECK-NEXT: RelativePath: "Level2A.h"
+// CHECK-NEXT: Imported: (null)
+// CHECK-NEXT: - Callback: FileChanged
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}Inputs/Level2A.h:1:1"
+// CHECK-NEXT: Reason: EnterFile
+// CHECK-NEXT: FileType: C_User
+// CHECK-NEXT: PrevFID: (invalid)
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK-NEXT: MacroNameTok: MACRO_2A
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: FileChanged
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}Inputs/Level1A.h:2:1"
+// CHECK-NEXT: Reason: ExitFile
+// CHECK-NEXT: FileType: C_User
+// CHECK-NEXT: PrevFID: "{{.*}}{{[/\\]}}Inputs/Level2A.h"
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK-NEXT: MacroNameTok: MACRO_1A
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: FileChanged
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-include.cpp:4:1"
+// CHECK-NEXT: Reason: ExitFile
+// CHECK-NEXT: FileType: C_User
+// CHECK-NEXT: PrevFID: "{{.*}}{{[/\\]}}Inputs/Level1A.h"
+// CHECK-NEXT: - Callback: InclusionDirective
+// CHECK-NEXT: IncludeTok: include
+// CHECK-NEXT: FileName: "Inputs/Level1B.h"
+// CHECK-NEXT: IsAngled: false
+// CHECK-NEXT: FilenameRange: "Inputs/Level1B.h"
+// CHECK-NEXT: File: "{{.*}}{{[/\\]}}Inputs/Level1B.h"
+// CHECK-NEXT: SearchPath: "{{.*}}{{[/\\]}}pp-trace"
+// CHECK-NEXT: RelativePath: "Inputs/Level1B.h"
+// CHECK-NEXT: Imported: (null)
+// CHECK-NEXT: - Callback: FileChanged
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}Inputs/Level1B.h:1:1"
+// CHECK-NEXT: Reason: EnterFile
+// CHECK-NEXT: FileType: C_User
+// CHECK-NEXT: PrevFID: (invalid)
+// CHECK-NEXT: - Callback: InclusionDirective
+// CHECK-NEXT: IncludeTok: include
+// CHECK-NEXT: FileName: "Level2B.h"
+// CHECK-NEXT: IsAngled: false
+// CHECK-NEXT: FilenameRange: "Level2B.h"
+// CHECK-NEXT: File: "{{.*}}{{[/\\]}}Inputs/Level2B.h"
+// CHECK-NEXT: SearchPath: "{{.*}}{{[/\\]}}Inputs"
+// CHECK-NEXT: RelativePath: "Level2B.h"
+// CHECK-NEXT: Imported: (null)
+// CHECK-NEXT: - Callback: FileChanged
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}Inputs/Level2B.h:1:1"
+// CHECK-NEXT: Reason: EnterFile
+// CHECK-NEXT: FileType: C_User
+// CHECK-NEXT: PrevFID: (invalid)
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK-NEXT: MacroNameTok: MACRO_2B
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: FileChanged
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}Inputs/Level1B.h:2:1"
+// CHECK-NEXT: Reason: ExitFile
+// CHECK-NEXT: FileType: C_User
+// CHECK-NEXT: PrevFID: "{{.*}}{{[/\\]}}Inputs/Level2B.h"
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK-NEXT: MacroNameTok: MACRO_1B
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: FileChanged
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-include.cpp:5:1"
+// CHECK-NEXT: Reason: ExitFile
+// CHECK-NEXT: FileType: C_User
+// CHECK-NEXT: PrevFID: "{{.*}}{{[/\\]}}Inputs/Level1B.h"
+// CHECK-NEXT: - Callback: EndOfMainFile
+// CHECK-NEXT: ...
diff --git a/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-macro.cpp b/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-macro.cpp
new file mode 100644
index 0000000..e6ba761
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-macro.cpp
@@ -0,0 +1,101 @@
+// RUN: pp-trace -ignore FileChanged %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s
+
+#define MACRO 1
+int i = MACRO;
+#if defined(MACRO)
+#endif
+#undef MACRO
+#if defined(MACRO)
+#endif
+#define FUNCMACRO(ARG1) ARG1
+int j = FUNCMACRO(1);
+#define X X_IMPL(a+y,b) X_IMPL2(c)
+#define X_IMPL(p1,p2)
+#define X_IMPL2(p1)
+X
+
+// CHECK: ---
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK: MacroNameTok: __STDC__
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK: MacroNameTok: __STDC_HOSTED__
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK: MacroNameTok: __cplusplus
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK: MacroNameTok: __STDC_UTF_16__
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK: MacroNameTok: __STDC_UTF_32__
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK: - Callback: MacroDefined
+// CHECK-NEXT: MacroNameTok: MACRO
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: MacroExpands
+// CHECK-NEXT: MacroNameTok: MACRO
+// CHECK-NEXT: MacroDefinition: [(local)]
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-macro.cpp:4:9", "{{.*}}{{[/\\]}}pp-trace-macro.cpp:4:9"]
+// CHECK-NEXT: Args: (null)
+// CHECK-NEXT: - Callback: Defined
+// CHECK-NEXT: MacroNameTok: MACRO
+// CHECK-NEXT: MacroDefinition: [(local)]
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-macro.cpp:5:5", "{{.*}}{{[/\\]}}pp-trace-macro.cpp:5:19"]
+// CHECK-NEXT: - Callback: If
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-macro.cpp:5:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-macro.cpp:5:4", "{{.*}}{{[/\\]}}pp-trace-macro.cpp:6:1"]
+// CHECK-NEXT: ConditionValue: CVK_True
+// CHECK-NEXT: - Callback: Endif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-macro.cpp:6:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-macro.cpp:5:2"
+// CHECK-NEXT: - Callback: MacroUndefined
+// CHECK-NEXT: MacroNameTok: MACRO
+// CHECK-NEXT: MacroDefinition: [(local)]
+// CHECK-NEXT: - Callback: Defined
+// CHECK-NEXT: MacroNameTok: MACRO
+// CHECK-NEXT: MacroDefinition: []
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-macro.cpp:8:5", "{{.*}}{{[/\\]}}pp-trace-macro.cpp:8:19"]
+// CHECK-NEXT: - Callback: If
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-macro.cpp:8:2"
+// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-macro.cpp:8:4", "{{.*}}{{[/\\]}}pp-trace-macro.cpp:9:1"]
+// CHECK-NEXT: ConditionValue: CVK_False
+// CHECK-NEXT: - Callback: Endif
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-macro.cpp:9:2"
+// CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-macro.cpp:8:2"
+// CHECK-NEXT: - Callback: SourceRangeSkipped
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-macro.cpp:8:1", "{{.*}}{{[/\\]}}pp-trace-macro.cpp:9:2"]
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK-NEXT: MacroNameTok: FUNCMACRO
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: MacroExpands
+// CHECK-NEXT: MacroNameTok: FUNCMACRO
+// CHECK-NEXT: MacroDefinition: [(local)]
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-macro.cpp:11:9", "{{.*}}{{[/\\]}}pp-trace-macro.cpp:11:20"]
+// CHECK-NEXT: Args: [1]
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK-NEXT: MacroNameTok: X
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK-NEXT: MacroNameTok: X_IMPL
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: MacroDefined
+// CHECK-NEXT: MacroNameTok: X_IMPL2
+// CHECK-NEXT: MacroDirective: MD_Define
+// CHECK-NEXT: - Callback: MacroExpands
+// CHECK-NEXT: MacroNameTok: X
+// CHECK-NEXT: MacroDefinition: [(local)]
+// CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-macro.cpp:15:1", "{{.*}}{{[/\\]}}pp-trace-macro.cpp:15:1"]
+// CHECK-NEXT: Args: (null)
+// CHECK-NEXT: - Callback: MacroExpands
+// CHECK-NEXT: MacroNameTok: X_IMPL
+// CHECK-NEXT: MacroDefinition: [(local)]
+// CHECK-NEXT: Range: [(nonfile), (nonfile)]
+// CHECK-NEXT: Args: [a <plus> y, b]
+// CHECK-NEXT: - Callback: MacroExpands
+// CHECK-NEXT: MacroNameTok: X_IMPL2
+// CHECK-NEXT: MacroDefinition: [(local)]
+// CHECK-NEXT: Range: [(nonfile), (nonfile)]
+// CHECK-NEXT: Args: [c]
+// CHECK-NEXT: - Callback: EndOfMainFile
+// CHECK-NEXT: ...
diff --git a/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-modules.cpp b/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-modules.cpp
new file mode 100644
index 0000000..5e9e1de
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-modules.cpp
@@ -0,0 +1,20 @@
+// RUN: rm -rf %t
+// RUN: pp-trace -ignore FileChanged,MacroDefined %s -x objective-c++ -undef -target x86_64 -std=c++11 -fmodules -fcxx-modules -fmodules-cache-path=%t -I%S -I%S/Input | FileCheck --strict-whitespace %s
+
+// CHECK: ---
+
+@import Level1A;
+
+// CHECK-NEXT: - Callback: moduleImport
+// CHECK-NEXT: ImportLoc: "{{.*}}{{[/\\]}}pp-trace-modules.cpp:[[@LINE-3]]:2"
+// CHECK-NEXT: Path: [{Name: Level1A, Loc: "{{.*}}{{[/\\]}}pp-trace-modules.cpp:[[@LINE-4]]:9"}]
+// CHECK-NEXT: Imported: Level1A
+
+@import Level1B.Level2B;
+
+// CHECK-NEXT: - Callback: moduleImport
+// CHECK-NEXT: ImportLoc: "{{.*}}{{[/\\]}}pp-trace-modules.cpp:[[@LINE-3]]:2"
+// CHECK-NEXT: Path: [{Name: Level1B, Loc: "{{.*}}{{[/\\]}}pp-trace-modules.cpp:[[@LINE-4]]:9"}, {Name: Level2B, Loc: "{{.*}}{{[/\\]}}pp-trace-modules.cpp:[[@LINE-4]]:17"}]
+// CHECK-NEXT: Imported: Level2B
+// CHECK-NEXT: - Callback: EndOfMainFile
+// CHECK-NEXT: ...
diff --git a/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-pragma-general.cpp b/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-pragma-general.cpp
new file mode 100644
index 0000000..6caef0b
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-pragma-general.cpp
@@ -0,0 +1,118 @@
+// RUN: pp-trace -ignore FileChanged,MacroDefined %s | FileCheck --strict-whitespace %s
+
+#pragma clang diagnostic push
+#pragma clang diagnostic pop
+#pragma clang diagnostic ignored "-Wformat"
+#pragma clang diagnostic warning "-Wformat"
+#pragma clang diagnostic error "-Wformat"
+#pragma clang diagnostic fatal "-Wformat"
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic pop
+#pragma GCC diagnostic ignored "-Wformat"
+#pragma GCC diagnostic warning "-Wformat"
+#pragma GCC diagnostic error "-Wformat"
+#pragma GCC diagnostic fatal "-Wformat"
+
+void foo() {
+#pragma clang __debug captured
+{ }
+}
+
+// CHECK: ---
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:3:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaDiagnosticPush
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:3:15"
+// CHECK-NEXT: Namespace: clang
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:4:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaDiagnosticPop
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:4:15"
+// CHECK-NEXT: Namespace: clang
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:5:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaDiagnostic
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:5:15"
+// CHECK-NEXT: Namespace: clang
+// CHECK-NEXT: Mapping: MAP_IGNORE
+// CHECK-NEXT: Str: -Wformat
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:6:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaDiagnostic
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:6:15"
+// CHECK-NEXT: Namespace: clang
+// CHECK-NEXT: Mapping: MAP_WARNING
+// CHECK-NEXT: Str: -Wformat
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:7:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaDiagnostic
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:7:15"
+// CHECK-NEXT: Namespace: clang
+// CHECK-NEXT: Mapping: MAP_ERROR
+// CHECK-NEXT: Str: -Wformat
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:8:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaDiagnostic
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:8:15"
+// CHECK-NEXT: Namespace: clang
+// CHECK-NEXT: Mapping: MAP_FATAL
+// CHECK-NEXT: Str: -Wformat
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:10:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaDiagnosticPush
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:10:13"
+// CHECK-NEXT: Namespace: GCC
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:11:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaDiagnosticPop
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:11:13"
+// CHECK-NEXT: Namespace: GCC
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:12:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaDiagnostic
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:12:13"
+// CHECK-NEXT: Namespace: GCC
+// CHECK-NEXT: Mapping: MAP_IGNORE
+// CHECK-NEXT: Str: -Wformat
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:13:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaDiagnostic
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:13:13"
+// CHECK-NEXT: Namespace: GCC
+// CHECK-NEXT: Mapping: MAP_WARNING
+// CHECK-NEXT: Str: -Wformat
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:14:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaDiagnostic
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:14:13"
+// CHECK-NEXT: Namespace: GCC
+// CHECK-NEXT: Mapping: MAP_ERROR
+// CHECK-NEXT: Str: -Wformat
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:15:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaDiagnostic
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:15:13"
+// CHECK-NEXT: Namespace: GCC
+// CHECK-NEXT: Mapping: MAP_FATAL
+// CHECK-NEXT: Str: -Wformat
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:18:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaDebug
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:18:23"
+// CHECK-NEXT: DebugType: captured
+// CHECK-NEXT: - Callback: EndOfMainFile
+// CHECK-NEXT: ...
diff --git a/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-pragma-ms.cpp b/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-pragma-ms.cpp
new file mode 100644
index 0000000..33c9f7f
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-pragma-ms.cpp
@@ -0,0 +1,100 @@
+// RUN: pp-trace -ignore FileChanged,MacroDefined %s -target x86_64-unknown-windows-msvc -fms-extensions -w | FileCheck --strict-whitespace %s
+
+#pragma comment(compiler, "compiler comment")
+#pragma comment(exestr, "exestr comment")
+#pragma comment(lib, "lib comment")
+#pragma comment(linker, "linker comment")
+#pragma comment(user, "user comment")
+
+#pragma detect_mismatch("name argument", "value argument")
+
+#pragma __debug(assert)
+
+#pragma message("message argument")
+
+#pragma warning(push, 1)
+#pragma warning(pop)
+#pragma warning(disable : 1 2 3 ; error : 4 5 6 ; suppress : 7 8 9)
+
+// CHECK: ---
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:3:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaComment
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:3:9"
+// CHECK-NEXT: Kind: compiler
+// CHECK-NEXT: Str: compiler comment
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:4:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaComment
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:4:9"
+// CHECK-NEXT: Kind: exestr
+// CHECK-NEXT: Str: exestr comment
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:5:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaComment
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:5:9"
+// CHECK-NEXT: Kind: lib
+// CHECK-NEXT: Str: lib comment
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:6:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaComment
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:6:9"
+// CHECK-NEXT: Kind: linker
+// CHECK-NEXT: Str: linker comment
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:7:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaComment
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:7:9"
+// CHECK-NEXT: Kind: user
+// CHECK-NEXT: Str: user comment
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:9:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaDetectMismatch
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:9:9"
+// CHECK-NEXT: Name: name argument
+// CHECK-NEXT: Value: value argument
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:11:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:13:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaMessage
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:13:9"
+// CHECK-NEXT: Namespace:
+// CHECK-NEXT: Kind: PMK_Message
+// CHECK-NEXT: Str: message argument
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:15:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaWarningPush
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:15:9"
+// CHECK-NEXT: Level: 1
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:16:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaWarningPop
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:16:9"
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:17:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaWarning
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:17:9"
+// CHECK-NEXT: WarningSpec: disable
+// CHECK-NEXT: Ids: [1, 2, 3]
+// CHECK-NEXT: - Callback: PragmaWarning
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:17:9"
+// CHECK-NEXT: WarningSpec: error
+// CHECK-NEXT: Ids: [4, 5, 6]
+// CHECK-NEXT: - Callback: PragmaWarning
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:17:9"
+// CHECK-NEXT: WarningSpec: suppress
+// CHECK-NEXT: Ids: [7, 8, 9]
+// CHECK-NEXT: - Callback: EndOfMainFile
+// CHECK-NEXT: ...
diff --git a/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-pragma-opencl.cpp b/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-pragma-opencl.cpp
new file mode 100644
index 0000000..cfd72c0
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/pp-trace/pp-trace-pragma-opencl.cpp
@@ -0,0 +1,33 @@
+// RUN: pp-trace -ignore FileChanged,MacroDefined %s -x cl | FileCheck --strict-whitespace %s
+
+#pragma OPENCL EXTENSION all : disable
+#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : disable
+#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable
+
+// CHECK: ---
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-opencl.cpp:3:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaOpenCLExtension
+// CHECK-NEXT: NameLoc: "{{.*}}{{[/\\]}}pp-trace-pragma-opencl.cpp:3:26"
+// CHECK-NEXT: Name: all
+// CHECK-NEXT: StateLoc: "{{.*}}{{[/\\]}}pp-trace-pragma-opencl.cpp:3:32"
+// CHECK-NEXT: State: 0
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-opencl.cpp:4:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaOpenCLExtension
+// CHECK-NEXT: NameLoc: "{{.*}}{{[/\\]}}pp-trace-pragma-opencl.cpp:4:26"
+// CHECK-NEXT: Name: cl_khr_int64_base_atomics
+// CHECK-NEXT: StateLoc: "{{.*}}{{[/\\]}}pp-trace-pragma-opencl.cpp:4:54"
+// CHECK-NEXT: State: 0
+// CHECK-NEXT: - Callback: PragmaDirective
+// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-opencl.cpp:5:1"
+// CHECK-NEXT: Introducer: PIK_HashPragma
+// CHECK-NEXT: - Callback: PragmaOpenCLExtension
+// CHECK-NEXT: NameLoc: "{{.*}}{{[/\\]}}pp-trace-pragma-opencl.cpp:5:26"
+// CHECK-NEXT: Name: cl_khr_int64_base_atomics
+// CHECK-NEXT: StateLoc: "{{.*}}{{[/\\]}}pp-trace-pragma-opencl.cpp:5:54"
+// CHECK-NEXT: State: 1
+// CHECK-NEXT: - Callback: EndOfMainFile
+// CHECK-NEXT: ...