// 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 <stdlib.h>
#include <array>
#include <cstring>
#include <vector>
#include "base/containers/span.h"
#include "base/memory/raw_ptr.h"
class A {
public:
A() = default;
// Expected rewrite:
// A(base::span<int> ptr) : member(ptr) {}
A(base::span<int> ptr) : member(ptr) {}
// Expected rewrite:
// void set(base::span<int> ptr);
void set(base::span<int> ptr);
// Expected rewrite:
// base::span<int> get(int i);
base::span<int> get(int i);
private:
// Expected rewrite:
// base::span<int> member;
base::span<int> member;
};
// Expected rewrite:
// void set(base::span<int> ptr)
void A::set(base::span<int> ptr) {
member = ptr;
}
// Expected rewrite:
// base::span<int> get(int i)
base::span<int> A::get(int i) {
return member;
}
int something_else() {
// Expected rewrite:
// base::span<int> ptr = {};
base::span<int> ptr = {};
A a(ptr);
// Expected rewrite:
// base::span<int> temp = a.get(1);
base::span<int> temp = a.get(1);
// Expected rewrite:
// int* temp2 = a.get(1234).data();
int* temp2 = a.get(1234).data();
// Leads temp's type to be rewritten along with other necessary changes.
return temp[1];
}
int offset(int n = 0) {
return n;
}
void fct() {
auto buf = std::vector<char>(1, 1);
// Expected rewrite:
// base::span<char> expected_data = buf;
base::span<char> expected_data = buf;
for (std::size_t ii = 0; ii < 1; ++ii) {
// buffer usage on expected_data
expected_data[ii] = ii * 3;
}
int index = buf.size() - 1;
// Expected rewrite:
// char* temp = expected_data++.data();
char* temp = (expected_data++).data();
// Expected rewrite:
// temp = (++expected_data).data();
temp = (++expected_data).data();
// Expected rewrite:
// temp = (expected_data + 1).data();
temp = (expected_data + 1).data();
// Expected rewrite:
// temp = (expected_data + index).data();
temp = (expected_data + index).data();
// Expected rewrite:
// temp = (expected_data + offset()).data();
temp = (expected_data + offset()).data();
// Expected rewrite:
// temp = (expected_data + offset(2)).data();
temp = (expected_data + offset(2)).data();
// Expected rewrite:
// temp = (expected_data + offset(index)).data();
temp = (expected_data + offset(index)).data();
// Expected rewrite:
// base::span<char> ptr = &buf[0];
base::span<char> ptr = &buf[0];
ptr[1] = 'x';
}
// cast expressions
namespace cast_exprs {
// Expected rewrite:
// void modify(base::span<int> buf)
void modify(base::span<int> buf) {
// expected rewrite:
// base::span<char> temp = reinterpret_cast<char*>(buf);
base::span<char> temp = reinterpret_cast<char*>(buf);
temp[2] = 'c';
}
void fct() {
int buf[10];
// Expected rewrite:
// base::span<char> as_char;
base::span<char> as_char = reinterpret_cast<char*>(buf);
as_char[4] = 'c';
// Expected rewrite:
// base::span<int> ptr;
base::span<int> ptr = buf;
// Usage as a buffer, ptr should become a span.
ptr[2] = 3;
modify(ptr);
}
} // namespace cast_exprs
namespace malloc_tests {
const char* get() {
return nullptr;
}
void fct() {
// Expected rewrite:
// base::span<int> buf = malloc(4*sizeof(int));
base::span<char> buf = (char*)malloc(4 * sizeof(int));
// Leads buf to be rewritten.
buf++;
const char* buf2 = nullptr;
(void)buf2[0];
(void)get()[0];
}
} // namespace malloc_tests
namespace function_params_and_return {
// TODO: Wrong rewrite generated here.
// Rewrites to: const base::span<int>
// Should rewrite to: base::span<const int>
const base::span<int> get_buf();
// TODO: Wrong rewrite generated here.
// Expected rewrite:
// base::span<const int> get_buf() {
const base::span<int> get_buf() {
static std::vector<int> buf;
return &buf[0];
}
void f() {
// Expected rewrite:
// base::span<const int> buf = get_buf();
base::span<const int> buf = get_buf();
(void)buf[0];
}
} // namespace function_params_and_return
namespace templated_stuff {
// Expected rewrite:
// base::span<T> get_buffer()
template <typename T>
base::span<T> get_buffer() {
static T buf[10];
return buf;
}
void fct() {
// Expected rewrite:
// base::span<int> buf = get_buffer<int>();
base::span<int> buf = get_buffer<int>();
buf[1] = 1;
// Expected rewrite:
// base::span<char> buf2 = get_buffer<char>();
base::span<char> buf2 = get_buffer<char>();
buf2[1] = 'a';
// Expected rewrite:
// memcpy(buf2.data(), buf.data(), 10
memcpy(buf2.data(), buf.data(), 10);
// Expected rewrite:
// memcpy((buf2++).data(), (++buf).data(), 10)
memcpy((buf2++).data(), (++buf).data(), 10);
int index = 11;
// Expected rewrite:
// memcpy((buf2 + 1).data(), (buf + index).data(), 10)
memcpy((buf2 + 1).data(), (buf + index).data(), 10);
// Expected rewrite:
// int i = (buf++)[0];
int i = (buf++)[0];
// i = (++buf)[0]
i = (++buf)[0];
// i = ((buf + index)[0])
i = ((buf + index)[0]);
// i = buf[0];
i = buf[0];
}
} // namespace templated_stuff
namespace buffers_into_arrays {
void fct() {
// Expected rewrite:
// std::array<int, 4> buf = {1, 2, 3, 4};
std::array<int, 4> buf = {1, 2, 3, 4};
int index = 0;
buf[index] = 11;
}
} // namespace buffers_into_arrays