Browse code

avp: warning fixes & more sane usr_avp struct

- type punning warning fixed (both for =-Wstrict-aliasing and
-Wstrict-aliasing=2)
- replaced usr_avp->data with a union (more sane, looks better)

Andrei Pelinescu-Onciul authored on 28/11/2008 15:24:01
Showing 2 changed files
... ...
@@ -154,7 +154,6 @@ avp_t *create_avp (avp_flags_t flags, avp_name_t name, avp_value_t val)
154 154
 	struct str_int_data *sid;
155 155
 	struct str_str_data *ssd;
156 156
 	int len;
157
-	void** p_data;
158 157
 
159 158
 	if (name.s.s == 0 && name.s.len == 0) {
160 159
 		LOG(L_ERR,"ERROR:avp:add_avp: 0 ID or NULL NAME AVP!");
... ...
@@ -169,15 +168,15 @@ avp_t *create_avp (avp_flags_t flags, avp_name_t name, avp_value_t val)
169 169
 			goto error;
170 170
 		}
171 171
 		if (flags&AVP_VAL_STR) {
172
-			len += sizeof(struct str_str_data)-sizeof(void*)
172
+			len += sizeof(struct str_str_data)-sizeof(union usr_avp_data)
173 173
 				+ name.s.len + 1 /* Terminating zero for regex search */
174 174
 				+ val.s.len + 1; /* Value is zero terminated */
175 175
 		} else {
176
-			len += sizeof(struct str_int_data)-sizeof(void*)
176
+			len += sizeof(struct str_int_data)-sizeof(union usr_avp_data)
177 177
 				+ name.s.len + 1; /* Terminating zero for regex search */
178 178
 		}
179 179
 	} else if (flags&AVP_VAL_STR) {
180
-		len += sizeof(str)-sizeof(void*) + val.s.len + 1;
180
+		len += sizeof(str)-sizeof(union usr_avp_data) + val.s.len + 1;
181 181
 	}
182 182
 
183 183
 	avp = (struct usr_avp*)shm_malloc( len );
... ...
@@ -189,17 +188,16 @@ avp_t *create_avp (avp_flags_t flags, avp_name_t name, avp_value_t val)
189 189
 	avp->flags = flags;
190 190
 	avp->id = (flags&AVP_NAME_STR)? compute_ID(&name.s) : name.n ;
191 191
 	avp->next = NULL;
192
-	p_data=&avp->data; /* strict aliasing /type punning warnings workarround */
193 192
 
194 193
 	switch ( flags&(AVP_NAME_STR|AVP_VAL_STR) )
