From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jim Wilson To: mark@markmitchell.com Cc: egcs@cygnus.com Subject: Re: aliasing problem with va_arg Date: Mon, 26 Oct 1998 20:42:00 -0000 Message-id: <199810262036.MAA12026@rtl.cygnus.com> References: <199810240115.SAA07392@smtp.earthlink.net> X-SW-Source: 1998-10/msg01047.html 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); }