diff options
author | Martin Sebor <msebor@redhat.com> | 2017-06-16 03:48:59 +0000 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2017-06-15 21:48:59 -0600 |
commit | c3684b7b86da9b6b01f6fb274227fc6401df053e (patch) | |
tree | 921877ef9f69c6bac6285495a3eec052a4fad2a3 /gcc/vec.h | |
parent | 6a382041ddccd829db190f7c112ecfff2e7d369a (diff) | |
download | gcc-c3684b7b86da9b6b01f6fb274227fc6401df053e.zip gcc-c3684b7b86da9b6b01f6fb274227fc6401df053e.tar.gz gcc-c3684b7b86da9b6b01f6fb274227fc6401df053e.tar.bz2 |
PR c++/80560 - warn on undefined memory operations involving non-trivial types
gcc/c-family/ChangeLog:
PR c++/80560
* c.opt (-Wclass-memaccess): New option.
gcc/cp/ChangeLog:
PR c++/80560
* call.c (first_non_public_field, maybe_warn_class_memaccess): New
functions.
(has_trivial_copy_assign_p, has_trivial_copy_p): Ditto.
(build_cxx_call): Call maybe_warn_class_memaccess.
gcc/ChangeLog:
PR c++/80560
* dumpfile.c (dump_register): Avoid calling memset to initialize
a class with a default ctor.
* gcc.c (struct compiler): Remove const qualification.
* genattrtab.c (gen_insn_reserv): Replace memset with initialization.
* hash-table.h: Ditto.
* ipa-cp.c (allocate_and_init_ipcp_value): Replace memset with
assignment.
* ipa-prop.c (ipa_free_edge_args_substructures): Ditto.
* omp-low.c (lower_omp_ordered_clauses): Replace memset with
default ctor.
* params.h (struct param_info): Make struct members non-const.
* tree-switch-conversion.c (emit_case_bit_tests): Replace memset
with default initialization.
* vec.h (vec_copy_construct, vec_default_construct): New helper
functions.
(vec<T>::copy, vec<T>::splice, vec<T>::reserve): Replace memcpy
with vec_copy_construct.
(vect<T>::quick_grow_cleared): Replace memset with default ctor.
(vect<T>::vec_safe_grow_cleared, vec_safe_grow_cleared): Same.
* doc/invoke.texi (-Wclass-memaccess): Document.
libcpp/ChangeLog:
PR c++/80560
* line-map.c (line_maps::~line_maps): Avoid calling htab_delete
with a null pointer.
(linemap_init): Avoid calling memset on an object of a non-trivial
type.
libitm/ChangeLog:
PR c++/80560
* beginend.cc (GTM::gtm_thread::rollback): Avoid calling memset
on an object of a non-trivial type.
(GTM::gtm_transaction_cp::commit): Use assignment instead of memcpy
to copy an object.
* method-ml.cc (orec_iterator::reinit): Avoid -Wclass-memaccess.
gcc/testsuite/ChangeLog:
PR c++/80560
* g++.dg/Wclass-memaccess.C: New test.
From-SVN: r249234
Diffstat (limited to 'gcc/vec.h')
-rw-r--r-- | gcc/vec.h | 41 |
1 files changed, 30 insertions, 11 deletions
@@ -407,6 +407,26 @@ struct GTY((user)) vec { }; +/* Default-construct N elements in DST. */ + +template <typename T> +inline void +vec_default_construct (T *dst, unsigned n) +{ + for ( ; n; ++dst, --n) + ::new (static_cast<void*>(dst)) T (); +} + +/* Copy-construct N elements in DST from *SRC. */ + +template <typename T> +inline void +vec_copy_construct (T *dst, const T *src, unsigned n) +{ + for ( ; n; ++dst, ++src, --n) + ::new (static_cast<void*>(dst)) T (*src); +} + /* Type to provide NULL values for vec<T, A, L>. This is used to provide nil initializers for vec instances. Since vec must be a POD, we cannot have proper ctor/dtor for it. To initialize @@ -612,7 +632,7 @@ vec_safe_grow_cleared (vec<T, A, vl_embed> *&v, unsigned len CXX_MEM_STAT_INFO) { unsigned oldlen = vec_safe_length (v); vec_safe_grow (v, len PASS_MEM_STAT); - memset (&(v->address ()[oldlen]), 0, sizeof (T) * (len - oldlen)); + vec_default_construct (v->address () + oldlen, len - oldlen); } @@ -818,7 +838,7 @@ vec<T, A, vl_embed>::copy (ALONE_MEM_STAT_DECL) const { vec_alloc (new_vec, len PASS_MEM_STAT); new_vec->embedded_init (len, len); - memcpy (new_vec->address (), m_vecdata, sizeof (T) * len); + vec_copy_construct (new_vec->address (), m_vecdata, len); } return new_vec; } @@ -835,7 +855,7 @@ vec<T, A, vl_embed>::splice (const vec<T, A, vl_embed> &src) if (len) { gcc_checking_assert (space (len)); - memcpy (address () + length (), src.address (), len * sizeof (T)); + vec_copy_construct (end (), src.address (), len); m_vecpfx.m_num += len; } } @@ -1089,13 +1109,12 @@ inline void vec<T, A, vl_embed>::quick_grow_cleared (unsigned len) { unsigned oldlen = length (); - size_t sz = sizeof (T) * (len - oldlen); + size_t growby = len - oldlen; quick_grow (len); - if (sz != 0) - memset (&(address ()[oldlen]), 0, sz); + if (growby != 0) + vec_default_construct (address () + oldlen, growby); } - /* Garbage collection support for vec<T, A, vl_embed>. */ template<typename T> @@ -1454,7 +1473,7 @@ vec<T, va_heap, vl_ptr>::reserve (unsigned nelems, bool exact MEM_STAT_DECL) va_heap::reserve (m_vec, nelems, exact PASS_MEM_STAT); if (handle_auto_vec) { - memcpy (m_vec->address (), oldvec->address (), sizeof (T) * oldsize); + vec_copy_construct (m_vec->address (), oldvec->address (), oldsize); m_vec->m_vecpfx.m_num = oldsize; } @@ -1616,10 +1635,10 @@ inline void vec<T, va_heap, vl_ptr>::safe_grow_cleared (unsigned len MEM_STAT_DECL) { unsigned oldlen = length (); - size_t sz = sizeof (T) * (len - oldlen); + size_t growby = len - oldlen; safe_grow (len PASS_MEM_STAT); - if (sz != 0) - memset (&(address ()[oldlen]), 0, sz); + if (growby != 0) + vec_default_construct (address () + oldlen, growby); } |