https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/157306
>From 4ab549990f3dc3f59a6346b32687e5ecbd495586 Mon Sep 17 00:00:00 2001 From: Victor Baranov <[email protected]> Date: Sat, 6 Sep 2025 22:54:31 +0300 Subject: [PATCH 1/2] [clang-tidy] Remove 'clang-analyzer-*' checks from default checks --- clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp | 3 +-- clang-tools-extra/docs/ReleaseNotes.rst | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp index bef3b938b5afd..ed9b195f0dbde 100644 --- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp +++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp @@ -102,8 +102,7 @@ Configuration files: )"); const char DefaultChecks[] = // Enable these checks by default: - "clang-diagnostic-*," // * compiler diagnostics - "clang-analyzer-*"; // * Static Analyzer checks + "clang-diagnostic-*"; // * compiler diagnostics static cl::opt<std::string> Checks("checks", desc(R"( Comma-separated list of globs with optional '-' diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index e1b6daf75457d..d97efe667f98e 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -139,6 +139,8 @@ Improvements to clang-tidy scripts by adding the `-hide-progress` option to suppress progress and informational messages. +- Removed `clang-analyzer-*` check from default checks in :program:`clang-tidy`. + New checks ^^^^^^^^^^ >From 54d4521e617091a520cf749cc714309891b7b582 Mon Sep 17 00:00:00 2001 From: Victor Baranov <[email protected]> Date: Sun, 21 Sep 2025 23:58:12 +0300 Subject: [PATCH 2/2] WIP --- .clang-tidy | 38 -- .../clang-tidy/add_check_alias.py | 426 ++++++++++++++++++ .../clang-tidy/tool/ClangTidyMain.cpp | 80 ++++ .../config-with-exclusion | 3 + .../config-with-inclusion | 3 + .../config-with-wildcard | 3 + .../config-without-analyzer | 3 + .../clang-analyzer-soft-deprecation.cpp | 35 ++ clang-tools-extra/test_here.cpp | 1 + test_warning.cpp | 4 + 10 files changed, 558 insertions(+), 38 deletions(-) delete mode 100644 .clang-tidy create mode 100755 clang-tools-extra/clang-tidy/add_check_alias.py create mode 100644 clang-tools-extra/test/clang-tidy/infrastructure/Inputs/clang-analyzer-soft-deprecation/config-with-exclusion create mode 100644 clang-tools-extra/test/clang-tidy/infrastructure/Inputs/clang-analyzer-soft-deprecation/config-with-inclusion create mode 100644 clang-tools-extra/test/clang-tidy/infrastructure/Inputs/clang-analyzer-soft-deprecation/config-with-wildcard create mode 100644 clang-tools-extra/test/clang-tidy/infrastructure/Inputs/clang-analyzer-soft-deprecation/config-without-analyzer create mode 100644 clang-tools-extra/test/clang-tidy/infrastructure/clang-analyzer-soft-deprecation.cpp create mode 100644 clang-tools-extra/test_here.cpp create mode 100644 test_warning.cpp diff --git a/.clang-tidy b/.clang-tidy deleted file mode 100644 index 06bb0f18e9d2e..0000000000000 --- a/.clang-tidy +++ /dev/null @@ -1,38 +0,0 @@ -Checks: > - -*, - clang-diagnostic-*, - llvm-*, - misc-*, - -misc-const-correctness, - -misc-include-cleaner, - -misc-no-recursion, - -misc-non-private-member-variables-in-classes, - -misc-unused-parameters, - -misc-use-anonymous-namespace, - readability-identifier-naming - -CheckOptions: - - key: readability-identifier-naming.ClassCase - value: CamelCase - - key: readability-identifier-naming.EnumCase - value: CamelCase - - key: readability-identifier-naming.FunctionCase - value: camelBack - # Exclude from scanning as this is an exported symbol used for fuzzing - # throughout the code base. - - key: readability-identifier-naming.FunctionIgnoredRegexp - value: "LLVMFuzzerTestOneInput" - - key: readability-identifier-naming.MemberCase - value: CamelCase - - key: readability-identifier-naming.ParameterCase - value: CamelCase - - key: readability-identifier-naming.UnionCase - value: CamelCase - - key: readability-identifier-naming.VariableCase - value: CamelCase - - key: readability-identifier-naming.IgnoreMainLikeFunctions - value: 1 - - key: readability-redundant-member-init.IgnoreBaseInCopyConstructors - value: 1 - - key: modernize-use-default-member-init.UseAssignment - value: 1 diff --git a/clang-tools-extra/clang-tidy/add_check_alias.py b/clang-tools-extra/clang-tidy/add_check_alias.py new file mode 100755 index 0000000000000..44d4b956f3686 --- /dev/null +++ b/clang-tools-extra/clang-tidy/add_check_alias.py @@ -0,0 +1,426 @@ +#!/usr/bin/env python3 +# +# ===- add_check_alias.py - clang-tidy check alias generator ----*- python -*--===# +# +# 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 +# +# ===-----------------------------------------------------------------------===# + +import argparse +import io +import os +import re +import sys + +# FIXME Python 3.9: Replace typing.Optional with builtins. +from typing import Optional, Dict + + +def get_camel_name(check_name: str) -> str: + return "".join(map(lambda elem: elem.capitalize(), check_name.split("-"))) + + +def get_camel_check_name(check_name: str) -> str: + return get_camel_name(check_name) + "Check" + + +def get_module_filename(module_path: str, module: str) -> str: + modulecpp = list( + filter( + lambda p: p.lower() == module.lower() + "tidymodule.cpp", + os.listdir(module_path), + ) + )[0] + return os.path.join(module_path, modulecpp) + + +def add_alias_to_module( + module_path: str, + alias_module: str, + alias_name: str, + target_module: str, + target_name: str, + target_check_class: str, + options: Dict[str, str], +) -> None: + """Add the alias registration to the module file.""" + filename = get_module_filename(module_path, alias_module) + with io.open(filename, "r", encoding="utf8") as f: + lines = f.readlines() + + alias_check_name = alias_module + "-" + alias_name + target_include = f"../{target_module}/{target_check_class}.h" + + print("Updating %s..." % filename) + with io.open(filename, "w", encoding="utf8", newline="\n") as f: + header_added = False + header_found = False + check_added = False + options_added = False + + alias_registration = ( + f" CheckFactories.registerCheck<{target_module}::{target_check_class}>(\n" + f' "{alias_check_name}");\n' + ) + + lines_iter = iter(lines) + try: + while True: + line = next(lines_iter) + + # Add include for the target check + if not header_added: + match = re.search('#include "(.*)"', line) + if match: + header_found = True + if match.group(1) > target_include: + header_added = True + f.write('#include "' + target_include + '"\n') + elif header_found: + header_added = True + f.write('#include "' + target_include + '"\n') + + # Add check registration + if not check_added: + if line.strip() == "}": + check_added = True + f.write(alias_registration) + else: + match = re.search( + r'registerCheck<(.*)> *\( *(?:"([^"]*)")?', line + ) + prev_line = None + if match: + current_check_name = match.group(2) + if current_check_name is None: + # If we didn't find the check name on this line, look on the + # next one. + prev_line = line + line = next(lines_iter) + match = re.search(' *"([^"]*)"', line) + if match: + current_check_name = match.group(1) + assert current_check_name + if current_check_name > alias_check_name: + check_added = True + f.write(alias_registration) + if prev_line: + f.write(prev_line) + + # Add options if they exist and we're in the getModuleOptions method + if options and not options_added and "getModuleOptions" in line: + # Look for the return statement to add options before it + while True: + f.write(line) + line = next(lines_iter) + if "return Options;" in line: + # Add the options before the return statement + for option_key, option_value in options.items(): + f.write( + f' Options.CheckOptions["{alias_check_name}.{option_key}"] = "{option_value}";\n' + ) + options_added = True + break + elif line.strip() == "}": + # If we hit the end of the function without finding return, add the options before the closing brace + for option_key, option_value in options.items(): + f.write( + f' Options.CheckOptions["{alias_check_name}.{option_key}"] = "{option_value}";\n' + ) + options_added = True + break + + f.write(line) + except StopIteration: + pass + + +def add_release_notes( + clang_tidy_path: str, + alias_name: str, + target_name: str, + alias_module: str, + target_module: str, +) -> None: + """Add a release notes entry for the new alias.""" + filename = os.path.normpath( + os.path.join(clang_tidy_path, "../docs/ReleaseNotes.rst") + ) + with io.open(filename, "r", encoding="utf8") as f: + lines = f.readlines() + + alias_check_name = alias_module + "-" + alias_name + target_check_name = target_module + "-" + target_name + + lineMatcher = re.compile("New check aliases") + nextSectionMatcher = re.compile("Changes in existing checks") + checkMatcher = re.compile("- New alias :doc:`(.*)") + + print("Updating %s..." % filename) + with io.open(filename, "w", encoding="utf8", newline="\n") as f: + note_added = False + header_found = False + add_note_here = False + + for line in lines: + if not note_added: + match = lineMatcher.match(line) + match_next = nextSectionMatcher.match(line) + match_check = checkMatcher.match(line) + if match_check: + last_check = match_check.group(1) + if last_check > alias_check_name: + add_note_here = True + + if match_next: + add_note_here = True + + if match: + header_found = True + f.write(line) + continue + + if line.startswith("^^^^"): + f.write(line) + continue + + if header_found and add_note_here: + if not line.startswith("^^^^"): + f.write( + f"""- New alias :doc:`{alias_check_name} + <clang-tidy/checks/{alias_module}/{alias_name}>` to + :doc:`{target_check_name} + <clang-tidy/checks/{target_module}/{target_name}>` was added. + +""" + ) + note_added = True + + f.write(line) + + +def write_alias_docs( + clang_tidy_path: str, + alias_name: str, + target_name: str, + alias_module: str, + target_module: str, +) -> None: + """Create the documentation file for the alias.""" + alias_check_name = alias_module + "-" + alias_name + target_check_name = target_module + "-" + target_name + + docs_dir = os.path.normpath( + os.path.join(clang_tidy_path, "../docs/clang-tidy/checks", alias_module) + ) + + # Create the module directory if it doesn't exist + os.makedirs(docs_dir, exist_ok=True) + + filename = os.path.join(docs_dir, alias_name + ".rst") + print("Creating %s..." % filename) + + with io.open(filename, "w", encoding="utf8", newline="\n") as f: + f.write( + f""".. title:: clang-tidy - {alias_check_name} +.. meta:: + :http-equiv=refresh: 5;URL=../{target_module}/{target_name}.html + +{alias_check_name} +{"=" * len(alias_check_name)} + +The {alias_check_name} check is an alias, please see +`{target_check_name} <../{target_module}/{target_name}.html>`_ +for more information. + +""" + ) + + +def update_target_docs( + clang_tidy_path: str, + alias_name: str, + target_name: str, + alias_module: str, + target_module: str, + options: Dict[str, str], +) -> None: + """Update the target check documentation to mention the alias.""" + filename = os.path.normpath( + os.path.join( + clang_tidy_path, + "../docs/clang-tidy/checks", + target_module, + target_name + ".rst", + ) + ) + + if not os.path.exists(filename): + print(f"Warning: Target documentation file {filename} not found") + return + + alias_check_name = alias_module + "-" + alias_name + + with io.open(filename, "r", encoding="utf8") as f: + content = f.read() + + # Check if alias section already exists + if f"{alias_module.upper()} alias" in content: + print(f"Alias section already exists in {filename}") + return + + # Add alias section at the end + alias_section = f""" + +{alias_module.upper()} alias +{"-" * (len(alias_module) + 6)} + +There is an alias of this check called {alias_check_name}.""" + + if options: + alias_section += f""" +In that version the options""" + option_names = list(options.keys()) + if len(option_names) == 1: + alias_section += f" :option:`{option_names[0]}` is" + else: + alias_section += " " + ", ".join( + f":option:`{name}`" for name in option_names[:-1] + ) + alias_section += f" and :option:`{option_names[-1]}` are" + alias_section += f" set to different defaults." + + alias_section += "\n" + + print("Updating %s..." % filename) + with io.open(filename, "w", encoding="utf8", newline="\n") as f: + f.write(content + alias_section) + + +def update_checks_list(clang_tidy_path: str) -> None: + """Update the main checks list documentation.""" + add_new_check_script = os.path.join(clang_tidy_path, "add_new_check.py") + os.system(f"python3 {add_new_check_script} --update-docs") + + +def parse_options(options_str: Optional[str]) -> Dict[str, str]: + """Parse the options string into a dictionary.""" + if not options_str: + return {} + + options = {} + for option in options_str.split(","): + if "=" in option: + key, value = option.split("=", 1) + options[key.strip()] = value.strip() + else: + print(f"Warning: Invalid option format '{option}', expected 'key=value'") + + return options + + +def main() -> None: + parser = argparse.ArgumentParser(description="Add a new clang-tidy check alias.") + parser.add_argument( + "alias_name", help="Name of the new alias (e.g., 'llvm-else-after-return')" + ) + parser.add_argument( + "target_name", + help="Name of the target check to alias (e.g., 'readability-else-after-return')", + ) + parser.add_argument( + "--options", + help="Comma-separated list of option overrides in the form key=value (e.g., 'WarnOnUnfixable=0,RefactorConditionVariables=0')", + default=None, + ) + parser.add_argument( + "--description", + help="Description for the alias (used in release notes)", + default="", + ) + parser.add_argument( + "--check-class-name", + help="Name of the check class (e.g., 'StrToNumCheck'). If not provided, will be inferred from target check name.", + default=None, + ) + + args = parser.parse_args() + + # Parse the check names + alias_parts = args.alias_name.split("-", 1) + target_parts = args.target_name.split("-", 1) + + if len(alias_parts) != 2 or len(target_parts) != 2: + print("Error: Check names must be in format 'module-checkname'") + return 1 + + alias_module, alias_name = alias_parts + target_module, target_name = target_parts + + # Parse options + options = parse_options(args.options) + + clang_tidy_path = os.path.dirname(sys.argv[0]) + alias_module_path = os.path.join(clang_tidy_path, alias_module) + + if not os.path.isdir(alias_module_path): + print(f"Error: Module directory '{alias_module_path}' does not exist") + return 1 + + # Determine the target check class name + if args.check_class_name: + target_check_class = args.check_class_name + else: + target_check_class = get_camel_check_name(target_name) + + # Check if target check exists + target_module_path = os.path.join(clang_tidy_path, target_module) + target_header = os.path.join(target_module_path, target_check_class + ".h") + + if not os.path.isfile(target_header): + print(f"Error: Target check header '{target_header}' does not exist") + print( + f" (Looking for class '{target_check_class}' in module '{target_module}')" + ) + if not args.check_class_name: + print( + f" You may need to specify --check-class-name if the class name doesn't match the check name" + ) + return 1 + + print(f"Adding alias '{args.alias_name}' -> '{args.target_name}'...") + + # Add alias to the module + add_alias_to_module( + alias_module_path, + alias_module, + alias_name, + target_module, + target_name, + target_check_class, + options, + ) + + # Create alias documentation + write_alias_docs( + clang_tidy_path, alias_name, target_name, alias_module, target_module + ) + + # Note: Skipping target documentation update as requested + + # Add release notes + add_release_notes( + clang_tidy_path, alias_name, target_name, alias_module, target_module + ) + + # Update the main documentation list + update_checks_list(clang_tidy_path) + + print("Done! Alias has been created successfully.") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp index ed9b195f0dbde..661b7f08a5360 100644 --- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp +++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp @@ -632,6 +632,86 @@ int clangTidyMain(int argc, const char **argv) { std::vector<std::string> EnabledChecks = getCheckNames(EffectiveOptions, AllowEnablingAnalyzerAlphaCheckers); + // Check for soft deprecation warning for clang-analyzer-* checks + if (!Quiet) { + bool HasAnalyzerChecks = llvm::any_of(EnabledChecks, [](const std::string &Check) { + return StringRef(Check).starts_with("clang-analyzer-"); + }); + + if (!HasAnalyzerChecks) { + // Check if user explicitly mentioned clang-analyzer-* in their configuration + bool ExplicitlyMentioned = false; + std::vector<clang::tidy::ClangTidyOptionsProvider::OptionsSource> + RawOptions = OptionsProvider->getRawOptions(FilePath); + + for (const auto &[Opts, Source] : RawOptions) { + if (Opts.Checks) { + GlobList CheckGlobs(*Opts.Checks); + for (const auto &Item : CheckGlobs.getItems()) { + if (Item.Text.contains("clang-analyzer-")) { + ExplicitlyMentioned = true; + break; + } + } + if (ExplicitlyMentioned) break; + } + } + + // Only show warning if user is using default checks or wildcard patterns + // that would have included clang-analyzer-* in the past + bool ShouldWarn = false; + if (!ExplicitlyMentioned && !EnabledChecks.empty()) { + // Show warning if using defaults (no -checks specified and no config file checks) + if (Checks.getNumOccurrences() == 0) { + bool HasConfigChecks = false; + for (const auto &[Opts, Source] : RawOptions) { + if (Opts.Checks && !Opts.Checks->empty()) { + HasConfigChecks = true; + break; + } + } + if (!HasConfigChecks) { + ShouldWarn = true; + } + } + // Or if using broad wildcard patterns + else { + // Check command line checks + if (Checks.getNumOccurrences() > 0) { + StringRef CheckStr = Checks; + if ((CheckStr == "*" || CheckStr.starts_with("*,") || + CheckStr.contains(",*,") || CheckStr.ends_with(",*")) && + !CheckStr.contains("clang-analyzer-")) { + ShouldWarn = true; + } + } + // Check config file checks if no command line checks + if (!ShouldWarn) { + for (const auto &[Opts, Source] : RawOptions) { + if (Opts.Checks) { + StringRef CheckStr = *Opts.Checks; + if ((CheckStr == "*" || CheckStr.starts_with("*,") || + CheckStr.contains(",*,") || CheckStr.ends_with(",*")) && + !CheckStr.contains("clang-analyzer-")) { + ShouldWarn = true; + break; + } + } + } + } + } + } + + if (ShouldWarn) { + llvm::WithColor::warning(llvm::errs()) + << "clang-analyzer-* checks are no longer enabled by default.\n" + << "If you want to enable clang-analyzer-* checks, use " + << "-checks='*,clang-analyzer-*' or add 'clang-analyzer-*' to " + << "your .clang-tidy configuration file.\n"; + } + } + } + if (ExplainConfig) { // FIXME: Show other ClangTidyOptions' fields, like ExtraArg. std::vector<clang::tidy::ClangTidyOptionsProvider::OptionsSource> diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/clang-analyzer-soft-deprecation/config-with-exclusion b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/clang-analyzer-soft-deprecation/config-with-exclusion new file mode 100644 index 0000000000000..a2084db3da707 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/clang-analyzer-soft-deprecation/config-with-exclusion @@ -0,0 +1,3 @@ +--- +Checks: '*,-clang-analyzer-*' +--- \ No newline at end of file diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/clang-analyzer-soft-deprecation/config-with-inclusion b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/clang-analyzer-soft-deprecation/config-with-inclusion new file mode 100644 index 0000000000000..1f38e120b7f43 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/clang-analyzer-soft-deprecation/config-with-inclusion @@ -0,0 +1,3 @@ +--- +Checks: '*,clang-analyzer-*' +--- \ No newline at end of file diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/clang-analyzer-soft-deprecation/config-with-wildcard b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/clang-analyzer-soft-deprecation/config-with-wildcard new file mode 100644 index 0000000000000..cbea8802814ce --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/clang-analyzer-soft-deprecation/config-with-wildcard @@ -0,0 +1,3 @@ +--- +Checks: '*' +--- \ No newline at end of file diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/clang-analyzer-soft-deprecation/config-without-analyzer b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/clang-analyzer-soft-deprecation/config-without-analyzer new file mode 100644 index 0000000000000..7678af6337c2f --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/clang-analyzer-soft-deprecation/config-without-analyzer @@ -0,0 +1,3 @@ +--- +Checks: 'readability-*,bugprone-*' +--- \ No newline at end of file diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/clang-analyzer-soft-deprecation.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/clang-analyzer-soft-deprecation.cpp new file mode 100644 index 0000000000000..1a2a7a65f6a35 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/infrastructure/clang-analyzer-soft-deprecation.cpp @@ -0,0 +1,35 @@ +// This test verifies the soft deprecation warning for clang-analyzer-* checks +// which are no longer enabled by default. + +// Test that warning appears with wildcard patterns that would have included clang-analyzer-* +// RUN: clang-tidy -checks='*' %s -- 2>&1 | FileCheck %s --check-prefix=CHECK-WILDCARD-WARNING +// RUN: clang-tidy -checks='*,readability-*' %s -- 2>&1 | FileCheck %s --check-prefix=CHECK-WILDCARD-WARNING +// RUN: clang-tidy -config-file=%S/Inputs/clang-analyzer-soft-deprecation/config-with-wildcard %s -- 2>&1 | FileCheck %s --check-prefix=CHECK-WILDCARD-WARNING + +// Test that warning does not appear when clang-analyzer-* is explicitly mentioned +// RUN: clang-tidy -checks=-clang-analyzer-* %s -- 2>&1 | FileCheck %s --check-prefix=CHECK-EXPLICIT-EXCLUSION --allow-empty +// RUN: clang-tidy -checks=clang-analyzer-* %s -- 2>&1 | FileCheck %s --check-prefix=CHECK-EXPLICIT-INCLUSION --allow-empty +// RUN: clang-tidy -checks='*,clang-analyzer-*' %s -- 2>&1 | FileCheck %s --check-prefix=CHECK-EXPLICIT-INCLUSION --allow-empty +// RUN: clang-tidy -checks='*,-clang-analyzer-*' %s -- 2>&1 | FileCheck %s --check-prefix=CHECK-EXPLICIT-EXCLUSION --allow-empty +// RUN: clang-tidy -config-file=%S/Inputs/clang-analyzer-soft-deprecation/config-with-exclusion %s -- 2>&1 | FileCheck %s --check-prefix=CHECK-CONFIG-EXCLUSION --allow-empty +// RUN: clang-tidy -config-file=%S/Inputs/clang-analyzer-soft-deprecation/config-with-inclusion %s -- 2>&1 | FileCheck %s --check-prefix=CHECK-CONFIG-INCLUSION --allow-empty + +// Test that warning does not appear in quiet mode +// RUN: clang-tidy --quiet -checks='*' %s -- 2>&1 | FileCheck %s --check-prefix=CHECK-QUIET --allow-empty + +// Test that warning does not appear with specific checks (not wildcards) +// RUN: clang-tidy -checks='readability-magic-numbers' %s -- 2>&1 | FileCheck %s --check-prefix=CHECK-SPECIFIC-CHECKS --allow-empty + +// CHECK-WILDCARD-WARNING: warning: clang-analyzer-* checks are no longer enabled by default. +// CHECK-WILDCARD-WARNING-NEXT: If you want to enable clang-analyzer-* checks, use -checks='*,clang-analyzer-*' or add 'clang-analyzer-*' to your .clang-tidy configuration file. + +// CHECK-EXPLICIT-EXCLUSION-NOT: clang-analyzer-* checks are no longer enabled by default +// CHECK-EXPLICIT-INCLUSION-NOT: clang-analyzer-* checks are no longer enabled by default +// CHECK-CONFIG-EXCLUSION-NOT: clang-analyzer-* checks are no longer enabled by default +// CHECK-CONFIG-INCLUSION-NOT: clang-analyzer-* checks are no longer enabled by default +// CHECK-QUIET-NOT: clang-analyzer-* checks are no longer enabled by default +// CHECK-SPECIFIC-CHECKS-NOT: clang-analyzer-* checks are no longer enabled by default + +int main() { + return 0; +} \ No newline at end of file diff --git a/clang-tools-extra/test_here.cpp b/clang-tools-extra/test_here.cpp new file mode 100644 index 0000000000000..76e8197013aab --- /dev/null +++ b/clang-tools-extra/test_here.cpp @@ -0,0 +1 @@ +int main() { return 0; } diff --git a/test_warning.cpp b/test_warning.cpp new file mode 100644 index 0000000000000..2846e71306b39 --- /dev/null +++ b/test_warning.cpp @@ -0,0 +1,4 @@ +// Simple test file for testing clang-tidy soft deprecation warning +int main() { + return 0; +} \ No newline at end of file _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
