[C/C++] Fix up build of GCC 4.6 and earlier with GCC 9+ (PR c/90677, take 2)
diff mbox series

Message ID 20191122141045.GB2466@tucnak
State New
Headers show
Series
  • [C/C++] Fix up build of GCC 4.6 and earlier with GCC 9+ (PR c/90677, take 2)
Related show

Commit Message

Jakub Jelinek Nov. 22, 2019, 2:10 p.m. UTC
On Wed, Nov 20, 2019 at 02:01:58PM -0500, Jason Merrill wrote:
> I would think that get_named_type should find struct or enum names that have
> been hidden by another declaration; that would fix this without
> special-casing cgraph_node.  For the C++ front-end, that would be
> 
> lookup_qualified_name (global_namespace, id, /*prefer_type*/2,
> /*complain*/false)

Ok, this patch does that, for C by going from I_TAG_BINDING to the global
level.  Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2019-11-22  Jakub Jelinek  <jakub@redhat.com>

	PR c/90677
	* c-common.h (identifier_global_tag): Declare.
	* c-format.c (get_pointer_to_named_type): Renamed to ...
	(get_named_type): ... this.  Use identifier_global_tag instead of
	identifier_global_value, handle the return value being a TYPE_P.
	(init_dynamic_diag_info): Adjust get_pointer_to_named_type callers
	to call get_named_type instead.  Formatting fixes.
c/
	* c-decl.c (identifier_global_tag): Define.
cp/
	* cp-objcp-common.c (identifier_global_tag): Define.
testsuite/
	* c-c++-common/pr90677.c: New test.


	Jakub

Comments

Jason Merrill Nov. 22, 2019, 7:38 p.m. UTC | #1
On 11/22/19 2:10 PM, Jakub Jelinek wrote:
> On Wed, Nov 20, 2019 at 02:01:58PM -0500, Jason Merrill wrote:
>> I would think that get_named_type should find struct or enum names that have
>> been hidden by another declaration; that would fix this without
>> special-casing cgraph_node.  For the C++ front-end, that would be
>>
>> lookup_qualified_name (global_namespace, id, /*prefer_type*/2,
>> /*complain*/false)
> 
> Ok, this patch does that, for C by going from I_TAG_BINDING to the global
> level.  Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK on Monday unless a C maintainer has a comment.

