File: macro-definitions-multiple-files-original.cc

package info (click to toggle)
chromium 139.0.7258.127-2
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 6,122,156 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 (230 lines) | stat: -rw-r--r-- 7,652 bytes parent folder | download | duplicates (3)
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <cassert>
#include <cstdint>
#include <cstring>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>

#include "usr/include/linux/netlink.h"

// NOTE: this exists as a regression test for crbug/357433195, where before the
// associated patch that added this, this would fail an assertion in
// extract_edits.py. However after fixing the assertion the code below doesn't
// get rewritten so original.cc == expected.cc, we're just asserting that the
// script doesn't fail on it.
namespace internal {
namespace {
using std::size_t;
// Expected rewrite:
// bool GetAddress(base::span<const struct nlmsghdr> header,
bool GetAddress(const struct nlmsghdr* header,
                int header_length,
                bool* really_deprecated) {
  if (really_deprecated) {
    *really_deprecated = false;
  }

  // Expected rewrite:
  // const struct nlmsghdr* msg = reinterpret_cast<const struct nlmsghdr*>(
  //     UNSAFE_TODO(NLMSG_DATA(header.data())));
  const struct nlmsghdr* msg =
      reinterpret_cast<const struct nlmsghdr*>(NLMSG_DATA(header));
  return true;
}

// Expected rewrite:
// template <typename T>
// T* SafelyCastNetlinkMsgData(base::span<const struct nlmsghdr> header,
//                             int length) {
template <typename T>
T* SafelyCastNetlinkMsgData(const struct nlmsghdr* header, int length) {
  if (length <= 0 || static_cast<size_t>(length) < NLMSG_HDRLEN + sizeof(T)) {
    return nullptr;
  }
  // Expected rewrite:
  // return reinterpret_cast<const T*>(UNSAFE_TODO(NLMSG_DATA(header.data())));
  return reinterpret_cast<const T*>(NLMSG_DATA(header));
}
}  // namespace
}  // namespace internal

// While fixing the above, the updating sometimes caused the rewrite to occur in
// the middle of the MACRO rather than inside the macro. This catches that case.

// Expected rewrite:
// dict.data()
#define CAST_FUN reinterpret_cast<std::size_t**>(dict);
#define CAST_FUN_2(x) reinterpret_cast<std::size_t**>(x);

// Expected rewrite:
// base::span<int*> dict
std::size_t check(int** dict, std::size_t N) {
  // Expected rewrite:
  // if (!dict.empty())
  if (dict) {
    for (int i = 0; i < N; ++i) {
      int* ptr = dict[i];
      // No expected rewrite
      std::size_t** new_ptr = CAST_FUN;
      // Expected rewrite:
      // dict.data()
      std::size_t** new_ptr_2 = CAST_FUN_2(dict);
      if (**new_ptr > 10) {
        return **new_ptr;
      } else {
        return **new_ptr_2;
      }
    }
  }
  return 10;
}

void checkMacroInFile() {
  int array[2][1] = {{int(2)}, {int(3)}};
  // Expected rewrite:
  // base::span<int*>
  int** front = reinterpret_cast<int**>(array);
  check(front, 2);
}

// Finally after fixing the initial multiple neighbors there was a new one and
// this one catches that. Again this used to crash and showcases the situations
// where the assertion would fail.
struct Entry {
  explicit Entry(std::string n) : name(n) {}
  std::string name;
  std::unordered_map<std::string, int> metrics;
};

class Recorder {
 public:
  // No expected rewrite.
  bool EntryHasMetricNoRewrites(const Entry* entry, std::string metric_name) {
    const int* val = nullptr;
    if (entry->metrics.find(metric_name) != entry->metrics.end()) {
      val = &entry->metrics.find(metric_name)->second;
    }
    return val != nullptr;
  }

  // No expected rewrite
  bool EntryHasMetricRhsRewrite(const Entry* const* entries,
                                size_t len,
                                std::string metric_name) {
    // Can't use entries like a buffer to avoid the rewrite.
    const int* val = nullptr;
    if (!entries || metric_name == "hello" || len > 3) {
      return false;
    }
    return true;
  }

