This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

avr-rtems broken on trunk -- need advice


The avr-rtems port will not build using a trunk compiler on a system with a reasonably modern glibc.

If we look at newlib-stdint.h, we have these wonderfully convoluted conditionals like:

#define INT8_TYPE (CHAR_TYPE_SIZE == 8 ? "signed char" : 0)

They get more complex, but essentially they have the property that if none of the tests hold true, the default value is "0", ie, NULL.


In the case of avr-rtems the problematic code is for the char16_t type initialized by c-common.c:

  char16_type_node = get_identifier (CHAR16_TYPE);


CHAR16_TYPE is defined as:

#ifdef UINT_LEAST16_TYPE
#define CHAR16_TYPE UINT_LEAST16_TYPE
#else
#define CHAR16_TYPE "short unsigned int"
#endif


So if we go to newlib-stdint.h we have:

#define UINT_LEAST16_TYPE (UINT16_TYPE ? UINT16_TYPE : UINT32_TYPE ? UINT32_TYPE : UINT64_TYPE ? UINT64_TYPE : 0)

Where under the hood a short's size varies on the avr port based on target flags.

Soooo, to see how this causes problems it's best to show you the cpp expanded code. If you have a weak stomach, stop reading immediately.

Here's the problematic line in source form:

  char16_type_node = get_identifier (CHAR16_TYPE);

And cpp expanded for avr-rtems:


c_global_trees[CTI_CHAR16_TYPE] = (__builtin_constant_p (((((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) : 16) == 16 ? "shor t unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 16 ? "unsigned int" : (8) == 16 ? "unsigned char" : 0) ? (((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? ( ((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) : 16) == 16 ? "short unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 16 ? "unsigned int" : (8) == 16 ? "unsigned char" : 0) : ((((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 16 : 32) == 32) ? "long unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 32 ? "unsigned int" : ((((g lobal_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) : 16) == 32 ? "short unsigned int" : (8) == 32 ? "unsigned char" : 0) ? ((((((global_ options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 16 : 32) == 32) ? "long unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 32 ? "unsigned int" : ((((global_options.x_targe t_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) : 16) == 32 ? "short unsigned int" : (8) == 32 ? "unsigned char" : 0) : (((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 16 : 32) == 64 ? "long unsigned int" : ((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 32 : 64) == 64 ? "long long unsigned int" : (((global_options.x_ta rget_flags & (1 << 4)) != 0) ? 8 : 16) == 64 ? "unsigned int" : 0) ? (((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 16 : 32) == 64 ? "long unsigned int" : ((((global_options.x_target_flag s & (1 << 4)) != 0) ? 8 : 16) == 8 ? 32 : 64) == 64 ? "long long unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 64 ? "unsigned int" : 0) : 0)) ? get_identifier_with_length ((((( (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) : 16) == 16 ? "short unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 16 ? "unsigned int" : (8) == 16 ? "unsigned char" : 0) ? (((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) : 16) == 16 ? "short unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 16 ? "unsigned int" : (8) == 16 ? "unsigned char" : 0) : ((((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 16 : 32) == 32) ? "long unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 32 ? "unsigned int" : ((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) : 16) == 32 ? "short unsigned int" : (8) == 32 ? "unsigned char" : 0) ? ((((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 16 : 32) == 32) ? "long unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 32 ? "unsigned int" : ((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? (((global_options.x _target_flags & (1 << 4)) != 0) ? 8 : 16) : 16) == 32 ? "short unsigned int" : (8) == 32 ? "unsigned char" : 0) : (((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 16 : 32) == 64 ? "long uns igned int" : ((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 32 : 64) == 64 ? "long long unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 64 ? "unsigned int" : 0) ? (((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 16 : 32) == 64 ? "long unsigned int" : ((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 32 : 64) == 64 ? "long lo ng unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 64 ? "unsigned int" : 0) : 0)), strlen (((((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? (((global_option s.x_target_flags & (1 << 4)) != 0) ? 8 : 16) : 16) == 16 ? "short unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 16 ? "unsigned int" : (8) == 16 ? "unsigned char" : 0) ? (((((gl obal_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) : 16) == 16 ? "short unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0 ) ? 8 : 16) == 16 ? "unsigned int" : (8) == 16 ? "unsigned char" : 0) : ((((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 16 : 32) == 32) ? "long unsigned int" : (((global_options.x_target_ flags & (1 << 4)) != 0) ? 8 : 16) == 32 ? "unsigned int" : ((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) : 16) == 32 ? "short unsigned int" : (8) == 32 ? "unsigned char" : 0) ? ((((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 16 : 32) == 32) ? "long unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 32 ? "unsigned int" : ((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) : 16) == 32 ? "short unsigned int" : (8) = = 32 ? "unsigned char" : 0) : (((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 16 : 32) == 64 ? "long unsigned int" : ((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 32 : 64) == 64 ? "long long unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 64 ? "unsigned int" : 0) ? (((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 16 : 32 ) == 64 ? "long unsigned int" : ((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 32 : 64) == 64 ? "long long unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 6 4 ? "unsigned int" : 0) : 0))) : get_identifier (((((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) : 16) == 16 ? "short unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 16 ? "unsigned int" : (8) == 16 ? "unsigned char" : 0) ? (((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? (((global_o ptions.x_target_flags & (1 << 4)) != 0) ? 8 : 16) : 16) == 16 ? "short unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 16 ? "unsigned int" : (8) == 16 ? "unsigned char" : 0) : (( ((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 16 : 32) == 32) ? "long unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 32 ? "unsigned int" : ((((global_opti ons.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) : 16) == 32 ? "short unsigned int" : (8) == 32 ? "unsigned char" : 0) ? ((((((global_options.x_ target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 16 : 32) == 32) ? "long unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 32 ? "unsigned int" : ((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) : 16) == 32 ? "short unsigned int" : (8) == 32 ? "unsigned char" : 0) : (((((global_options.x_target_flags & (1 << 4 )) != 0) ? 8 : 16) == 8 ? 16 : 32) == 64 ? "long unsigned int" : ((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 32 : 64) == 64 ? "long long unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 64 ? "unsigned int" : 0) ? (((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 16 : 32) == 64 ? "long unsigned int" : ((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 32 : 64) == 64 ? "long long unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 64 ? "unsigned int" : 0) : 0)));

OK, so clean up after you just lost your lunch...


If you look closely, you'll see a calls to strlen in there. I'll highlight one:

strlen (((((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) : 16) == 16 ? "short unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 16 ? "unsigned int" : (8) == 16 ? "unsigned char" : 0) ? (((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) : 16) == 16 ? "short unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 16 ? "unsigned int" : (8) == 16 ? "unsigned char" : 0) : ((((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 16 : 32) == 32) ? "long unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 32 ? "unsigned int" : ((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) : 16) == 32 ? "short unsigned int" : (8) == 32 ? "unsigned char" : 0) ? ((((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 16 : 32) == 32) ? "long unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 32 ? "unsigned int" : ((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) : 16) == 32 ? "short unsigned int" : (8) == 32 ? "unsigned char" : 0) : (((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 16 : 32) == 64 ? "long unsigned int" : ((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 32 : 64) == 64 ? "long long unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 64 ? "unsigned int" : 0) ? (((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 16 : 32) == 64 ? "long unsigned int" : ((((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 8 ? 32 : 64) == 64 ? "long long unsigned int" : (((global_options.x_target_flags & (1 << 4)) != 0) ? 8 : 16) == 64 ? "unsigned int" : 0) : 0))

Note how "0" might get passed to strlen. That's verboten and GCC naturally complains:

In file included from ../../../gcc/gcc/c-family/c-common.c:32:0:
../../../gcc/gcc/c-family/c-common.c: In function âvoid c_common_nodes_and_builtins()â: ../../../gcc/gcc/stringpool.h:39:53: error: null argument where non-null required (argument 1) [-Werror=nonnull]
     ? get_identifier_with_length ((str), strlen (str))  \
                                                     ^
../../../gcc/gcc/c-family/c-common.c:6008:22: note: in expansion of macro âget_identifierâ
   char16_type_node = get_identifier (CHAR16_TYPE);
                      ^
../../../gcc/gcc/stringpool.h:39:53: error: null argument where non-null required (argument 1) [-Werror=nonnull]
     ? get_identifier_with_length ((str), strlen (str))  \
                                                     ^
../../../gcc/gcc/c-family/c-common.c:6024:22: note: in expansion of macro âget_identifierâ
   char32_type_node = get_identifier (CHAR32_TYPE);
                      ^
cc1plus: all warnings being treated as errors


In the interest of keeping my sanity, I'd just change that last default value to something like "unknown type error" or somesuch. But I'm sure there's a better way. Suggestions?

FWIW, where's the set of broken type definition macros I could find easily:

./config/newlib-stdint.h:#define INT8_TYPE (CHAR_TYPE_SIZE == 8 ? "signed char" : 0) ./config/newlib-stdint.h:#define INT16_TYPE (SHORT_TYPE_SIZE == 16 ? "short int" : INT_TYPE_SIZE == 16 ? "int" : CHAR_TYPE_SIZE == 16 ? "signed char" : 0) ./config/newlib-stdint.h:#define INT32_TYPE (STDINT_LONG32 ? "long int" : INT_TYPE_SIZE == 32 ? "int" : SHORT_TYPE_SIZE == 32 ? "short int" : CHAR_TYPE_SIZE == 32 ? "signed char" : 0) ./config/newlib-stdint.h:#define INT64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : LONG_LONG_TYPE_SIZE == 64 ? "long long int" : INT_TYPE_SIZE == 64 ? "int" : 0) ./config/newlib-stdint.h:#define UINT8_TYPE (CHAR_TYPE_SIZE == 8 ? "unsigned char" : 0) ./config/newlib-stdint.h:#define UINT16_TYPE (SHORT_TYPE_SIZE == 16 ? "short unsigned int" : INT_TYPE_SIZE == 16 ? "unsigned int" : CHAR_TYPE_SIZE == 16 ? "unsigned char" : 0) ./config/newlib-stdint.h:#define UINT32_TYPE (STDINT_LONG32 ? "long unsigned int" : INT_TYPE_SIZE == 32 ? "unsigned int" : SHORT_TYPE_SIZE == 32 ? "short unsigned int" : CHAR_TYPE_SIZE == 32 ? "unsigned char" : 0) ./config/newlib-stdint.h:#define UINT64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : LONG_LONG_TYPE_SIZE == 64 ? "long long unsigned int" : INT_TYPE_SIZE == 64 ? "unsigned int" : 0) ./config/newlib-stdint.h:#define INT_LEAST8_TYPE (INT8_TYPE ? INT8_TYPE : INT16_TYPE ? INT16_TYPE : INT32_TYPE ? INT32_TYPE : INT64_TYPE ? INT64_TYPE : 0) ./config/newlib-stdint.h:#define INT_LEAST16_TYPE (INT16_TYPE ? INT16_TYPE : INT32_TYPE ? INT32_TYPE : INT64_TYPE ? INT64_TYPE : 0) ./config/newlib-stdint.h:#define INT_LEAST32_TYPE (INT32_TYPE ? INT32_TYPE : INT64_TYPE ? INT64_TYPE : 0) ./config/newlib-stdint.h:#define UINT_LEAST8_TYPE (UINT8_TYPE ? UINT8_TYPE : UINT16_TYPE ? UINT16_TYPE : UINT32_TYPE ? UINT32_TYPE : UINT64_TYPE ? UINT64_TYPE : 0) ./config/newlib-stdint.h:#define UINT_LEAST16_TYPE (UINT16_TYPE ? UINT16_TYPE : UINT32_TYPE ? UINT32_TYPE : UINT64_TYPE ? UINT64_TYPE : 0) ./config/newlib-stdint.h:#define UINT_LEAST32_TYPE (UINT32_TYPE ? UINT32_TYPE : UINT64_TYPE ? UINT64_TYPE : 0) ./config/avr/avr-stdint.h:#define INT64_TYPE (INT_TYPE_SIZE == 16 ? "long long int" : 0) ./config/avr/avr-stdint.h:#define UINT64_TYPE (INT_TYPE_SIZE == 16 ? "long long unsigned int" : 0)



You might legitimately ask why something like h8300-rtems doesn't hit this. I believe it's because the h8300 has a constant SHORT_TYPE_SIZE, which is enough to simplify things to the point where GCC knows NULL isn't going to get passed to strlen. Contrast to the avr where SHORT_TYPE_SIZE varies.

Thoughts or suggestions?

jeff


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]