> 2019-11-22  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c/90677
> 	* c-common.h (identifier_global_tag): Declare.
> 	* c-format.c (get_pointer_to_named_type): Renamed to ...
> 	(get_named_type): ... this.  Use identifier_global_tag instead of
> 	identifier_global_value, handle the return value being a TYPE_P.
> 	(init_dynamic_diag_info): Adjust get_pointer_to_named_type callers
> 	to call get_named_type instead.  Formatting fixes.
> c/
> 	* c-decl.c (identifier_global_tag): Define.
> cp/
> 	* cp-objcp-common.c (identifier_global_tag): Define.
> testsuite/
> 	* c-c++-common/pr90677.c: New test.
> 
> --- gcc/c-family/c-common.h.jj	2019-11-15 09:28:56.904930082 +0100
> +++ gcc/c-family/c-common.h	2019-11-22 12:47:45.261379415 +0100
> @@ -811,6 +811,7 @@ extern void c_register_addr_space (const
>   extern bool in_late_binary_op;
>   extern const char *c_addr_space_name (addr_space_t as);
>   extern tree identifier_global_value (tree);
> +extern tree identifier_global_tag (tree);
>   extern bool names_builtin_p (const char *);
>   extern tree c_linkage_bindings (tree);
>   extern void record_builtin_type (enum rid, const char *, tree);
> --- gcc/c-family/c-format.c.jj	2019-11-19 22:26:45.842300595 +0100
> +++ gcc/c-family/c-format.c	2019-11-22 13:12:12.765658215 +0100
> @@ -4899,31 +4899,32 @@ init_dynamic_gfc_info (void)
>       }
>   }
>   
> -/* Lookup the type named NAME and return a pointer-to-NAME type if found.
> -   Otherwise, return void_type_node if NAME has not been used yet, or NULL_TREE if
> -   NAME is not a type (issuing an error).  */
> +/* Lookup the type named NAME and return a NAME type if found.
> +   Otherwise, return void_type_node if NAME has not been used yet,
> +   or NULL_TREE if NAME is not a type (issuing an error).  */
>   
>   static tree
> -get_pointer_to_named_type (const char *name)
> +get_named_type (const char *name)
>   {
> -  tree result;
> -  if ((result = maybe_get_identifier (name)))
> +  if (tree result = maybe_get_identifier (name))
>       {
> -      result = identifier_global_value (result);
> +      result = identifier_global_tag (result);
>         if (result)
>   	{
> -	  if (TREE_CODE (result) != TYPE_DECL)
> +	  if (TYPE_P (result))
> +	    ;
> +	  else if (TREE_CODE (result) == TYPE_DECL)
> +	    result = TREE_TYPE (result);
> +	  else
>   	    {
>   	      error ("%qs is not defined as a type", name);
>   	      result = NULL_TREE;
>   	    }
> -	  else
> -	    result = TREE_TYPE (result);
>   	}
> +      return result;
>       }
>     else
> -    result = void_type_node;
> -  return result;
> +    return void_type_node;
>   }
>   
>   /* Determine the types of "tree" and "location_t" in the code being
> @@ -4953,23 +4954,24 @@ init_dynamic_diag_info (void)
>   	 an extra type level.  */
>         if ((local_tree_type_node = maybe_get_identifier ("tree")))
>   	{
> -	  local_tree_type_node = identifier_global_value (local_tree_type_node);
> +	  local_tree_type_node
> +	    = identifier_global_value (local_tree_type_node);
>   	  if (local_tree_type_node)
>   	    {
>   	      if (TREE_CODE (local_tree_type_node) != TYPE_DECL)
>   		{
>   		  error ("%<tree%> is not defined as a type");
> -		  local_tree_type_node = 0;
> +		  local_tree_type_node = NULL_TREE;
>   		}
>   	      else if (TREE_CODE (TREE_TYPE (local_tree_type_node))
>   		       != POINTER_TYPE)
>   		{
>   		  error ("%<tree%> is not defined as a pointer type");
> -		  local_tree_type_node = 0;
> +		  local_tree_type_node = NULL_TREE;
>   		}
>   	      else
> -		local_tree_type_node =
> -		  TREE_TYPE (TREE_TYPE (local_tree_type_node));
> +		local_tree_type_node
> +		  = TREE_TYPE (TREE_TYPE (local_tree_type_node));
>   	    }
>   	}
>         else
> @@ -4979,12 +4981,12 @@ init_dynamic_diag_info (void)
>     /* Similar to the above but for gimple*.  */
>     if (!local_gimple_ptr_node
>         || local_gimple_ptr_node == void_type_node)
> -    local_gimple_ptr_node = get_pointer_to_named_type ("gimple");
> +    local_gimple_ptr_node = get_named_type ("gimple");
>   
>     /* Similar to the above but for cgraph_node*.  */
>     if (!local_cgraph_node_ptr_node
>         || local_cgraph_node_ptr_node == void_type_node)
> -    local_cgraph_node_ptr_node = get_pointer_to_named_type ("cgraph_node");
> +    local_cgraph_node_ptr_node = get_named_type ("cgraph_node");
>   
>     static tree hwi;
>   
> --- gcc/c/c-decl.c.jj	2019-11-20 09:24:25.793311423 +0100
> +++ gcc/c/c-decl.c	2019-11-22 12:48:35.697598249 +0100
> @@ -10168,6 +10168,20 @@ identifier_global_value	(tree t)
>     return NULL_TREE;
>   }
>   
> +/* Return the global value of tag T as a symbol.  */
> +
> +tree
> +identifier_global_tag (tree t)
> +{
> +  struct c_binding *b;
> +
> +  for (b = I_TAG_BINDING (t); b; b = b->shadowed)
> +    if (B_IN_FILE_SCOPE (b) || B_IN_EXTERNAL_SCOPE (b))
> +      return b->decl;
> +
> +  return NULL_TREE;
> +}
> +
>   /* Returns true if NAME refers to a built-in function or function-like
>      operator.  */
>   
> --- gcc/cp/cp-objcp-common.c.jj	2019-11-22 11:51:28.090682190 +0100
> +++ gcc/cp/cp-objcp-common.c	2019-11-22 12:51:44.500674052 +0100
> @@ -349,6 +349,15 @@ identifier_global_value (tree name)
>     return get_global_binding (name);
>   }
>   
> +/* Similarly, but return struct/class/union NAME instead.  */
> +
> +tree
> +identifier_global_tag (tree name)
> +{
> +  return lookup_qualified_name (global_namespace, name, /*prefer_type*/2,
> +				/*complain*/false);
> +}
> +
>   /* Returns true if NAME refers to a built-in function or function-like
>      operator.  */
>   
> --- gcc/testsuite/c-c++-common/pr90677.c.jj	2019-11-22 12:40:14.835355655 +0100
> +++ gcc/testsuite/c-c++-common/pr90677.c	2019-11-22 12:40:14.835355655 +0100
> @@ -0,0 +1,11 @@
> +/* PR c/90677 */
> +/* { dg-do compile } */
> +/* { dg-options "-W -Wall" } */
> +
> +struct cgraph_node;
> +union tree_node;
> +typedef union tree_node *tree;
> +union gimple_statement_d;
> +typedef union gimple_statement_d *gimple;
> +struct cgraph_node *cgraph_node (tree);
> +void foo (int, const char *, ...) __attribute__((__format__(__gcc_diag__, 2, 3)));
> 
> 	Jakub
>
Joseph Myers Nov. 22, 2019, 9:31 p.m. UTC | #2
On Fri, 22 Nov 2019, Jason Merrill wrote:

