Fix compiler warnings introduced by -Wextra
Signed-off-by: gatecat <gatecat@ds0.me>
This commit is contained in:
parent
17183fff05
commit
23413a4d12
@ -95,6 +95,7 @@ template <typename T1, typename T2>
|
|||||||
class ValueArray2 {
|
class ValueArray2 {
|
||||||
public:
|
public:
|
||||||
ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {}
|
ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {}
|
||||||
|
ValueArray2(const ValueArray2& other) = default;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
operator ParamGenerator<T>() const {
|
operator ParamGenerator<T>() const {
|
||||||
|
@ -106,7 +106,8 @@ if (MSVC)
|
|||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG /W4 /wd4100 /wd4244 /wd4125 /wd4800 /wd4456 /wd4458 /wd4305 /wd4459 /wd4121 /wd4996")
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG /W4 /wd4100 /wd4244 /wd4125 /wd4800 /wd4456 /wd4458 /wd4305 /wd4459 /wd4121 /wd4996")
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /W4 /wd4100 /wd4244 /wd4125 /wd4800 /wd4456 /wd4458 /wd4305 /wd4459 /wd4121 /wd4996 /wd4127")
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /W4 /wd4100 /wd4244 /wd4125 /wd4800 /wd4456 /wd4458 /wd4305 /wd4459 /wd4121 /wd4996 /wd4127")
|
||||||
else()
|
else()
|
||||||
set(WARN_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Werror=sign-compare -Werror=return-type")
|
# N.B. the -Wno-array-bounds is to work around a false positive in GCC 9
|
||||||
|
set(WARN_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wno-array-bounds -Werror=sign-compare -Werror=return-type")
|
||||||
if (WERROR)
|
if (WERROR)
|
||||||
set(WARN_FLAGS "${WARN_FLAGS} -Werror")
|
set(WARN_FLAGS "${WARN_FLAGS} -Werror")
|
||||||
endif()
|
endif()
|
||||||
|
@ -99,7 +99,7 @@ inline void assert_fail_impl_str(std::string message, const char *expr_str, cons
|
|||||||
#define NPNR_ASSERT_FALSE(msg) (assert_fail_impl(msg, "false", __FILE__, __LINE__))
|
#define NPNR_ASSERT_FALSE(msg) (assert_fail_impl(msg, "false", __FILE__, __LINE__))
|
||||||
#define NPNR_ASSERT_FALSE_STR(msg) (assert_fail_impl_str(msg, "false", __FILE__, __LINE__))
|
#define NPNR_ASSERT_FALSE_STR(msg) (assert_fail_impl_str(msg, "false", __FILE__, __LINE__))
|
||||||
|
|
||||||
#define STRINGIFY(x) #x
|
#define NPNR_STRINGIFY(x) #x
|
||||||
|
|
||||||
struct BaseCtx;
|
struct BaseCtx;
|
||||||
struct Context;
|
struct Context;
|
||||||
@ -541,7 +541,7 @@ struct Property
|
|||||||
ret.is_string = false;
|
ret.is_string = false;
|
||||||
ret.str.reserve(len);
|
ret.str.reserve(len);
|
||||||
for (int i = offset; i < offset + len; i++)
|
for (int i = offset; i < offset + len; i++)
|
||||||
ret.str.push_back(i < int(str.size()) ? str[i] : padding);
|
ret.str.push_back(i < int(str.size()) ? str[i] : char(padding));
|
||||||
ret.update_intval();
|
ret.update_intval();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1255,7 +1255,7 @@ template <typename R> struct BaseArch : ArchAPI<R>
|
|||||||
// Default, trivial, implementations of Arch API functions for arches that don't need complex behaviours
|
// Default, trivial, implementations of Arch API functions for arches that don't need complex behaviours
|
||||||
|
|
||||||
// Basic config
|
// Basic config
|
||||||
virtual IdString archId() const override { return this->id(STRINGIFY(ARCHNAME)); }
|
virtual IdString archId() const override { return this->id(NPNR_STRINGIFY(ARCHNAME)); }
|
||||||
virtual IdString archArgsToId(typename R::ArchArgsT args) const override { return IdString(); }
|
virtual IdString archArgsToId(typename R::ArchArgsT args) const override { return IdString(); }
|
||||||
virtual int getTilePipDimZ(int x, int y) const override { return 1; }
|
virtual int getTilePipDimZ(int x, int y) const override { return 1; }
|
||||||
virtual char getNameDelimiter() const override { return ' '; }
|
virtual char getNameDelimiter() const override { return ' '; }
|
||||||
|
@ -31,8 +31,8 @@ NPNR_PACKED_STRUCT(template <typename T> struct RelSlice {
|
|||||||
const T *begin() const { return get(); }
|
const T *begin() const { return get(); }
|
||||||
const T *end() const { return get() + length; }
|
const T *end() const { return get() + length; }
|
||||||
|
|
||||||
const size_t size() const { return length; }
|
size_t size() const { return length; }
|
||||||
const ptrdiff_t ssize() const { return length; }
|
ptrdiff_t ssize() const { return length; }
|
||||||
|
|
||||||
const T &operator*() const { return *(get()); }
|
const T &operator*() const { return *(get()); }
|
||||||
|
|
||||||
|
@ -1211,7 +1211,7 @@ Router2Cfg::Router2Cfg(Context *ctx)
|
|||||||
hist_cong_weight = ctx->setting<float>("router2/histCongWeight", 1.0f);
|
hist_cong_weight = ctx->setting<float>("router2/histCongWeight", 1.0f);
|
||||||
curr_cong_mult = ctx->setting<float>("router2/currCongWeightMult", 2.0f);
|
curr_cong_mult = ctx->setting<float>("router2/currCongWeightMult", 2.0f);
|
||||||
estimate_weight = ctx->setting<float>("router2/estimateWeight", 1.75f);
|
estimate_weight = ctx->setting<float>("router2/estimateWeight", 1.75f);
|
||||||
perf_profile = ctx->setting<float>("router2/perfProfile", false);
|
perf_profile = ctx->setting<bool>("router2/perfProfile", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -56,7 +56,6 @@ struct Location
|
|||||||
Location() : x(-1), y(-1){};
|
Location() : x(-1), y(-1){};
|
||||||
Location(int16_t x, int16_t y) : x(x), y(y){};
|
Location(int16_t x, int16_t y) : x(x), y(y){};
|
||||||
Location(const LocationPOD &pod) : x(pod.x), y(pod.y){};
|
Location(const LocationPOD &pod) : x(pod.x), y(pod.y){};
|
||||||
Location(const Location &loc) : x(loc.x), y(loc.y){};
|
|
||||||
|
|
||||||
bool operator==(const Location &other) const { return x == other.x && y == other.y; }
|
bool operator==(const Location &other) const { return x == other.x && y == other.y; }
|
||||||
bool operator!=(const Location &other) const { return x != other.x || y != other.y; }
|
bool operator!=(const Location &other) const { return x != other.x || y != other.y; }
|
||||||
|
@ -77,7 +77,7 @@ bool Arch::apply_lpf(std::string filename, std::istream &in)
|
|||||||
std::string tmp;
|
std::string tmp;
|
||||||
while (ss >> tmp)
|
while (ss >> tmp)
|
||||||
words.push_back(tmp);
|
words.push_back(tmp);
|
||||||
if (words.size() >= 0) {
|
if (words.size() > 0) {
|
||||||
std::string verb = words.at(0);
|
std::string verb = words.at(0);
|
||||||
if (verb == "BLOCK") {
|
if (verb == "BLOCK") {
|
||||||
if (words.size() != 2 || (words.at(1) != "ASYNCPATHS" && words.at(1) != "RESETPATHS"))
|
if (words.size() != 2 || (words.at(1) != "ASYNCPATHS" && words.at(1) != "RESETPATHS"))
|
||||||
|
@ -441,7 +441,7 @@ void DedicatedInterconnect::find_dedicated_interconnect()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < bel_data.num_bel_wires; ++i) {
|
for (int i = 0; i < bel_data.num_bel_wires; ++i) {
|
||||||
if (bel_data.types[i] != PORT_IN) {
|
if (bel_data.types[i] != PORT_IN) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -470,7 +470,7 @@ void DedicatedInterconnect::find_dedicated_interconnect()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < bel_data.num_bel_wires; ++i) {
|
for (int i = 0; i < bel_data.num_bel_wires; ++i) {
|
||||||
if (bel_data.types[i] != PORT_OUT) {
|
if (bel_data.types[i] != PORT_OUT) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1018,7 +1018,7 @@ size_t ModuleReader::translate_port_index(LogicalNetlist::Netlist::PortInstance:
|
|||||||
NPNR_ASSERT(port.isBus());
|
NPNR_ASSERT(port.isBus());
|
||||||
uint32_t idx = port_inst.getBusIdx().getIdx();
|
uint32_t idx = port_inst.getBusIdx().getIdx();
|
||||||
size_t width = get_port_width(port);
|
size_t width = get_port_width(port);
|
||||||
NPNR_ASSERT(idx >= 0 && idx < width);
|
NPNR_ASSERT(idx < width);
|
||||||
return width - 1 - idx;
|
return width - 1 - idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -613,20 +613,20 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
// fall through the ++
|
// fall through the ++
|
||||||
case ID_LUT7:
|
case ID_LUT7:
|
||||||
z++;
|
z++;
|
||||||
dff = false;
|
dff = false; /* fall-through*/
|
||||||
case ID_LUT6:
|
case ID_LUT6:
|
||||||
z++;
|
z++;
|
||||||
dff = false;
|
dff = false; /* fall-through*/
|
||||||
case ID_LUT5:
|
case ID_LUT5:
|
||||||
z++;
|
z++; /* fall-through*/
|
||||||
case ID_LUT4:
|
case ID_LUT4:
|
||||||
z++;
|
z++; /* fall-through*/
|
||||||
case ID_LUT3:
|
case ID_LUT3:
|
||||||
z++;
|
z++; /* fall-through*/
|
||||||
case ID_LUT2:
|
case ID_LUT2:
|
||||||
z++;
|
z++; /* fall-through*/
|
||||||
case ID_LUT1:
|
case ID_LUT1:
|
||||||
z++;
|
z++; /* fall-through*/
|
||||||
case ID_LUT0:
|
case ID_LUT0:
|
||||||
// common LUT+DFF code
|
// common LUT+DFF code
|
||||||
snprintf(buf, 32, "R%dC%d_SLICE%d", row + 1, col + 1, z);
|
snprintf(buf, 32, "R%dC%d_SLICE%d", row + 1, col + 1, z);
|
||||||
@ -654,23 +654,23 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ID_IOBJ:
|
case ID_IOBJ:
|
||||||
z++;
|
z++; /* fall-through*/
|
||||||
case ID_IOBI:
|
case ID_IOBI:
|
||||||
z++;
|
z++; /* fall-through*/
|
||||||
case ID_IOBH:
|
case ID_IOBH:
|
||||||
z++;
|
z++; /* fall-through*/
|
||||||
case ID_IOBG:
|
case ID_IOBG:
|
||||||
z++;
|
z++; /* fall-through*/
|
||||||
case ID_IOBF:
|
case ID_IOBF:
|
||||||
z++;
|
z++; /* fall-through*/
|
||||||
case ID_IOBE:
|
case ID_IOBE:
|
||||||
z++;
|
z++; /* fall-through*/
|
||||||
case ID_IOBD:
|
case ID_IOBD:
|
||||||
z++;
|
z++; /* fall-through*/
|
||||||
case ID_IOBC:
|
case ID_IOBC:
|
||||||
z++;
|
z++; /* fall-through*/
|
||||||
case ID_IOBB:
|
case ID_IOBB:
|
||||||
z++;
|
z++; /* fall-through*/
|
||||||
case ID_IOBA:
|
case ID_IOBA:
|
||||||
snprintf(buf, 32, "R%dC%d_IOB%c", row + 1, col + 1, 'A' + z);
|
snprintf(buf, 32, "R%dC%d_IOB%c", row + 1, col + 1, 'A' + z);
|
||||||
belname = id(buf);
|
belname = id(buf);
|
||||||
|
16
gowin/arch.h
16
gowin/arch.h
@ -348,9 +348,9 @@ struct Arch : BaseArch<ArchRanges>
|
|||||||
|
|
||||||
int getGridDimX() const override { return gridDimX; }
|
int getGridDimX() const override { return gridDimX; }
|
||||||
int getGridDimY() const override { return gridDimY; }
|
int getGridDimY() const override { return gridDimY; }
|
||||||
int getTileBelDimZ(int x, int y) const { return tileBelDimZ[x][y]; }
|
int getTileBelDimZ(int x, int y) const override { return tileBelDimZ[x][y]; }
|
||||||
int getTilePipDimZ(int x, int y) const { return tilePipDimZ[x][y]; }
|
int getTilePipDimZ(int x, int y) const override { return tilePipDimZ[x][y]; }
|
||||||
char getNameDelimiter() const
|
char getNameDelimiter() const override
|
||||||
{
|
{
|
||||||
return ' '; /* use a non-existent delimiter as we aren't using IdStringLists yet */
|
return ' '; /* use a non-existent delimiter as we aren't using IdStringLists yet */
|
||||||
}
|
}
|
||||||
@ -431,13 +431,13 @@ struct Arch : BaseArch<ArchRanges>
|
|||||||
bool place() override;
|
bool place() override;
|
||||||
bool route() override;
|
bool route() override;
|
||||||
|
|
||||||
bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayQuad &delay) const;
|
bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayQuad &delay) const override;
|
||||||
// Get the port class, also setting clockInfoCount to the number of TimingClockingInfos associated with a port
|
// Get the port class, also setting clockInfoCount to the number of TimingClockingInfos associated with a port
|
||||||
TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const;
|
TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const override;
|
||||||
// Get the TimingClockingInfo of a port
|
// Get the TimingClockingInfo of a port
|
||||||
TimingClockingInfo getPortClockingInfo(const CellInfo *cell, IdString port, int index) const;
|
TimingClockingInfo getPortClockingInfo(const CellInfo *cell, IdString port, int index) const override;
|
||||||
|
|
||||||
bool isBelLocationValid(BelId bel) const;
|
bool isBelLocationValid(BelId bel) const override;
|
||||||
|
|
||||||
static const std::string defaultPlacer;
|
static const std::string defaultPlacer;
|
||||||
static const std::vector<std::string> availablePlacers;
|
static const std::vector<std::string> availablePlacers;
|
||||||
@ -446,7 +446,7 @@ struct Arch : BaseArch<ArchRanges>
|
|||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
// Internal usage
|
// Internal usage
|
||||||
void assignArchInfo();
|
void assignArchInfo() override;
|
||||||
bool cellsCompatible(const CellInfo **cells, int count) const;
|
bool cellsCompatible(const CellInfo **cells, int count) const;
|
||||||
|
|
||||||
std::vector<IdString> cell_types;
|
std::vector<IdString> cell_types;
|
||||||
|
@ -61,10 +61,10 @@ std::unique_ptr<Context> GowinCommandHandler::createContext(std::unordered_map<s
|
|||||||
log_error("Invalid device %s\n", device.c_str());
|
log_error("Invalid device %s\n", device.c_str());
|
||||||
}
|
}
|
||||||
ArchArgs chipArgs;
|
ArchArgs chipArgs;
|
||||||
char buf[32];
|
char buf[36];
|
||||||
snprintf(buf, 32, "GW1N%s-%s", match[1].str().c_str(), match[3].str().c_str());
|
snprintf(buf, 36, "GW1N%s-%s", match[1].str().c_str(), match[3].str().c_str());
|
||||||
chipArgs.device = buf;
|
chipArgs.device = buf;
|
||||||
snprintf(buf, 32, "GW1N-%s", match[3].str().c_str());
|
snprintf(buf, 36, "GW1N-%s", match[3].str().c_str());
|
||||||
chipArgs.family = buf;
|
chipArgs.family = buf;
|
||||||
chipArgs.package = match[4];
|
chipArgs.package = match[4];
|
||||||
chipArgs.speed = match[5];
|
chipArgs.speed = match[5];
|
||||||
|
@ -202,6 +202,8 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PickedElement &operator=(const PickedElement &other) = default;
|
||||||
|
|
||||||
DecalXY decal(Context *ctx) const
|
DecalXY decal(Context *ctx) const
|
||||||
{
|
{
|
||||||
DecalXY decal;
|
DecalXY decal;
|
||||||
|
@ -52,8 +52,6 @@ template <typename CoordinateT, typename ElementT> class QuadTreeNode
|
|||||||
|
|
||||||
BoundingBox() : x0_(pinf), y0_(pinf), x1_(ninf), y1_(ninf) {}
|
BoundingBox() : x0_(pinf), y0_(pinf), x1_(ninf), y1_(ninf) {}
|
||||||
|
|
||||||
BoundingBox(const BoundingBox &other) : x0_(other.x0_), y0_(other.y0_), x1_(other.x1_), y1_(other.y1_) {}
|
|
||||||
|
|
||||||
// Whether a bounding box contains a given points.
|
// Whether a bounding box contains a given points.
|
||||||
// A point is defined to be in a bounding box when it's not lesser than
|
// A point is defined to be in a bounding box when it's not lesser than
|
||||||
// the lower coordinate or greater than the higher coordinate, eg:
|
// the lower coordinate or greater than the higher coordinate, eg:
|
||||||
|
@ -218,7 +218,7 @@ template <typename ElementT> class ElementList : public Item
|
|||||||
name.remove(0, prefix.size());
|
name.remove(0, prefix.size());
|
||||||
|
|
||||||
auto item = new IdStringItem(ctx_, idstring, this, child_type_);
|
auto item = new IdStringItem(ctx_, idstring, this, child_type_);
|
||||||
managed_[idstring] = std::move(std::unique_ptr<Item>(item));
|
managed_[idstring] = std::unique_ptr<Item>(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,7 +306,7 @@ template <typename ElementT> class ElementXYRoot : public Item
|
|||||||
|
|
||||||
// Create X list Item.
|
// Create X list Item.
|
||||||
auto item = new Item(QString("X%1").arg(i), this);
|
auto item = new Item(QString("X%1").arg(i), this);
|
||||||
managed_labels_.push_back(std::move(std::unique_ptr<Item>(item)));
|
managed_labels_.push_back(std::unique_ptr<Item>(item));
|
||||||
|
|
||||||
for (auto j : y_present) {
|
for (auto j : y_present) {
|
||||||
// Create Y list ElementList.
|
// Create Y list ElementList.
|
||||||
@ -314,7 +314,7 @@ template <typename ElementT> class ElementXYRoot : public Item
|
|||||||
new ElementList<ElementT>(ctx_, QString("Y%1").arg(j), item, &map_, i, j, getter_, child_type_);
|
new ElementList<ElementT>(ctx_, QString("Y%1").arg(j), item, &map_, i, j, getter_, child_type_);
|
||||||
// Pre-populate list with one element, other Qt will never ask for more.
|
// Pre-populate list with one element, other Qt will never ask for more.
|
||||||
item2->fetchMore(1);
|
item2->fetchMore(1);
|
||||||
managed_lists_.push_back(std::move(std::unique_ptr<ElementList<ElementT>>(item2)));
|
managed_lists_.push_back(std::unique_ptr<ElementList<ElementT>>(item2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,6 +153,7 @@ std::string Arch::get_full_chip_name() const
|
|||||||
break;
|
break;
|
||||||
case ArchArgs::SPEED_3:
|
case ArchArgs::SPEED_3:
|
||||||
name += "3";
|
name += "3";
|
||||||
|
break;
|
||||||
case ArchArgs::SPEED_4:
|
case ArchArgs::SPEED_4:
|
||||||
name += "4";
|
name += "4";
|
||||||
break;
|
break;
|
||||||
|
@ -48,7 +48,6 @@ struct Location
|
|||||||
Location() : x(-1), y(-1){};
|
Location() : x(-1), y(-1){};
|
||||||
Location(int16_t x, int16_t y) : x(x), y(y){};
|
Location(int16_t x, int16_t y) : x(x), y(y){};
|
||||||
Location(const LocationPOD &pod) : x(pod.x), y(pod.y){};
|
Location(const LocationPOD &pod) : x(pod.x), y(pod.y){};
|
||||||
Location(const Location &loc) : x(loc.x), y(loc.y){};
|
|
||||||
|
|
||||||
bool operator==(const Location &other) const { return x == other.x && y == other.y; }
|
bool operator==(const Location &other) const { return x == other.x && y == other.y; }
|
||||||
bool operator!=(const Location &other) const { return x != other.x || y != other.y; }
|
bool operator!=(const Location &other) const { return x != other.x || y != other.y; }
|
||||||
|
@ -114,20 +114,6 @@ static std::vector<bool> int_to_bitvector(int val, int size)
|
|||||||
return bv;
|
return bv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<bool> str_to_bitvector(std::string str, int size)
|
|
||||||
{
|
|
||||||
std::vector<bool> bv;
|
|
||||||
bv.resize(size, 0);
|
|
||||||
if (str.substr(0, 2) != "0b")
|
|
||||||
log_error("error parsing value '%s', expected 0b prefix\n", str.c_str());
|
|
||||||
for (int i = 0; i < int(str.size()) - 2; i++) {
|
|
||||||
char c = str.at((str.size() - i) - 1);
|
|
||||||
NPNR_ASSERT(c == '0' || c == '1');
|
|
||||||
bv.at(i) = (c == '1');
|
|
||||||
}
|
|
||||||
return bv;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string intstr_or_default(const std::unordered_map<IdString, Property> &ct, const IdString &key,
|
std::string intstr_or_default(const std::unordered_map<IdString, Property> &ct, const IdString &key,
|
||||||
std::string def = "0")
|
std::string def = "0")
|
||||||
{
|
{
|
||||||
|
2
tests
2
tests
@ -1 +1 @@
|
|||||||
Subproject commit 32db04a11077e7a32adc6f3d473e5cbefe83ff0a
|
Subproject commit 34c511444eff51291fa732369e434ff687de310f
|
Loading…
Reference in New Issue
Block a user