On Wed, Nov 20, 2019 at 12:30 AM Jakub Jelinek <ja...@redhat.com> wrote: > > Hi! > > The following patch fixes build of older GCC releases with newer ones. > In GCC 4.6 and earlier, we had: > struct cgraph_node; > struct cgraph_node *cgraph_node (tree); > and that is something on which GCC 9+ code errors on if it sees any > __gcc_diag__ and similar attributes, because cgraph_node it wants to find is > not a type. > > As older GCC releases don't have the __gcc_diag__ etc. attributes guarded on > no newer GCC releases, only on minimum GCC version that does support it, > I think we need to make sure we don't reject what older GCCs used to have. > > The following patch does that. In addition, get_pointer_to_named_type > looked misnamed, because we actually aren't interested in getting gimple * > etc. type, but gimple. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk > and eventually 9 too?
Nothing on the specific patch but I wonder if we should change the error ()s in init_dynamic_diag_info to warnings to make stage1 uses fine? That probably then boils down to ignoring __gcc_diag__ formats when initializing wasn't suceessful. It also looks like we repeatedly do work in init_dynamic_diag_info ... Richard. > 2019-11-19 Jakub Jelinek <ja...@redhat.com> > > PR c/90677 > * c-format.c (get_pointer_to_named_type): Renamed to ... > (get_named_type): ... this. If result is FUNCTION_DECL for > cgraph_node, return cgraph_node from pointee of return type if > possible instead of emitting an error. > (init_dynamic_diag_info): Adjust get_pointer_to_named_type callers > to call get_named_type instead. Formatting fixes. > > * c-c++-common/pr90677.c: New test. > > --- gcc/c-family/c-format.c.jj 2019-10-05 09:35:12.917997709 +0200 > +++ gcc/c-family/c-format.c 2019-11-19 13:05:10.113308578 +0100 > @@ -4899,21 +4899,39 @@ 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 id = maybe_get_identifier (name)) > { > - result = identifier_global_value (result); > + result = identifier_global_value (id); > if (result) > { > if (TREE_CODE (result) != TYPE_DECL) > { > + if (TREE_CODE (result) == FUNCTION_DECL > + && !strcmp (name, "cgraph_node") > + && TREE_CODE (TREE_TYPE (result)) == FUNCTION_TYPE) > + { > + /* Before GCC 4.7, there used to be > + struct cgraph_node; > + struct cgraph_node *cgraph_node (tree); > + Don't error in this case, so that GCC 9+ can still > + compile GCC 4.6 and earlier. */ > + tree res = TREE_TYPE (TREE_TYPE (result)); > + if (TREE_CODE (res) == POINTER_TYPE > + && (TYPE_NAME (TREE_TYPE (res)) == id > + || (TREE_CODE (TYPE_NAME (TREE_TYPE (res))) > + == TYPE_DECL > + && (DECL_NAME (TYPE_NAME (TREE_TYPE (res))) > + == id)))) > + return TREE_TYPE (res); > + } > error ("%qs is not defined as a type", name); > result = NULL_TREE; > } > @@ -4953,23 +4971,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 +4998,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/testsuite/c-c++-common/pr90677.c.jj 2019-11-19 13:02:45.709465310 > +0100 > +++ gcc/testsuite/c-c++-common/pr90677.c 2019-11-19 13:03:58.925371802 > +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 >