mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-17 20:16:46 +00:00

This is an ongoing series of commits that are reformatting our Python code. Reformatting is done with `black`. If you end up having problems merging this commit because you have made changes to a python file, the best way to handle that is to run git checkout --ours <yourfile> and then reformat it with black. If you run into any problems, post to discourse about it and we will try to help. RFC Thread below: https://discourse.llvm.org/t/rfc-document-and-standardize-python-code-style Reviewed By: MatzeB Differential Revision: https://reviews.llvm.org/D150761
145 lines
4.3 KiB
Python
145 lines
4.3 KiB
Python
#!/usr/bin/env python
|
|
#
|
|
# ===- check-analyzer-fixit.py - Static Analyzer test helper ---*- 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
|
|
#
|
|
# ===------------------------------------------------------------------------===#
|
|
#
|
|
# This file copy-pasted mostly from the Clang-Tidy's 'check_clang_tidy.py'.
|
|
#
|
|
# ===------------------------------------------------------------------------===#
|
|
|
|
r"""
|
|
Clang Static Analyzer test helper
|
|
=================================
|
|
|
|
This script runs the Analyzer in fix-it mode and verify fixes, warnings, notes.
|
|
|
|
Usage:
|
|
check-analyzer-fixit.py <source-file> <temp-file> [analyzer arguments]
|
|
|
|
Example:
|
|
// RUN: %check-analyzer-fixit %s %t -analyzer-checker=core
|
|
"""
|
|
|
|
import argparse
|
|
import os
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
|
|
|
|
def write_file(file_name, text):
|
|
with open(file_name, "w") as f:
|
|
f.write(text)
|
|
|
|
|
|
def run_test_once(args, extra_args):
|
|
input_file_name = args.input_file_name
|
|
temp_file_name = args.temp_file_name
|
|
clang_analyzer_extra_args = extra_args
|
|
|
|
file_name_with_extension = input_file_name
|
|
_, extension = os.path.splitext(file_name_with_extension)
|
|
if extension not in [".c", ".hpp", ".m", ".mm"]:
|
|
extension = ".cpp"
|
|
temp_file_name = temp_file_name + extension
|
|
|
|
with open(input_file_name, "r") as input_file:
|
|
input_text = input_file.read()
|
|
|
|
# Remove the contents of the CHECK lines to avoid CHECKs matching on
|
|
# themselves. We need to keep the comments to preserve line numbers while
|
|
# avoiding empty lines which could potentially trigger formatting-related
|
|
# checks.
|
|
cleaned_test = re.sub("// *CHECK-[A-Z0-9\-]*:[^\r\n]*", "//", input_text)
|
|
write_file(temp_file_name, cleaned_test)
|
|
|
|
original_file_name = temp_file_name + ".orig"
|
|
write_file(original_file_name, cleaned_test)
|
|
|
|
try:
|
|
builtin_include_dir = subprocess.check_output(
|
|
["clang", "-print-file-name=include"], stderr=subprocess.STDOUT
|
|
).decode()
|
|
except subprocess.CalledProcessError as e:
|
|
print("Cannot print Clang include directory: " + e.output.decode())
|
|
|
|
builtin_include_dir = os.path.normpath(builtin_include_dir)
|
|
|
|
args = (
|
|
[
|
|
"clang",
|
|
"-cc1",
|
|
"-internal-isystem",
|
|
builtin_include_dir,
|
|
"-nostdsysteminc",
|
|
"-analyze",
|
|
"-analyzer-constraints=range",
|
|
"-analyzer-config",
|
|
"apply-fixits=true",
|
|
]
|
|
+ clang_analyzer_extra_args
|
|
+ ["-verify", temp_file_name]
|
|
)
|
|
|
|
print("Running " + str(args) + "...")
|
|
|
|
try:
|
|
clang_analyzer_output = subprocess.check_output(
|
|
args, stderr=subprocess.STDOUT
|
|
).decode()
|
|
except subprocess.CalledProcessError as e:
|
|
print("Clang Static Analyzer test failed:\n" + e.output.decode())
|
|
raise
|
|
|
|
print(
|
|
"----------------- Clang Static Analyzer output -----------------\n"
|
|
+ clang_analyzer_output
|
|
+ "\n--------------------------------------------------------------"
|
|
)
|
|
|
|
try:
|
|
diff_output = subprocess.check_output(
|
|
["diff", "-u", original_file_name, temp_file_name], stderr=subprocess.STDOUT
|
|
)
|
|
except subprocess.CalledProcessError as e:
|
|
diff_output = e.output
|
|
|
|
print(
|
|
"----------------------------- Fixes ----------------------------\n"
|
|
+ diff_output.decode()
|
|
+ "\n--------------------------------------------------------------"
|
|
)
|
|
|
|
try:
|
|
subprocess.check_output(
|
|
[
|
|
"FileCheck",
|
|
"-input-file=" + temp_file_name,
|
|
input_file_name,
|
|
"-check-prefixes=CHECK-FIXES",
|
|
"-strict-whitespace",
|
|
],
|
|
stderr=subprocess.STDOUT,
|
|
)
|
|
except subprocess.CalledProcessError as e:
|
|
print("FileCheck failed:\n" + e.output.decode())
|
|
raise
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("input_file_name")
|
|
parser.add_argument("temp_file_name")
|
|
|
|
args, extra_args = parser.parse_known_args()
|
|
run_test_once(args, extra_args)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|