This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: aliasing problem with va_arg
- To: mark at markmitchell dot com
- Subject: Re: aliasing problem with va_arg
- From: Jim Wilson <wilson at cygnus dot com>
- Date: Mon, 26 Oct 1998 12:36:32 -0800
- cc: egcs at cygnus dot com
Right, as per our discussion on Tuesday. Is it really as hard as you
say to do this? This is clearly the right fix. For now, we don't
have to give good alias sets to the things we're loading; just 0 will
do for safety sake.
It shouldn't be hard for most targets. Primarily it will be time consuming,
because there are 30 different ports that will need to be fixed. I'd rather
see them all fixed than to just fix a few, because if we don't fix them
all now, we probably never will, and that could lead to long term maintenance
problems.
There are a few targets where making the change will be hard. The MIPS
for instance supports many different macros, big endian vs little endian,
hard-float vs soft-float, 32 bit vs 64 bit, plus the effects of supporting
multiple ABIs (o32, n32, n64, EABI). I'd expect it to get a little tricky
to get them all right.
How hard would fixing the macros be? Would you mind sending me the
preprocessed sun-solaris2 source for your example, so that I could
look at it with a cross-compiler?
I didn't even think of fixing va-sparc.h. I just assumed it couldn't be.
It is possible that we might be able to do something there.
FYI It is possible to preprocess this with a cross-compiler. I did
"make xgcc cpp cc1 stmp-int-hdrs" and then "./xgcc -B./ tmp.c -E > tmp.i".
I don't bother to build or use a native compiler while looking at this problem.
I thought of another idea, add a new type qualifier, e.g. __alias, __norestrct,
which has the effect of making a type that can alias any other type. We
could then make get_alias_set return zero for types with this qualifier,
and modify the va-sparc.h file to use it.
A copy of the preprocessed file follows.
Jim
# 1 "tmp.c"
# 1 "include/stdarg.h" 1 3
# 1 "include/va-sparc.h" 1 3
typedef void * __gnuc_va_list;
# 47 "include/va-sparc.h" 3
void va_end (__gnuc_va_list);
enum __va_type_classes {
__no_type_class = -1,
__void_type_class,
__integer_type_class,
__char_type_class,
__enumeral_type_class,
__boolean_type_class,
__pointer_type_class,
__reference_type_class,
__offset_type_class,
__real_type_class,
__complex_type_class,
__function_type_class,
__method_type_class,
__record_type_class,
__union_type_class,
__array_type_class,
__string_type_class,
__set_type_class,
__file_type_class,
__lang_type_class
};
# 134 "include/va-sparc.h" 3
# 159 "include/va-sparc.h" 3
# 30 "include/stdarg.h" 2 3
# 168 "include/stdarg.h" 3
typedef __gnuc_va_list va_list;
# 240 "include/stdarg.h" 3
# 1 "tmp.c" 2
extern double bar (double);
double foo (va_list ap) {
double d = __extension__ (*({((__builtin_classify_type (*( double *) 0) >= __record_type_class || (__builtin_classify_type (*( double *) 0) == __real_type_class && sizeof ( double ) == 16)) ? (( ap ) = (char *)( ap ) + (((sizeof ( double * ) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) , *( double **) (void *) ((char *)( ap ) - (((sizeof ( double * ) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) )) : (((sizeof ( double ) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) == 8 ? ({ union {char __d[sizeof ( double )]; int __i[2];} __u; __u.__i[0] = ((int *) (void *) ( ap ))[0]; __u.__i[1] = ((int *) (void *) ( ap ))[1]; ( ap ) = (char *)( ap ) + 8; ( double *) (void *) __u.__d; }) : (( ap ) = (char *)( ap ) + (((sizeof ( double ) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) , (( double *) (void *) ((char *)( ap ) - (((sizeof ( double ) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) ))));})) ;
return bar (d);
}