1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
/* Reduced from linux-5.10.162's drivers-base-bus.c */
/* { dg-additional-options "-fno-delete-null-pointer-checks -O2" } */
#define NULL ((void*)0)
typedef unsigned int __kernel_size_t;
typedef int __kernel_ssize_t;
typedef __kernel_size_t size_t;
typedef __kernel_ssize_t ssize_t;
struct list_head
{
struct list_head *next, *prev;
};
struct kobject
{
/* [...snip...] */
};
struct attribute
{
/* [...snip...] */
};
static inline
void
sysfs_remove_file_ns(struct kobject* kobj,
const struct attribute* attr,
const void* ns)
{
}
static inline
void
sysfs_remove_file(struct kobject* kobj, const struct attribute* attr)
{
sysfs_remove_file_ns(kobj, attr, NULL);
}
extern struct kobject*
kobject_get(struct kobject* kobj);
extern void
kobject_put(struct kobject* kobj);
struct kset
{
struct list_head list;
/* [...snip...] */
struct kobject kobj;
/* [...snip...] */
} __attribute__((__designated_init__));
static inline
struct kset*
to_kset(struct kobject* kobj)
{
return kobj ? ({
void* __mptr = (void*)(kobj);
((struct kset*)(__mptr - __builtin_offsetof(struct kset, kobj)));
}) : NULL;
}
static inline
struct kset*
kset_get(struct kset* k)
{
return k ? to_kset(kobject_get(&k->kobj)) : NULL;
}
static inline
void
kset_put(struct kset* k)
{
kobject_put(&k->kobj);
}
struct bus_type
{
/* [...snip...] */
struct device* dev_root;
/* [...snip...] */
struct subsys_private* p;
/* [...snip...] */
};
struct bus_attribute
{
struct attribute attr;
/* [...snip...] */
};
extern void
device_unregister(struct device* dev);
struct subsys_private
{
struct kset subsys;
/* [...snip...] */
};
static struct bus_type*
bus_get(struct bus_type* bus)
{
if (bus) { /* { dg-bogus "check of 'bus' for NULL after already dereferencing it" } */
kset_get(&bus->p->subsys);
return bus;
}
return NULL;
}
static void
bus_put(struct bus_type* bus)
{
if (bus)
kset_put(&bus->p->subsys);
}
void
bus_remove_file(struct bus_type* bus, struct bus_attribute* attr)
{
if (bus_get(bus)) {
sysfs_remove_file(&bus->p->subsys.kobj, &attr->attr);
bus_put(bus);
}
}
extern ssize_t
drivers_autoprobe_show(struct bus_type* bus, char* buf);
extern ssize_t
drivers_autoprobe_store(struct bus_type* bus, const char* buf, size_t count);
extern struct bus_attribute bus_attr_drivers_autoprobe;
static void
remove_probe_files(struct bus_type* bus)
{
bus_remove_file(bus, &bus_attr_drivers_autoprobe);
/* [...snip...] */
}
void
bus_unregister(struct bus_type* bus)
{
/* [...snip...] */
if (bus->dev_root) /* { dg-bogus "pointer 'bus' is dereferenced here" } */
device_unregister(bus->dev_root);
/* [...snip...] */
remove_probe_files(bus);
/* [...snip...] */
}
|