/* Poison symbols at compile time.

   Copyright (C) 2017-2021 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef COMMON_POISON_H
#define COMMON_POISON_H

#include "traits.h"
#include "obstack.h"

/* Poison memset of non-POD types.  The idea is catching invalid
   initialization of non-POD structs that is easy to be introduced as
   side effect of refactoring.  For example, say this:

 struct S { VEC(foo_s) *m_data; };

is converted to this at some point:

 struct S {
   S() { m_data.reserve (10); }
   std::vector<foo> m_data;
 };

and old code was initializing S objects like this:

 struct S s;
 memset (&s, 0, sizeof (S)); // whoops, now wipes vector.

Declaring memset as deleted for non-POD types makes the memset above
be a compile-time error.  */

/* Helper for SFINAE.  True if "T *" is memsettable.  I.e., if T is
   either void, or POD.  */
template<typename T>
struct IsMemsettable
  : gdb::Or<std::is_void<T>,
	    std::is_pod<T>>
{};

template <typename T,
	  typename = gdb::Requires<gdb::Not<IsMemsettable<T>>>>
void *memset (T *s, int c, size_t n) = delete;

#if HAVE_IS_TRIVIALLY_COPYABLE

/* Similarly, poison memcpy and memmove of non trivially-copyable
   types, which is undefined.  */

/* True if "T *" is relocatable.  I.e., copyable with memcpy/memmove.
   I.e., T is either trivially copyable, or void.  */
template<typename T>
struct IsRelocatable
  : gdb::Or<std::is_void<T>,
	    std::is_trivially_copyable<T>>
{};

/* True if both source and destination are relocatable.  */

template <typename D, typename S>
using BothAreRelocatable
  = gdb::And<IsRelocatable<D>, IsRelocatable<S>>;

template <typename D, typename S,
	  typename = gdb::Requires<gdb::Not<BothAreRelocatable<D, S>>>>
void *memcpy (D *dest, const S *src, size_t n) = delete;

template <typename D, typename S,
	  typename = gdb::Requires<gdb::Not<BothAreRelocatable<D, S>>>>
void *memmove (D *dest, const S *src, size_t n) = delete;

#endif /* HAVE_IS_TRIVIALLY_COPYABLE */

/* Poison XNEW and friends to catch usages of malloc-style allocations on
   objects that require new/delete.  */

template<typename T>
#if HAVE_IS_TRIVIALLY_CONSTRUCTIBLE
using IsMallocable = std::is_trivially_constructible<T>;
#else
using IsMallocable = std::true_type;
#endif

template<typename T>
using IsFreeable = gdb::Or<std::is_trivially_destructible<T>, std::is_void<T>>;

template <typename T, typename = gdb::Requires<gdb::Not<IsFreeable<T>>>>
void free (T *ptr) = delete;

template<typename T>
static T *
xnew ()
{
  static_assert (IsMallocable<T>::value, "Trying to use XNEW with a non-POD \
data type.  Use operator new instead.");
  return XNEW (T);
}

#undef XNEW
#define XNEW(T) xnew<T>()

template<typename T>
static T *
xcnew ()
{
  static_assert (IsMallocable<T>::value, "Trying to use XCNEW with a non-POD \
data type.  Use operator new instead.");
  return XCNEW (T);
}

#undef XCNEW
#define XCNEW(T) xcnew<T>()

template<typename T>
static void
xdelete (T *p)
{
  static_assert (IsFreeable<T>::value, "Trying to use XDELETE with a non-POD \
data type.  Use operator delete instead.");
  XDELETE (p);
}

#undef XDELETE
#define XDELETE(P) xdelete (P)

template<typename T>
static T *
xnewvec (size_t n)
{
  static_assert (IsMallocable<T>::value, "Trying to use XNEWVEC with a \
non-POD data type.  Use operator new[] (or std::vector) instead.");
  return XNEWVEC (T, n);
}

#undef XNEWVEC
#define XNEWVEC(T, N) xnewvec<T> (N)

template<typename T>
static T *
xcnewvec (size_t n)
{
  static_assert (IsMallocable<T>::value, "Trying to use XCNEWVEC with a \
non-POD data type.  Use operator new[] (or std::vector) instead.");
  return XCNEWVEC (T, n);
}

#undef XCNEWVEC
#define XCNEWVEC(T, N) xcnewvec<T> (N)

template<typename T>
static T *
xresizevec (T *p, size_t n)
{
  static_assert (IsMallocable<T>::value, "Trying to use XRESIZEVEC with a \
non-POD data type.");
  return XRESIZEVEC (T, p, n);
}

#undef XRESIZEVEC
#define XRESIZEVEC(T, P, N) xresizevec<T> (P, N)

template<typename T>
static void
xdeletevec (T *p)
{
  static_assert (IsFreeable<T>::value, "Trying to use XDELETEVEC with a \
non-POD data type.  Use operator delete[] (or std::vector) instead.");
  XDELETEVEC (p);
}

#undef XDELETEVEC
#define XDELETEVEC(P) xdeletevec (P)

template<typename T>
static T *
xnewvar (size_t s)
{
  static_assert (IsMallocable<T>::value, "Trying to use XNEWVAR with a \
non-POD data type.");
  return XNEWVAR (T, s);;
}

#undef XNEWVAR
#define XNEWVAR(T, S) xnewvar<T> (S)

template<typename T>
static T *
xcnewvar (size_t s)
{
  static_assert (IsMallocable<T>::value, "Trying to use XCNEWVAR with a \
non-POD data type.");
  return XCNEWVAR (T, s);
}

#undef XCNEWVAR
#define XCNEWVAR(T, S) xcnewvar<T> (S)

template<typename T>
static T *
xresizevar (T *p, size_t s)
{
  static_assert (IsMallocable<T>::value, "Trying to use XRESIZEVAR with a \
non-POD data type.");
  return XRESIZEVAR (T, p, s);
}

#undef XRESIZEVAR
#define XRESIZEVAR(T, P, S) xresizevar<T> (P, S)

template<typename T>
static T *
xobnew (obstack *ob)
{
  static_assert (IsMallocable<T>::value, "Trying to use XOBNEW with a \
non-POD data type.");
  return XOBNEW (ob, T);
}

#undef XOBNEW
#define XOBNEW(O, T) xobnew<T> (O)

template<typename T>
static T *
xobnewvec (obstack *ob, size_t n)
{
  static_assert (IsMallocable<T>::value, "Trying to use XOBNEWVEC with a \
non-POD data type.");
  return XOBNEWVEC (ob, T, n);
}

#undef XOBNEWVEC
#define XOBNEWVEC(O, T, N) xobnewvec<T> (O, N)

#endif /* COMMON_POISON_H */
