| // Copyright 2016 Google Inc. All rights reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package config |
| |
| import ( |
| "android/soong/android" |
| "strings" |
| ) |
| |
| var ( |
| // Some clang-tidy checks have bugs or don't work for Android. |
| // They are disabled here, overriding any locally selected checks. |
| globalNoCheckList = []string{ |
| // https://b.corp.google.com/issues/153464409 |
| // many local projects enable cert-* checks, which |
| // trigger bugprone-reserved-identifier. |
| "-bugprone-reserved-identifier*,-cert-dcl51-cpp,-cert-dcl37-c", |
| // http://b/153757728 |
| "-readability-qualified-auto", |
| // http://b/193716442 |
| "-bugprone-implicit-widening-of-multiplication-result", |
| // Too many existing functions trigger this rule, and fixing it requires large code |
| // refactoring. The cost of maintaining this tidy rule outweighs the benefit it brings. |
| "-bugprone-easily-swappable-parameters", |
| // http://b/216364337 - TODO: Follow-up after compiler update to |
| // disable or fix individual instances. |
| "-cert-err33-c", |
| } |
| |
| // Some clang-tidy checks are included in some tidy_checks_as_errors lists, |
| // but not all warnings are fixed/suppressed yet. These checks are not |
| // disabled in the TidyGlobalNoChecks list, so we can see them and fix/suppress them. |
| globalNoErrorCheckList = []string{ |
| // http://b/155034563 |
| "-bugprone-signed-char-misuse", |
| // http://b/155034972 |
| "-bugprone-branch-clone", |
| } |
| ) |
| |
| func init() { |
| // Many clang-tidy checks like altera-*, llvm-*, modernize-* |
| // are not designed for Android source code or creating too |
| // many (false-positive) warnings. The global default tidy checks |
| // should include only tested groups and exclude known noisy checks. |
| // See https://clang.llvm.org/extra/clang-tidy/checks/list.html |
| pctx.VariableFunc("TidyDefaultGlobalChecks", func(ctx android.PackageVarContext) string { |
| if override := ctx.Config().Getenv("DEFAULT_GLOBAL_TIDY_CHECKS"); override != "" { |
| return override |
| } |
| checks := strings.Join([]string{ |
| "-*", |
| "android-*", |
| "bugprone-*", |
| "cert-*", |
| "clang-diagnostic-unused-command-line-argument", |
| // Select only google-* checks that do not have thousands of warnings. |
| // Add more such checks when we clean up source code. |
| // "google-build-using-namespace", |
| // "google-default-arguments", |
| // "google-explicit-constructor", |
| // "google-global-names-in-headers", |
| // "google-runtime-int", |
| "google-build-explicit-make-pair", |
| "google-build-namespaces", |
| "google-runtime-operator", |
| "google-upgrade-*", |
| "misc-*", |
| "performance-*", |
| "portability-*", |
| "-bugprone-easily-swappable-parameters", |
| "-bugprone-narrowing-conversions", |
| "-misc-no-recursion", |
| "-misc-non-private-member-variables-in-classes", |
| "-misc-unused-parameters", |
| "-performance-no-int-to-ptr", |
| // the following groups are excluded by -* |
| // -altera-* |
| // -cppcoreguidelines-* |
| // -darwin-* |
| // -fuchsia-* |
| // -hicpp-* |
| // -llvm-* |
| // -llvmlibc-* |
| // -modernize-* |
| // -mpi-* |
| // -objc-* |
| // -readability-* |
| // -zircon-* |
| }, ",") |
| // clang-analyzer-* checks are too slow to be in the default for WITH_TIDY=1. |
| // nightly builds add CLANG_ANALYZER_CHECKS=1 to run those checks. |
| // The insecureAPI.DeprecatedOrUnsafeBufferHandling warning does not apply to Android. |
| if ctx.Config().IsEnvTrue("CLANG_ANALYZER_CHECKS") { |
| checks += ",clang-analyzer-*,-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling" |
| } |
| return checks |
| }) |
| |
| // There are too many clang-tidy warnings in external and vendor projects. |
| // Enable only some google checks for these projects. |
| pctx.VariableFunc("TidyExternalVendorChecks", func(ctx android.PackageVarContext) string { |
| if override := ctx.Config().Getenv("DEFAULT_EXTERNAL_VENDOR_TIDY_CHECKS"); override != "" { |
| return override |
| } |
| return strings.Join([]string{ |
| "-*", |
| "clang-diagnostic-unused-command-line-argument", |
| "google-build-explicit-make-pair", |
| "google-build-namespaces", |
| "google-runtime-operator", |
| "google-upgrade-*", |
| }, ",") |
| }) |
| |
| pctx.VariableFunc("TidyGlobalNoChecks", func(ctx android.PackageVarContext) string { |
| return strings.Join(globalNoCheckList, ",") |
| }) |
| |
| pctx.VariableFunc("TidyGlobalNoErrorChecks", func(ctx android.PackageVarContext) string { |
| return strings.Join(globalNoErrorCheckList, ",") |
| }) |
| |
| // To reduce duplicate warnings from the same header files, |
| // header-filter will contain only the module directory and |
| // those specified by DEFAULT_TIDY_HEADER_DIRS. |
| pctx.VariableFunc("TidyDefaultHeaderDirs", func(ctx android.PackageVarContext) string { |
| return ctx.Config().Getenv("DEFAULT_TIDY_HEADER_DIRS") |
| }) |
| |
| // Use WTIH_TIDY_FLAGS to pass extra global default clang-tidy flags. |
| pctx.VariableFunc("TidyWithTidyFlags", func(ctx android.PackageVarContext) string { |
| return ctx.Config().Getenv("WITH_TIDY_FLAGS") |
| }) |
| } |
| |
| type PathBasedTidyCheck struct { |
| PathPrefix string |
| Checks string |
| } |
| |
| const tidyDefault = "${config.TidyDefaultGlobalChecks}" |
| const tidyExternalVendor = "${config.TidyExternalVendorChecks}" |
| const tidyDefaultNoAnalyzer = "${config.TidyDefaultGlobalChecks},-clang-analyzer-*" |
| |
| // This is a map of local path prefixes to the set of default clang-tidy checks |
| // to be used. |
| // The last matched local_path_prefix should be the most specific to be used. |
| var DefaultLocalTidyChecks = []PathBasedTidyCheck{ |
| {"external/", tidyExternalVendor}, |
| {"external/google", tidyDefault}, |
| {"external/webrtc", tidyDefault}, |
| {"external/googletest/", tidyExternalVendor}, |
| {"frameworks/compile/mclinker/", tidyExternalVendor}, |
| {"hardware/qcom", tidyExternalVendor}, |
| {"vendor/", tidyExternalVendor}, |
| {"vendor/google", tidyDefault}, |
| {"vendor/google_arc/libs/org.chromium.arc.mojom", tidyExternalVendor}, |
| {"vendor/google_devices", tidyExternalVendor}, |
| } |
| |
| var reversedDefaultLocalTidyChecks = reverseTidyChecks(DefaultLocalTidyChecks) |
| |
| func reverseTidyChecks(in []PathBasedTidyCheck) []PathBasedTidyCheck { |
| ret := make([]PathBasedTidyCheck, len(in)) |
| for i, check := range in { |
| ret[len(in)-i-1] = check |
| } |
| return ret |
| } |
| |
| func TidyChecksForDir(dir string) string { |
| dir = dir + "/" |
| for _, pathCheck := range reversedDefaultLocalTidyChecks { |
| if strings.HasPrefix(dir, pathCheck.PathPrefix) { |
| return pathCheck.Checks |
| } |
| } |
| return tidyDefault |
| } |
| |
| // Returns a globally disabled tidy checks, overriding locally selected checks. |
| func TidyGlobalNoChecks() string { |
| if len(globalNoCheckList) > 0 { |
| return ",${config.TidyGlobalNoChecks}" |
| } |
| return "" |
| } |
| |
| // Returns a globally allowed/no-error tidy checks, appended to -warnings-as-errors. |
| func TidyGlobalNoErrorChecks() string { |
| if len(globalNoErrorCheckList) > 0 { |
| return ",${config.TidyGlobalNoErrorChecks}" |
| } |
| return "" |
| } |
| |
| func TidyFlagsForSrcFile(srcFile android.Path, flags string) string { |
| // Disable clang-analyzer-* checks globally for generated source files |
| // because some of them are too huge. Local .bp files can add wanted |
| // clang-analyzer checks through the tidy_checks property. |
| // Need to do this patch per source file, because some modules |
| // have both generated and organic source files. |
| if _, ok := srcFile.(android.WritablePath); ok { |
| if strings.Contains(flags, tidyDefault) { |
| return strings.ReplaceAll(flags, tidyDefault, tidyDefaultNoAnalyzer) |
| } |
| } |
| return flags |
| } |