  // Expected rewrite:
  // base::span<const Entry* const>
  bool EntryHasMetricFullRewrite(const Entry* const* entries,
                                 size_t len,
                                 std::string metric_name) {
    const int* val = nullptr;
    for (size_t i = 0; i < len; ++i) {
      const Entry* entry = entries[i];
      if (entry->metrics.find(metric_name) != entry->metrics.end()) {
        val = &entry->metrics.find(metric_name)->second;
      }
    }
    return val != nullptr;
  }

  // No expected rewrite.
  std::vector<const Entry*> GetEntriesByName(std::string name) const {
    std::vector<const Entry*> result;
    for (const auto& entry : entries_) {
      if (entry->name == name) {
        result.push_back(entry.get());
      }
    }
    return result;
  }
  std::vector<std::unique_ptr<Entry>> entries_;
};

// No expected rewrite.
#define EXPECT_HAS_UKM_NO_REWRITE(name) \
  assert(test_recorder_->EntryHasMetricNoRewrites(entry, name));

// Expected rewrite:
// test_entries.data()
#define EXPECT_HAS_UKM_RHS_REWRITE(name)                        \
  assert(test_recorder_->EntryHasMetricRhsRewrite(test_entries, \
                                                  entries.size(), name));

// No expected rewrite.
#define EXPECT_HAS_UKM_FULL_REWRITE(name)                        \
  assert(test_recorder_->EntryHasMetricFullRewrite(test_entries, \
                                                   entries.size(), name));

void MediaMetricsProviderTestTestUkm() {
  Recorder recorder_;
  Recorder* test_recorder_ = &recorder_;
  test_recorder_->entries_.push_back(std::make_unique<Entry>("foo"));
  // Test when neither lhs nor rhs gets rewritten this is the common case in the
  // code base.
  {
    const auto& entries = test_recorder_->GetEntriesByName("foo");
    assert(1u == entries.size());
    // No expected rewrite.
    for (const Entry* entry : entries) {
      // This macro references |entry| and thus would need to rewrite it as
      // .data() if we changed the for loop to a base::span (which we don't).
      EXPECT_HAS_UKM_NO_REWRITE("bar");
    }
  }
  {
    const auto& entries = test_recorder_->GetEntriesByName("foo");
    assert(1u == entries.size());
    // No expected rewrite.
    for (const Entry* entry : entries) {
      // This macro references |entry| and thus would need to rewrite it as
      // .data() if we changed the for loop to a base::span (which we don't).
      EXPECT_HAS_UKM_NO_REWRITE("bar");
    }
  }

  // Test how we handle macros when the function (lhs) doesn't get rewritten but
  // the rhs does.
  {
    const auto& entries = test_recorder_->GetEntriesByName("foo");
    // Expected rewrite:
    // base::span<const Entry*> test_entries = entries;
    const Entry* const* test_entries = entries.data();
    const_cast<const Entry**>(test_entries)[0] = nullptr;
    EXPECT_HAS_UKM_RHS_REWRITE("bar");
  }
  {
    const auto& entries = test_recorder_->GetEntriesByName("foo");
    // Expected rewrite:
    // base::span<const Entry*> test_entries = entries;
    const Entry* const* test_entries = entries.data();
    const_cast<const Entry**>(test_entries)[0] = nullptr;
    EXPECT_HAS_UKM_RHS_REWRITE("bar");
  }

  // Test how we handle macros when the function and the rhs gets rewritten.
  {
    const auto& entries = test_recorder_->GetEntriesByName("foo");
    // Expected rewrite:
    // base::span<const Entry* const> test_entries = entries;
    const Entry* const* test_entries = entries.data();
    EXPECT_HAS_UKM_FULL_REWRITE("bar");
  }
  {
    const auto& entries = test_recorder_->GetEntriesByName("foo");
    // Expected rewrite:
    // base::span<const Entry* const> test_entries = entries;
    const Entry* const* test_entries = entries.data();
    EXPECT_HAS_UKM_FULL_REWRITE("bar");
  }
}