195 194
 	{
196 195
 		case 0:
197 196
 			/* avp type ID, int value */
198
-			avp->data = (void*)(long)val.n;
197
+			avp->d.l = val.n;
199 198
 			break;
200 199
 		case AVP_NAME_STR:
201 200
 			/* avp type str, int value */
202
-			sid = (struct str_int_data*)p_data;
201
+			sid = (struct str_int_data*)&avp->d.data[0];
203 202
 			sid->val = val.n;
204 203
 			sid->name.len =name.s.len;
205 204
 			sid->name.s = (char*)sid + sizeof(struct str_int_data);
... ...
@@ -208,7 +206,7 @@ avp_t *create_avp (avp_flags_t flags, avp_name_t name, avp_value_t val)
208 208
 			break;
209 209
 		case AVP_VAL_STR:
210 210
 			/* avp type ID, str value */
211
-			s = (str*)p_data;
211
+			s = (str*)&avp->d.data[0];
212 212
 			s->len = val.s.len;
213 213
 			s->s = (char*)s + sizeof(str);
214 214
 			memcpy( s->s, val.s.s , s->len);
... ...
@@ -216,7 +214,7 @@ avp_t *create_avp (avp_flags_t flags, avp_name_t name, avp_value_t val)
216 216
 			break;
217 217
 		case AVP_NAME_STR|AVP_VAL_STR:
218 218
 			/* avp type str, str value */
219
-			ssd = (struct str_str_data*)p_data;
219
+			ssd = (struct str_str_data*)&avp->d.data[0];
220 220
 			ssd->name.len = name.s.len;
221 221
 			ssd->name.s = (char*)ssd + sizeof(struct str_str_data);
222 222
 			memcpy( ssd->name.s , name.s.s, name.s.len);
... ...
@@ -298,7 +296,6 @@ int add_avp_before(avp_t *avp, avp_flags_t flags, avp_name_t name, avp_value_t v
298 298
 /* get value functions */
299 299
 inline str* get_avp_name(avp_t *avp)
300 300
 {
301
-	void** p_data; /* strict aliasing /type punning warnings workarround */
302 301
 	
303 302
 	switch ( avp->flags&(AVP_NAME_STR|AVP_VAL_STR) )
304 303
 	{
... ...
@@ -309,12 +306,10 @@ inline str* get_avp_name(avp_t *avp)
309 309
 			return 0;
310 310
 		case AVP_NAME_STR:
311 311
 			/* avp type str, int value */
312
-			p_data=&avp->data;
313
-			return &((struct str_int_data*)p_data)->name;
312
+			return &((struct str_int_data*)&avp->d.data[0])->name;
314 313
 		case AVP_NAME_STR|AVP_VAL_STR:
315 314
 			/* avp type str, str value */
316
-			p_data=&avp->data;
317
-			return &((struct str_str_data*)p_data)->name;
315
+			return &((struct str_str_data*)&avp->d.data[0])->name;
318 316
 	}
319 317
 
320 318
 	LOG(L_ERR,"BUG:avp:get_avp_name: unknown avp type (name&val) %d\n",
... ...
@@ -325,28 +320,26 @@ inline str* get_avp_name(avp_t *avp)
325 325
 
326 326
 inline void get_avp_val(avp_t *avp, avp_value_t *val)
327 327
 {
328
-	void** p_data; /* strict aliasing /type punning warnings workarround */
329 328
 	
330 329
 	if (avp==0 || val==0)
331 330
 		return;
332 331
 
333
-	p_data=&avp->data;
334 332
 	switch ( avp->flags&(AVP_NAME_STR|AVP_VAL_STR) ) {
335 333
 		case 0:
336 334
 			/* avp type ID, int value */
337
-			val->n = (long)(avp->data);
335
+			val->n = avp->d.l;
338 336
 			break;
339 337
 		case AVP_NAME_STR:
340 338
 			/* avp type str, int value */
341
-			val->n = ((struct str_int_data*)p_data)->val;
339
+			val->n = ((struct str_int_data*)&avp->d.data[0])->val;
342 340
 			break;
343 341
 		case AVP_VAL_STR:
344 342
 			/* avp type ID, str value */
345
-			val->s = *(str*)(void*)(&avp->data);
343
+			val->s = *(str*)&avp->d.data[0];
346 344
 			break;
347 345
 		case AVP_NAME_STR|AVP_VAL_STR:
348 346
 			/* avp type str, str value */
349
-			val->s = (((struct str_str_data*)p_data)->val);
347
+			val->s = ((struct str_str_data*)&avp->d.data[0])->val;
350 348
 			break;
351 349
 	}
352 350
 }
... ...
@@ -89,12 +89,18 @@ typedef union {
89 89
 #define avp_value_t	int_str
90 90
 #define avp_index_t	unsigned short
91 91
 
92
+union usr_avp_data{
93
+	void *p; /* forces alignment */
94
+	long l;
95
+	char data[sizeof(void*)]; /* used to access other types, var length */
96
+};
97
+
92 98
 typedef struct usr_avp {
93 99
 	avp_id_t id;
94
-	     /* Flags that are kept for the AVP lifetime */
100
+	/* Flags that are kept for the AVP lifetime */
95 101
 	avp_flags_t flags;
96 102
 	struct usr_avp *next;
97
-	void *data;
103
+	union usr_avp_data d; /* var length */
98 104
 } avp_t;
99 105
 
100 106
 typedef avp_t* avp_list_t;