> On 11/22/19 2:10 PM, Jakub Jelinek wrote:
> > On Wed, Nov 20, 2019 at 02:01:58PM -0500, Jason Merrill wrote:
> > > I would think that get_named_type should find struct or enum names that
> > > have
> > > been hidden by another declaration; that would fix this without
> > > special-casing cgraph_node.  For the C++ front-end, that would be
> > > 
> > > lookup_qualified_name (global_namespace, id, /*prefer_type*/2,
> > > /*complain*/false)
> > 
> > Ok, this patch does that, for C by going from I_TAG_BINDING to the global
> > level.  Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> 
> OK on Monday unless a C maintainer has a comment.

I'm fine with this patch.

Patch
diff mbox series

--- gcc/c-family/c-common.h.jj	2019-11-15 09:28:56.904930082 +0100
+++ gcc/c-family/c-common.h	2019-11-22 12:47:45.261379415 +0100
@@ -811,6 +811,7 @@  extern void c_register_addr_space (const
 extern bool in_late_binary_op;
 extern const char *c_addr_space_name (addr_space_t as);
 extern tree identifier_global_value (tree);
+extern tree identifier_global_tag (tree);
 extern bool names_builtin_p (const char *);
 extern tree c_linkage_bindings (tree);
 extern void record_builtin_type (enum rid, const char *, tree);
--- gcc/c-family/c-format.c.jj	2019-11-19 22:26:45.842300595 +0100
+++ gcc/c-family/c-format.c	2019-11-22 13:12:12.765658215 +0100
@@ -4899,31 +4899,32 @@  init_dynamic_gfc_info (void)
     }
 }
 
-/* Lookup the type named NAME and return a pointer-to-NAME type if found.
-   Otherwise, return void_type_node if NAME has not been used yet, or NULL_TREE if
-   NAME is not a type (issuing an error).  */
+/* Lookup the type named NAME and return a NAME type if found.
+   Otherwise, return void_type_node if NAME has not been used yet,
+   or NULL_TREE if NAME is not a type (issuing an error).  */
 
 static tree
