view gcc/testsuite/g++.dg/Wclass-memaccess-3.C @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
line wrap: on
line source

/* PR c++/84850 - -Wclass-memaccess on a memcpy in a copy assignment
   operator with no nontrivial bases or members
   { dg-do compile }
   { dg-options "-Wclass-memaccess -ftrack-macro-expansion=0" } */

typedef __SIZE_TYPE__ size_t;

extern "C" void* memcpy (void*, const void*, size_t);
extern "C" void* memset (void*, int, size_t);

template <int>
struct EmptyClass { };

template <int>
struct TrivialClass
{
  bool a;
  int b;
  void *c;
  double d[2];
  void (*e)();
};

template <int>
struct HasDefault
{
  HasDefault ();
};

/* Verify that raw memory accesses from non-static members of a class with
   an empty base is not diagnosed.  */

struct EmptyWithBase: EmptyClass<0>, EmptyClass<1>, EmptyClass<2>
{
  EmptyWithBase ()
  {
    memset (this, 0, sizeof *this);
  }

  EmptyWithBase (const EmptyWithBase &x)
  {
    memcpy (this, &x, sizeof *this);
  }

  ~EmptyWithBase ()
  {
    memset (this, 0, sizeof *this);
  }

  void operator= (const EmptyWithBase &x)
  {
    memcpy (this, &x, sizeof *this);
  }

  void clear ()
  {
    memset (this, 0, sizeof *this);   // { dg-bogus "\\\[-Wclass-memaccess" }
  }

  void copy (const void *p)
  {
    memcpy (this, p, sizeof *this);   // { dg-bogus "\\\[-Wclass-memaccess" }
  }

  static void bad_clear (EmptyWithBase &x)
  {
    memset (&x, 0, sizeof x);         // { dg-warning "\\\[-Wclass-memaccess" }
  }

  static void bad_copy (EmptyWithBase &x, const void *p)
  {
    memcpy (&x, p, sizeof x);         // { dg-warning "\\\[-Wclass-memaccess" }
  }
};

/* Verify that raw memory accesses from non-static members of a class with
   all trivial members is not diagnosed.  */

struct HasTrivialMembers
{
  bool a;
  int b;
  void *c;
  double d[2];
  void (*e)();

  TrivialClass<1> trivial;

  HasTrivialMembers ()
  {
    memset (this, 0, sizeof *this);
  }

  HasTrivialMembers (const HasTrivialMembers &x)
  {
    memcpy (this, &x, sizeof *this);
  }

  ~HasTrivialMembers ()
  {
    memset (this, 0, sizeof *this);
  }

  void operator= (const HasTrivialMembers &x)
  {
    memcpy (this, &x, sizeof *this);
  }

  void clear ()
  {
    memset (this, 0, sizeof *this);   // { dg-bogus "\\\[-Wclass-memaccess" }
  }

  void copy (const void *p)
  {
    memcpy (this, p, sizeof *this);   // { dg-bogus "\\\[-Wclass-memaccess" }
  }

  static void bad_clear (HasTrivialMembers &x)
  {
    memset (&x, 0, sizeof x);         // { dg-warning "\\\[-Wclass-memaccess" }
  }

  static void bad_copy (HasTrivialMembers &x, const void *p)
  {
    memcpy (&x, p, sizeof x);         // { dg-warning "\\\[-Wclass-memaccess" }
  }
};

/* Verify that raw memory accesses from non-static members of a class with
   a trivial base class and no non-trivial members is not diagnosed.  */

struct HasTrivialBase: TrivialClass<1>
{
  TrivialClass<2> a[2];

  HasTrivialBase ()
  {
    memset (this, 0, sizeof *this);   // { dg-bogus "\\\[-Wclass-memaccess" }
  }

  HasTrivialBase (const HasTrivialBase &x)
  {
    memcpy (this, &x, sizeof *this);  // { dg-bogus "\\\[-Wclass-memaccess" }
  }

  ~HasTrivialBase ()
  {
    memset (this, 0, sizeof *this);   // { dg-bogus "\\\[-Wclass-memaccess" }
  }

  void operator= (const HasTrivialBase &x)
  {
    memcpy (this, &x, sizeof *this);
  }

