view gcc/testsuite/gcc.dg/analyzer/data-model-5b.c @ 152:2b5abeee2509

update gcc11
author anatofuz
date Mon, 25 May 2020 07:50:57 +0900
parents 1830386684a0
children
line wrap: on
line source

/* A toy re-implementation of CPython's object model.  */

#include <stddef.h>
#include <string.h>
#include <stdlib.h>

typedef struct base_obj base_obj;
typedef struct type_obj type_obj;
typedef struct string_obj string_obj;

struct base_obj
{
  struct type_obj *ob_type;
  int ob_refcnt;
};

struct type_obj
{
  base_obj tp_base;
  void (*tp_dealloc) (base_obj *);
};

struct string_obj
{
  base_obj str_base;
  size_t str_len;
  char str_buf[];
};

extern void type_del (base_obj *);
extern void str_del (base_obj *);

type_obj type_type = {
  { &type_type, 1},
  type_del
};

type_obj str_type = {
  { &str_type, 1},
  str_del
};

base_obj *alloc_obj (type_obj *ob_type, size_t sz)
{
  base_obj *obj = (base_obj *)malloc (sz);
  if (!obj)
    return NULL;
  obj->ob_type = ob_type;
  obj->ob_refcnt = 1;
  return obj;
}

string_obj *new_string_obj (const char *str)
{
  //__analyzer_dump ();
  size_t len = strlen (str);
#if 1
  string_obj *str_obj
    = (string_obj *)alloc_obj (&str_type, sizeof (string_obj) + len + 1);
#else
  string_obj *str_obj = (string_obj *)malloc (sizeof (string_obj) + len + 1);
  if (!str_obj)
    return NULL;
  str_obj->str_base.ob_type = &str_type;
  str_obj->str_base.ob_refcnt = 1;
#endif
  str_obj->str_len = len; /* { dg-warning "dereference of NULL 'str_obj'" } */
  memcpy (str_obj->str_buf, str, len);
  str_obj->str_buf[len] = '\0';
  return str_obj;
}

void unref (string_obj *obj)
{
  //__analyzer_dump();
  if (--obj->str_base.ob_refcnt == 0)
    {
      //__analyzer_dump();
      obj->str_base.ob_type->tp_dealloc ((base_obj *)obj); /* { dg-bogus "use of uninitialized value '<unknown>'" "" { xfail *-*-* } } */
      // TODO (xfail): not sure what's going on here
    }
}

void test_1 (const char *str)
{
  string_obj *obj = new_string_obj (str);
  //__analyzer_dump();
  if (obj)
    unref (obj);
}