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) | expand |
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 >
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.
--- 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)));