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 168
 			goto error;
170 169
 		}
171 170
 		if (flags&AVP_VAL_STR) {
172
-			len += sizeof(struct str_str_data)-sizeof(void*)
171
+			len += sizeof(struct str_str_data)-sizeof(union usr_avp_data)
173 172
 				+ name.s.len + 1 /* Terminating zero for regex search */
174 173
 				+ val.s.len + 1; /* Value is zero terminated */
175 174
 		} else {
176
-			len += sizeof(struct str_int_data)-sizeof(void*)
175
+			len += sizeof(struct str_int_data)-sizeof(union usr_avp_data)
177 176
 				+ name.s.len + 1; /* Terminating zero for regex search */
178 177
 		}
179 178
 	} else if (flags&AVP_VAL_STR) {
180
-		len += sizeof(str)-sizeof(void*) + val.s.len + 1;
179
+		len += sizeof(str)-sizeof(union usr_avp_data) + val.s.len + 1;
181 180
 	}
182 181
 
183 182
 	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 188
 	avp->flags = flags;
190 189
 	avp->id = (flags&AVP_NAME_STR)? compute_ID(&name.s) : name.n ;
191 190
 	avp->next = NULL;
192
-	p_data=&avp->data; /* strict aliasing /type punning warnings workarround */
193 191
 
194 192
 	switch ( flags&(AVP_NAME_STR|AVP_VAL_STR) )
195 193
 	{
196 194
 		case 0:
197 195
 			/* avp type ID, int value */
198
-			avp->data = (void*)(long)val.n;
196
+			avp->d.l = val.n;
199 197
 			break;
200 198
 		case AVP_NAME_STR:
201 199
 			/* avp type str, int value */
202
-			sid = (struct str_int_data*)p_data;
200
+			sid = (struct str_int_data*)&avp->d.data[0];
203 201
 			sid->val = val.n;
204 202
 			sid->name.len =name.s.len;
205 203
 			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 206
 			break;
209 207
 		case AVP_VAL_STR:
210 208
 			/* avp type ID, str value */
211
-			s = (str*)p_data;
209
+			s = (str*)&avp->d.data[0];
212 210
 			s->len = val.s.len;
213 211
 			s->s = (char*)s + sizeof(str);
214 212
 			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 214
 			break;
217 215
 		case AVP_NAME_STR|AVP_VAL_STR:
218 216
 			/* avp type str, str value */
219
-			ssd = (struct str_str_data*)p_data;
217
+			ssd = (struct str_str_data*)&avp->d.data[0];
220 218
 			ssd->name.len = name.s.len;
221 219
 			ssd->name.s = (char*)ssd + sizeof(struct str_str_data);
222 220
 			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 296
 /* get value functions */
299 297
 inline str* get_avp_name(avp_t *avp)
300 298
 {
301
-	void** p_data; /* strict aliasing /type punning warnings workarround */
302 299
 	
303 300
 	switch ( avp->flags&(AVP_NAME_STR|AVP_VAL_STR) )
304 301
 	{
... ...
@@ -309,12 +306,10 @@ inline str* get_avp_name(avp_t *avp)
309 306
 			return 0;
310 307
 		case AVP_NAME_STR:
311 308
 			/* avp type str, int value */
312
-			p_data=&avp->data;
313
-			return &((struct str_int_data*)p_data)->name;
309
+			return &((struct str_int_data*)&avp->d.data[0])->name;
314 310
 		case AVP_NAME_STR|AVP_VAL_STR:
315 311
 			/* avp type str, str value */
316
-			p_data=&avp->data;
317
-			return &((struct str_str_data*)p_data)->name;
312
+			return &((struct str_str_data*)&avp->d.data[0])->name;
318 313
 	}
319 314
 
320 315
 	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 320
 
326 321
 inline void get_avp_val(avp_t *avp, avp_value_t *val)
327 322
 {
328
-	void** p_data; /* strict aliasing /type punning warnings workarround */
329 323
 	
330 324
 	if (avp==0 || val==0)
331 325
 		return;
332 326
 
333
-	p_data=&avp->data;
334 327
 	switch ( avp->flags&(AVP_NAME_STR|AVP_VAL_STR) ) {
335 328
 		case 0:
336 329
 			/* avp type ID, int value */
337
-			val->n = (long)(avp->data);
330
+			val->n = avp->d.l;
338 331
 			break;
339 332
 		case AVP_NAME_STR:
340 333
 			/* avp type str, int value */
341
-			val->n = ((struct str_int_data*)p_data)->val;
334
+			val->n = ((struct str_int_data*)&avp->d.data[0])->val;
342 335
 			break;
343 336
 		case AVP_VAL_STR:
344 337
 			/* avp type ID, str value */
345
-			val->s = *(str*)(void*)(&avp->data);
338
+			val->s = *(str*)&avp->d.data[0];
346 339
 			break;
347 340
 		case AVP_NAME_STR|AVP_VAL_STR:
348 341
 			/* avp type str, str value */
349
-			val->s = (((struct str_str_data*)p_data)->val);
342
+			val->s = ((struct str_str_data*)&avp->d.data[0])->val;
350 343
 			break;
351 344
 	}
352 345
 }
... ...
@@ -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;