-get_pointer_to_named_type (const char *name)
+get_named_type (const char *name)
 {
-  tree result;
-  if ((result = maybe_get_identifier (name)))
+  if (tree result = maybe_get_identifier (name))
     {
-      result = identifier_global_value (result);
+      result = identifier_global_tag (result);
       if (result)
 	{
-	  if (TREE_CODE (result) != TYPE_DECL)
+	  if (TYPE_P (result))
+	    ;
+	  else if (TREE_CODE (result) == TYPE_DECL)
+	    result = TREE_TYPE (result);
+	  else
 	    {
 	      error ("%qs is not defined as a type", name);
 	      result = NULL_TREE;
 	    }
-	  else
-	    result = TREE_TYPE (result);
 	}
+      return result;
     }
   else
-    result = void_type_node;
-  return result;
+    return void_type_node;
 }
 
 /* Determine the types of "tree" and "location_t" in the code being
@@ -4953,23 +4954,24 @@  init_dynamic_diag_info (void)
 	 an extra type level.  */
       if ((local_tree_type_node = maybe_get_identifier ("tree")))
 	{
-	  local_tree_type_node = identifier_global_value (local_tree_type_node);
+	  local_tree_type_node
+	    = identifier_global_value (local_tree_type_node);
 	  if (local_tree_type_node)
 	    {
 	      if (TREE_CODE (local_tree_type_node) != TYPE_DECL)
 		{
 		  error ("%<tree%> is not defined as a type");
-		  local_tree_type_node = 0;
+		  local_tree_type_node = NULL_TREE;
 		}
 	      else if (TREE_CODE (TREE_TYPE (local_tree_type_node))
 		       != POINTER_TYPE)
 		{
 		  error ("%<tree%> is not defined as a pointer type");
-		  local_tree_type_node = 0;
+		  local_tree_type_node = NULL_TREE;
 		}
 	      else
-		local_tree_type_node =
-		  TREE_TYPE (TREE_TYPE (local_tree_type_node));
+		local_tree_type_node
+		  = TREE_TYPE (TREE_TYPE (local_tree_type_node));
 	    }
 	}
       else
@@ -4979,12 +4981,12 @@  init_dynamic_diag_info (void)
   /* Similar to the above but for gimple*.  */
   if (!local_gimple_ptr_node
       || local_gimple_ptr_node == void_type_node)
-    local_gimple_ptr_node = get_pointer_to_named_type ("gimple");
+    local_gimple_ptr_node = get_named_type ("gimple");
 
   /* Similar to the above but for cgraph_node*.  */
   if (!local_cgraph_node_ptr_node
       || local_cgraph_node_ptr_node == void_type_node)
-    local_cgraph_node_ptr_node = get_pointer_to_named_type ("cgraph_node");
+    local_cgraph_node_ptr_node = get_named_type ("cgraph_node");
 
   static tree hwi;
 
--- gcc/c/c-decl.c.jj	2019-11-20 09:24:25.793311423 +0100
+++ gcc/c/c-decl.c	2019-11-22 12:48:35.697598249 +0100
@@ -10168,6 +10168,20 @@  identifier_global_value	(tree t)
   return NULL_TREE;
 }
 
+/* Return the global value of tag T as a symbol.  */
+
+tree
+identifier_global_tag (tree t)
+{
+  struct c_binding *b;
+
+  for (b = I_TAG_BINDING (t); b; b = b->shadowed)
+    if (B_IN_FILE_SCOPE (b) || B_IN_EXTERNAL_SCOPE (b))
+      return b->decl;
+
+  return NULL_TREE;
+}
+
 /* Returns true if NAME refers to a built-in function or function-like
    operator.  */
 
--- gcc/cp/cp-objcp-common.c.jj	2019-11-22 11:51:28.090682190 +0100
+++ gcc/cp/cp-objcp-common.c	2019-11-22 12:51:44.500674052 +0100
@@ -349,6 +349,15 @@  identifier_global_value (tree name)
   return get_global_binding (name);
 }
 
+/* Similarly, but return struct/class/union NAME instead.  */
+
+tree
+identifier_global_tag (tree name)
+{
+  return lookup_qualified_name (global_namespace, name, /*prefer_type*/2,
+				/*complain*/false);
+}
+
 /* Returns true if NAME refers to a built-in function or function-like
    operator.  */
 
--- gcc/testsuite/c-c++-common/pr90677.c.jj	2019-11-22 12:40:14.835355655 +0100
+++ gcc/testsuite/c-c++-common/pr90677.c	2019-11-22 12:40:14.835355655 +0100
@@ -0,0 +1,11 @@ 
+/* PR c/90677 */
+/* { dg-do compile } */
+/* { dg-options "-W -Wall" } */
+
+struct cgraph_node;
+union tree_node;
+typedef union tree_node *tree;
+union gimple_statement_d;
+typedef union gimple_statement_d *gimple;
+struct cgraph_node *cgraph_node (tree);
+void foo (int, const char *, ...) __attribute__((__format__(__gcc_diag__, 2, 3)));