Daily bump.
[official-gcc.git] / gcc / testsuite / gcc.dg / analyzer / data-model-5b.c
blobcd6a4df00dd940457d6c0b750432569cded09695
1 /* A toy re-implementation of CPython's object model. */
3 #include <stddef.h>
4 #include <string.h>
5 #include <stdlib.h>
7 typedef struct base_obj base_obj;
8 typedef struct type_obj type_obj;
9 typedef struct string_obj string_obj;
11 struct base_obj
13 struct type_obj *ob_type;
14 int ob_refcnt;
17 struct type_obj
19 base_obj tp_base;
20 void (*tp_dealloc) (base_obj *);
23 struct string_obj
25 base_obj str_base;
26 size_t str_len;
27 char str_buf[];
30 extern void type_del (base_obj *);
31 extern void str_del (base_obj *);
33 type_obj type_type = {
34 { &type_type, 1},
35 type_del
38 type_obj str_type = {
39 { &str_type, 1},
40 str_del
43 base_obj *alloc_obj (type_obj *ob_type, size_t sz)
45 base_obj *obj = (base_obj *)malloc (sz);
46 if (!obj)
47 return NULL;
48 obj->ob_type = ob_type;
49 obj->ob_refcnt = 1;
50 return obj;
53 string_obj *new_string_obj (const char *str)
55 //__analyzer_dump ();
56 size_t len = strlen (str);
57 #if 1
58 string_obj *str_obj
59 = (string_obj *)alloc_obj (&str_type, sizeof (string_obj) + len + 1);
60 #else
61 string_obj *str_obj = (string_obj *)malloc (sizeof (string_obj) + len + 1);
62 if (!str_obj)
63 return NULL;
64 str_obj->str_base.ob_type = &str_type;
65 str_obj->str_base.ob_refcnt = 1;
66 #endif
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';
70 return str_obj;
73 void unref (string_obj *obj)
75 //__analyzer_dump();
76 if (--obj->str_base.ob_refcnt == 0)
78 //__analyzer_dump();
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);
86 //__analyzer_dump();
87 if (obj)
88 unref (obj);
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. */