File: RawPtrPlugin.cpp

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (136 lines) | stat: -rw-r--r-- 5,191 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "RawPtrPlugin.h"

#include "FindBadRawPtrPatterns.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/Frontend/FrontendPluginRegistry.h"
#include "llvm/Support/TimeProfiler.h"

using namespace clang;

namespace {

// Name of a cmdline parameter that can be used to specify a file listing fields
// that should not be rewritten to use raw_ptr<T>.
//
// See also:
// - OutputSectionHelper
// - FilterFile
const char kExcludeFieldsArgPrefix[] = "exclude-fields=";

// Name of a cmdline parameter that can be used to add a regular expressions
// that matches paths that should be excluded from the raw pointer usage checks.
const char kRawPtrExcludePathArgPrefix[] = "raw-ptr-exclude-path=";

// Name of a cmdline parameter that can be used to add a regular expressions
// that matches paths that should be excluded from the bad raw_ptr casts checks.
const char kBadRawPtrCastExcludePathArgPrefix[] =
    "check-bad-raw-ptr-cast-exclude-path=";

// Name of a cmdline parameter that can be used to add a regular expressions
// that matches function names that should be excluded from the bad raw_ptr cast
// checks. All implicit casts in CallExpr to the specified functions are
// excluded from the check. Use if you know that function does not break a
// reference count.
const char kCheckBadRawPtrCastExcludeFuncArgPrefix[] =
    "check-bad-raw-ptr-cast-exclude-func=";

}  // namespace

namespace raw_ptr_plugin {

namespace {

class PluginConsumer : public ASTConsumer {
 public:
  PluginConsumer(CompilerInstance* instance, const Options& options)
      : options_(options), instance_(*instance) {}

  void HandleTranslationUnit(clang::ASTContext& context) override {
    llvm::TimeTraceScope TimeScope("HandleTranslationUnit for raw-ptr plugin");
    if (options_.check_bad_raw_ptr_cast || options_.check_raw_ptr_fields ||
        options_.check_raw_ref_fields ||
        (options_.check_raw_ptr_to_stack_allocated &&
         !options_.disable_check_raw_ptr_to_stack_allocated_error) ||
        options_.check_span_fields) {
      FindBadRawPtrPatterns(options_, context, instance_);
    }
  }

 private:
  // Options.
  const Options options_;

  clang::CompilerInstance& instance_;
};

}  // namespace

RawPtrPlugin::RawPtrPlugin() {}

std::unique_ptr<ASTConsumer> RawPtrPlugin::CreateASTConsumer(
    CompilerInstance& instance,
    llvm::StringRef ref) {
  return std::make_unique<PluginConsumer>(&instance, options_);
}

bool RawPtrPlugin::ParseArgs(const CompilerInstance& instance,
                             const std::vector<std::string>& args) {
  for (llvm::StringRef arg : args) {
    if (arg.starts_with(kExcludeFieldsArgPrefix)) {
      options_.exclude_fields_file =
          arg.substr(strlen(kExcludeFieldsArgPrefix)).str();
    } else if (arg.starts_with(kRawPtrExcludePathArgPrefix)) {
      options_.raw_ptr_paths_to_exclude_lines.push_back(
          arg.substr(strlen(kRawPtrExcludePathArgPrefix)).str());
    } else if (arg.starts_with(kCheckBadRawPtrCastExcludeFuncArgPrefix)) {
      options_.check_bad_raw_ptr_cast_exclude_funcs.push_back(
          arg.substr(strlen(kCheckBadRawPtrCastExcludeFuncArgPrefix)).str());
    } else if (arg.starts_with(kBadRawPtrCastExcludePathArgPrefix)) {
      options_.check_bad_raw_ptr_cast_exclude_paths.push_back(
          arg.substr(strlen(kBadRawPtrCastExcludePathArgPrefix)).str());
    } else if (arg == "check-bad-raw-ptr-cast") {
      options_.check_bad_raw_ptr_cast = true;
    } else if (arg == "check-raw-ptr-fields") {
      options_.check_raw_ptr_fields = true;
    } else if (arg == "check-raw-ptr-to-stack-allocated") {
      options_.check_raw_ptr_to_stack_allocated = true;
    } else if (arg == "disable-check-raw-ptr-to-stack-allocated-error") {
      options_.disable_check_raw_ptr_to_stack_allocated_error = true;
    } else if (arg == "check-raw-ref-fields") {
      options_.check_raw_ref_fields = true;
    } else if (arg == "check-ptrs-to-non-string-literals") {
      // Rewriting const char pointers was skipped for performance as they are
      // likely to point to string literals.
      //
      // This exclusion mechanism also wrongly excluded some non-string-literals
      // like `const uint8_t*` and `const int8*`.
      //
      // This flag is added to gradually re-include these types in the
      // enforcement plugin.
      //
      // TODO(https://crbug.com/331840473) Remove this flag
      // once the necessary members are rewritten and the raw_ptr enforcement
      // plugin is up to date.
      options_.check_ptrs_to_non_string_literals = true;
    } else if (arg == "check-span-fields") {
      options_.check_span_fields = true;
    } else if (arg == "enable-match-profiling") {
      options_.enable_match_profiling = true;
    } else {
      llvm::errs() << "Unknown clang plugin argument: " << arg << "\n";
      return false;
    }
  }

  return true;
}

}  // namespace raw_ptr_plugin

static FrontendPluginRegistry::Add<raw_ptr_plugin::RawPtrPlugin> X(
    "raw-ptr-plugin",
    "Check pointers for safety");