This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C/C++ PATCH] Fix up build of GCC 4.6 and earlier with GCC 9+ (PR c/90677)
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: "Joseph S. Myers" <joseph at codesourcery dot com>, Marek Polacek <polacek at redhat dot com>, Jason Merrill <jason at redhat dot com>, Nathan Sidwell <nathan at acm dot org>, GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 20 Nov 2019 11:25:46 +0100
- Subject: Re: [C/C++ PATCH] Fix up build of GCC 4.6 and earlier with GCC 9+ (PR c/90677)
- References: <20191119232943.GN4650@tucnak>
On Wed, Nov 20, 2019 at 12:30 AM Jakub Jelinek <jakub@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 <jakub@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
>