diff --git a/uppsrc/Core/BlockStream.cpp b/uppsrc/Core/BlockStream.cpp index dc2ceb8df..2cbd28510 100644 --- a/uppsrc/Core/BlockStream.cpp +++ b/uppsrc/Core/BlockStream.cpp @@ -17,7 +17,7 @@ void BlockStream::SetBufferSize(dword size) while(size >> (n + 1)) n++; pagesize = 1 << n; - pagemask = (int64)-1 << n; + pagemask = (uint64)-1 << n; if(buffer) delete[] buffer; buffer = new byte[pagesize]; diff --git a/uppsrc/Core/Defs.h b/uppsrc/Core/Defs.h index 4ca3cfedb..73e0f361f 100644 --- a/uppsrc/Core/Defs.h +++ b/uppsrc/Core/Defs.h @@ -540,3 +540,11 @@ type& GLOBAL_VP_INIT(type, name, param) #define GLOBAL_V_INIT(type, name) GLOBAL_VP_INIT(type, name, init_) #define GLOBAL_VAR_INIT(type, name) type& GLOBAL_V_INIT(type, name) + +#if __GNUC__ > 6 + #define NOUBSAN __attribute__((no_sanitize_undefined)) +#elif __clang__ > 6 + #define NOUBSAN __attribute__((no_sanitize("undefined"))) +#else + #define NOUBSAN +#endif diff --git a/uppsrc/Core/Hash.cpp b/uppsrc/Core/Hash.cpp index 61bddfbab..a961f6bfb 100644 --- a/uppsrc/Core/Hash.cpp +++ b/uppsrc/Core/Hash.cpp @@ -295,8 +295,9 @@ void HashBase::Swap(HashBase& b) { } -#ifdef CPU_X86 +#ifdef CPU_UNALIGNED +NOUBSAN // CPU supports unaligned memory access unsigned memhash(const void *ptr, size_t count) { unsigned hash = 1234567890U; diff --git a/uppsrc/Core/InetUtil.cpp b/uppsrc/Core/InetUtil.cpp index df9ab1c10..ab0b947fb 100644 --- a/uppsrc/Core/InetUtil.cpp +++ b/uppsrc/Core/InetUtil.cpp @@ -235,12 +235,14 @@ String QPDecode(const char *s, bool underscore_to_space) return r; } -String Base64Encode(const char *b, const char *e) +String Base64Encode(const char *_b, const char *_e) { static const char encoder[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; + const byte *b = (byte *)_b; // avoid left shift of negative value sanitizer issue + const byte *e = (byte *)_e; if(b == e) return Null; int out = (int(e - b) + 2) / 3 * 4; diff --git a/uppsrc/Core/Ops.h b/uppsrc/Core/Ops.h index c955095c8..d56453c7b 100644 --- a/uppsrc/Core/Ops.h +++ b/uppsrc/Core/Ops.h @@ -1,11 +1,11 @@ #if defined(CPU_UNALIGNED) && defined(CPU_LE) || __ARM_ARCH_7A__ -inline int Peek16le(const void *ptr) { return *(const word *)ptr; } -inline int Peek32le(const void *ptr) { return *(const dword *)ptr; } -inline int64 Peek64le(const void *ptr) { return *(const int64 *)ptr; } +NOUBSAN inline int Peek16le(const void *ptr) { return *(const word *)ptr; } +NOUBSAN inline int Peek32le(const void *ptr) { return *(const dword *)ptr; } +NOUBSAN inline int64 Peek64le(const void *ptr) { return *(const int64 *)ptr; } -inline void Poke16le(const void *ptr, int val) { *(word *)ptr = val; } -inline void Poke32le(const void *ptr, int val) { *(dword *)ptr = val; } -inline void Poke64le(const void *ptr, int64 val) { *(int64 *)ptr = val; } +NOUBSAN inline void Poke16le(const void *ptr, int val) { *(word *)ptr = val; } +NOUBSAN inline void Poke32le(const void *ptr, int val) { *(dword *)ptr = val; } +NOUBSAN inline void Poke64le(const void *ptr, int64 val) { *(int64 *)ptr = val; } #else inline int Peek16le(const void *ptr) { return MAKEWORD(((byte *)ptr)[0], ((byte *)ptr)[1]); } inline int Peek32le(const void *ptr) { return MAKELONG(Peek16le(ptr), Peek16le((byte *)ptr + 2)); } diff --git a/uppsrc/Core/Other.h b/uppsrc/Core/Other.h index fd60b1c38..a966f2294 100644 --- a/uppsrc/Core/Other.h +++ b/uppsrc/Core/Other.h @@ -284,20 +284,20 @@ protected: void LPN(int i) { link_prev[i]->link_next[i] = link_next[i]->link_prev[i] = (T *)this; } public: - T *GetPtr() { return (T *) this; } + NOUBSAN T *GetPtr() { return (T *) this; } const T *GetPtr() const { return (const T *) this; } T *GetNext(int i = 0) { return link_next[i]; } T *GetPrev(int i = 0) { return link_prev[i]; } const T *GetNext(int i = 0) const { return link_next[i]; } const T *GetPrev(int i = 0) const { return link_prev[i]; } - void LinkSelf(int i = 0) { link_next[i] = link_prev[i] = (T *)this; } + NOUBSAN void LinkSelf(int i = 0) { link_next[i] = link_prev[i] = (T *)this; } void LinkSelfAll() { for(int i = 0; i < N; i++) LinkSelf(i); } void Unlink(int i = 0) { link_next[i]->link_prev[i] = link_prev[i]; link_prev[i]->link_next[i] = link_next[i]; LinkSelf(i); } void UnlinkAll() { for(int i = 0; i < N; i++) Unlink(i); } - void LinkBefore(Link *n, int i = 0) { link_next[i] = (T *)n; link_prev[i] = link_next[i]->link_prev[i]; LPN(i); } - void LinkAfter(Link *p, int i = 0) { link_prev[i] = (T *)p; link_next[i] = link_prev[i]->link_next[i]; LPN(i); } + NOUBSAN void LinkBefore(Link *n, int i = 0) { link_next[i] = (T *)n; link_prev[i] = link_next[i]->link_prev[i]; LPN(i); } + NOUBSAN void LinkAfter(Link *p, int i = 0) { link_prev[i] = (T *)p; link_next[i] = link_prev[i]->link_next[i]; LPN(i); } T *InsertNext(int i = 0) { T *x = new T; x->LinkAfter(this, i); return x; } T *InsertPrev(int i = 0) { T *x = new T; x->LinkBefore(this, i); return x; } diff --git a/uppsrc/Core/Stream.h b/uppsrc/Core/Stream.h index 81c706829..4ba821ba3 100644 --- a/uppsrc/Core/Stream.h +++ b/uppsrc/Core/Stream.h @@ -91,7 +91,7 @@ public: byte *PutPtr(int size = 1) { ASSERT(size > 0); if(ptr + size <= wrlim) { byte *p = ptr; ptr += size; return p; }; return NULL; } const byte *GetSzPtr(int& size) { Term(); size = int(rdlim - ptr); byte *p = ptr; ptr += size; return p; } - void Put(const void *data, int size) { ASSERT(size >= 0); if(ptr + size <= wrlim) { memcpy(ptr, data, size); ptr += size; } else _Put(data, size); } + void Put(const void *data, int size) { ASSERT(size >= 0); if(size) if(ptr + size <= wrlim) { memcpy(ptr, data, size); ptr += size; } else _Put(data, size); } int Get(void *data, int size) { ASSERT(size >= 0); if(ptr + size <= rdlim) { memcpy(data, ptr, size); ptr += size; return size; } return _Get(data, size); } void Put(const String& s) { Put((const char *) s, s.GetLength()); } @@ -113,10 +113,10 @@ public: bool GetAll(Huge& h, size_t size); int Get8() { return ptr < rdlim ? *ptr++ : _Get8(); } -#ifdef CPU_X86 - int Get16() { if(ptr + 1 >= rdlim) return _Get16(); int q = *(word *)ptr; ptr += 2; return q; } - int Get32() { if(ptr + 3 >= rdlim) return _Get32(); int q = *(dword *)ptr; ptr += 4; return q; } - int64 Get64() { if(ptr + 7 >= rdlim) return _Get64(); int64 q = *(int64 *)ptr; ptr += 8; return q; } +#if defined(CPU_UNALIGNED) && defined(CPU_LE) + NOUBSAN int Get16() { if(ptr + 1 >= rdlim) return _Get16(); int q = *(word *)ptr; ptr += 2; return q; } + NOUBSAN int Get32() { if(ptr + 3 >= rdlim) return _Get32(); int q = *(dword *)ptr; ptr += 4; return q; } + NOUBSAN int64 Get64() { if(ptr + 7 >= rdlim) return _Get64(); int64 q = *(int64 *)ptr; ptr += 8; return q; } #else int Get16() { return _Get16(); } int Get32() { return _Get32(); } @@ -143,10 +143,10 @@ public: String GetLine(); -#ifdef CPU_X86 - void Put16(word q) { if(ptr + 1 < wrlim) { *(word *)ptr = q; ptr += 2; } else Put(&q, 2); } - void Put32(dword q) { if(ptr + 3 < wrlim) { *(dword *)ptr = q; ptr += 4; } else Put(&q, 4); } - void Put64(int64 q) { if(ptr + 7 < wrlim) { *(int64 *)ptr = q; ptr += 8; } else Put(&q, 8); } +#if defined(CPU_UNALIGNED) && defined(CPU_LE) + NOUBSAN void Put16(word q) { if(ptr + 1 < wrlim) { *(word *)ptr = q; ptr += 2; } else Put(&q, 2); } + NOUBSAN void Put32(dword q) { if(ptr + 3 < wrlim) { *(dword *)ptr = q; ptr += 4; } else Put(&q, 4); } + NOUBSAN void Put64(int64 q) { if(ptr + 7 < wrlim) { *(int64 *)ptr = q; ptr += 8; } else Put(&q, 8); } #else void Put16(word q) { Put(&q, 2); } void Put32(dword q) { Put(&q, 4); } diff --git a/uppsrc/Core/lheap.cpp b/uppsrc/Core/lheap.cpp index 1cbb2a526..0f431536a 100644 --- a/uppsrc/Core/lheap.cpp +++ b/uppsrc/Core/lheap.cpp @@ -43,7 +43,7 @@ void Heap::GlobalLInit() } k = LBINS - 1; for(int i = MAXBLOCK / 8; i >= 0; i--) { - while(i * 8 < BinSz[k] && k >= 0) k--; + while(k >= 0 && i * 8 < BinSz[k]) k--; BlBin[i] = k; } BlBin[0] = 0; diff --git a/uppsrc/CppBase/CppBase.h b/uppsrc/CppBase/CppBase.h index 461664ec6..ffc6f312b 100644 --- a/uppsrc/CppBase/CppBase.h +++ b/uppsrc/CppBase/CppBase.h @@ -448,29 +448,27 @@ struct Parser { }; struct Decla { - bool s_static; - bool s_extern; - bool s_register; - bool s_mutable; - bool s_explicit; - bool s_virtual; + bool s_static = false; + bool s_extern = false; + bool s_register = false; + bool s_mutable = false; + bool s_explicit = false; + bool s_virtual = false; String name; - bool function; - bool type_def; - bool isfriend; - bool istemplate; - bool istructor; - bool isdestructor; - bool isptr; - bool nofn; - bool oper; - bool castoper; + bool function = false; + bool type_def = false; + bool isfriend = false; + bool istemplate = false; + bool istructor = false; + bool isdestructor = false; + bool isptr = false; + bool nofn = false; + bool oper = false; + bool castoper = false; String tnames; String type; String natural; - - Decla(); }; struct Decl : Decla { diff --git a/uppsrc/CppBase/Parser.cpp b/uppsrc/CppBase/Parser.cpp index f2fee3c0b..b7e5666a2 100644 --- a/uppsrc/CppBase/Parser.cpp +++ b/uppsrc/CppBase/Parser.cpp @@ -352,15 +352,6 @@ bool Parser::IsNamespace(const String& scope) return memcmp(~context.ns, ~scope, l) == 0 && findarg(context.ns[l], '\0', ':') >= 0; } -Parser::Decla::Decla() -{ - function = type_def = false; - s_static = s_register = s_extern = s_mutable = s_explicit = s_virtual = false; - isfriend = istemplate = istructor = isptr = nofn = false; - castoper = oper = false; -} - - bool Parser::Key(int code) { if(lex == code) { diff --git a/uppsrc/CtrlLib/ChGtk0.cpp b/uppsrc/CtrlLib/ChGtk0.cpp index 0e2d9cf58..01ccaf625 100644 --- a/uppsrc/CtrlLib/ChGtk0.cpp +++ b/uppsrc/CtrlLib/ChGtk0.cpp @@ -473,6 +473,7 @@ void GtkIml(int uii, GtkWidget *w, int shadow, const char *detail, int type, int GtkIml(uii + 3, w, shadow, 4, detail, type, cx, cy, rect, maxcx, maxcy); } +NOUBSAN // we are treating fg and following GdkColor arrays as single array Color ChGtkColor(int ii, GtkWidget *widget) { GdkColor cc = ((GtkStyle *)gtk_widget_get_style(widget))->fg[ii]; diff --git a/uppsrc/Draw/Uhd.cpp b/uppsrc/Draw/Uhd.cpp index 665f934ce..73d503062 100644 --- a/uppsrc/Draw/Uhd.cpp +++ b/uppsrc/Draw/Uhd.cpp @@ -85,10 +85,10 @@ Image Upscale2x(const Image& src) struct SFilter : ImageFilter9 { // Improve contours virtual RGBA operator()(const RGBA **mx) { RGBA s = mx[1][1]; - int l = mx[0][1].a; - int r = mx[2][1].a; - int t = mx[1][0].a; - int b = mx[1][2].a; + dword l = mx[0][1].a; + dword r = mx[2][1].a; + dword t = mx[1][0].a; + dword b = mx[1][2].a; int l1 = 110; int l2 = 230; return l * r * t * b != 0 || s.a > l1 || mx[0][1].a > l2 || mx[2][1].a > l2 || mx[1][0].a > l2 || mx[1][2].a > l2 ? s diff --git a/uppsrc/IconDes/IconDes.h b/uppsrc/IconDes/IconDes.h index ae68348a4..010abb23f 100644 --- a/uppsrc/IconDes/IconDes.h +++ b/uppsrc/IconDes/IconDes.h @@ -168,10 +168,10 @@ private: Point startpoint; Rect m1refresh; void (IconDes::*tool)(Point p, dword flags); - bool doselection; - bool selectrect; + bool doselection = false; + bool selectrect = false; int paste_mode; - bool show_small; + bool show_small = false; ScrollBars sb; Scroller scroller; diff --git a/uppsrc/IconDes/ImageOp.cpp b/uppsrc/IconDes/ImageOp.cpp index d29a6b59c..93380f2bf 100644 --- a/uppsrc/IconDes/ImageOp.cpp +++ b/uppsrc/IconDes/ImageOp.cpp @@ -160,7 +160,7 @@ String PackImlData(const Vector& image) for(const ImageIml& m : image) { const Image& img = m.image; StringStream ss; - ss.Put((img.GetResolution() << 6) | m.flags); + ss.Put(((dword)img.GetResolution() << 6) | m.flags); Size sz = img.GetSize(); ss.Put16le(sz.cx); ss.Put16le(sz.cy); diff --git a/uppsrc/RichEdit/Editor.cpp b/uppsrc/RichEdit/Editor.cpp index f6aaad8c0..e226c9170 100644 --- a/uppsrc/RichEdit/Editor.cpp +++ b/uppsrc/RichEdit/Editor.cpp @@ -69,7 +69,7 @@ Zoom RichEdit::GetZoom() const Size RichEdit::GetZoomedPage() const { - return Size(GetTextRect().Width(), pagesz.cy == INT_MAX ? INT_MAX : GetZoom() * pagesz.cy); + return Size(GetTextRect().Width(), pagesz.cy == INT_MAX ? INT_MAX / 2 : GetZoom() * pagesz.cy); } int RichEdit::GetPosY(PageY py) const diff --git a/uppsrc/RichText/Table.h b/uppsrc/RichText/Table.h index 3a87f0a78..2b22352ec 100644 --- a/uppsrc/RichText/Table.h +++ b/uppsrc/RichText/Table.h @@ -117,7 +117,7 @@ private: }; struct TabLayout : Layout { - bool hasheader; + bool hasheader = false; Layout header; Size sz; PageY py; diff --git a/uppsrc/RichText/Text.h b/uppsrc/RichText/Text.h index 2f54e18de..27d00bb0d 100644 --- a/uppsrc/RichText/Text.h +++ b/uppsrc/RichText/Text.h @@ -2,7 +2,7 @@ class RichText : public RichTxt, public DeepCopyOption { mutable Mutex mutex; // To cover all those laze evaluation scenarios RichStyles style; String footer_hack; // ugly hack - bool nolinks; // another ugly hack + bool nolinks = false; // another ugly hack void Init(); diff --git a/uppsrc/RichText/Txt.h b/uppsrc/RichText/Txt.h index 2daa348c6..190268e91 100644 --- a/uppsrc/RichText/Txt.h +++ b/uppsrc/RichText/Txt.h @@ -114,9 +114,9 @@ protected: int r_parti; int r_paraocx; int r_paraocy; - bool r_keep; - bool r_keepnext; - bool r_newpage; + bool r_keep = false; + bool r_keepnext = false; + bool r_newpage = false; void Init();