  void clear ()
  {
    memset (this, 0, sizeof *this);   // { dg-bogus "\\\[-Wclass-memaccess" }
  }

  void copy (void *p)
  {
    memcpy (this, p, sizeof *this);   // { dg-bogus "\\\[-Wclass-memaccess" }
  }
};


struct HasTrivialBases: TrivialClass<1>, TrivialClass<2>
{
  TrivialClass<3> a[2];

  HasTrivialBases ()
  {
    memset (this, 0, sizeof *this);   // { dg-bogus "\\\[-Wclass-memaccess" }
  }

  HasTrivialBases (const HasTrivialBases &x)
  {
    memcpy (this, &x, sizeof *this);  // { dg-bogus "\\\[-Wclass-memaccess" }
  }

  ~HasTrivialBases ()
  {
    memset (this, 0, sizeof *this);   // { dg-bogus "\\\[-Wclass-memaccess" }
  }

  void operator= (const HasTrivialBases &x)
  {
    memcpy (this, &x, sizeof *this);
  }

  void clear ()
  {
    memset (this, 0, sizeof *this);   // { dg-bogus "\\\[-Wclass-memaccess" }
  }

  void copy (void *p)
  {
    memcpy (this, p, sizeof *this);   // { dg-bogus "\\\[-Wclass-memaccess" }
  }
};

struct DerivesFromNontrivialClass: HasDefault<1> { };

/* Verify that raw memory accesses from members of a class with a non-trivial
   base class is diagnosed.  */

struct HasNonTrivialBase: TrivialClass<1>, TrivialClass<2>,
			  DerivesFromNontrivialClass,
			  TrivialClass<3>, TrivialClass<4>
{
  HasNonTrivialBase ()
  {
    memset (this, 0, sizeof *this);   // { dg-warning "\\\[-Wclass-memaccess" }
  }

  HasNonTrivialBase (const HasNonTrivialBase &x)
  {
    memcpy (this, &x, sizeof *this);  // { dg-warning "\\\[-Wclass-memaccess" }
  }

  ~HasNonTrivialBase ()
  {
    memset (this, 0, sizeof *this);   // { dg-warning "\\\[-Wclass-memaccess" }
  }

  HasNonTrivialBase& operator= (const HasNonTrivialBase &x)
  {
    memcpy (this, &x, sizeof *this);  // { dg-warning "\\\[-Wclass-memaccess" }
    return *this;
  }

  void clear ()
  {
    memset (this, 0, sizeof *this);   // { dg-warning "\\\[-Wclass-memaccess" }
  }

  void copy (void *p)
  {
    memcpy (this, p, sizeof *this);   // { dg-warning "\\\[-Wclass-memaccess" }
  }
};

struct DerivesIndidirectlyFromNontrivialClass:
  TrivialClass<1>, TrivialClass<2>,
  DerivesFromNontrivialClass,
  TrivialClass<3>, TrivialClass<4> { };

/* Verify that raw memory accesses from members of a class with a non-trivial
   indirect base class is diagnosed.  */

struct HasIndirectNonTrivialBase: TrivialClass<5>, TrivialClass<6>,
				  TrivialClass<7>, TrivialClass<8>,
				  DerivesIndidirectlyFromNontrivialClass
{
  HasIndirectNonTrivialBase ()
  {
    memset (this, 0, sizeof *this);   // { dg-warning "\\\[-Wclass-memaccess" }
  }

  HasIndirectNonTrivialBase (const HasIndirectNonTrivialBase &x)
  {
    memcpy (this, &x, sizeof *this);  // { dg-warning "\\\[-Wclass-memaccess" }
  }

  ~HasIndirectNonTrivialBase ()
  {
    memset (this, 0, sizeof *this);   // { dg-warning "\\\[-Wclass-memaccess" }
  }

  HasIndirectNonTrivialBase& operator= (const HasIndirectNonTrivialBase &x)
  {
    memcpy (this, &x, sizeof *this);  // { dg-warning "\\\[-Wclass-memaccess" }
    return *this;
  }

  void clear ()
  {
    memset (this, 0, sizeof *this);   // { dg-warning "\\\[-Wclass-memaccess" }
  }

  void copy (void *p)
  {
    memcpy (this, p, sizeof *this);   // { dg-warning "\\\[-Wclass-memaccess" }
  }
};