summaryrefslogtreecommitdiffstats
path: root/test/clang-tidy
diff options
context:
space:
mode:
Diffstat (limited to 'test/clang-tidy')
-rw-r--r--test/clang-tidy/Inputs/Headers/stdio.h18
-rw-r--r--test/clang-tidy/Inputs/absl/time/time.h20
-rw-r--r--test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/a.h1
-rw-r--r--test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/b.h2
-rw-r--r--test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/c.h2
-rw-r--r--test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/module.modulemap3
-rw-r--r--test/clang-tidy/abseil-duration-addition.cpp98
-rw-r--r--test/clang-tidy/abseil-duration-conversion-cast.cpp95
-rw-r--r--test/clang-tidy/abseil-duration-unnecessary-conversion.cpp111
-rw-r--r--test/clang-tidy/abseil-time-comparison.cpp129
-rw-r--r--test/clang-tidy/abseil-time-subtraction.cpp117
-rw-r--r--test/clang-tidy/abseil-upgrade-duration-conversions.cpp33
-rw-r--r--test/clang-tidy/alternative-fixes.cpp9
-rw-r--r--test/clang-tidy/bugprone-argument-comment-literals.cpp124
-rw-r--r--test/clang-tidy/bugprone-exception-escape-openmp.cpp29
-rw-r--r--[-rwxr-xr-x]test/clang-tidy/bugprone-parent-virtual-call.cpp0
-rw-r--r--test/clang-tidy/bugprone-sizeof-expression.cpp29
-rw-r--r--test/clang-tidy/bugprone-string-constructor.cpp8
-rw-r--r--test/clang-tidy/bugprone-string-integer-assignment.cpp60
-rw-r--r--test/clang-tidy/bugprone-too-small-loop-variable-magniute-bits-upper-limit.cpp23
-rw-r--r--test/clang-tidy/bugprone-too-small-loop-variable.cpp6
-rwxr-xr-xtest/clang-tidy/check_clang_tidy.py7
-rw-r--r--test/clang-tidy/clang-tidy-diff.cpp1
-rw-r--r--test/clang-tidy/clang-tidy-mac-libcxx.cpp2
-rw-r--r--test/clang-tidy/cppcoreguidelines-macro-usage.cpp2
-rw-r--r--test/clang-tidy/expand-modular-headers-ppcallbacks.cpp35
-rw-r--r--test/clang-tidy/export-diagnostics.cpp13
-rw-r--r--test/clang-tidy/google-objc-function-naming.m10
-rw-r--r--test/clang-tidy/google-objc-global-variable-declaration.mm10
-rw-r--r--test/clang-tidy/google-runtime-int.m32
-rw-r--r--test/clang-tidy/llvm-prefer-isa-or-dyn-cast-in-conditionals.cpp132
-rw-r--r--test/clang-tidy/misc-non-private-member-variables-in-classes.cpp17
-rw-r--r--test/clang-tidy/modernize-avoid-bind.cpp44
-rw-r--r--test/clang-tidy/modernize-avoid-c-arrays-ignores-main.cpp18
-rw-r--r--test/clang-tidy/modernize-avoid-c-arrays-ignores-three-arg-main.cpp20
-rw-r--r--test/clang-tidy/modernize-redundant-void-arg.cpp7
-rw-r--r--test/clang-tidy/modernize-use-default-member-init-assignment.cpp8
-rw-r--r--test/clang-tidy/modernize-use-default-member-init.cpp18
-rw-r--r--test/clang-tidy/modernize-use-override-no-destructors.cpp16
-rw-r--r--test/clang-tidy/modernize-use-override-with-macro.cpp70
-rw-r--r--test/clang-tidy/modernize-use-override-with-no-macro-inscope.cpp28
-rw-r--r--test/clang-tidy/nolint.cpp3
-rw-r--r--test/clang-tidy/objc-property-declaration.m1
-rw-r--r--test/clang-tidy/objc-super-self.m86
-rw-r--r--test/clang-tidy/openmp-exception-escape.cpp132
-rw-r--r--test/clang-tidy/openmp-use-default-none.cpp160
-rw-r--r--test/clang-tidy/readability-avoid-underscore-in-googletest-name.cpp108
-rw-r--r--test/clang-tidy/readability-else-after-return.cpp12
-rw-r--r--test/clang-tidy/readability-misleading-indentation.cpp13
-rw-r--r--test/clang-tidy/readability-redundant-smartptr-get-msvc.cpp94
-rw-r--r--test/clang-tidy/readability-uppercase-literal-suffix-float16.cpp51
-rw-r--r--test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp28
-rw-r--r--test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp15
-rw-r--r--test/clang-tidy/run-clang-tidy.cpp1
-rw-r--r--test/clang-tidy/static-analyzer-config.cpp2
55 files changed, 2050 insertions, 63 deletions
diff --git a/test/clang-tidy/Inputs/Headers/stdio.h b/test/clang-tidy/Inputs/Headers/stdio.h
new file mode 100644
index 00000000..eebe9fd9
--- /dev/null
+++ b/test/clang-tidy/Inputs/Headers/stdio.h
@@ -0,0 +1,18 @@
+//===--- stdio.h - Stub header for tests ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _STDIO_H_
+#define _STDIO_H_
+
+// A header intended to contain C standard input and output library
+// declarations.
+
+int printf(const char *, ...);
+
+#endif // _STDIO_H_
+
diff --git a/test/clang-tidy/Inputs/absl/time/time.h b/test/clang-tidy/Inputs/absl/time/time.h
index 9d136a5d..5454f978 100644
--- a/test/clang-tidy/Inputs/absl/time/time.h
+++ b/test/clang-tidy/Inputs/absl/time/time.h
@@ -14,11 +14,14 @@ public:
Duration &operator/=(float r);
Duration &operator/=(double r);
template <typename T> Duration &operator/=(T r);
+
+ Duration &operator+(Duration d);
};
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);
+int64_t operator/(Duration lhs, Duration rhs);
class Time{};
@@ -55,6 +58,21 @@ int64_t ToInt64Milliseconds(Duration d);
int64_t ToInt64Microseconds(Duration d);
int64_t ToInt64Nanoseconds(Duration d);
+int64_t ToUnixHours(Time t);
+int64_t ToUnixMinutes(Time t);
+int64_t ToUnixSeconds(Time t);
+int64_t ToUnixMillis(Time t);
+int64_t ToUnixMicros(Time t);
+int64_t ToUnixNanos(Time t);
+Time FromUnixHours(int64_t);
+Time FromUnixMinutes(int64_t);
+Time FromUnixSeconds(int64_t);
+Time FromUnixMillis(int64_t);
+Time FromUnixMicros(int64_t);
+Time FromUnixNanos(int64_t);
+
+Time Now();
+
// Relational Operators
constexpr bool operator<(Duration lhs, Duration rhs);
constexpr bool operator>(Duration lhs, Duration rhs);
@@ -69,4 +87,6 @@ inline Time operator+(Duration lhs, Time rhs);
inline Time operator-(Time lhs, Duration rhs);
inline Duration operator-(Time lhs, Time rhs);
+double FDivDuration(Duration num, Duration den);
+
} // namespace absl
diff --git a/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/a.h b/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/a.h
new file mode 100644
index 00000000..6651b4fa
--- /dev/null
+++ b/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/a.h
@@ -0,0 +1 @@
+#define a
diff --git a/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/b.h b/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/b.h
new file mode 100644
index 00000000..446eda1a
--- /dev/null
+++ b/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/b.h
@@ -0,0 +1,2 @@
+#include "a.h"
+#define b
diff --git a/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/c.h b/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/c.h
new file mode 100644
index 00000000..0d4c60df
--- /dev/null
+++ b/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/c.h
@@ -0,0 +1,2 @@
+#include "b.h"
+#define c
diff --git a/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/module.modulemap b/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/module.modulemap
new file mode 100644
index 00000000..d04240af
--- /dev/null
+++ b/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/module.modulemap
@@ -0,0 +1,3 @@
+module a { header "a.h" export * }
+module b { header "b.h" export * use a }
+module c { header "c.h" export * use b }
diff --git a/test/clang-tidy/abseil-duration-addition.cpp b/test/clang-tidy/abseil-duration-addition.cpp
new file mode 100644
index 00000000..33cfc58f
--- /dev/null
+++ b/test/clang-tidy/abseil-duration-addition.cpp
@@ -0,0 +1,98 @@
+// RUN: %check_clang_tidy %s abseil-duration-addition %t -- -- -I%S/Inputs
+
+#include "absl/time/time.h"
+
+void f() {
+ absl::Time t;
+ int i;
+
+ i = absl::ToUnixHours(t) + 5;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+ // CHECK-FIXES: absl::ToUnixHours(t + absl::Hours(5))
+ i = absl::ToUnixMinutes(t) + 5;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+ // CHECK-FIXES: absl::ToUnixMinutes(t + absl::Minutes(5))
+ i = absl::ToUnixSeconds(t) + 5;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+ // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(5))
+ i = absl::ToUnixMillis(t) + 5;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+ // CHECK-FIXES: absl::ToUnixMillis(t + absl::Milliseconds(5))
+ i = absl::ToUnixMicros(t) + 5;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+ // CHECK-FIXES: absl::ToUnixMicros(t + absl::Microseconds(5))
+ i = absl::ToUnixNanos(t) + 5;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+ // CHECK-FIXES: absl::ToUnixNanos(t + absl::Nanoseconds(5))
+
+ i = 3 + absl::ToUnixHours(t);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+ // CHECK-FIXES: absl::ToUnixHours(absl::Hours(3) + t)
+ i = 3 + absl::ToUnixMinutes(t);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+ // CHECK-FIXES: absl::ToUnixMinutes(absl::Minutes(3) + t)
+ i = 3 + absl::ToUnixSeconds(t);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+ // CHECK-FIXES: absl::ToUnixSeconds(absl::Seconds(3) + t)
+ i = 3 + absl::ToUnixMillis(t);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+ // CHECK-FIXES: absl::ToUnixMillis(absl::Milliseconds(3) + t)
+ i = 3 + absl::ToUnixMicros(t);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+ // CHECK-FIXES: absl::ToUnixMicros(absl::Microseconds(3) + t)
+ i = 3 + absl::ToUnixNanos(t);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+ // CHECK-FIXES: absl::ToUnixNanos(absl::Nanoseconds(3) + t)
+
+ // Undoing inverse conversions
+ i = absl::ToUnixMicros(t) + absl::ToInt64Microseconds(absl::Seconds(1));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+ // CHECK-FIXES: absl::ToUnixMicros(t + absl::Seconds(1))
+
+ // Parens
+ i = 3 + (absl::ToUnixHours(t));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+ // CHECK-FIXES: absl::ToUnixHours(absl::Hours(3) + t)
+
+ // Float folding
+ i = absl::ToUnixSeconds(t) + 5.0;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+ // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(5))
+
+ // We can rewrite the argument of the duration conversion
+#define THIRTY absl::FromUnixSeconds(30)
+ i = absl::ToUnixSeconds(THIRTY) + 1;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+ // CHECK-FIXES: absl::ToUnixSeconds(THIRTY + absl::Seconds(1))
+#undef THIRTY
+
+ // Some other contexts
+ if (absl::ToUnixSeconds(t) + 1.0 > 10) {}
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+ // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(1))
+
+ // These should not match
+ i = 5 + 6;
+ i = absl::ToUnixSeconds(t) - 1.0;
+ i = absl::ToUnixSeconds(t) * 1.0;
+ i = absl::ToUnixSeconds(t) / 1.0;
+ i += absl::ToInt64Microseconds(absl::Seconds(1));
+
+#define PLUS_FIVE(z) absl::ToUnixSeconds(z) + 5
+ i = PLUS_FIVE(t);
+#undef PLUS_FIVE
+}
+
+// Within a templated function
+template<typename T>
+void foo(absl::Time t) {
+ int i = absl::ToUnixNanos(t) + T{};
+ // CHECK-MESSAGES: [[@LINE-1]]:11: warning: perform addition in the duration domain [abseil-duration-addition]
+ // CHECK-FIXES: absl::ToUnixNanos(t + absl::Nanoseconds(T{}))
+}
+
+void g() {
+ absl::Time t;
+ foo<int>(t);
+ foo<double>(t);
+}
diff --git a/test/clang-tidy/abseil-duration-conversion-cast.cpp b/test/clang-tidy/abseil-duration-conversion-cast.cpp
new file mode 100644
index 00000000..260aa327
--- /dev/null
+++ b/test/clang-tidy/abseil-duration-conversion-cast.cpp
@@ -0,0 +1,95 @@
+// RUN: %check_clang_tidy %s abseil-duration-conversion-cast %t -- -- -I%S/Inputs
+
+#include "absl/time/time.h"
+
+void f() {
+ absl::Duration d1;
+ double x;
+ int i;
+
+ i = static_cast<int>(absl::ToDoubleHours(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
+ // CHECK-FIXES: absl::ToInt64Hours(d1);
+ x = static_cast<float>(absl::ToInt64Hours(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast]
+ // CHECK-FIXES: absl::ToDoubleHours(d1);
+ i = static_cast<int>(absl::ToDoubleMinutes(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
+ // CHECK-FIXES: absl::ToInt64Minutes(d1);
+ x = static_cast<float>(absl::ToInt64Minutes(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast]
+ // CHECK-FIXES: absl::ToDoubleMinutes(d1);
+ i = static_cast<int>(absl::ToDoubleSeconds(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
+ // CHECK-FIXES: absl::ToInt64Seconds(d1);
+ x = static_cast<float>(absl::ToInt64Seconds(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast]
+ // CHECK-FIXES: absl::ToDoubleSeconds(d1);
+ i = static_cast<int>(absl::ToDoubleMilliseconds(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
+ // CHECK-FIXES: absl::ToInt64Milliseconds(d1);
+ x = static_cast<float>(absl::ToInt64Milliseconds(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast]
+ // CHECK-FIXES: absl::ToDoubleMilliseconds(d1);
+ i = static_cast<int>(absl::ToDoubleMicroseconds(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
+ // CHECK-FIXES: absl::ToInt64Microseconds(d1);
+ x = static_cast<float>(absl::ToInt64Microseconds(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast]
+ // CHECK-FIXES: absl::ToDoubleMicroseconds(d1);
+ i = static_cast<int>(absl::ToDoubleNanoseconds(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
+ // CHECK-FIXES: absl::ToInt64Nanoseconds(d1);
+ x = static_cast<float>(absl::ToInt64Nanoseconds(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast]
+ // CHECK-FIXES: absl::ToDoubleNanoseconds(d1);
+
+ // Functional-style casts
+ i = int(absl::ToDoubleHours(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
+ // CHECK-FIXES: absl::ToInt64Hours(d1);
+ x = float(absl::ToInt64Microseconds(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast]
+ // CHECK-FIXES: absl::ToDoubleMicroseconds(d1);
+
+ // C-style casts
+ i = (int) absl::ToDoubleHours(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
+ // CHECK-FIXES: absl::ToInt64Hours(d1);
+ x = (float) absl::ToInt64Microseconds(d1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast]
+ // CHECK-FIXES: absl::ToDoubleMicroseconds(d1);
+
+ // Type aliasing
+ typedef int FancyInt;
+ typedef float FancyFloat;
+
+ FancyInt j = static_cast<FancyInt>(absl::ToDoubleHours(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
+ // CHECK-FIXES: absl::ToInt64Hours(d1);
+ FancyFloat k = static_cast<FancyFloat>(absl::ToInt64Microseconds(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:18: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast]
+ // CHECK-FIXES: absl::ToDoubleMicroseconds(d1);
+
+ // Macro handling
+ // We want to transform things in macro arguments
+#define EXTERNAL(x) (x) + 5
+ i = EXTERNAL(static_cast<int>(absl::ToDoubleSeconds(d1)));
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
+ // CHECK-FIXES: EXTERNAL(absl::ToInt64Seconds(d1));
+#undef EXTERNAL
+
+ // We don't want to transform this which get split across macro boundaries
+#define SPLIT(x) static_cast<int>((x)) + 5
+ i = SPLIT(absl::ToDoubleSeconds(d1));
+#undef SPLIT
+
+ // We also don't want to transform things inside of a macro definition
+#define INTERNAL(x) static_cast<int>(absl::ToDoubleSeconds((x))) + 5
+ i = INTERNAL(d1);
+#undef INTERNAL
+
+ // These shouldn't be converted
+ i = static_cast<int>(absl::ToInt64Seconds(d1));
+ i = static_cast<float>(absl::ToDoubleSeconds(d1));
+}
diff --git a/test/clang-tidy/abseil-duration-unnecessary-conversion.cpp b/test/clang-tidy/abseil-duration-unnecessary-conversion.cpp
new file mode 100644
index 00000000..d32837f8
--- /dev/null
+++ b/test/clang-tidy/abseil-duration-unnecessary-conversion.cpp
@@ -0,0 +1,111 @@
+// RUN: %check_clang_tidy %s abseil-duration-unnecessary-conversion %t -- -- -I%S/Inputs
+
+#include "absl/time/time.h"
+
+void f() {
+ absl::Duration d1, d2;
+
+ // Floating point
+ d2 = absl::Hours(absl::ToDoubleHours(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+ d2 = absl::Minutes(absl::ToDoubleMinutes(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+ d2 = absl::Seconds(absl::ToDoubleSeconds(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+ d2 = absl::Milliseconds(absl::ToDoubleMilliseconds(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+ d2 = absl::Microseconds(absl::ToDoubleMicroseconds(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+ d2 = absl::Nanoseconds(absl::ToDoubleNanoseconds(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+
+ // Integer point
+ d2 = absl::Hours(absl::ToInt64Hours(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+ d2 = absl::Minutes(absl::ToInt64Minutes(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+ d2 = absl::Seconds(absl::ToInt64Seconds(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+ d2 = absl::Milliseconds(absl::ToInt64Milliseconds(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+ d2 = absl::Microseconds(absl::ToInt64Microseconds(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+ d2 = absl::Nanoseconds(absl::ToInt64Nanoseconds(d1));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+
+ d2 = absl::Hours(d1 / absl::Hours(1));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+ d2 = absl::Minutes(d1 / absl::Minutes(1));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+ d2 = absl::Seconds(d1 / absl::Seconds(1));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+ d2 = absl::Milliseconds(d1 / absl::Milliseconds(1));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+ d2 = absl::Microseconds(d1 / absl::Microseconds(1));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+ d2 = absl::Nanoseconds(d1 / absl::Nanoseconds(1));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+
+ d2 = absl::Hours(absl::FDivDuration(d1, absl::Hours(1)));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+ d2 = absl::Minutes(absl::FDivDuration(d1, absl::Minutes(1)));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+ d2 = absl::Seconds(absl::FDivDuration(d1, absl::Seconds(1)));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+ d2 = absl::Milliseconds(absl::FDivDuration(d1, absl::Milliseconds(1)));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+ d2 = absl::Microseconds(absl::FDivDuration(d1, absl::Microseconds(1)));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+ d2 = absl::Nanoseconds(absl::FDivDuration(d1, absl::Nanoseconds(1)));
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: d2 = d1
+
+ // As macro argument
+#define PLUS_FIVE_S(x) x + absl::Seconds(5)
+ d2 = PLUS_FIVE_S(absl::Seconds(absl::ToInt64Seconds(d1)));
+ // CHECK-MESSAGES: [[@LINE-1]]:20: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+ // CHECK-FIXES: PLUS_FIVE_S(d1)
+#undef PLUS_FIVE_S
+
+ // Split by macro: should not change
+#define TOSECONDS(x) absl::Seconds(x)
+ d2 = TOSECONDS(absl::ToInt64Seconds(d1));
+#undef TOSECONDS
+
+ // Don't change something inside a macro definition
+#define VALUE(x) absl::Hours(absl::ToInt64Hours(x));
+ d2 = VALUE(d1);
+#undef VALUE
+
+ // These should not match
+ d2 = absl::Seconds(absl::ToDoubleMilliseconds(d1));
+ d2 = absl::Seconds(4);
+ int i = absl::ToInt64Milliseconds(d1);
+ d2 = absl::Hours(d1 / absl::Minutes(1));
+ d2 = absl::Seconds(d1 / absl::Seconds(30));
+ d2 = absl::Hours(absl::FDivDuration(d1, absl::Minutes(1)));
+ d2 = absl::Milliseconds(absl::FDivDuration(d1, absl::Milliseconds(20)));
+}
diff --git a/test/clang-tidy/abseil-time-comparison.cpp b/test/clang-tidy/abseil-time-comparison.cpp
new file mode 100644
index 00000000..ab03020c
--- /dev/null
+++ b/test/clang-tidy/abseil-time-comparison.cpp
@@ -0,0 +1,129 @@
+// RUN: %check_clang_tidy %s abseil-time-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::ToUnixSeconds(t1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: absl::FromUnixSeconds(x) > t1;
+ b = x >= absl::ToUnixSeconds(t1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: absl::FromUnixSeconds(x) >= t1;
+ b = x == absl::ToUnixSeconds(t1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: absl::FromUnixSeconds(x) == t1;
+ b = x <= absl::ToUnixSeconds(t1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: absl::FromUnixSeconds(x) <= t1;
+ b = x < absl::ToUnixSeconds(t1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: absl::FromUnixSeconds(x) < t1;
+ b = x == absl::ToUnixSeconds(t1 - d2);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: absl::FromUnixSeconds(x) == t1 - d2;
+ b = absl::ToUnixSeconds(t1) > absl::ToUnixSeconds(t2);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: t1 > t2;
+
+ // Check against the LHS
+ b = absl::ToUnixSeconds(t1) < x;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: t1 < absl::FromUnixSeconds(x);
+ b = absl::ToUnixSeconds(t1) <= x;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: t1 <= absl::FromUnixSeconds(x);
+ b = absl::ToUnixSeconds(t1) == x;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: t1 == absl::FromUnixSeconds(x);
+ b = absl::ToUnixSeconds(t1) >= x;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: t1 >= absl::FromUnixSeconds(x);
+ b = absl::ToUnixSeconds(t1) > x;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: t1 > absl::FromUnixSeconds(x);
+
+ // Comparison against zero
+ b = absl::ToUnixSeconds(t1) < 0.0;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: t1 < absl::UnixEpoch();
+ b = absl::ToUnixSeconds(t1) < 0;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: t1 < absl::UnixEpoch();
+
+ // Scales other than Seconds
+ b = x > absl::ToUnixMicros(t1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: absl::FromUnixMicros(x) > t1;
+ b = x >= absl::ToUnixMillis(t1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: absl::FromUnixMillis(x) >= t1;
+ b = x == absl::ToUnixNanos(t1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: absl::FromUnixNanos(x) == t1;
+ b = x <= absl::ToUnixMinutes(t1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: absl::FromUnixMinutes(x) <= t1;
+ b = x < absl::ToUnixHours(t1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: absl::FromUnixHours(x) < t1;
+
+ // A long expression
+ bool some_condition;
+ int very_very_very_very_long_variable_name;
+ absl::Time SomeTime;
+ if (some_condition && very_very_very_very_long_variable_name
+ < absl::ToUnixSeconds(SomeTime)) {
+ // CHECK-MESSAGES: [[@LINE-2]]:25: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: if (some_condition && absl::FromUnixSeconds(very_very_very_very_long_variable_name) < SomeTime) {
+ return;
+ }
+
+ // A complex expression
+ int y;
+ b = (y + 5) * 10 > absl::ToUnixMillis(t1);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: absl::FromUnixMillis((y + 5) * 10) > t1;
+
+ // 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::ToUnixSeconds(t1));
+ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: VALUE_IF(1, absl::FromUnixSeconds(5) > t1);
+#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::ToUnixSeconds(t1));
+ // CHECK-MESSAGES: [[@LINE-1]]:24: warning: perform comparison in the time domain [abseil-time-comparison]
+ // CHECK-FIXES: VALUE_IF(1, absl::FromUnixSeconds(5) > t1);
+#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, t1, Unix);
+#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, t1, Unix);
+#undef VALUE_IF
+#undef VALUE_IF_2
+
+ // These should not match
+ b = 6 < 4;
+
+#define TODOUBLE(x) absl::ToUnixSeconds(x)
+ b = 5.0 > TODOUBLE(t1);
+#undef TODOUBLE
+#define THIRTY 30.0
+ b = THIRTY > absl::ToUnixSeconds(t1);
+#undef THIRTY
+}
diff --git a/test/clang-tidy/abseil-time-subtraction.cpp b/test/clang-tidy/abseil-time-subtraction.cpp
new file mode 100644
index 00000000..6f5d4b45
--- /dev/null
+++ b/test/clang-tidy/abseil-time-subtraction.cpp
@@ -0,0 +1,117 @@
+// RUN: %check_clang_tidy %s abseil-time-subtraction %t -- -- -I%S/Inputs
+
+#include "absl/time/time.h"
+
+void g(absl::Duration d);
+
+void f() {
+ absl::Time t;
+ int x, y;
+ absl::Duration d;
+
+ d = absl::Hours(absl::ToUnixHours(t) - x);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: d = (t - absl::FromUnixHours(x));
+ d = absl::Minutes(absl::ToUnixMinutes(t) - x);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: d = (t - absl::FromUnixMinutes(x));
+ d = absl::Seconds(absl::ToUnixSeconds(t) - x);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: d = (t - absl::FromUnixSeconds(x));
+ d = absl::Milliseconds(absl::ToUnixMillis(t) - x);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: d = (t - absl::FromUnixMillis(x));
+ d = absl::Microseconds(absl::ToUnixMicros(t) - x);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: d = (t - absl::FromUnixMicros(x));
+ d = absl::Nanoseconds(absl::ToUnixNanos(t) - x);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: d = (t - absl::FromUnixNanos(x));
+
+ y = x - absl::ToUnixHours(t);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: y = absl::ToInt64Hours(absl::FromUnixHours(x) - t);
+ y = x - absl::ToUnixMinutes(t);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: y = absl::ToInt64Minutes(absl::FromUnixMinutes(x) - t);
+ y = x - absl::ToUnixSeconds(t);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: y = absl::ToInt64Seconds(absl::FromUnixSeconds(x) - t);
+ y = x - absl::ToUnixMillis(t);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: y = absl::ToInt64Milliseconds(absl::FromUnixMillis(x) - t);
+ y = x - absl::ToUnixMicros(t);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: y = absl::ToInt64Microseconds(absl::FromUnixMicros(x) - t);
+ y = x - absl::ToUnixNanos(t);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: y = absl::ToInt64Nanoseconds(absl::FromUnixNanos(x) - t);
+
+ // Check parenthesis placement
+ d = 5 * absl::Seconds(absl::ToUnixSeconds(t) - x);
+ // CHECK-MESSAGES: [[@LINE-1]]:11: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: d = 5 * (t - absl::FromUnixSeconds(x));
+ d = absl::Seconds(absl::ToUnixSeconds(t) - x) / 5;
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: d = (t - absl::FromUnixSeconds(x)) / 5;
+
+ // No extra parens around arguments
+ g(absl::Seconds(absl::ToUnixSeconds(t) - x));
+ // CHECK-MESSAGES: [[@LINE-1]]:5: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: g(t - absl::FromUnixSeconds(x));
+ g(absl::Seconds(x - absl::ToUnixSeconds(t)));
+ // CHECK-MESSAGES: [[@LINE-1]]:5: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: g(absl::FromUnixSeconds(x) - t);
+
+ // More complex subexpressions
+ d = absl::Hours(absl::ToUnixHours(t) - 5 * x);
+ // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: d = (t - absl::FromUnixHours(5 * x));
+
+ // These should not trigger; they are likely bugs
+ d = absl::Milliseconds(absl::ToUnixSeconds(t) - x);
+ d = absl::Seconds(absl::ToUnixMicros(t) - x);
+
+ // Various macro scenarios
+#define SUB(z, t1) z - absl::ToUnixSeconds(t1)
+ y = SUB(x, t);
+#undef SUB
+
+#define MILLIS(t1) absl::ToUnixMillis(t1)
+ y = x - MILLIS(t);
+#undef MILLIS
+
+#define HOURS(z) absl::Hours(z)
+ d = HOURS(absl::ToUnixHours(t) - x);
+#undef HOURS
+
+ // This should match the expression inside the macro invocation.
+#define SECONDS(z) absl::Seconds(z)
+ d = SECONDS(x - absl::ToUnixSeconds(t));
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: SECONDS(absl::ToInt64Seconds(absl::FromUnixSeconds(x) - t))
+#undef SECONDS
+}
+
+template<typename T>
+void func(absl::Time t, T x) {
+ absl::Duration d = absl::Seconds(absl::ToUnixSeconds(t) - x);
+ // CHECK-MESSAGES: [[@LINE-1]]:22: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: absl::Duration d = t - absl::FromUnixSeconds(x);
+}
+
+void g() {
+ func(absl::Now(), 5);
+}
+
+absl::Duration parens_in_return() {
+ absl::Time t;
+ int x;
+
+ return absl::Seconds(absl::ToUnixSeconds(t) - x);
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: return t - absl::FromUnixSeconds(x);
+ return absl::Seconds(x - absl::ToUnixSeconds(t));
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: perform subtraction in the time domain [abseil-time-subtraction]
+ // CHECK-FIXES: return absl::FromUnixSeconds(x) - t;
+}
diff --git a/test/clang-tidy/abseil-upgrade-duration-conversions.cpp b/test/clang-tidy/abseil-upgrade-duration-conversions.cpp
index 7d8ad43e..fed0f8bd 100644
--- a/test/clang-tidy/abseil-upgrade-duration-conversions.cpp
+++ b/test/clang-tidy/abseil-upgrade-duration-conversions.cpp
@@ -430,3 +430,36 @@ void factoryInMacros() {
factoryTemplateAndMacro<ConvertibleTo<int>>();
TemplateFactoryInMacro(ConvertibleTo<int>());
}
+
+// This is a reduced test-case for PR39949 and manifested in this check.
+namespace std {
+template <typename _Tp>
+_Tp declval();
+
+template <typename _Functor, typename... _ArgTypes>
+struct __res {
+ template <typename... _Args>
+ static decltype(declval<_Functor>()(_Args()...)) _S_test(int);
+
+ template <typename...>
+ static void _S_test(...);
+
+ typedef decltype(_S_test<_ArgTypes...>(0)) type;
+};
+
+template <typename>
+struct function;
+
+template <typename... _ArgTypes>
+struct function<void(_ArgTypes...)> {
+ template <typename _Functor,
+ typename = typename __res<_Functor, _ArgTypes...>::type>
+ function(_Functor) {}
+};
+} // namespace std
+
+typedef std::function<void(void)> F;
+
+F foo() {
+ return F([] {});
+}
diff --git a/test/clang-tidy/alternative-fixes.cpp b/test/clang-tidy/alternative-fixes.cpp
new file mode 100644
index 00000000..d5cee68d
--- /dev/null
+++ b/test/clang-tidy/alternative-fixes.cpp
@@ -0,0 +1,9 @@
+// RUN: %check_clang_tidy %s "llvm-namespace-comment,clang-diagnostic-*" %t
+void foo(int a) {
+ if (a = 1) {
+ // CHECK-NOTES: [[@LINE-1]]:9: warning: using the result of an assignment as a condition without parentheses [clang-diagnostic-parentheses]
+ // CHECK-NOTES: [[@LINE-2]]:9: note: place parentheses around the assignment to silence this warning
+ // CHECK-NOTES: [[@LINE-3]]:9: note: use '==' to turn this assignment into an equality comparison
+ // CHECK-FIXES: if ((a = 1)) {
+ }
+}
diff --git a/test/clang-tidy/bugprone-argument-comment-literals.cpp b/test/clang-tidy/bugprone-argument-comment-literals.cpp
new file mode 100644
index 00000000..739c9a59
--- /dev/null
+++ b/test/clang-tidy/bugprone-argument-comment-literals.cpp
@@ -0,0 +1,124 @@
+// RUN: %check_clang_tidy %s bugprone-argument-comment %t -- \
+// RUN: -config="{CheckOptions: [{key: CommentBoolLiterals, value: 1},{key: CommentIntegerLiterals, value: 1}, {key: CommentFloatLiterals, value: 1}, {key: CommentUserDefinedLiterals, value: 1}, {key: CommentStringLiterals, value: 1}, {key: CommentNullPtrs, value: 1}, {key: CommentCharacterLiterals, value: 1}]}" --
+
+struct A {
+ void foo(bool abc);
+ void foo(bool abc, bool cde);
+ void foo(const char *, bool abc);
+ void foo(int iabc);
+ void foo(float fabc);
+ void foo(double dabc);
+ void foo(const char *strabc);
+ void fooW(const wchar_t *wstrabc);
+ void fooPtr(A *ptrabc);
+ void foo(char chabc);
+};
+
+#define FOO 1
+
+void g(int a);
+void h(double b);
+void i(const char *c);
+
+double operator"" _km(long double);
+
+void test() {
+ A a;
+
+ a.foo(true);
+ // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment]
+ // CHECK-FIXES: a.foo(/*abc=*/true);
+
+ a.foo(false);
+ // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment]
+ // CHECK-FIXES: a.foo(/*abc=*/false);
+
+ a.foo(true, false);
+ // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment]
+ // CHECK-MESSAGES: [[@LINE-2]]:15: warning: argument comment missing for literal argument 'cde' [bugprone-argument-comment]
+ // CHECK-FIXES: a.foo(/*abc=*/true, /*cde=*/false);
+
+ a.foo(false, true);
+ // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment]
+ // CHECK-MESSAGES: [[@LINE-2]]:16: warning: argument comment missing for literal argument 'cde' [bugprone-argument-comment]
+ // CHECK-FIXES: a.foo(/*abc=*/false, /*cde=*/true);
+
+ a.foo(/*abc=*/false, true);
+ // CHECK-MESSAGES: [[@LINE-1]]:24: warning: argument comment missing for literal argument 'cde' [bugprone-argument-comment]
+ // CHECK-FIXES: a.foo(/*abc=*/false, /*cde=*/true);
+
+ a.foo(false, /*cde=*/true);
+ // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment]
+ // CHECK-FIXES: a.foo(/*abc=*/false, /*cde=*/true);
+
+ bool val1 = true;
+ bool val2 = false;
+ a.foo(val1, val2);
+
+ a.foo("", true);
+ // CHECK-MESSAGES: [[@LINE-1]]:13: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment]
+ // CHECK-FIXES: a.foo("", /*abc=*/true);
+
+ a.foo(0);
+ // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'iabc' [bugprone-argument-comment]
+ // CHECK-FIXES: a.foo(/*iabc=*/0);
+
+ a.foo(1.0f);
+ // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'fabc' [bugprone-argument-comment]
+ // CHECK-FIXES: a.foo(/*fabc=*/1.0f);
+
+ a.foo(1.0);
+ // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'dabc' [bugprone-argument-comment]
+ // CHECK-FIXES: a.foo(/*dabc=*/1.0);
+
+ int val3 = 10;
+ a.foo(val3);
+
+ float val4 = 10.0;
+ a.foo(val4);
+
+ double val5 = 10.0;
+ a.foo(val5);
+
+ a.foo("Hello World");
+ // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'strabc' [bugprone-argument-comment]
+ // CHECK-FIXES: a.foo(/*strabc=*/"Hello World");
+ //
+ a.fooW(L"Hello World");
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: argument comment missing for literal argument 'wstrabc' [bugprone-argument-comment]
+ // CHECK-FIXES: a.fooW(/*wstrabc=*/L"Hello World");
+
+ a.fooPtr(nullptr);
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: argument comment missing for literal argument 'ptrabc' [bugprone-argument-comment]
+ // CHECK-FIXES: a.fooPtr(/*ptrabc=*/nullptr);
+
+ a.foo(402.0_km);
+ // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'dabc' [bugprone-argument-comment]
+ // CHECK-FIXES: a.foo(/*dabc=*/402.0_km);
+
+ a.foo('A');
+ // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'chabc' [bugprone-argument-comment]
+ // CHECK-FIXES: a.foo(/*chabc=*/'A');
+
+ g(FOO);
+ h(1.0f);
+ // CHECK-MESSAGES: [[@LINE-1]]:5: warning: argument comment missing for literal argument 'b' [bugprone-argument-comment]
+ // CHECK-FIXES: h(/*b=*/1.0f);
+ i(__FILE__);
+
+ // FIXME Would like the below to add argument comments.
+ g((1));
+ // FIXME But we should not add argument comments here.
+ g(_Generic(0, int : 0));
+}
+
+void f(bool _with_underscores_);
+void ignores_underscores() {
+ f(false);
+ // CHECK-MESSAGES: [[@LINE-1]]:5: warning: argument comment missing for literal argument '_with_underscores_' [bugprone-argument-comment]
+ // CHECK-FIXES: f(/*_with_underscores_=*/false);
+
+ f(true);
+ // CHECK-MESSAGES: [[@LINE-1]]:5: warning: argument comment missing for literal argument
+ // CHECK-FIXES: f(/*_with_underscores_=*/true);
+}
diff --git a/test/clang-tidy/bugprone-exception-escape-openmp.cpp b/test/clang-tidy/bugprone-exception-escape-openmp.cpp
new file mode 100644
index 00000000..101c339b
--- /dev/null
+++ b/test/clang-tidy/bugprone-exception-escape-openmp.cpp
@@ -0,0 +1,29 @@
+// RUN: %check_clang_tidy %s bugprone-exception-escape %t -- -extra-arg=-fopenmp=libomp -extra-arg=-fexceptions --
+
+int thrower() {
+ throw 42;
+}
+
+void ok_parallel() {
+#pragma omp parallel
+ thrower();
+}
+
+void bad_for_header_XFAIL(const int a) noexcept {
+#pragma omp for
+ for (int i = 0; i < thrower(); i++)
+ ;
+ // FIXME: this really should be caught by bugprone-exception-escape.
+ // https://bugs.llvm.org/show_bug.cgi?id=41102
+}
+
+void ok_forloop(const int a) {
+#pragma omp for
+ for (int i = 0; i < a; i++)
+ thrower();
+}
+
+void some_exception_just_so_that_check_clang_tidy_shuts_up() noexcept {
+ thrower();
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:6: warning: an exception may be thrown in function 'some_exception_just_so_that_check_clang_tidy_shuts_up' which should not throw exceptions
diff --git a/test/clang-tidy/bugprone-parent-virtual-call.cpp b/test/clang-tidy/bugprone-parent-virtual-call.cpp
index ad845886..ad845886 100755..100644
--- a/test/clang-tidy/bugprone-parent-virtual-call.cpp
+++ b/test/clang-tidy/bugprone-parent-virtual-call.cpp
diff --git a/test/clang-tidy/bugprone-sizeof-expression.cpp b/test/clang-tidy/bugprone-sizeof-expression.cpp
index 683ad083..57b73ea4 100644
--- a/test/clang-tidy/bugprone-sizeof-expression.cpp
+++ b/test/clang-tidy/bugprone-sizeof-expression.cpp
@@ -231,6 +231,35 @@ int Test5() {
return sum;
}
+int Test6() {
+ int sum = 0;
+
+ struct S A = AsStruct(), B = AsStruct();
+ struct S *P = &A, *Q = &B;
+ sum += sizeof(struct S) == P - Q;
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+ sum += 5 * sizeof(S) != P - Q;
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+ sum += sizeof(S) < P - Q;
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+ sum += 5 * sizeof(S) <= P - Q;
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+ sum += 5 * sizeof(*P) >= P - Q;
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+ sum += Q - P > 3 * sizeof(*P);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+ sum += sizeof(S) + (P - Q);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+ sum += 5 * sizeof(S) - (P - Q);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+ sum += (P - Q) / sizeof(S);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+ sum += (P - Q) / sizeof(*Q);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+
+ return sum;
+}
+
int ValidExpressions() {
int A[] = {1, 2, 3, 4};
static const char str[] = "hello";
diff --git a/test/clang-tidy/bugprone-string-constructor.cpp b/test/clang-tidy/bugprone-string-constructor.cpp
index 3ab4f424..9e11a32a 100644
--- a/test/clang-tidy/bugprone-string-constructor.cpp
+++ b/test/clang-tidy/bugprone-string-constructor.cpp
@@ -65,3 +65,11 @@ void Valid() {
std::string s2("test", 3);
std::string s3("test");
}
+
+namespace instantiation_dependent_exprs {
+template<typename T>
+struct S {
+ bool x;
+ std::string f() { return x ? "a" : "b"; }
+};
+}
diff --git a/test/clang-tidy/bugprone-string-integer-assignment.cpp b/test/clang-tidy/bugprone-string-integer-assignment.cpp
index c4e13fc4..18fe5ef4 100644
--- a/test/clang-tidy/bugprone-string-integer-assignment.cpp
+++ b/test/clang-tidy/bugprone-string-integer-assignment.cpp
@@ -7,18 +7,29 @@ struct basic_string {
basic_string& operator=(basic_string);
basic_string& operator+=(T);
basic_string& operator+=(basic_string);
+ const T &operator[](int i) const;
+ T &operator[](int i);
};
typedef basic_string<char> string;
typedef basic_string<wchar_t> wstring;
+
+int tolower(int i);
+int toupper(int i);
}
+int tolower(int i);
+int toupper(int i);
+
typedef int MyArcaneChar;
+constexpr char kCharConstant = 'a';
+
int main() {
std::string s;
std::wstring ws;
int x = 5;
+ const char c = 'c';
s = 6;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: an integer is interpreted as a character code when assigning {{.*}} [bugprone-string-integer-assignment]
@@ -47,7 +58,52 @@ int main() {
std::basic_string<MyArcaneChar> as;
as = 6;
-// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: an integer is interpreted as a chara
-// CHECK-FIXES: {{^}} as = 6;{{$}}
+ as = static_cast<MyArcaneChar>(6);
+ as = 'a';
+
+ s += toupper(x);
+ s += tolower(x);
+ s += (std::tolower(x));
+
+ s += c & s[1];
+ s += c ^ s[1];
+ s += c | s[1];
+
+ s[x] += 1;
+ s += s[x];
+ as += as[x];
+
+ // Likely character expressions.
+ s += x & 0xff;
+ s += 0xff & x;
+ s += x % 26;
+ s += 26 % x;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: an integer is interpreted as a chara
+ // CHECK-FIXES: {{^}} s += std::to_string(26 % x);{{$}}
+ s += c | 0x80;
+ s += c | 0x8000;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: an integer is interpreted as a chara
+ // CHECK-FIXES: {{^}} s += std::to_string(c | 0x8000);{{$}}
+ as += c | 0x8000;
+
+ s += 'a' + (x % 26);
+ s += kCharConstant + (x % 26);
+ s += 'a' + (s[x] & 0xf);
+ s += (x % 10) + 'b';
+
+ s += x > 255 ? c : x;
+ s += x > 255 ? 12 : x;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: an integer is interpreted as a chara
+ // CHECK-FIXES: {{^}} s += std::to_string(x > 255 ? 12 : x);{{$}}
+}
+
+namespace instantiation_dependent_exprs {
+template<typename T>
+struct S {
+ static constexpr T t = 0x8000;
+ std::string s;
+ void f(char c) { s += c | static_cast<int>(t); }
+};
+template S<int>;
}
diff --git a/test/clang-tidy/bugprone-too-small-loop-variable-magniute-bits-upper-limit.cpp b/test/clang-tidy/bugprone-too-small-loop-variable-magniute-bits-upper-limit.cpp
new file mode 100644
index 00000000..d602a1d0
--- /dev/null
+++ b/test/clang-tidy/bugprone-too-small-loop-variable-magniute-bits-upper-limit.cpp
@@ -0,0 +1,23 @@
+// RUN: %check_clang_tidy %s bugprone-too-small-loop-variable %t -- -- --target=x86_64-linux
+
+// MagnitudeBitsUpperLimit = 16 (default value)
+
+unsigned long size() { return 294967296l; }
+
+void voidFilteredOutForLoop1() {
+ for (long i = 0; i < size(); ++i) {
+ // no warning
+ }
+}
+
+void voidCaughtForLoop1() {
+ for (int i = 0; i < size(); ++i) {
+ // no warning
+ }
+}
+
+void voidCaughtForLoop2() {
+ for (short i = 0; i < size(); ++i) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: loop variable has narrower type 'short' than iteration's upper bound 'unsigned long' [bugprone-too-small-loop-variable]
+ }
+}
diff --git a/test/clang-tidy/bugprone-too-small-loop-variable.cpp b/test/clang-tidy/bugprone-too-small-loop-variable.cpp
index f11dd499..5a633559 100644
--- a/test/clang-tidy/bugprone-too-small-loop-variable.cpp
+++ b/test/clang-tidy/bugprone-too-small-loop-variable.cpp
@@ -1,4 +1,8 @@
-// RUN: %check_clang_tidy %s bugprone-too-small-loop-variable %t -- -- --target=x86_64-linux
+// RUN: %check_clang_tidy %s bugprone-too-small-loop-variable %t -- \
+// RUN: -config="{CheckOptions: \
+// RUN: [{key: bugprone-too-small-loop-variable.MagnitudeBitsUpperLimit, \
+// RUN: value: 1024}]}" \
+// RUN: -- --target=x86_64-linux
long size() { return 294967296l; }
diff --git a/test/clang-tidy/check_clang_tidy.py b/test/clang-tidy/check_clang_tidy.py
index 9768011a..5d808f40 100755
--- a/test/clang-tidy/check_clang_tidy.py
+++ b/test/clang-tidy/check_clang_tidy.py
@@ -2,10 +2,9 @@
#
#===- 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.
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
#===------------------------------------------------------------------------===#
diff --git a/test/clang-tidy/clang-tidy-diff.cpp b/test/clang-tidy/clang-tidy-diff.cpp
index 146287bf..2e18a43c 100644
--- a/test/clang-tidy/clang-tidy-diff.cpp
+++ b/test/clang-tidy/clang-tidy-diff.cpp
@@ -23,5 +23,4 @@ struct B : public A {
// CHECK-QUIET-NOT: warning:
};
// CHECK-SANITY-NOT: Suppressed
-// CHECK: Suppressed 1 warnings (1 due to line filter).
// CHECK-QUIET-NOT: Suppressed
diff --git a/test/clang-tidy/clang-tidy-mac-libcxx.cpp b/test/clang-tidy/clang-tidy-mac-libcxx.cpp
index 153a5d6e..d124a344 100644
--- a/test/clang-tidy/clang-tidy-mac-libcxx.cpp
+++ b/test/clang-tidy/clang-tidy-mac-libcxx.cpp
@@ -8,7 +8,7 @@
// 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: echo '[{"directory":"%t","command":"%t/mock-libcxx/bin/clang++ -stdlib=libc++ -std=c++11 -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'
diff --git a/test/clang-tidy/cppcoreguidelines-macro-usage.cpp b/test/clang-tidy/cppcoreguidelines-macro-usage.cpp
index a4948f5b..edce328e 100644
--- a/test/clang-tidy/cppcoreguidelines-macro-usage.cpp
+++ b/test/clang-tidy/cppcoreguidelines-macro-usage.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-macro-usage %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-macro-usage %t -- -header-filter=.* -system-headers --
#ifndef INCLUDE_GUARD
#define INCLUDE_GUARD
diff --git a/test/clang-tidy/expand-modular-headers-ppcallbacks.cpp b/test/clang-tidy/expand-modular-headers-ppcallbacks.cpp
new file mode 100644
index 00000000..d191922d
--- /dev/null
+++ b/test/clang-tidy/expand-modular-headers-ppcallbacks.cpp
@@ -0,0 +1,35 @@
+// Sanity-check. Run without modules:
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: cp %S/Inputs/expand-modular-headers-ppcallbacks/* %t/
+// RUN: %check_clang_tidy %s readability-identifier-naming %t/without-modules -- \
+// RUN: -config="CheckOptions: [{ \
+// RUN: key: readability-identifier-naming.MacroDefinitionCase, value: UPPER_CASE }]" \
+// RUN: -header-filter=.* \
+// RUN: -- -x c++ -std=c++11 -I%t/
+//
+// Run clang-tidy on a file with modular includes:
+//
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: cp %S/Inputs/expand-modular-headers-ppcallbacks/* %t/
+// RUN: %check_clang_tidy %s readability-identifier-naming %t/with-modules -- \
+// RUN: -config="CheckOptions: [{ \
+// RUN: key: readability-identifier-naming.MacroDefinitionCase, value: UPPER_CASE }]" \
+// RUN: -header-filter=.* \
+// RUN: -- -x c++ -std=c++11 -I%t/ \
+// RUN: -fmodules -fimplicit-modules -fno-implicit-module-maps \
+// RUN: -fmodule-map-file=%t/module.modulemap \
+// RUN: -fmodules-cache-path=%t/module-cache/
+#include "c.h"
+
+// CHECK-MESSAGES: a.h:1:9: warning: invalid case style for macro definition 'a' [readability-identifier-naming]
+// CHECK-MESSAGES: a.h:1:9: note: FIX-IT applied suggested code changes
+// CHECK-MESSAGES: b.h:2:9: warning: invalid case style for macro definition 'b'
+// CHECK-MESSAGES: b.h:2:9: note: FIX-IT applied suggested code changes
+// CHECK-MESSAGES: c.h:2:9: warning: invalid case style for macro definition 'c'
+// CHECK-MESSAGES: c.h:2:9: note: FIX-IT applied suggested code changes
+
+#define m
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for macro definition 'm'
+// CHECK-MESSAGES: :[[@LINE-2]]:9: note: FIX-IT applied suggested code changes
diff --git a/test/clang-tidy/export-diagnostics.cpp b/test/clang-tidy/export-diagnostics.cpp
index 5eda2042..14a6a40d 100644
--- a/test/clang-tidy/export-diagnostics.cpp
+++ b/test/clang-tidy/export-diagnostics.cpp
@@ -13,16 +13,19 @@ X(f)
// 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: DiagnosticMessage:
+// CHECK-YAML-NEXT: Message: 'no previous prototype for function
+// ''ff'''
+// CHECK-YAML-NEXT: FilePath: '{{.*}}-input.cpp'
+// CHECK-YAML-NEXT: FileOffset: 30
+// CHECK-YAML-NEXT: Replacements: []
// 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: Replacements: []
// CHECK-YAML-NEXT: - Message: expanded from here
// CHECK-YAML-NEXT: FilePath: ''
// CHECK-YAML-NEXT: FileOffset: 0
-// CHECK-YAML-NEXT: Replacements: []
+// CHECK-YAML-NEXT: Replacements: []
// CHECK-YAML-NEXT: ...
-
diff --git a/test/clang-tidy/google-objc-function-naming.m b/test/clang-tidy/google-objc-function-naming.m
index d0336d26..01433d9f 100644
--- a/test/clang-tidy/google-objc-function-naming.m
+++ b/test/clang-tidy/google-objc-function-naming.m
@@ -1,4 +1,12 @@
-// RUN: %check_clang_tidy %s google-objc-function-naming %t
+// RUN: %check_clang_tidy %s google-objc-function-naming %t -- -- -isystem %S/Inputs/Headers
+
+#include <stdio.h>
+
+static void TestImplicitFunctionDeclaration(int a) {
+ // Call a builtin function so that the compiler generates an implicit
+ // function declaration.
+ printf("%d", a);
+}
typedef _Bool bool;
diff --git a/test/clang-tidy/google-objc-global-variable-declaration.mm b/test/clang-tidy/google-objc-global-variable-declaration.mm
new file mode 100644
index 00000000..a6b0f6ee
--- /dev/null
+++ b/test/clang-tidy/google-objc-global-variable-declaration.mm
@@ -0,0 +1,10 @@
+// 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";
+
+class MyTest {
+ static int not_objc_style;
+};
diff --git a/test/clang-tidy/google-runtime-int.m b/test/clang-tidy/google-runtime-int.m
new file mode 100644
index 00000000..dd1225c9
--- /dev/null
+++ b/test/clang-tidy/google-runtime-int.m
@@ -0,0 +1,32 @@
+// RUN: clang-tidy -checks=-*,google-runtime-int %s 2>&1 -- | count 0
+// RUN: clang-tidy -checks=-*,google-runtime-int %s 2>&1 -- -x objective-c++ | count 0
+
+typedef long NSInteger;
+typedef unsigned long NSUInteger;
+
+@interface NSString
+@property(readonly) NSInteger integerValue;
+@property(readonly) long long longLongValue;
+@property(readonly) NSUInteger length;
+@end
+
+NSInteger Foo(NSString *s) {
+ return [s integerValue];
+}
+
+long long Bar(NSString *s) {
+ return [s longLongValue];
+}
+
+NSUInteger Baz(NSString *s) {
+ return [s length];
+}
+
+unsigned short NSSwapShort(unsigned short inv);
+
+long DoSomeMath(long a, short b) {
+ short c = NSSwapShort(b);
+ long a2 = a * 5L;
+ return a2 + c;
+}
+
diff --git a/test/clang-tidy/llvm-prefer-isa-or-dyn-cast-in-conditionals.cpp b/test/clang-tidy/llvm-prefer-isa-or-dyn-cast-in-conditionals.cpp
new file mode 100644
index 00000000..48652d52
--- /dev/null
+++ b/test/clang-tidy/llvm-prefer-isa-or-dyn-cast-in-conditionals.cpp
@@ -0,0 +1,132 @@
+// RUN: %check_clang_tidy %s llvm-prefer-isa-or-dyn-cast-in-conditionals %t
+
+struct X;
+struct Y;
+struct Z {
+ int foo();
+ X *bar();
+ X *cast(Y*);
+ bool baz(Y*);
+};
+
+template <class X, class Y>
+bool isa(Y *);
+template <class X, class Y>
+X *cast(Y *);
+template <class X, class Y>
+X *dyn_cast(Y *);
+template <class X, class Y>
+X *dyn_cast_or_null(Y *);
+
+bool foo(Y *y, Z *z) {
+ if (auto x = cast<X>(y))
+ return true;
+ // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: cast<> in conditional will assert rather than return a null pointer [llvm-prefer-isa-or-dyn-cast-in-conditionals]
+ // CHECK-FIXES: if (auto x = dyn_cast<X>(y))
+
+ while (auto x = cast<X>(y))
+ break;
+ // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: cast<> in conditional
+ // CHECK-FIXES: while (auto x = dyn_cast<X>(y))
+
+ if (cast<X>(y))
+ return true;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: cast<> in conditional
+ // CHECK-FIXES: if (isa<X>(y))
+
+ while (cast<X>(y))
+ break;
+ // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: cast<> in conditional
+ // CHECK-FIXES: while (isa<X>(y))
+
+ do {
+ break;
+ } while (cast<X>(y));
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: cast<> in conditional
+ // CHECK-FIXES: while (isa<X>(y));
+
+ if (dyn_cast<X>(y))
+ return true;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: return value from dyn_cast<> not used [llvm-prefer-isa-or-dyn-cast-in-conditionals]
+ // CHECK-FIXES: if (isa<X>(y))
+
+ while (dyn_cast<X>(y))
+ break;
+ // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: return value from dyn_cast<> not used
+ // CHECK-FIXES: while (isa<X>(y))
+
+ do {
+ break;
+ } while (dyn_cast<X>(y));
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: return value from dyn_cast<> not used
+ // CHECK-FIXES: while (isa<X>(y));
+
+ if (y && isa<X>(y))
+ return true;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred over an explicit test for null followed by calling isa<> [llvm-prefer-isa-or-dyn-cast-in-conditionals]
+ // CHECK-FIXES: if (isa_and_nonnull<X>(y))
+
+ if (z->bar() && isa<Y>(z->bar()))
+ return true;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred
+ // CHECK-FIXES: if (isa_and_nonnull<Y>(z->bar()))
+
+ if (z->bar() && cast<Y>(z->bar()))
+ return true;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred
+ // CHECK-FIXES: if (isa_and_nonnull<Y>(z->bar()))
+
+ if (z->bar() && dyn_cast<Y>(z->bar()))
+ return true;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred
+ // CHECK-FIXES: if (isa_and_nonnull<Y>(z->bar()))
+
+ if (z->bar() && dyn_cast_or_null<Y>(z->bar()))
+ return true;
+ // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred
+ // CHECK-FIXES: if (isa_and_nonnull<Y>(z->bar()))
+
+ bool b = z->bar() && cast<Y>(z->bar());
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: isa_and_nonnull<> is preferred
+ // CHECK-FIXES: bool b = isa_and_nonnull<Y>(z->bar());
+
+ // These don't trigger a warning.
+ if (auto x = cast<Z>(y)->foo())
+ return true;
+ if (auto x = z->cast(y))
+ return true;
+ while (auto x = cast<Z>(y)->foo())
+ break;
+ if (cast<Z>(y)->foo())
+ return true;
+ if (z->cast(y))
+ return true;
+ while (cast<Z>(y)->foo())
+ break;
+ if (y && cast<X>(z->bar()))
+ return true;
+ if (z && cast<Z>(y)->foo())
+ return true;
+ bool b2 = y && cast<X>(z);
+ if(z->cast(y))
+ return true;
+ if (z->baz(cast<Y>(z)))
+ return true;
+
+#define CAST(T, Obj) cast<T>(Obj)
+#define AUTO_VAR_CAST(X, Y, Z) auto X = cast<Y>(Z)
+#define ISA(T, Obj) isa<T>(Obj)
+#define ISA_OR_NULL(T, Obj) Obj &&isa<T>(Obj)
+
+ // Macros don't trigger warning.
+ if (auto x = CAST(X, y))
+ return true;
+ if (AUTO_VAR_CAST(x, X, z))
+ return true;
+ if (z->bar() && ISA(Y, z->bar()))
+ return true;
+ if (ISA_OR_NULL(Y, z->bar()))
+ return true;
+
+ return false;
+}
diff --git a/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp b/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp
index 31052716..2a93ff6a 100644
--- a/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp
+++ b/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp
@@ -35,6 +35,23 @@ 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.
diff --git a/test/clang-tidy/modernize-avoid-bind.cpp b/test/clang-tidy/modernize-avoid-bind.cpp
index 1c78b9e6..721801be 100644
--- a/test/clang-tidy/modernize-avoid-bind.cpp
+++ b/test/clang-tidy/modernize-avoid-bind.cpp
@@ -77,3 +77,47 @@ void n() {
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
// CHECK-FIXES: auto clj = [] { return C::add(1, 1); };
}
+
+// Let's fake a minimal std::function-like facility.
+namespace std {
+template <typename _Tp>
+_Tp declval();
+
+template <typename _Functor, typename... _ArgTypes>
+struct __res {
+ template <typename... _Args>
+ static decltype(declval<_Functor>()(_Args()...)) _S_test(int);
+
+ template <typename...>
+ static void _S_test(...);
+
+ using type = decltype(_S_test<_ArgTypes...>(0));
+};
+
+template <typename>
+struct function;
+
+template <typename... _ArgTypes>
+struct function<void(_ArgTypes...)> {
+ template <typename _Functor,
+ typename = typename __res<_Functor, _ArgTypes...>::type>
+ function(_Functor) {}
+};
+} // namespace std
+
+struct Thing {};
+void UseThing(Thing *);
+
+struct Callback {
+ Callback();
+ Callback(std::function<void()>);
+ void Reset(std::function<void()>);
+};
+
+void test(Thing *t) {
+ Callback cb;
+ if (t)
+ cb.Reset(std::bind(UseThing, t));
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
+ // CHECK-FIXES: cb.Reset([=] { return UseThing(t); });
+}
diff --git a/test/clang-tidy/modernize-avoid-c-arrays-ignores-main.cpp b/test/clang-tidy/modernize-avoid-c-arrays-ignores-main.cpp
new file mode 100644
index 00000000..6549422f
--- /dev/null
+++ b/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/test/clang-tidy/modernize-avoid-c-arrays-ignores-three-arg-main.cpp b/test/clang-tidy/modernize-avoid-c-arrays-ignores-three-arg-main.cpp
new file mode 100644
index 00000000..22a4016f
--- /dev/null
+++ b/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/test/clang-tidy/modernize-redundant-void-arg.cpp b/test/clang-tidy/modernize-redundant-void-arg.cpp
index 44a726b5..0fad5d55 100644
--- a/test/clang-tidy/modernize-redundant-void-arg.cpp
+++ b/test/clang-tidy/modernize-redundant-void-arg.cpp
@@ -489,6 +489,13 @@ void lambda_expression_with_macro_test(){
// CHECK-FIXES: []() BODY;
}
+namespace qqq {
+void foo() BODY
+void bar(void) BODY;
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: redundant void argument list in function definition
+// CHECK-FIXES: void bar() 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]
diff --git a/test/clang-tidy/modernize-use-default-member-init-assignment.cpp b/test/clang-tidy/modernize-use-default-member-init-assignment.cpp
index fdc0db18..b98055c9 100644
--- a/test/clang-tidy/modernize-use-default-member-init-assignment.cpp
+++ b/test/clang-tidy/modernize-use-default-member-init-assignment.cpp
@@ -166,6 +166,14 @@ struct PositiveEnum {
// CHECK-FIXES: Enum e = Foo;
};
+struct PositiveValueEnum {
+ PositiveValueEnum() : e() {}
+ // CHECK-FIXES: PositiveValueEnum() {}
+ Enum e;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'e'
+ // CHECK-FIXES: Enum e{};
+};
+
struct PositiveString {
PositiveString() : s("foo") {}
// CHECK-FIXES: PositiveString() {}
diff --git a/test/clang-tidy/modernize-use-default-member-init.cpp b/test/clang-tidy/modernize-use-default-member-init.cpp
index 0ed65df3..825bfa0b 100644
--- a/test/clang-tidy/modernize-use-default-member-init.cpp
+++ b/test/clang-tidy/modernize-use-default-member-init.cpp
@@ -165,6 +165,14 @@ struct PositiveEnum {
// CHECK-FIXES: Enum e{Foo};
};
+struct PositiveValueEnum {
+ PositiveValueEnum() : e() {}
+ // CHECK-FIXES: PositiveValueEnum() {}
+ Enum e;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'e'
+ // CHECK-FIXES: Enum e{};
+};
+
struct PositiveString {
PositiveString() : s("foo") {}
// CHECK-FIXES: PositiveString() {}
@@ -382,6 +390,16 @@ struct ExistingString {
const char *e4 = "bar";
};
+struct UnionExisting {
+ UnionExisting() : e(5.0) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: member initializer for 'e' is redundant
+ // CHECK-FIXES: UnionExisting() {}
+ union {
+ int i;
+ double e = 5.0;
+ };
+};
+
template <typename T>
struct NegativeTemplateExisting {
NegativeTemplateExisting(int) : t(0) {}
diff --git a/test/clang-tidy/modernize-use-override-no-destructors.cpp b/test/clang-tidy/modernize-use-override-no-destructors.cpp
new file mode 100644
index 00000000..eaadb07b
--- /dev/null
+++ b/test/clang-tidy/modernize-use-override-no-destructors.cpp
@@ -0,0 +1,16 @@
+// RUN: %check_clang_tidy %s modernize-use-override %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-override.IgnoreDestructors, value: 1}]}" \
+// RUN: -- -std=c++11
+
+struct Base {
+ virtual ~Base();
+ virtual void f();
+};
+
+struct Simple : public Base {
+ virtual ~Simple();
+ // CHECK-MESSAGES-NOT: warning:
+ virtual void f();
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} void f() override;
+};
diff --git a/test/clang-tidy/modernize-use-override-with-macro.cpp b/test/clang-tidy/modernize-use-override-with-macro.cpp
new file mode 100644
index 00000000..ad682f15
--- /dev/null
+++ b/test/clang-tidy/modernize-use-override-with-macro.cpp
@@ -0,0 +1,70 @@
+// RUN: %check_clang_tidy %s modernize-use-override %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-override.OverrideSpelling, value: 'OVERRIDE'},{key: modernize-use-override.FinalSpelling, value: 'FINAL'}]}" \
+// RUN: -- -std=c++11
+
+#define ABSTRACT = 0
+
+#define OVERRIDE override
+#define FINAL final
+#define VIRTUAL virtual
+#define NOT_VIRTUAL
+#define NOT_OVERRIDE
+
+#define MUST_USE_RESULT __attribute__((warn_unused_result))
+#define UNUSED __attribute__((unused))
+
+struct Base {
+ virtual ~Base() {}
+ virtual void a();
+ virtual void b();
+ virtual void c();
+ virtual void e() = 0;
+ virtual void f2() const = 0;
+ virtual void g() = 0;
+ virtual void j() const;
+ virtual void k() = 0;
+ virtual void l() const;
+};
+
+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 function with 'OVERRIDE' or (rarely) 'FINAL' [modernize-use-override]
+ // CHECK-FIXES: {{^}} void a() OVERRIDE;
+
+ virtual void b();
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using 'OVERRIDE' or (rarely) 'FINAL' instead of 'virtual' [modernize-use-override]
+ // CHECK-FIXES: {{^}} void b() OVERRIDE;
+
+ virtual void c();
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} void c() OVERRIDE;
+
+ virtual void e() = 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+ // CHECK-FIXES: {{^}} void e() 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 void k() OVERRIDE;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant since the function is already declared 'OVERRIDE' [modernize-use-override]
+ // CHECK-FIXES: {{^}} void k() OVERRIDE;
+
+ virtual void l() const OVERRIDE;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant since the function is already declared 'OVERRIDE' [modernize-use-override]
+ // CHECK-FIXES: {{^}} void l() const OVERRIDE;
+};
diff --git a/test/clang-tidy/modernize-use-override-with-no-macro-inscope.cpp b/test/clang-tidy/modernize-use-override-with-no-macro-inscope.cpp
new file mode 100644
index 00000000..97b71053
--- /dev/null
+++ b/test/clang-tidy/modernize-use-override-with-no-macro-inscope.cpp
@@ -0,0 +1,28 @@
+// RUN: %check_clang_tidy %s modernize-use-override %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-use-override.OverrideSpelling, value: 'CUSTOM_OVERRIDE'},{key: modernize-use-override.FinalSpelling, value: 'CUSTOM_FINAL'}]}" \
+// RUN: -- -std=c++11
+
+// As if the macro was not defined.
+//#define CUSTOM_OVERRIDE override
+//#define CUSTOM_FINAL override
+
+struct Base {
+ virtual ~Base() {}
+ virtual void a();
+ virtual void b();
+};
+
+struct SimpleCases : public Base {
+public:
+ virtual ~SimpleCases();
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using 'CUSTOM_OVERRIDE' or (rarely) 'CUSTOM_FINAL' instead of 'virtual' [modernize-use-override]
+ // CHECK-FIXES: {{^}} virtual ~SimpleCases();
+
+ void a();
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this function with 'CUSTOM_OVERRIDE' or (rarely) 'CUSTOM_FINAL' [modernize-use-override]
+ // CHECK-FIXES: {{^}} void a();
+
+ virtual void b();
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using 'CUSTOM_OVERRIDE' or (rarely) 'CUSTOM_FINAL' instead of 'virtual' [modernize-use-override]
+ // CHECK-FIXES: {{^}} virtual void b();
+};
diff --git a/test/clang-tidy/nolint.cpp b/test/clang-tidy/nolint.cpp
index 24c37228..a2d2c10a 100644
--- a/test/clang-tidy/nolint.cpp
+++ b/test/clang-tidy/nolint.cpp
@@ -31,6 +31,7 @@ void f() {
int i;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: unused variable 'i' [clang-diagnostic-unused-variable]
int j; // NOLINT
+ int k; // NOLINT(clang-diagnostic-unused-variable)
}
#define MACRO(X) class X { X(int i); };
@@ -47,4 +48,4 @@ MACRO_NOLINT
#define DOUBLE_MACRO MACRO(H) // NOLINT
DOUBLE_MACRO
-// CHECK-MESSAGES: Suppressed 12 warnings (12 NOLINT)
+// CHECK-MESSAGES: Suppressed 13 warnings (13 NOLINT)
diff --git a/test/clang-tidy/objc-property-declaration.m b/test/clang-tidy/objc-property-declaration.m
index 07a06205..b56bdcd1 100644
--- a/test/clang-tidy/objc-property-declaration.m
+++ b/test/clang-tidy/objc-property-declaration.m
@@ -46,6 +46,7 @@ typedef void *CGColorRef;
@property(strong, nonatomic) NSString *URLStr;
@property(assign, nonatomic) int abc_camelCase;
@property(strong, nonatomic) NSString *abc_URL;
+@property(strong, nonatomic) NSString *opac2_sourceComponent;
@end
@interface Foo ()
diff --git a/test/clang-tidy/objc-super-self.m b/test/clang-tidy/objc-super-self.m
new file mode 100644
index 00000000..9653cd22
--- /dev/null
+++ b/test/clang-tidy/objc-super-self.m
@@ -0,0 +1,86 @@
+// RUN: %check_clang_tidy %s objc-super-self %t
+
+@interface NSObject
+- (instancetype)init;
+- (instancetype)self;
+@end
+
+@interface NSObjectDerivedClass : NSObject
+@end
+
+@implementation NSObjectDerivedClass
+
+- (instancetype)init {
+ return [super self];
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious invocation of 'self' in initializer; did you mean to invoke a superclass initializer? [objc-super-self]
+// CHECK-FIXES: return [super init];
+}
+
+- (instancetype)initWithObject:(NSObject *)obj {
+ self = [super self];
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious invocation of 'self' in initializer; did you mean to invoke a superclass initializer? [objc-super-self]
+// CHECK-FIXES: self = [super init];
+ if (self) {
+ // ...
+ }
+ return self;
+}
+
+#define INITIALIZE() [super self]
+
+- (instancetype)initWithObject:(NSObject *)objc a:(int)a {
+ return INITIALIZE();
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious invocation of 'self' in initializer; did you mean to invoke a superclass initializer? [objc-super-self]
+// CHECK-FIXES: return INITIALIZE();
+}
+
+#define INITIALIZER_IMPL() return [super self]
+
+- (instancetype)initWithObject:(NSObject *)objc b:(int)b {
+ INITIALIZER_IMPL();
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: suspicious invocation of 'self' in initializer; did you mean to invoke a superclass initializer? [objc-super-self]
+// CHECK-FIXES: INITIALIZER_IMPL();
+}
+
+#define INITIALIZER_METHOD self
+
+- (instancetype)initWithObject:(NSObject *)objc c:(int)c {
+ return [super INITIALIZER_METHOD];
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious invocation of 'self' in initializer; did you mean to invoke a superclass initializer? [objc-super-self]
+// CHECK-FIXES: return [super INITIALIZER_METHOD];
+}
+
+#define RECEIVER super
+
+- (instancetype)initWithObject:(NSObject *)objc d:(int)d {
+ return [RECEIVER self];
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious invocation of 'self' in initializer; did you mean to invoke a superclass initializer? [objc-super-self]
+// CHECK-FIXES: return [RECEIVER self];
+}
+
+- (instancetype)foo {
+ return [super self];
+}
+
+- (instancetype)bar {
+ return [self self];
+}
+
+@end
+
+@interface RootClass
+- (instancetype)init;
+- (instancetype)self;
+@end
+
+@interface NotNSObjectDerivedClass : RootClass
+@end
+
+@implementation NotNSObjectDerivedClass
+
+- (instancetype)init {
+ return [super self];
+}
+
+@end
+
diff --git a/test/clang-tidy/openmp-exception-escape.cpp b/test/clang-tidy/openmp-exception-escape.cpp
new file mode 100644
index 00000000..73345836
--- /dev/null
+++ b/test/clang-tidy/openmp-exception-escape.cpp
@@ -0,0 +1,132 @@
+// RUN: %check_clang_tidy %s openmp-exception-escape %t -- -extra-arg=-fopenmp=libomp -extra-arg=-fexceptions -config="{CheckOptions: [{key: openmp-exception-escape.IgnoredExceptions, value: 'ignored, ignored2'}]}" --
+
+int thrower() {
+ throw 42;
+}
+
+class ignored {};
+class ignored2 {};
+namespace std {
+class bad_alloc {};
+} // namespace std
+
+void parallel() {
+#pragma omp parallel
+ thrower();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: an exception thrown inside of the OpenMP 'parallel' region is not caught in that same region
+}
+
+void ignore() {
+#pragma omp parallel
+ throw ignored();
+}
+
+void ignore2() {
+#pragma omp parallel
+ throw ignored2();
+}
+
+void standalone_directive() {
+#pragma omp taskwait
+ throw ignored(); // not structured block
+}
+
+void ignore_alloc() {
+#pragma omp parallel
+ throw std::bad_alloc();
+}
+
+void parallel_caught() {
+#pragma omp parallel
+ {
+ try {
+ thrower();
+ } catch (...) {
+ }
+ }
+}
+
+void for_header(const int a) {
+ // Only the body of the loop counts.
+#pragma omp for
+ for (int i = 0; i < thrower(); i++)
+ ;
+}
+
+void forloop(const int a) {
+#pragma omp for
+ for (int i = 0; i < a; i++)
+ thrower();
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception thrown inside of the OpenMP 'for' region is not caught in that same region
+}
+
+void parallel_forloop(const int a) {
+#pragma omp parallel
+ {
+#pragma omp for
+ for (int i = 0; i < a; i++)
+ thrower();
+ thrower();
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: an exception thrown inside of the OpenMP 'parallel' region is not caught in that same region
+ // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: an exception thrown inside of the OpenMP 'for' region is not caught in that same region
+ }
+}
+
+void parallel_forloop_caught(const int a) {
+#pragma omp parallel
+ {
+#pragma omp for
+ for (int i = 0; i < a; i++) {
+ try {
+ thrower();
+ } catch (...) {
+ }
+ }
+ thrower();
+ // CHECK-MESSAGES: :[[@LINE-9]]:3: warning: an exception thrown inside of the OpenMP 'parallel' region is not caught in that same region
+ }
+}
+
+void parallel_caught_forloop(const int a) {
+#pragma omp parallel
+ {
+#pragma omp for
+ for (int i = 0; i < a; i++)
+ thrower();
+ try {
+ thrower();
+ } catch (...) {
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:7: warning: an exception thrown inside of the OpenMP 'for' region is not caught in that same region
+ }
+}
+
+void parallel_outercaught_forloop(const int a) {
+#pragma omp parallel
+ {
+ try {
+#pragma omp for
+ for (int i = 0; i < a; i++)
+ thrower();
+ thrower();
+ } catch (...) {
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:9: warning: an exception thrown inside of the OpenMP 'for' region is not caught in that same region
+ }
+}
+
+void parallel_outercaught_forloop_caught(const int a) {
+#pragma omp parallel
+ {
+ try {
+#pragma omp for
+ for (int i = 0; i < a; i++) {
+ try {
+ thrower();
+ } catch (...) {
+ }
+ }
+ } catch (...) {
+ }
+ }
+}
diff --git a/test/clang-tidy/openmp-use-default-none.cpp b/test/clang-tidy/openmp-use-default-none.cpp
new file mode 100644
index 00000000..1a374bde
--- /dev/null
+++ b/test/clang-tidy/openmp-use-default-none.cpp
@@ -0,0 +1,160 @@
+// RUN: %check_clang_tidy %s openmp-use-default-none %t -- -- -x c++ -fopenmp=libomp -fopenmp-version=40
+// RUN: %check_clang_tidy %s openmp-use-default-none %t -- -- -x c -fopenmp=libomp -fopenmp-version=40
+
+//----------------------------------------------------------------------------//
+// Null cases.
+//----------------------------------------------------------------------------//
+
+// 'for' directive can not have 'default' clause, no diagnostics.
+void n0(const int a) {
+#pragma omp for
+ for (int b = 0; b < a; b++)
+ ;
+}
+
+//----------------------------------------------------------------------------//
+// Single-directive positive cases.
+//----------------------------------------------------------------------------//
+
+// 'parallel' directive.
+
+// 'parallel' directive can have 'default' clause, but said clause is not
+// specified, diagnosed.
+void p0_0() {
+#pragma omp parallel
+ ;
+ // CHECK-NOTES: :[[@LINE-2]]:9: warning: OpenMP directive 'parallel' does not specify 'default' clause, consider specifying 'default(none)' clause
+}
+
+// 'parallel' directive can have 'default' clause, and said clause specified,
+// with 'none' kind, all good.
+void p0_1() {
+#pragma omp parallel default(none)
+ ;
+}
+
+// 'parallel' directive can have 'default' clause, and said clause specified,
+// but with 'shared' kind, which is not 'none', diagnose.
+void p0_2() {
+#pragma omp parallel default(shared)
+ ;
+ // CHECK-NOTES: :[[@LINE-2]]:9: warning: OpenMP directive 'parallel' specifies 'default(shared)' clause, consider using 'default(none)' clause instead
+ // CHECK-NOTES: :[[@LINE-3]]:22: note: existing 'default' clause specified here
+}
+
+// 'task' directive.
+
+// 'task' directive can have 'default' clause, but said clause is not
+// specified, diagnosed.
+void p1_0() {
+#pragma omp task
+ ;
+ // CHECK-NOTES: :[[@LINE-2]]:9: warning: OpenMP directive 'task' does not specify 'default' clause, consider specifying 'default(none)' clause
+}
+
+// 'task' directive can have 'default' clause, and said clause specified,
+// with 'none' kind, all good.
+void p1_1() {
+#pragma omp task default(none)
+ ;
+}
+
+// 'task' directive can have 'default' clause, and said clause specified,
+// but with 'shared' kind, which is not 'none', diagnose.
+void p1_2() {
+#pragma omp task default(shared)
+ ;
+ // CHECK-NOTES: :[[@LINE-2]]:9: warning: OpenMP directive 'task' specifies 'default(shared)' clause, consider using 'default(none)' clause instead
+ // CHECK-NOTES: :[[@LINE-3]]:18: note: existing 'default' clause specified here
+}
+
+// 'teams' directive. (has to be inside of 'target' directive)
+
+// 'teams' directive can have 'default' clause, but said clause is not
+// specified, diagnosed.
+void p2_0() {
+#pragma omp target
+#pragma omp teams
+ ;
+ // CHECK-NOTES: :[[@LINE-2]]:9: warning: OpenMP directive 'teams' does not specify 'default' clause, consider specifying 'default(none)' clause
+}
+
+// 'teams' directive can have 'default' clause, and said clause specified,
+// with 'none' kind, all good.
+void p2_1() {
+#pragma omp target
+#pragma omp teams default(none)
+ ;
+}
+
+// 'teams' directive can have 'default' clause, and said clause specified,
+// but with 'shared' kind, which is not 'none', diagnose.
+void p2_2() {
+#pragma omp target
+#pragma omp teams default(shared)
+ ;
+ // CHECK-NOTES: :[[@LINE-2]]:9: warning: OpenMP directive 'teams' specifies 'default(shared)' clause, consider using 'default(none)' clause instead
+ // CHECK-NOTES: :[[@LINE-3]]:19: note: existing 'default' clause specified here
+}
+
+// 'taskloop' directive.
+
+// 'taskloop' directive can have 'default' clause, but said clause is not
+// specified, diagnosed.
+void p3_0(const int a) {
+#pragma omp taskloop
+ for (int b = 0; b < a; b++)
+ ;
+ // CHECK-NOTES: :[[@LINE-3]]:9: warning: OpenMP directive 'taskloop' does not specify 'default' clause, consider specifying 'default(none)' clause
+}
+
+// 'taskloop' directive can have 'default' clause, and said clause specified,
+// with 'none' kind, all good.
+void p3_1(const int a) {
+#pragma omp taskloop default(none) shared(a)
+ for (int b = 0; b < a; b++)
+ ;
+}
+
+// 'taskloop' directive can have 'default' clause, and said clause specified,
+// but with 'shared' kind, which is not 'none', diagnose.
+void p3_2(const int a) {
+#pragma omp taskloop default(shared)
+ for (int b = 0; b < a; b++)
+ ;
+ // CHECK-NOTES: :[[@LINE-3]]:9: warning: OpenMP directive 'taskloop' specifies 'default(shared)' clause, consider using 'default(none)' clause instead
+ // CHECK-NOTES: :[[@LINE-4]]:22: note: existing 'default' clause specified here
+}
+
+//----------------------------------------------------------------------------//
+// Combined directives.
+// Let's not test every single possible permutation/combination of directives,
+// but just *one* combined directive. The rest will be the same.
+//----------------------------------------------------------------------------//
+
+// 'parallel' directive can have 'default' clause, but said clause is not
+// specified, diagnosed.
+void p4_0(const int a) {
+#pragma omp parallel for
+ for (int b = 0; b < a; b++)
+ ;
+ // CHECK-NOTES: :[[@LINE-3]]:9: warning: OpenMP directive 'parallel for' does not specify 'default' clause, consider specifying 'default(none)' clause
+}
+
+// 'parallel' directive can have 'default' clause, and said clause specified,
+// with 'none' kind, all good.
+void p4_1(const int a) {
+#pragma omp parallel for default(none) shared(a)
+ for (int b = 0; b < a; b++)
+ ;
+}
+
+// 'parallel' directive can have 'default' clause, and said clause specified,
+// but with 'shared' kind, which is not 'none', diagnose.
+void p4_2(const int a) {
+#pragma omp parallel for default(shared)
+ for (int b = 0; b < a; b++)
+ ;
+ // CHECK-NOTES: :[[@LINE-3]]:9: warning: OpenMP directive 'parallel for' specifies 'default(shared)' clause, consider using 'default(none)' clause instead
+ // CHECK-NOTES: :[[@LINE-4]]:26: note: existing 'default' clause specified here
+}
diff --git a/test/clang-tidy/readability-avoid-underscore-in-googletest-name.cpp b/test/clang-tidy/readability-avoid-underscore-in-googletest-name.cpp
new file mode 100644
index 00000000..6e8a5c2d
--- /dev/null
+++ b/test/clang-tidy/readability-avoid-underscore-in-googletest-name.cpp
@@ -0,0 +1,108 @@
+// RUN: %check_clang_tidy %s google-readability-avoid-underscore-in-googletest-name %t
+
+#define TEST(test_case_name, test_name) void test_case_name##test_name()
+#define TEST_F(test_case_name, test_name) void test_case_name##test_name()
+#define TEST_P(test_case_name, test_name) void test_case_name##test_name()
+#define TYPED_TEST(test_case_name, test_name) void test_case_name##test_name()
+#define TYPED_TEST_P(test_case_name, test_name) void test_case_name##test_name()
+#define FRIEND_TEST(test_case_name, test_name) void test_case_name##test_name()
+
+TEST(TestCaseName, Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TEST(TestCaseName, DISABLED_Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TEST(TestCaseName, Illegal_Test_Name) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TEST(Illegal_TestCaseName, TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using "_" in test case name "Illegal_TestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TEST(Illegal_Test_CaseName, TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using "_" in test case name "Illegal_Test_CaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TEST(Illegal_TestCaseName, Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using "_" in test case name "Illegal_TestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+// CHECK-MESSAGES: :[[@LINE-2]]:28: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TEST_F(TestCaseFixtureName, Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TEST_F(TestCaseFixtureName, DISABLED_Illegal_Test_Name) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TEST_F(TestCaseFixtureName, Illegal_Test_Name) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TEST_F(Illegal_TestCaseFixtureName, TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_TestCaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TEST_F(Illegal_TestCaseFixtureName, Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_TestCaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+// CHECK-MESSAGES: :[[@LINE-2]]:37: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TEST_F(Illegal_Test_CaseFixtureName, TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_Test_CaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TEST_P(ParameterizedTestCaseFixtureName, Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TEST_P(ParameterizedTestCaseFixtureName, DISABLED_Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TEST_P(ParameterizedTestCaseFixtureName, Illegal_Test_Name) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TEST_P(Illegal_ParameterizedTestCaseFixtureName, TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_ParameterizedTestCaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TEST_P(Illegal_ParameterizedTestCaseFixtureName, Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_ParameterizedTestCaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+// CHECK-MESSAGES: :[[@LINE-2]]:50: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TEST_P(Illegal_Parameterized_TestCaseFixtureName, TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_Parameterized_TestCaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TYPED_TEST(TypedTestCaseName, Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TYPED_TEST(TypedTestCaseName, DISABLED_Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TYPED_TEST(TypedTestCaseName, Illegal_Test_Name) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TYPED_TEST(Illegal_TypedTestCaseName, TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid using "_" in test case name "Illegal_TypedTestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TYPED_TEST(Illegal_TypedTestCaseName, Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid using "_" in test case name "Illegal_TypedTestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+// CHECK-MESSAGES: :[[@LINE-2]]:39: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TYPED_TEST(Illegal_Typed_TestCaseName, TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid using "_" in test case name "Illegal_Typed_TestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TYPED_TEST_P(TypeParameterizedTestCaseName, Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TYPED_TEST_P(TypeParameterizedTestCaseName, DISABLED_Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TYPED_TEST_P(TypeParameterizedTestCaseName, Illegal_Test_Name) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TYPED_TEST_P(Illegal_TypeParameterizedTestCaseName, TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: avoid using "_" in test case name "Illegal_TypeParameterizedTestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TYPED_TEST_P(Illegal_TypeParameterizedTestCaseName, Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: avoid using "_" in test case name "Illegal_TypeParameterizedTestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+// CHECK-MESSAGES: :[[@LINE-2]]:53: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TYPED_TEST_P(Illegal_Type_ParameterizedTestCaseName, TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: avoid using "_" in test case name "Illegal_Type_ParameterizedTestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+// Underscores are allowed to disable a test with the DISABLED_ prefix.
+// https://github.com/google/googletest/blob/master/googletest/docs/faq.md#why-should-test-suite-names-and-test-names-not-contain-underscore
+TEST(TestCaseName, TestName) {}
+TEST(TestCaseName, DISABLED_TestName) {}
+
+TEST_F(TestCaseFixtureName, TestName) {}
+TEST_F(TestCaseFixtureName, DISABLED_TestName) {}
+
+TEST_P(ParameterizedTestCaseFixtureName, TestName) {}
+TEST_P(ParameterizedTestCaseFixtureName, DISABLED_TestName) {}
+
+TYPED_TEST(TypedTestName, TestName) {}
+TYPED_TEST(TypedTestName, DISABLED_TestName) {}
+
+TYPED_TEST_P(TypeParameterizedTestName, TestName) {}
+TYPED_TEST_P(TypeParameterizedTestName, DISABLED_TestName) {}
+
+FRIEND_TEST(FriendTest, Is_NotChecked) {}
+FRIEND_TEST(Friend_Test, IsNotChecked) {}
+FRIEND_TEST(Friend_Test, Is_NotChecked) {}
diff --git a/test/clang-tidy/readability-else-after-return.cpp b/test/clang-tidy/readability-else-after-return.cpp
index 7e950928..b06c02c9 100644
--- a/test/clang-tidy/readability-else-after-return.cpp
+++ b/test/clang-tidy/readability-else-after-return.cpp
@@ -105,3 +105,15 @@ void foo() {
}
}
}
+
+extern int *g();
+extern void h(int **x);
+
+int *decl_in_condition() {
+ if (int *x = g()) {
+ return x;
+ } else {
+ h(&x);
+ return x;
+ }
+}
diff --git a/test/clang-tidy/readability-misleading-indentation.cpp b/test/clang-tidy/readability-misleading-indentation.cpp
index 59d5f406..40399492 100644
--- a/test/clang-tidy/readability-misleading-indentation.cpp
+++ b/test/clang-tidy/readability-misleading-indentation.cpp
@@ -8,7 +8,7 @@ void foo2();
foo1(); \
foo2();
-int main()
+void f()
{
bool cond1 = true;
bool cond2 = true;
@@ -90,7 +90,7 @@ int main()
else {
}
// CHECK-MESSAGES: :[[@LINE-2]]:8: warning: different indentation for 'if' and corresponding 'else' [readability-misleading-indentation]
-
+
if (cond1) {
if (cond1) {
}
@@ -109,3 +109,12 @@ int main()
BLOCK
}
+
+void g(bool x) {
+ if (x)
+ #pragma unroll
+ for (int k = 0; k < 1; ++k) {}
+
+ #pragma unroll
+ for (int k = 0; k < 1; ++k) {}
+}
diff --git a/test/clang-tidy/readability-redundant-smartptr-get-msvc.cpp b/test/clang-tidy/readability-redundant-smartptr-get-msvc.cpp
new file mode 100644
index 00000000..bd8990a2
--- /dev/null
+++ b/test/clang-tidy/readability-redundant-smartptr-get-msvc.cpp
@@ -0,0 +1,94 @@
+// RUN: %check_clang_tidy %s readability-redundant-smartptr-get %t
+
+#define NULL __null
+
+namespace std {
+
+// MSVC headers define operator templates instead of plain operators.
+
+template <typename T>
+struct unique_ptr {
+ template <typename T2 = T>
+ T2& operator*() const;
+ template <typename T2 = T>
+ T2* operator->() const;
+ T* get() const;
+ explicit operator bool() const noexcept;
+};
+
+template <typename T>
+struct shared_ptr {
+ template <typename T2 = T>
+ T2& operator*() const;
+ template <typename T2 = T>
+ T2* operator->() const;
+ T* get() const;
+ explicit operator bool() const noexcept;
+};
+
+} // namespace std
+
+struct Bar {
+ void Do();
+ void ConstDo() const;
+};
+
+void Positive() {
+ 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();
+
+ 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 = nullptr != ss->get();
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: redundant get() call
+ // CHECK-MESSAGES: nullptr != ss->get();
+ // CHECK-FIXES: bb = nullptr != *ss;
+
+ 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);
+}
diff --git a/test/clang-tidy/readability-uppercase-literal-suffix-float16.cpp b/test/clang-tidy/readability-uppercase-literal-suffix-float16.cpp
new file mode 100644
index 00000000..b2b858f9
--- /dev/null
+++ b/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/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp b/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp
index 4d41db7a..50e75fae 100644
--- a/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp
+++ b/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp
@@ -97,34 +97,6 @@ void floating_point_suffix() {
static constexpr auto v13 = 1.e0Q; // OK.
static_assert(is_same<decltype(v13), const __float128>::value, "");
static_assert(v13 == 1., "");
-
- // _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 floating_point_complex_suffix() {
diff --git a/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp b/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp
index 4cc9d6d2..415c6d8e 100644
--- a/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp
+++ b/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp
@@ -93,21 +93,6 @@ void floating_point_suffix() {
static constexpr auto v12 = 0xfp0Q; // OK.
static_assert(is_same<decltype(v12), const __float128>::value, "");
static_assert(v12 == 0xfp0, "");
-
- // _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, "");
}
void floating_point_complex_suffix() {
diff --git a/test/clang-tidy/run-clang-tidy.cpp b/test/clang-tidy/run-clang-tidy.cpp
index 2207e430..31c4d681 100644
--- a/test/clang-tidy/run-clang-tidy.cpp
+++ b/test/clang-tidy/run-clang-tidy.cpp
@@ -1,3 +1,4 @@
+// RUN: %run_clang_tidy --help
// 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
diff --git a/test/clang-tidy/static-analyzer-config.cpp b/test/clang-tidy/static-analyzer-config.cpp
index 9ca87cf8..d07c0c3a 100644
--- a/test/clang-tidy/static-analyzer-config.cpp
+++ b/test/clang-tidy/static-analyzer-config.cpp
@@ -1,5 +1,5 @@
// REQUIRES: static-analyzer
-// RUN: clang-tidy %s -checks='-*,clang-analyzer-unix.Malloc' -config='{CheckOptions: [{ key: "clang-analyzer-unix.Malloc:Optimistic", value: true}]}' -- | FileCheck %s
+// RUN: clang-tidy %s -checks='-*,clang-analyzer-unix.Malloc' -config='{CheckOptions: [{ key: "clang-analyzer-unix.DynamicMemoryModeling:Optimistic", value: true}]}' -- | FileCheck %s
typedef __typeof(sizeof(int)) size_t;
void *malloc(size_t);
void free(void *);