Merge branch 'check-headers-max-warn'
Check compilation of all wx headers with all gcc warnings enabled. This should make it impossible to introduce problems that only appear when -Wpedantic or -Wany-other-not-completely-unreasonable-warning is enabled when building user code including wx headers again. See https://github.com/wxWidgets/wxWidgets/pull/2033
This commit is contained in:
@@ -371,7 +371,7 @@ extern void WXDLLIMPEXP_BASE wxAbort();
|
||||
wxFAIL_COND_MSG(#cond, msg); \
|
||||
op; \
|
||||
} \
|
||||
struct wxDummyCheckStruct /* just to force a semicolon */
|
||||
struct wxMAKE_UNIQUE_NAME(wxDummyCheckStruct) /* to force a semicolon */
|
||||
|
||||
// check which returns with the specified return code if the condition fails
|
||||
#define wxCHECK_MSG(cond, rc, msg) wxCHECK2_MSG(cond, return rc, msg)
|
||||
|
@@ -542,12 +542,14 @@ typedef short int WXTYPE;
|
||||
/* ---------------------------------------------------------------------------- */
|
||||
|
||||
/* Printf-like attribute definitions to obtain warnings with GNU C/C++ */
|
||||
#if defined(__GNUC__) && !wxUSE_UNICODE
|
||||
# define WX_ATTRIBUTE_FORMAT(like, m, n) __attribute__ ((__format__ (like, m, n)))
|
||||
#else
|
||||
# define WX_ATTRIBUTE_FORMAT(like, m, n)
|
||||
#endif
|
||||
|
||||
#ifndef WX_ATTRIBUTE_PRINTF
|
||||
# if defined(__GNUC__) && !wxUSE_UNICODE
|
||||
# define WX_ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
|
||||
# else
|
||||
# define WX_ATTRIBUTE_PRINTF(m, n)
|
||||
# endif
|
||||
# define WX_ATTRIBUTE_PRINTF(m, n) WX_ATTRIBUTE_FORMAT(__printf__, m, n)
|
||||
|
||||
# define WX_ATTRIBUTE_PRINTF_1 WX_ATTRIBUTE_PRINTF(1, 2)
|
||||
# define WX_ATTRIBUTE_PRINTF_2 WX_ATTRIBUTE_PRINTF(2, 3)
|
||||
@@ -662,6 +664,9 @@ typedef short int WXTYPE;
|
||||
wxGCC_WARNING_SUPPRESS(float-equal)
|
||||
inline bool wxIsSameDouble(double x, double y) { return x == y; }
|
||||
wxGCC_WARNING_RESTORE(float-equal)
|
||||
|
||||
Note that these macros apply to both gcc and clang, even though they only
|
||||
have "GCC" in their names.
|
||||
*/
|
||||
#if defined(__clang__) || wxCHECK_GCC_VERSION(4, 6)
|
||||
# define wxGCC_WARNING_SUPPRESS(x) \
|
||||
@@ -674,6 +679,17 @@ typedef short int WXTYPE;
|
||||
# define wxGCC_WARNING_RESTORE(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
Similar macros but for gcc-specific warnings.
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
# define wxGCC_ONLY_WARNING_SUPPRESS(x) wxGCC_WARNING_SUPPRESS(x)
|
||||
# define wxGCC_ONLY_WARNING_RESTORE(x) wxGCC_WARNING_RESTORE(x)
|
||||
#else
|
||||
# define wxGCC_ONLY_WARNING_SUPPRESS(x)
|
||||
# define wxGCC_ONLY_WARNING_RESTORE(x)
|
||||
#endif
|
||||
|
||||
/* Specific macros for -Wcast-function-type warning new in gcc 8. */
|
||||
#if wxCHECK_GCC_VERSION(8, 0)
|
||||
#define wxGCC_WARNING_SUPPRESS_CAST_FUNCTION_TYPE() \
|
||||
|
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
#define wxDFB_DECLARE_INTERFACE(name) \
|
||||
class wx##name; \
|
||||
typedef wxDfbPtr<wx##name> wx##name##Ptr;
|
||||
typedef wxDfbPtr<wx##name> wx##name##Ptr
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@@ -1140,9 +1140,9 @@ private:
|
||||
{
|
||||
}
|
||||
|
||||
wxGridBlocks(iterator_impl begin, iterator_impl end) :
|
||||
m_begin(begin),
|
||||
m_end(end)
|
||||
wxGridBlocks(iterator_impl ibegin, iterator_impl iend) :
|
||||
m_begin(ibegin),
|
||||
m_end(iend)
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -274,6 +274,12 @@ extern WXDLLIMPEXP_DATA_CORE(wxGraphicsMatrix) wxNullGraphicsMatrix;
|
||||
// and how they are spread out in a gradient
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// gcc 9 gives a nonsensical warning about implicitly generated move ctor not
|
||||
// throwing but not being noexcept, suppress it.
|
||||
#if wxCHECK_GCC_VERSION(9, 1) && !wxCHECK_GCC_VERSION(10, 0)
|
||||
wxGCC_WARNING_SUPPRESS(noexcept)
|
||||
#endif
|
||||
|
||||
// Describes a single gradient stop.
|
||||
class wxGraphicsGradientStop
|
||||
{
|
||||
@@ -306,6 +312,10 @@ private:
|
||||
float m_pos;
|
||||
};
|
||||
|
||||
#if wxCHECK_GCC_VERSION(9, 1) && !wxCHECK_GCC_VERSION(10, 0)
|
||||
wxGCC_WARNING_RESTORE(noexcept)
|
||||
#endif
|
||||
|
||||
// A collection of gradient stops ordered by their positions (from lowest to
|
||||
// highest). The first stop (index 0, position 0.0) is always the starting
|
||||
// colour and the last one (index GetCount() - 1, position 1.0) is the end
|
||||
|
@@ -497,15 +497,15 @@ private:
|
||||
|
||||
public:
|
||||
wxIntegerHash() { }
|
||||
size_t operator()( long x ) const { return longHash( x ); }
|
||||
size_t operator()( unsigned long x ) const { return ulongHash( x ); }
|
||||
size_t operator()( int x ) const { return intHash( x ); }
|
||||
size_t operator()( unsigned int x ) const { return uintHash( x ); }
|
||||
size_t operator()( short x ) const { return shortHash( x ); }
|
||||
size_t operator()( unsigned short x ) const { return ushortHash( x ); }
|
||||
size_t operator()( long x ) const wxNOEXCEPT { return longHash( x ); }
|
||||
size_t operator()( unsigned long x ) const wxNOEXCEPT { return ulongHash( x ); }
|
||||
size_t operator()( int x ) const wxNOEXCEPT { return intHash( x ); }
|
||||
size_t operator()( unsigned int x ) const wxNOEXCEPT { return uintHash( x ); }
|
||||
size_t operator()( short x ) const wxNOEXCEPT { return shortHash( x ); }
|
||||
size_t operator()( unsigned short x ) const wxNOEXCEPT { return ushortHash( x ); }
|
||||
#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
||||
size_t operator()( wxLongLong_t x ) const { return longlongHash(x); }
|
||||
size_t operator()( wxULongLong_t x ) const { return longlongHash(x); }
|
||||
size_t operator()( wxLongLong_t x ) const wxNOEXCEPT { return longlongHash(x); }
|
||||
size_t operator()( wxULongLong_t x ) const wxNOEXCEPT { return longlongHash(x); }
|
||||
#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
||||
|
||||
wxIntegerHash& operator=(const wxIntegerHash&) { return *this; }
|
||||
@@ -517,15 +517,15 @@ public:
|
||||
struct WXDLLIMPEXP_BASE wxIntegerHash
|
||||
{
|
||||
wxIntegerHash() { }
|
||||
unsigned long operator()( long x ) const { return (unsigned long)x; }
|
||||
unsigned long operator()( unsigned long x ) const { return x; }
|
||||
unsigned long operator()( int x ) const { return (unsigned long)x; }
|
||||
unsigned long operator()( unsigned int x ) const { return x; }
|
||||
unsigned long operator()( short x ) const { return (unsigned long)x; }
|
||||
unsigned long operator()( unsigned short x ) const { return x; }
|
||||
unsigned long operator()( long x ) const wxNOEXCEPT { return (unsigned long)x; }
|
||||
unsigned long operator()( unsigned long x ) const wxNOEXCEPT { return x; }
|
||||
unsigned long operator()( int x ) const wxNOEXCEPT { return (unsigned long)x; }
|
||||
unsigned long operator()( unsigned int x ) const wxNOEXCEPT { return x; }
|
||||
unsigned long operator()( short x ) const wxNOEXCEPT { return (unsigned long)x; }
|
||||
unsigned long operator()( unsigned short x ) const wxNOEXCEPT { return x; }
|
||||
#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
||||
wxULongLong_t operator()( wxLongLong_t x ) const { return static_cast<wxULongLong_t>(x); }
|
||||
wxULongLong_t operator()( wxULongLong_t x ) const { return x; }
|
||||
wxULongLong_t operator()( wxLongLong_t x ) const wxNOEXCEPT { return static_cast<wxULongLong_t>(x); }
|
||||
wxULongLong_t operator()( wxULongLong_t x ) const wxNOEXCEPT { return x; }
|
||||
#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
||||
};
|
||||
|
||||
@@ -552,27 +552,27 @@ struct WXDLLIMPEXP_BASE wxPointerHash
|
||||
wxPointerHash() { }
|
||||
|
||||
#ifdef wxNEEDS_WX_HASH_MAP
|
||||
wxUIntPtr operator()( const void* k ) const { return wxPtrToUInt(k); }
|
||||
wxUIntPtr operator()( const void* k ) const wxNOEXCEPT { return wxPtrToUInt(k); }
|
||||
#else
|
||||
size_t operator()( const void* k ) const { return (size_t)k; }
|
||||
size_t operator()( const void* k ) const wxNOEXCEPT { return (size_t)k; }
|
||||
#endif
|
||||
};
|
||||
|
||||
struct WXDLLIMPEXP_BASE wxPointerEqual
|
||||
{
|
||||
wxPointerEqual() { }
|
||||
bool operator()( const void* a, const void* b ) const { return a == b; }
|
||||
bool operator()( const void* a, const void* b ) const wxNOEXCEPT { return a == b; }
|
||||
};
|
||||
|
||||
// wxString, char*, wchar_t*
|
||||
struct WXDLLIMPEXP_BASE wxStringHash
|
||||
{
|
||||
wxStringHash() {}
|
||||
unsigned long operator()( const wxString& x ) const
|
||||
unsigned long operator()( const wxString& x ) const wxNOEXCEPT
|
||||
{ return stringHash( x.wx_str() ); }
|
||||
unsigned long operator()( const wchar_t* x ) const
|
||||
unsigned long operator()( const wchar_t* x ) const wxNOEXCEPT
|
||||
{ return stringHash( x ); }
|
||||
unsigned long operator()( const char* x ) const
|
||||
unsigned long operator()( const char* x ) const wxNOEXCEPT
|
||||
{ return stringHash( x ); }
|
||||
|
||||
#if WXWIN_COMPATIBILITY_2_8
|
||||
@@ -591,12 +591,12 @@ struct WXDLLIMPEXP_BASE wxStringHash
|
||||
struct WXDLLIMPEXP_BASE wxStringEqual
|
||||
{
|
||||
wxStringEqual() {}
|
||||
bool operator()( const wxString& a, const wxString& b ) const
|
||||
bool operator()( const wxString& a, const wxString& b ) const wxNOEXCEPT
|
||||
{ return a == b; }
|
||||
bool operator()( const wxChar* a, const wxChar* b ) const
|
||||
bool operator()( const wxChar* a, const wxChar* b ) const wxNOEXCEPT
|
||||
{ return wxStrcmp( a, b ) == 0; }
|
||||
#if wxUSE_UNICODE
|
||||
bool operator()( const char* a, const char* b ) const
|
||||
bool operator()( const char* a, const char* b ) const wxNOEXCEPT
|
||||
{ return strcmp( a, b ) == 0; }
|
||||
#endif // wxUSE_UNICODE
|
||||
};
|
||||
|
@@ -63,7 +63,5 @@ private:
|
||||
wxDECLARE_DYNAMIC_CLASS(wxCursor);
|
||||
};
|
||||
|
||||
extern WXDLLIMPEXP_CORE void wxSetCursor(const wxCursor& cursor);
|
||||
|
||||
#endif
|
||||
// _WX_CURSOR_H_
|
||||
|
@@ -52,7 +52,7 @@ public:
|
||||
wxIcon GetIcon() const
|
||||
{
|
||||
// don't use wxDynamicCast, icons and bitmaps are really the same thing
|
||||
return *(wxIcon*)&m_messageBitmap;
|
||||
return *(const wxIcon*)&m_messageBitmap;
|
||||
}
|
||||
|
||||
// for compatibility with wxMSW
|
||||
|
@@ -49,21 +49,21 @@ public:
|
||||
m_addrFrame = addrFrame;
|
||||
}
|
||||
|
||||
virtual size_t GetParamCount() const
|
||||
virtual size_t GetParamCount() const wxOVERRIDE
|
||||
{
|
||||
ConstCast()->OnGetParam();
|
||||
return DoGetParamCount();
|
||||
}
|
||||
|
||||
virtual bool
|
||||
GetParam(size_t n, wxString *type, wxString *name, wxString *value) const;
|
||||
GetParam(size_t n, wxString *type, wxString *name, wxString *value) const wxOVERRIDE;
|
||||
|
||||
// callback used by OnGetParam(), don't call directly
|
||||
void OnParam(wxSYMBOL_INFO *pSymInfo);
|
||||
|
||||
protected:
|
||||
virtual void OnGetName();
|
||||
virtual void OnGetLocation();
|
||||
virtual void OnGetName() wxOVERRIDE;
|
||||
virtual void OnGetLocation() wxOVERRIDE;
|
||||
|
||||
void OnGetParam();
|
||||
|
||||
@@ -96,9 +96,9 @@ public:
|
||||
// only
|
||||
wxStackWalker(const char * WXUNUSED(argv0) = NULL) { }
|
||||
|
||||
virtual void Walk(size_t skip = 1, size_t maxDepth = wxSTACKWALKER_MAX_DEPTH);
|
||||
virtual void Walk(size_t skip = 1, size_t maxDepth = wxSTACKWALKER_MAX_DEPTH) wxOVERRIDE;
|
||||
#if wxUSE_ON_FATAL_EXCEPTION
|
||||
virtual void WalkFromException(size_t maxDepth = wxSTACKWALKER_MAX_DEPTH);
|
||||
virtual void WalkFromException(size_t maxDepth = wxSTACKWALKER_MAX_DEPTH) wxOVERRIDE;
|
||||
#endif // wxUSE_ON_FATAL_EXCEPTION
|
||||
|
||||
|
||||
|
@@ -47,6 +47,4 @@ private:
|
||||
wxDECLARE_DYNAMIC_CLASS(wxCursor);
|
||||
};
|
||||
|
||||
extern WXDLLIMPEXP_CORE void wxSetCursor(const wxCursor& cursor);
|
||||
|
||||
#endif // _WX_CURSOR_H_
|
||||
|
@@ -29,7 +29,7 @@ public:
|
||||
|
||||
// implementation only
|
||||
void QtUpdateState();
|
||||
virtual int GetEventType() const = 0;
|
||||
virtual int QtGetEventType() const = 0;
|
||||
|
||||
protected:
|
||||
virtual wxBitmap DoGetBitmap(State state) const wxOVERRIDE;
|
||||
|
@@ -22,7 +22,6 @@ class WXDLLIMPEXP_CORE wxBitmap : public wxBitmapBase
|
||||
public:
|
||||
wxBitmap();
|
||||
wxBitmap(QPixmap pix);
|
||||
wxBitmap(const wxBitmap& bmp);
|
||||
wxBitmap(const char bits[], int width, int height, int depth = 1);
|
||||
wxBitmap(int width, int height, int depth = wxBITMAP_SCREEN_DEPTH);
|
||||
wxBitmap(const wxSize& sz, int depth = wxBITMAP_SCREEN_DEPTH);
|
||||
|
@@ -32,7 +32,7 @@ public:
|
||||
virtual wxWindow *SetDefault() wxOVERRIDE;
|
||||
|
||||
// implementation only
|
||||
virtual int GetEventType() const wxOVERRIDE { return wxEVT_BUTTON; }
|
||||
virtual int QtGetEventType() const wxOVERRIDE { return wxEVT_BUTTON; }
|
||||
|
||||
private:
|
||||
wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxButton);
|
||||
|
@@ -36,7 +36,7 @@ public:
|
||||
virtual bool IsChecked() const wxOVERRIDE;
|
||||
|
||||
virtual void SetBitmap(const wxBitmap& bitmap);
|
||||
virtual const wxBitmap& GetBitmap() const { return m_bitmap; };
|
||||
virtual const wxBitmap& GetBitmap() const { return m_bitmap; }
|
||||
|
||||
virtual QAction *GetHandle() const;
|
||||
|
||||
|
@@ -36,7 +36,7 @@ public:
|
||||
virtual bool GetValue() const wxOVERRIDE;
|
||||
|
||||
// implementation only
|
||||
virtual int GetEventType() const wxOVERRIDE { return wxEVT_TOGGLEBUTTON; }
|
||||
virtual int QtGetEventType() const wxOVERRIDE { return wxEVT_TOGGLEBUTTON; }
|
||||
|
||||
private:
|
||||
wxDECLARE_DYNAMIC_CLASS(wxToggleButton);
|
||||
|
@@ -139,10 +139,10 @@ WXDLLIMPEXP_BASE wxObject *wxCreateDynamicObject(const wxString& name);
|
||||
|
||||
#define wxDECLARE_ABSTRACT_CLASS(name) \
|
||||
public: \
|
||||
static wxClassInfo ms_classInfo; \
|
||||
wxWARNING_SUPPRESS_MISSING_OVERRIDE() \
|
||||
virtual wxClassInfo *GetClassInfo() const; \
|
||||
wxWARNING_RESTORE_MISSING_OVERRIDE()
|
||||
wxWARNING_RESTORE_MISSING_OVERRIDE() \
|
||||
static wxClassInfo ms_classInfo
|
||||
|
||||
#define wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(name) \
|
||||
wxDECLARE_NO_ASSIGN_CLASS(name); \
|
||||
|
@@ -554,6 +554,12 @@ private:
|
||||
if ( cacheBegin == NULL )
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
// gcc 7 warns about not being able to optimize this loop because of
|
||||
// possible loop variable overflow, really not sure what to do about
|
||||
// this, so just disable this warnings for now
|
||||
wxGCC_ONLY_WARNING_SUPPRESS(unsafe-loop-optimizations)
|
||||
|
||||
Cache::Element * const cacheEnd = GetCacheEnd();
|
||||
for ( Cache::Element *c = cacheBegin; c != cacheEnd; c++ )
|
||||
{
|
||||
@@ -561,6 +567,8 @@ private:
|
||||
return c;
|
||||
}
|
||||
|
||||
wxGCC_ONLY_WARNING_RESTORE(unsafe-loop-optimizations)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -569,6 +577,12 @@ private:
|
||||
// its corresponding index in the byte string or not
|
||||
Cache::Element *GetCacheElement() const
|
||||
{
|
||||
// gcc warns about cacheBegin and c inside the loop being possibly null,
|
||||
// but this shouldn't actually be the case
|
||||
#if wxCHECK_GCC_VERSION(6,1)
|
||||
wxGCC_ONLY_WARNING_SUPPRESS(null-dereference)
|
||||
#endif
|
||||
|
||||
Cache::Element * const cacheBegin = GetCacheBegin();
|
||||
Cache::Element * const cacheEnd = GetCacheEnd();
|
||||
Cache::Element * const cacheStart = cacheBegin + LastUsedCacheElement();
|
||||
@@ -598,6 +612,10 @@ private:
|
||||
}
|
||||
|
||||
return c;
|
||||
|
||||
#if wxCHECK_GCC_VERSION(6,1)
|
||||
wxGCC_ONLY_WARNING_RESTORE(null-dereference)
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t DoPosToImpl(size_t pos) const
|
||||
|
@@ -31,6 +31,10 @@
|
||||
class WXDLLIMPEXP_FWD_BASE wxCStrData;
|
||||
class WXDLLIMPEXP_FWD_BASE wxString;
|
||||
|
||||
// There are a lot of structs with intentionally private ctors in this file,
|
||||
// suppress gcc warnings about this.
|
||||
wxGCC_WARNING_SUPPRESS(ctor-dtor-privacy)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// WX_DEFINE_VARARG_FUNC* macros
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -1248,4 +1252,6 @@ private:
|
||||
inline void name(_WX_VARARG_FIXED_UNUSED_EXPAND(numfixed, fixed)) \
|
||||
{}
|
||||
|
||||
wxGCC_WARNING_RESTORE(ctor-dtor-privacy)
|
||||
|
||||
#endif // _WX_STRVARARG_H_
|
||||
|
@@ -79,7 +79,10 @@ public:
|
||||
return m_indexAccel == -1 ? wxT('\0') : (wxChar)m_label[m_indexAccel];
|
||||
}
|
||||
|
||||
virtual wxWindow *GetInputWindow() const wxOVERRIDE { return (wxWindow*)this; }
|
||||
virtual wxWindow *GetInputWindow() const wxOVERRIDE
|
||||
{
|
||||
return const_cast<wxControl*>(this);
|
||||
}
|
||||
|
||||
protected:
|
||||
// common part of all ctors
|
||||
|
@@ -1052,9 +1052,16 @@ inline wchar_t* wxGetenv(const wxScopedWCharBuffer& name) { return wxCRT_GetenvW
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING
|
||||
WX_ATTRIBUTE_FORMAT(__strftime__, 3, 4)
|
||||
inline size_t wxStrftime(char *s, size_t max,
|
||||
const wxString& format, const struct tm *tm)
|
||||
{ return wxCRT_StrftimeA(s, max, format.mb_str(), tm); }
|
||||
{
|
||||
wxGCC_ONLY_WARNING_SUPPRESS(format-nonliteral)
|
||||
|
||||
return wxCRT_StrftimeA(s, max, format.mb_str(), tm);
|
||||
|
||||
wxGCC_ONLY_WARNING_RESTORE(format-nonliteral)
|
||||
}
|
||||
#endif // wxNO_IMPLICIT_WXSTRING_ENCODING
|
||||
|
||||
inline size_t wxStrftime(wchar_t *s, size_t max,
|
||||
|
@@ -276,6 +276,8 @@
|
||||
#endif
|
||||
|
||||
|
||||
wxGCC_ONLY_WARNING_SUPPRESS(format-nonliteral)
|
||||
|
||||
WX_DEFINE_VARARG_FUNC_SANS_N0(int, wxPrintf, 1, (const wxFormatString&),
|
||||
wxCRT_PrintfNative, wxCRT_PrintfA)
|
||||
inline int wxPrintf(const wxFormatString& s)
|
||||
@@ -290,6 +292,8 @@ inline int wxFprintf(FILE *f, const wxFormatString& s)
|
||||
return wxFprintf(f, wxASCII_STR("%s"), s.InputAsString());
|
||||
}
|
||||
|
||||
wxGCC_ONLY_WARNING_RESTORE(format-nonliteral)
|
||||
|
||||
// va_list versions of printf functions simply forward to the respective
|
||||
// CRT function; note that they assume that va_list was created using
|
||||
// wxArgNormalizer<T>!
|
||||
|
Reference in New Issue
Block a user