From: Nathan Sidwell <nathan@acm.org>
To: Martin Sebor <msebor@gmail.com>,
Gcc Patch List <gcc-patches@gcc.gnu.org>
Subject: Re: correct attribute ifunc C++ type safety (PR 82301)
Date: Thu, 28 Sep 2017 14:26:00 -0000 [thread overview]
Message-ID: <fa7cea04-b394-539c-50ea-3f7387cff929@acm.org> (raw)
In-Reply-To: <42ebe275-53db-35c9-4199-85b7423cd711@gmail.com>
On 09/24/2017 06:03 PM, Martin Sebor wrote:
> r253041 enhanced type checking for alias and ifunc attributes to
> detect declarations of incompatible aliases, or ifunc resolvers
> that return pointers to functions of an incompatible type. More
> extensive testing exposed a bug in the implementation of the ifunc
> attribute handling in C++ where the checker expected the ifunc
> resolver to return a pointer to a member function when the
> implementation actually expects it return a pointer to a non-
> member function.
>
> In a discussion of the test suite failures, Jakub also suggested
> to break the enhanced warning out of -Wattributes and issue it
> under a different option.
>
> The attached patch corrects the C++ problem and moves the warning
> under -Wincompatible-pointer-types. Since this is a C-only option,
> the patch also enables for it C++. Since the option is enabled by
> default, the patch further requires -Wextra to issue the warning
> for ifunc resolvers returning void*. However, the patched checker
> diagnoses other incompatibilities without it.
>
> Martin
I find the maybe_diag_incompatible_alias function confusing.
> +/* Check declaration of the type of ALIAS for compatibility with its TARGET
> + (which may be an ifunc resolver) and issue a diagnostic when they are
> + not compatible according to language rules (plus a C++ extension for
> + non-static member functions). */
> +
> +static void
> +maybe_diag_incompatible_alias (tree alias, tree target)
> +{
> + tree altype = TREE_TYPE (alias);
> + tree targtype = TREE_TYPE (target);
> +
> + bool ifunc = lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias));
> + if (ifunc)
I think it might be clearer if this was broken out into a diag_ifunc
function? But see below ...
> + {
> + /* Handle attribute ifunc first. */
> +
> + tree funcptr = altype;
> +
> + /* Set FUNCPTR to the type of the alias target. If the type
> + is a non-static member function of class C, construct a type
> + of an ordinary function taking C* as the first argument,
> + followed by the member function argument list, and use it
> + instead to check for compatibilties. FUNCPTR is used only
> + in diagnostics. */
This comment is self-contradictory.
1 Set FUNCPTR
2 Do some method-type shenanigans
3 Use it to check for incompatibilites
4 FUNCPTR is only used in diags
Which of #3 and #4 is true?
> +
> + if (TREE_CODE (altype) == METHOD_TYPE)
> + {
IMHO put the description of the METHOD_TYPE chicanery inside the block
doing it? FWIW, although the change being made works on many (most?)
ABIs, it's not formally correct and I think fails on some where 'this'
is passed specially. You might want to note that?
> + tree rettype = TREE_TYPE (altype);
> + tree args = TYPE_ARG_TYPES (altype);
> + altype = build_function_type (rettype, args);
> + funcptr = altype;
> + }
> +
> + if ((!FUNC_OR_METHOD_TYPE_P (targtype)
> + || (prototype_p (altype)
> + && prototype_p (targtype)
> + && !types_compatible_p (altype, targtype))))
> + {
> + funcptr = build_pointer_type (funcptr);
> +
> + if (warning_at (DECL_SOURCE_LOCATION (target),
> + OPT_Wincompatible_pointer_types,
> + "%<ifunc%> resolver for %qD should return %qT",
> + alias, funcptr))
> + inform (DECL_SOURCE_LOCATION (alias),
> + "resolver indirect function declared here");
> + }
this block is almost the same as the non-ifunc block. Surely they can
be the same code? (by generalizing one of the cases until it turns into
the other?)
> + /* Deal with static member function pointers. */
I do not understand this comment or condition. We seem to have dealt
with pointers already and the conditions seem confused.
> + if (TREE_CODE (targtype) != RECORD_TYPE
> + || TYPE_FIELDS (targtype)
> + || TREE_CODE (TREE_TYPE (TYPE_FIELDS (targtype))) != POINTER_TYPE
> + || (TREE_CODE (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (targtype))))
> + != METHOD_TYPE))
if
not a record,
or has TYPE_FIELDS non-NULL
or the first field doesn't have pointer type (we can't get here)
or something else about the first field
oh, I think it's trying to spot the pointer to NON-static member
function internal record type. But brokenly. I think pmf record_types
have DECL_ARTIFICIAL and BUILTIN_LOCATION, that might be useful.
> + {
> + funcptr = build_pointer_type (funcptr);
> +
> + error ("%<ifunc%> resolver for %qD must return %qT",
> + alias, funcptr);
> +
> + inform (DECL_SOURCE_LOCATION (alias),
> + "resolver indirect function declared here");
> + }
> + }
> +
> + if ((!FUNC_OR_METHOD_TYPE_P (targtype)
> + || (prototype_p (altype)
> + && prototype_p (targtype)
> + && !types_compatible_p (altype, targtype))))
Similar to above, already noted.
Is this function called before we know whether we've enabled the
appropriate warnings? It would be better to bail out sooner if the
warnings are disabled.
nathan
--
Nathan Sidwell
next prev parent reply other threads:[~2017-09-28 14:26 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-25 1:03 Martin Sebor
2017-09-27 15:22 ` Martin Sebor
2017-09-28 11:23 ` Pedro Alves
2017-09-29 15:57 ` Martin Sebor
2017-09-28 14:26 ` Nathan Sidwell [this message]
2017-10-04 19:40 ` Martin Sebor
2017-10-11 11:53 ` Nathan Sidwell
2017-10-11 17:26 ` Jeff Law
2017-10-11 16:32 ` [PING] " Martin Sebor
2017-10-11 16:34 ` Nathan Sidwell
2017-10-11 16:46 ` Martin Sebor
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=fa7cea04-b394-539c-50ea-3f7387cff929@acm.org \
--to=nathan@acm.org \
--cc=gcc-patches@gcc.gnu.org \
--cc=msebor@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).