On Mon, 10 Jun 2019 17:09:10 -0500 Segher Boessenkool <seg...@kernel.crashing.org> wrote:
> On Mon, Jun 10, 2019 at 08:58:00PM +0100, Jozef Lawrynowicz wrote: > > On Mon, 10 Jun 2019 13:32:42 -0500 > > Segher Boessenkool <seg...@kernel.crashing.org> wrote: > > > That is not a fix, that is sweeping the problem under the rug. > > > > > > As a somewhat dirty hack I added > > > > > > #if __MSP430X_LARGE__ > > > #undef __SIZE_TYPE__ > > > __extension__ typedef unsigned __int20 __SIZE_TYPE__; > > > #endif > > > > > > to the start of the installed stddef.h, and that fixes the problem fine, > > > for correct programs that do not forget to include <stddef.h> (directly > > > or indirectly), anyway. > > > But we have some 850 generic tests in gcc/testsuite that use __SIZE_TYPE__ > > without including stddef.h. They just rely on the preprocessor to expand > > this > > using the builtin macro definition. > > I did say it is a dirty hack, right? > > You could call lang_hooks.types.register_builtin_type defining the type > __SIZE_TYPE__ as the int20 partial int type, and then define SIZE_TYPE as > just __SIZE_TYPE__. That is the same effectively, just not using the > header file. > > So something like > > tree type_node = builtin_type_for_size (20, 1); > lang_hooks.types.register_builtin_type (type_node, "__SIZE_TYPE__"); > > or maybe > > tree type_node = builtin_type_for_size (POINTER_SIZE, 1); > lang_hooks.types.register_builtin_type (type_node, "__SIZE_TYPE__"); > > in msp430.c, and > > #define SIZE_TYPE "__SIZE_TYPE__" > > in msp430.h? > > > Segher Thanks for the pointers, they've put me on the right track I think. It doesn't look like we can create the new type in the msp430 backend - the SIZE_TYPE macro is examined quite early and only a couple of basic backend initialization functions are called before SIZE_TYPE is needed in c_common_nodes_and_builtins(). TARGET_INIT_BUILTINS seemed most appropriate, but by then it's too late to create the type and use it in msp430.h. Instead I fixed it by creating a new type "__int20__" in the middle-end, which can then be used for SIZE_TYPE in msp430.h. __int20__ is not really a proper type - it shares it's "RID" values with __int20, but it means we can gate the ISO C pedwarn so it only is emitted for __int20 and not __int20__. It's ok for __int20 and __int20__ to have identical behavior, aside from the pedwarn, which is why sharing the RIDs should be ok. I think this solution fits ok with the existing behavior related to "pedantic" warnings, since alternate keywords beginning and ending with "__" are considered GNU Extensions and don't pedwarn. I guess "__int20" isn't technically a "keyword" in the same sense as "asm" for example. But its a "reserved word" and this fix fits this pattern of surrounding with double-underscores. Any thoughts on this approach in my attached (rough) patch? So far I regtested it fine with the GCC C testsuite for msp430-elf. Also need to do the same for PTRDIFF_TYPE and make that use __int20__. I initially implemented this by giving the __intN__ types their own new set of RIDs so they are completely distinct from __intN, but it requires quite a lot of duplicated code whenever RID_INT_N_* or RID_{FIRST,LAST}_INT_N are used, just to handle the new RIDs. This patch is at least quite concise and gets the job done. Of course, if the __intN__ types really should have their own unique RIDs then I can do it that way instead. Thanks, Jozef
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 4057be3aaed..57e84b84f07 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -4024,8 +4024,14 @@ c_common_nodes_and_builtins (void) sprintf (name, "__int%d", int_n_data[i].bitsize); record_builtin_type ((enum rid)(RID_FIRST_INT_N + i), name, int_n_trees[i].signed_type); + sprintf (name, "__int%d__", int_n_data[i].bitsize); + record_builtin_type ((enum rid)(RID_FIRST_INT_N + i), name, + int_n_trees[i].signed_type); + sprintf (name, "__int%d unsigned", int_n_data[i].bitsize); record_builtin_type (RID_MAX, name, int_n_trees[i].unsigned_type); + sprintf (name, "__int%d__ unsigned", int_n_data[i].bitsize); + record_builtin_type (RID_MAX, name, int_n_trees[i].unsigned_type); } if (c_dialect_cxx ()) diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 87ce853d4b7..cb2f49fa5a2 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -10637,7 +10637,11 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs, case RID_INT_N_2: case RID_INT_N_3: specs->int_n_idx = i - RID_INT_N_0; - if (!in_system_header_at (input_location)) + if (!in_system_header_at (input_location) + /* If the INT_N type ends in "__", and so is of the format + "__intN__", don't pedwarn. */ + && (strncmp (IDENTIFIER_POINTER (type) + + (IDENTIFIER_LENGTH (type) - 2), "__", 2) != 0)) pedwarn (loc, OPT_Wpedantic, "ISO C does not support %<__int%d%> types", int_n_data[specs->int_n_idx].bitsize); diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index df1a3042276..98508721ed9 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -157,6 +157,11 @@ c_parse_init (void) id = get_identifier (name); C_SET_RID_CODE (id, RID_FIRST_INT_N + i); C_IS_RESERVED_WORD (id) = 1; + + sprintf (name, "__int%d__", int_n_data[i].bitsize); + id = get_identifier (name); + C_SET_RID_CODE (id, RID_FIRST_INT_N + i); + C_IS_RESERVED_WORD (id) = 1; } } diff --git a/gcc/config/msp430/msp430.h b/gcc/config/msp430/msp430.h index c0aa8eacd96..689ed26f5e2 100644 --- a/gcc/config/msp430/msp430.h +++ b/gcc/config/msp430/msp430.h @@ -185,7 +185,7 @@ extern const char * msp430_select_hwmult_lib (int, const char **); /* Layout of Source Language Data Types */ #undef SIZE_TYPE -#define SIZE_TYPE (TARGET_LARGE ? "__int20 unsigned" : "unsigned int") +#define SIZE_TYPE (TARGET_LARGE ? "__int20__ unsigned" : "unsigned int") #undef PTRDIFF_TYPE #define PTRDIFF_TYPE (TARGET_LARGE ? "__int20" : "int") #undef WCHAR_TYPE diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 20965e49fe4..526c95e3539 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -262,6 +262,11 @@ init_reswords (void) id = get_identifier (name); C_SET_RID_CODE (id, RID_FIRST_INT_N + i); set_identifier_kind (id, cik_keyword); + + sprintf (name, "__int%d__", int_n_data[i].bitsize); + id = get_identifier (name); + C_SET_RID_CODE (id, RID_FIRST_INT_N + i); + set_identifier_kind (id, cik_keyword); } } diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c index e155ea33d32..2769719995b 100644 --- a/gcc/lto/lto-lang.c +++ b/gcc/lto/lto-lang.c @@ -1260,9 +1260,9 @@ lto_build_c_type_nodes (void) if (int_n_enabled_p[i]) { char name[50]; - sprintf (name, "__int%d unsigned", int_n_data[i].bitsize); + sprintf (name, "int%d", int_n_data[i].bitsize); - if (strcmp (name, SIZE_TYPE) == 0) + if (strstr (SIZE_TYPE, name) != NULL) { intmax_type_node = int_n_trees[i].signed_type; uintmax_type_node = int_n_trees[i].unsigned_type; diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 5d6f2e0166c..b9d60823a68 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -2717,9 +2717,9 @@ initialize_sizetypes (void) if (int_n_enabled_p[i]) { char name[50]; - sprintf (name, "__int%d unsigned", int_n_data[i].bitsize); + sprintf (name, "int%d", int_n_data[i].bitsize); - if (strcmp (name, SIZETYPE) == 0) + if (strstr (SIZETYPE, name) != NULL) { precision = int_n_data[i].bitsize; } diff --git a/gcc/tree.c b/gcc/tree.c index e879f15a841..9a7cb476ae4 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -10383,9 +10383,9 @@ build_common_tree_nodes (bool signed_char) if (int_n_enabled_p[i]) { char name[50]; - sprintf (name, "__int%d unsigned", int_n_data[i].bitsize); + sprintf (name, "int%d", int_n_data[i].bitsize); - if (strcmp (name, SIZE_TYPE) == 0) + if (strstr (SIZE_TYPE, name) != NULL) { size_type_node = int_n_trees[i].unsigned_type; } @@ -10410,8 +10410,9 @@ build_common_tree_nodes (bool signed_char) if (int_n_enabled_p[i]) { char name[50]; - sprintf (name, "__int%d", int_n_data[i].bitsize); - if (strcmp (name, PTRDIFF_TYPE) == 0) + sprintf (name, "int%d", int_n_data[i].bitsize); + + if (strstr (PTRDIFF_TYPE, name) != NULL) ptrdiff_type_node = int_n_trees[i].signed_type; } if (ptrdiff_type_node == NULL_TREE) -- 2.17.1