Ivan Maidanski [Fri, 21 Oct 2016 18:57:15 +0000 (21:57 +0300)]
Workaround 'tainted int used as loop bound' static analysis tool warning
No need to check upper bound of n here, so a dummy check is added.
* tests/test_cpp.cc (main) [LINT2]: Check upper bound of n local
variable (the check is actually dummy).
* tests/test_cpp.cc (main): Reformat code (which handles n variable).
Ivan Maidanski [Fri, 21 Oct 2016 08:42:26 +0000 (11:42 +0300)]
Fix 'ISO C90 forbids mixed declarations and code' compiler warning
* pthread_support.c [GC_PTHREADS && !GC_WIN32_THREADS]
(GC_thread_exit_proc): Move GC_log_printf() call down to be after local
variables declarations.
* thread_local_alloc.c [THREAD_LOCAL_ALLOC && USE_PTHREAD_SPECIFIC
&& !USE_WIN32_SPECIFIC]: Add {} to have "k" local variable declaration
before any statement in a block.
Ivan Maidanski [Tue, 18 Oct 2016 21:42:29 +0000 (00:42 +0300)]
Workaround 'variable reassigned before old value used' cppcheck warnings
* misc.c (GC_call_with_gc_active): Call GC_noop1 for
GC_traced_stack_sect and GC_blocked_sp (before restoring their original
values) if CPPCHECK.
* win32_threads.c (GC_do_blocking_inner): Call GC_noop1 for
thread_blocked_sp field (before restoring its original value)
if CPPCHECK.
* win32_threads.c (GC_call_with_gc_active): Call GC_noop1 for
traced_stack_sect field (before restoring its original value)
if CPPCHECK.
Ivan Maidanski [Tue, 18 Oct 2016 09:24:34 +0000 (12:24 +0300)]
Workaround 'obsolete function alloca() called' cppcheck warnings
* dyn_load.c [AIX] (GC_register_dynamic_libraries): Code refactoring
to have alloca() call only once (at the beginning of a block); use
variable-length array instead of alloca() if CPPCHECK.
* include/private/gc_priv.h (GC_on_abort): Move definition upper (to be
before ABORT definition); define it to empty if PCR (this is needed for
CPPCHECK).
* include/private/gc_priv.h (ABORT): Specially define to
{GC_on_abort(msg);abort();} block statement if CPPCHECK.
* tests/test.c (chktree): Check for n is zero only once; add comment.
Ivan Maidanski [Tue, 18 Oct 2016 08:14:22 +0000 (11:14 +0300)]
Workaround 'passing untyped NULL to variadic function' cppcheck warning
The portability warning "Passing NULL after the last typed argument to
a variadic function leads to undefined behavior" was reported for
ABORT_ARG2(..., DATASTART, DATAEND) call in GC_register_data_segments.
Ivan Maidanski [Tue, 18 Oct 2016 07:59:20 +0000 (10:59 +0300)]
Workaround 'struct member is never used' cppcheck style warnings
* os_dep.c [OS2] (GC_register_data_segments): Assign 0 to
hdrdos.padding, hdr386.exe_format_level/os/padding1/padding2,
seg.pagemap/mapsize/reserved fields if CPPCHECK; add comment.
* os_dep.c [MPROTECT_VDB && DARWIN] (GC_mprotect_thread): Assign 0 to
the first element of reply.data, msg.data fields if CPPCHECK; add
comment.
* typd_mlc.c (TAG): Define to ad.ad_tag (instead of ld.ld_tag).
Ivan Maidanski [Mon, 17 Oct 2016 22:42:22 +0000 (01:42 +0300)]
Fix 'variable assigned a value that is never used' cppcheck style warnings
* dyn_load.c [USE_PROC_FOR_LIBRARIES] (GC_register_map_entries): Remove
datastart local variable.
* extra/AmigaOS.c [GC_AMIGA_DS] (GC_register_data_segments): Remove
num local variable.
* extra/MacOS.c (firstTime): Remove.
* extra/MacOS.c (GC_MacTemporaryNewPtr): Do not define firstTime if
SHARED_LIBRARY_BUILD.
* extra/MacOS.c (GC_MacFreeTemporaryMemory): Do not define (and update)
totalMemoryUsed if SHARED_LIBRARY_BUILD.
* extra/msvc_dbg.c (GetDescriptionFromAddress): Do not assign size
variable when its value no longer used.
* include/private/gc_locks.h [PCR && THREADS] (DCL_LOCK_STATE): Define
to empty if CPPCHECK.
* mach_dep.c [MACOS && __MWERKS__ && POWERPC] (getRegisters): Declare
as external of CPPCHECK (as cppcheck does not recognize "asm" in
function declaration).
Ivan Maidanski [Wed, 5 Oct 2016 08:32:00 +0000 (11:32 +0300)]
Eliminate 'address of local variable returned' static analyzer warning
* mark_rts.c [__GNUC__ >= 4] (GC_approx_sp): Use
__builtin_frame_address(0) instead of &sp (but still write the value to
the volatile local variable to force stack to grow if necessary).
* tools/setjmp_t.c [__GNUC__ >= 4] (nested_sp): Return
__builtin_frame_address(0) instead of sp.
Ivan Maidanski [Wed, 5 Oct 2016 08:04:25 +0000 (11:04 +0300)]
Fix tools/setjmp_t to prevent nested_sp inlining
Inlined nested_sp might cause incorrect result of nested_sp()<sp.
* tools/setjmp_t.c (nested_sp): Change return from int* to word.
* tools/setjmp_t.c (nested_sp_fn): New global volatile variable
initialized to nested_sp.
* tools/setjmp_t.c (main): Use nested_sp_fn instead of nested_sp;
remove redundant cast.
* os_dep.c [USE_MUNMAP && LINT2] (GC_unmap, GC_remap, GC_unmap_gap):
Call GC_noop1(result) where result is returned by mmap or VirtualAlloc.
* os_dep.c [USE_MUNMAP && NACL] (GC_remap): Rename mmap_result local
variable to result.
* os_dep.c [USE_MUNMAP && !USE_WINALLOC] (GC_unmap_gap): Update
GC_unmapped_bytes (by len) only if len is non-zero.
Ivan Maidanski [Mon, 3 Oct 2016 07:22:59 +0000 (10:22 +0300)]
Workaround 'local variable size too big' static analyzer warning
* mark.c [PARALLEL_MARK] (LOCAL_MARK_STACK_SIZE): Define to smaller
value if LINT2 (to avoid static analysis tool warning that
local_mark_stack local variable size is very big).
Ivan Maidanski [Fri, 30 Sep 2016 14:12:24 +0000 (17:12 +0300)]
Fix potential overflow in decrement when computing GC_markers_m1
Also, call WARN if a non-positive value is specified in GC_MARKERS.
* pthread_support.c [PARALLEL_MARK] (GC_thr_init): Replace markers_m1
local variable with markers one; keep real number of markers in
"markers" variable (not a decremented one); treat invalid (i.e.
non-positive) markers value (obtained from GC_MARKERS environment
variable) the same way as too big ones (i.e. set to maximum number of
markers in this case); adjust WARN message accordingly; report invalid
or too big markers value in WARN.
* win32_threads.c [PARALLEL_MARK] (GC_thr_init): Likewise.
* pthread_support.c [PARALLEL_MARK] (GC_thr_init): Adjust code
indentation.
Ivan Maidanski [Fri, 30 Sep 2016 12:46:42 +0000 (15:46 +0300)]
Fix GC_requested_heapsize increment in GC_init
Also eliminate static analyzer warning about potential overflow in
initial_heap_sz * HBLKSIZE.
* misc.c (GC_init): Change initial_heap_sz to keep size value in bytes
instead of HBLKSIZE units (thus, GC_requested_heapsize is incremented
by a number of bytes not HBLKSIZE units).
Ivan Maidanski [Thu, 29 Sep 2016 21:53:23 +0000 (00:53 +0300)]
Fix printf format specifiers in extra files
(to eliminate cppcheck warnings)
* extra/MacOS.c (GC_MacFreeTemporaryMemory): Cast GC_gc_no to unsigned
long, and adjust fprintf format specifier appropriately.
* extra/msvc_dbg.c (GetDescriptionFromAddress): Cast line_number to
int when passed to wsprintf() to match format specifier.
Ivan Maidanski [Wed, 28 Sep 2016 08:32:55 +0000 (11:32 +0300)]
Eliminate 'write to memory that was const-qualified' code analyzer warning
* cord/cordbscs.c (CORD_from_fn): Rename to CORD_from_fn_inner; make it
static; change return type from CORD to CordRep*; define public
CORD_from_fn which simply calls CORD_from_fn_inner (with the type cast
to CORD).
* cord/cordbscs.c (CORD_substr_closure): Call CORD_from_fn_inner
instead of CORD_from_fn (thus remove the cast from const type to
a non-const one).
Ivan Maidanski [Wed, 28 Sep 2016 07:27:12 +0000 (10:27 +0300)]
Fix CORD_substr_closure for the case when CORD_from_fn returns C string
* cord/cordbscs.c (CORD_substr_closure): Change type of "result" local
variable from CORD to CordRep* (insert necessary type casts); update
function.header only if function.null field is zero (i.e. CORD_from_fn
returned pointer to CordRep, not a pointer to C character string).
Ivan Maidanski [Wed, 28 Sep 2016 07:04:39 +0000 (10:04 +0300)]
Eliminate 'comparison is always false' static analyzer warning in finalize
GC_enqueue_all_finalizers code refactoring is done (removal of the
unreachable statement) to eliminate the warning.
* finalize.c (GC_enqueue_all_finalizers): Remove "prev_fo" local
variable; remove "register" keyword for local variables;
remove the pointer to the chain of hash table entries from the roots
(i.e. setting the roots pointer to null) at the beginning of processing
the chain (instead of updating the roots pointer on deletion of each
entry and finally setting it to null); remove fo_set_next(prev_fo) as
it is never called (because prev_fo was always null); update
GC_fo_entries only when the whole table processed (i.e. all items
removed).
Ivan Maidanski [Tue, 27 Sep 2016 17:39:44 +0000 (20:39 +0300)]
Eliminate 'deref-of-null' static analyzer warning in register_finalizer
* finalize.c (GC_register_finalizer_inner): Add GC_ASSERT that fn and
hhdr are non-NULL (instead of specifying this in a comment) if new_fo
is non-NULL (new_fo is returned by GC_oom_fn).
Ivan Maidanski [Tue, 27 Sep 2016 17:23:19 +0000 (20:23 +0300)]
Fix 'label cannot be reached' static analyzer warning in disclaim_test
* disclaim_test.c (GROW_LIMIT): Define to MUTATE_CNT/10 (instead of 10000000), so that it is always less than MUTATE_CNT (thus
i > GROW_LIMIT is not always false, thus all switch cases are
reachable).
Ivan Maidanski [Tue, 27 Sep 2016 07:47:00 +0000 (10:47 +0300)]
Code refactoring of huge_test
* tests/huge_test.c [!GC_MAXIMUM_HEAP_SIZE] (GC_MAXIMUM_HEAP_SIZE,
GC_INITIAL_HEAP_SIZE): Define (before include gc.h); move the comment
from main().
* tests/huge_test.c (CHECK_ALLOC_FAILED): New macro.
* tests/huge_test.c (main): Remove "r" local variable; do not call
GC_set_max_heap_size and GC_expand_hp explicitly (as it is done
by GC_INIT provided GC_MAXIMUM_HEAP_SIZE and GC_INITIAL_HEAP_SIZE are
defined); use CHECK_ALLOC_FAILED (instead of if/fprintf/exit).
Ivan Maidanski [Mon, 19 Sep 2016 21:07:47 +0000 (00:07 +0300)]
Fix malloc routines to prevent size value wrap-around
See issue #135 on Github.
* allchblk.c (GC_allochblk, GC_allochblk_nth): Use
OBJ_SZ_TO_BLOCKS_CHECKED instead of OBJ_SZ_TO_BLOCKS.
* malloc.c (GC_alloc_large): Likewise.
* alloc.c (GC_expand_hp_inner): Type of "bytes" local variable changed
from word to size_t; cast ROUNDUP_PAGESIZE argument to size_t; prevent
overflow when computing GC_heapsize+bytes > GC_max_heapsize.
* dbg_mlc.c (GC_debug_malloc, GC_debug_malloc_ignore_off_page,
GC_debug_malloc_atomic_ignore_off_page, GC_debug_generic_malloc,
GC_debug_generic_malloc_inner,
GC_debug_generic_malloc_inner_ignore_off_page,
GC_debug_malloc_stubborn, GC_debug_malloc_atomic,
GC_debug_malloc_uncollectable, GC_debug_malloc_atomic_uncollectable):
Use SIZET_SAT_ADD (instead of "+" operator) to add extra bytes to lb
value.
* fnlz_mlc.c (GC_finalized_malloc): Likewise.
* gcj_mlc.c (GC_debug_gcj_malloc): Likewise.
* include/private/gc_priv.h (ROUNDUP_GRANULE_SIZE, ROUNDED_UP_GRANULES,
ADD_SLOP, ROUNDUP_PAGESIZE): Likewise.
* include/private/gcconfig.h (GET_MEM): Likewise.
* mallocx.c (GC_malloc_many, GC_memalign): Likewise.
* os_dep.c (GC_wince_get_mem, GC_win32_get_mem): Likewise.
* typd_mlc.c (GC_malloc_explicitly_typed,
GC_malloc_explicitly_typed_ignore_off_page,
GC_calloc_explicitly_typed): Likewise.
* headers.c (GC_scratch_alloc): Change type of bytes_to_get from word
to size_t (because ROUNDUP_PAGESIZE_IF_MMAP result type changed).
* include/private/gc_priv.h: Include limits.h (unless SIZE_MAX already
defined).
* include/private/gc_priv.h (GC_SIZE_MAX, GC_SQRT_SIZE_MAX): Move from
malloc.c file.
* include/private/gc_priv.h (SIZET_SAT_ADD): New macro (defined before
include gcconfig.h).
* include/private/gc_priv.h (EXTRA_BYTES, GC_page_size): Change type
to size_t.
* os_dep.c (GC_page_size): Likewise.
* include/private/gc_priv.h (ROUNDUP_GRANULE_SIZE, ROUNDED_UP_GRANULES,
ADD_SLOP, ROUNDUP_PAGESIZE): Add comment about the argument.
* include/private/gcconfig.h (GET_MEM): Likewise.
* include/private/gc_priv.h (ROUNDUP_GRANULE_SIZE, ROUNDED_UP_GRANULES,
ADD_SLOP, OBJ_SZ_TO_BLOCKS, ROUNDUP_PAGESIZE,
ROUNDUP_PAGESIZE_IF_MMAP): Rename argument to "lb".
* include/private/gc_priv.h (OBJ_SZ_TO_BLOCKS_CHECKED): New macro.
* include/private/gcconfig.h (GC_win32_get_mem, GC_wince_get_mem,
GC_unix_get_mem): Change argument type from word to int.
* os_dep.c (GC_unix_mmap_get_mem, GC_unix_get_mem,
GC_unix_sbrk_get_mem, GC_wince_get_mem, GC_win32_get_mem): Likewise.
* malloc.c (GC_alloc_large_and_clear): Call OBJ_SZ_TO_BLOCKS only
if no value wrap around is guaranteed.
* malloc.c (GC_generic_malloc): Do not check for lb_rounded < lb case
(because ROUNDED_UP_GRANULES and GRANULES_TO_BYTES guarantees no value
wrap around).
* mallocx.c (GC_generic_malloc_ignore_off_page): Likewise.
* misc.c (GC_init_size_map): Change "i" local variable type from int
to size_t.
* os_dep.c (GC_write_fault_handler, catch_exception_raise): Likewise.
* misc.c (GC_envfile_init): Cast len to size_t when passed to
ROUNDUP_PAGESIZE_IF_MMAP.
* os_dep.c (GC_setpagesize): Cast GC_sysinfo.dwPageSize and
GETPAGESIZE() to size_t (when setting GC_page_size).
* os_dep.c (GC_unix_mmap_get_mem, GC_unmap_start, GC_remove_protection):
Expand ROUNDUP_PAGESIZE macro but without value wrap-around checking
(the argument is of word type).
* os_dep.c (GC_unix_mmap_get_mem): Replace -GC_page_size with
~GC_page_size+1 (because GC_page_size is unsigned); remove redundant
cast to size_t.
* os_dep.c (GC_unix_sbrk_get_mem): Add explicit cast of GC_page_size
to SBRK_ARG_T.
* os_dep.c (GC_wince_get_mem): Change type of res_bytes local variable
to size_t.
* typd_mlc.c: Do not include limits.h.
* typd_mlc.c (GC_SIZE_MAX, GC_SQRT_SIZE_MAX): Remove (as defined in
gc_priv.h now).
Ivan Maidanski [Fri, 23 Sep 2016 06:39:18 +0000 (09:39 +0300)]
Fix page calculation in checksums
While consistent use of rounding mode for computing GC_faulted entries
is ok, the proper way of getting page number of an address is just to
clear the lowest bits of the latter.
* checksums.c (GC_record_fault, GC_was_faulted): Do not round-up when
computing page.
* checksums.c (GC_record_fault): Add assertion that GC_page_size is
initialized.
Ivan Maidanski [Thu, 15 Sep 2016 15:40:21 +0000 (18:40 +0300)]
Fix calloc_explicitly_typed in case of lb*n overflow
* typd_mlc.c: Include limits.h (for SIZE_MAX).
* typd_mlc.c (GC_SIZE_MAX, GC_SQRT_SIZE_MAX): New macro (same as in
malloc.c).
* typd_mlc.c (GC_calloc_explicitly_typed): Return NULL if lb * n
overflows (same algorithm as in calloc defined in malloc.c); eliminate
lb *= n code duplication.
Ivan Maidanski [Thu, 15 Sep 2016 06:47:23 +0000 (09:47 +0300)]
Fix double multiplication of lb by n in calloc_explicitly_typed
* typd_mlc.c (GC_calloc_explicitly_typed): Do not multiply lb by n
twice (when passed to GC_malloc in case of
GC_general_register_disappearing_link fails).
Ivan Maidanski [Wed, 14 Sep 2016 22:03:15 +0000 (01:03 +0300)]
Eliminate 'constructor with 1 argument is not explicit' cppcheck warning
Note that -D CPPCHECK should be passed to cppcheck to activate
this workaround.
* include/gc_allocator.h (GC_ATTR_EXPLICIT): New macro (defined to
"explicit" keyword if at least C++11 or CPPCHECK, otherwise to empty).
* include/gc_allocator.h (gc_allocator::gc_allocator,
gc_allocator_ignore_off_page::gc_allocator_ignore_off_page,
traceable_allocator::traceable_allocator): Use GC_ATTR_EXPLICIT.
* tests/test_cpp.cc (A::A, B::B, C::C, D::D): Likewise.
* tests/test_cpp.cc (GC_ATTR_EXPLICIT): Define macro (as empty) unless
already defined in included gc_allocator.h.
Ivan Maidanski [Wed, 14 Sep 2016 06:21:02 +0000 (09:21 +0300)]
Workaround 'suspicious pointer subtraction' cppcheck warning in gc_cpp
* include/gc_cpp.h (gc_cleanup::gc_cleanup): Add extra parentheses
around (char*)this to outline that "this" pointer subtraction is
intentional (i.e., "this->" was not intended).
Ivan Maidanski [Mon, 12 Sep 2016 18:55:25 +0000 (21:55 +0300)]
Workaround 'va_list used before va_start' cppcheck error in cord
Note that -D CPPCHECK should be passed to cppcheck to activate
this workaround.
* cord/cordprnt.c (CORD_vsprintf) [CPPCHECK]: Force to use va_copy
and va_end.
* cord/cordprnt.c (CORD_vsprintf): Set res to -1 if invalid format
specifier (instead of immediate return -1); call va_end at a single
place.
Ivan Maidanski [Mon, 29 Aug 2016 12:58:00 +0000 (15:58 +0300)]
Eliminate 'checking if unsigned variable is <0' cppcheck style warning
* cord/cordbscs.c (CORD_from_fn, CORD_substr): Do not expect size_t
value to be negative (replace <=0 comparison with ==0 one).
* cord/cordxtra.c (CORD_cmp): Likewise.
* cord/cordbscs.c (CORD_substr): Remove obsolete comment (about SunOS 4
which had signed size_t type).
Ivan Maidanski [Thu, 18 Aug 2016 22:43:25 +0000 (01:43 +0300)]
Eliminate 'cast to void* from int' compiler warnings (Darwin/x64)
* darwin_stop_world.c (GC_stack_range_for, GC_suspend_thread_list,
GC_stop_world, GC_thread_resume, GC_start_world): Cast thread variable
to pointer via word type.
* darwin_stop_world.c (GC_stop_world): Cast stop_info.mach_thread to
pointer via word type.
Ivan Maidanski [Thu, 11 Aug 2016 19:55:21 +0000 (22:55 +0300)]
Improve Travis CI configuration (use both compilers, enable more features)
* .travis.yml (compiler): Add (use both gcc and clang)
* .travis.yml (install): Use autogen.sh instead of autoreconf and
automake; add options to configure (to cover more code during testing);
do not invoke make.
* .travis.yml (script): Pass -j to make.
Ivan Maidanski [Thu, 11 Aug 2016 08:56:44 +0000 (11:56 +0300)]
Workaround missing getcontext() in Docker osrf/ubuntu_32bit
* mach_dep.c [NO_GETCONTEXT] (GC_with_callee_saves_pushed): Call WARN
instead of ABORT if getcontext() failed; do not set context variable
if getcontext() failed; fallback to other register retrieval methods
(__builtin_unwind_init or setjmp) if context variable is NULL.
* mach_dep.c (GC_with_callee_saves_pushed): Reformat code.
Ivan Maidanski [Mon, 8 Aug 2016 18:49:20 +0000 (21:49 +0300)]
Fix 'unknown type name GC_INNER' compilation error (FreeBSD)
(fix commit f13a9559)
See issue #132. The reason of compilation failure is GC_INNER macro
used before its definition. The solution is to move
GC_FreeBSDGetDataStart prototype from gcconfig.h to gc_priv.h.