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

Reply via email to