1 /* A toy re-implementation of CPython's object model. */
7 typedef struct base_obj base_obj
;
8 typedef struct type_obj type_obj
;
9 typedef struct string_obj string_obj
;
13 struct type_obj
*ob_type
;
20 void (*tp_dealloc
) (base_obj
*);
30 extern void type_del (base_obj
*);
31 extern void str_del (base_obj
*);
33 type_obj type_type
= {
43 base_obj
*alloc_obj (type_obj
*ob_type
, size_t sz
)
45 base_obj
*obj
= (base_obj
*)malloc (sz
);
48 obj
->ob_type
= ob_type
;
53 string_obj
*new_string_obj (const char *str
)
56 size_t len
= strlen (str
);
59 = (string_obj
*)alloc_obj (&str_type
, sizeof (string_obj
) + len
+ 1);
61 string_obj
*str_obj
= (string_obj
*)malloc (sizeof (string_obj
) + len
+ 1);
64 str_obj
->str_base
.ob_type
= &str_type
;
65 str_obj
->str_base
.ob_refcnt
= 1;
67 str_obj
->str_len
= len
; /* { dg-warning "dereference of NULL 'str_obj'" } */
68 memcpy (str_obj
->str_buf
, str
, len
);
69 str_obj
->str_buf
[len
] = '\0';
73 void unref (string_obj
*obj
)
76 if (--obj
->str_base
.ob_refcnt
== 0)
79 obj
->str_base
.ob_type
->tp_dealloc ((base_obj
*)obj
);
83 void test_1 (const char *str
)
85 string_obj
*obj
= new_string_obj (str
);
89 } /* { dg-bogus "leak" "" { xfail *-*-* } } */
90 /* XFAIL (false leak):
91 Given that we only know "len" symbolically, this line:
92 str_obj->str_buf[len] = '\0';
93 is a symbolic write which could clobber the ob_type or ob_refcnt.
94 It reports a leak when following the path where the refcount is clobbered
95 to be a value that leads to the deallocator not being called. */