OK.

On Fri, Mar 9, 2018 at 6:05 AM, Jakub Jelinek <ja...@redhat.com> wrote:
> On Thu, Mar 08, 2018 at 04:06:24PM -0500, Jason Merrill wrote:
>> On Thu, Mar 8, 2018 at 1:01 PM, Jakub Jelinek <ja...@redhat.com> wrote:
>> > The C FE just warns and doesn't override builtins, but C++ FE
>> > on say int __builtin_trap (); will override the builtin, so later
>> > builtin_decl_explicit will return the bogus user function which e.g.
>> > doesn't have any merged attributes, can have different arguments or
>> > return type etc.
>> >
>> > This patch prevents that; generally the builtins we want to override
>> > are the DECL_ANTICIPATED which we handle properly earlier.
>> >
>> > The testcase in the PR ICEs not because of the argument mismatch (there is
>> > none in this case) or return value mismatch (because nothing cares about 
>> > the
>> > return value), but because the new decl lacks noreturn attribute and GCC
>> > relies on builtin_decl_explicit (BUILT_IN_TRAP) to be really noreturn.
>> >
>> > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>> > Or shall we error on these, or ignore the name checks and just
>> > if (DECL_BUILT_IN (olddecl)) return NULL_TREE;, something else?
>>
>> Seems like returning NULL_TREE means that we overload the built-in,
>> which also seems undesirable; what if we return olddecl unmodified?
>> It would also be good to improve the diagnostic to say that we're
>> ignoring the declaration.  Perhaps as a permerror.
>
> So like this (if it passes bootstrap/regtest, though I think we don't have
> any tests other than these new ones that cover it anyway, so I don't expect
> issues)?
>
> 2018-03-09  Jakub Jelinek  <ja...@redhat.com>
>
>         PR c++/84724
>         * decl.c (duplicate_decls): Don't override __* prefixed builtins
>         except for __[^b]*_chk, instead issue permerror and for -fpermissive
>         also a note and return olddecl.
>
>         * g++.dg/ext/pr84724.C: New test.
>
> --- gcc/cp/decl.c.jj    2018-03-08 21:53:44.989559552 +0100
> +++ gcc/cp/decl.c       2018-03-09 11:53:58.557156637 +0100
> @@ -1566,6 +1566,33 @@ next_arg:;
>                    || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
>                                  TYPE_ARG_TYPES (TREE_TYPE (olddecl))))
>             {
> +             /* Don't really override olddecl for __* prefixed builtins
> +                except for __[^b]*_chk, the compiler might be using those
> +                explicitly.  */
> +             if (DECL_BUILT_IN (olddecl))
> +               {
> +                 tree id = DECL_NAME (olddecl);
> +                 const char *name = IDENTIFIER_POINTER (id);
> +                 size_t len;
> +
> +                 if (name[0] == '_'
> +                     && name[1] == '_'
> +                     && (strncmp (name + 2, "builtin_",
> +                                  strlen ("builtin_")) == 0
> +                         || (len = strlen (name)) <= strlen ("___chk")
> +                         || memcmp (name + len - strlen ("_chk"),
> +                                    "_chk", strlen ("_chk") + 1) != 0))
> +                   {
> +                     if (permerror (DECL_SOURCE_LOCATION (newdecl),
> +                                    "new declaration %q#D ambiguates 
> built-in"
> +                                    " declaration %q#D", newdecl, olddecl)
> +                         && flag_permissive)
> +                       inform (DECL_SOURCE_LOCATION (newdecl),
> +                               "ignoring the %q#D declaration", newdecl);
> +                     return olddecl;
> +                   }
> +               }
> +
>               /* A near match; override the builtin.  */
>
>               if (TREE_PUBLIC (newdecl))
> --- gcc/testsuite/g++.dg/ext/pr84724-1.C.jj     2018-03-09 11:44:49.037993207 
> +0100
> +++ gcc/testsuite/g++.dg/ext/pr84724-1.C        2018-03-09 11:57:11.599204801 
> +0100
> @@ -0,0 +1,14 @@
> +// PR c++/84724
> +// { dg-do compile }
> +// { dg-options "-O3 -fpermissive" }
> +
> +int __builtin_trap ();         // { dg-warning "ambiguates built-in 
> declaration" }
> +                               // { dg-message "ignoring the 'int 
> __builtin_trap\\(\\)' declaration" "" { target *-*-* } .-1 }
> +
> +int
> +foo ()
> +{
> +  int b;
> +  int c (&b);                  // { dg-warning "invalid conversion from" }
> +  return b %= b ? c : 0;
> +}
> --- gcc/testsuite/g++.dg/ext/pr84724-2.C.jj     2018-03-09 11:57:26.017208398 
> +0100
> +++ gcc/testsuite/g++.dg/ext/pr84724-2.C        2018-03-09 11:57:40.775212078 
> +0100
> @@ -0,0 +1,14 @@
> +// PR c++/84724
> +// { dg-do compile }
> +// { dg-options "-O3 -fpermissive -w" }
> +
> +int __builtin_trap ();         // { dg-bogus "ambiguates built-in 
> declaration" }
> +                               // { dg-bogus "ignoring the 'int 
> __builtin_trap\\(\\)' declaration" "" { target *-*-* } .-1 }
> +
> +int
> +foo ()
> +{
> +  int b;
> +  int c (&b);                  // { dg-bogus "invalid conversion from" }
> +  return b %= b ? c : 0;
> +}
> --- gcc/testsuite/g++.dg/ext/pr84724-3.C.jj     2018-03-09 11:57:50.000214382 
> +0100
> +++ gcc/testsuite/g++.dg/ext/pr84724-3.C        2018-03-09 11:58:10.797219571 
> +0100
> @@ -0,0 +1,5 @@
> +// PR c++/84724
> +// { dg-do compile }
> +// { dg-options "" }
> +
> +int __builtin_trap ();         // { dg-error "ambiguates built-in 
> declaration" }
>
>
>         Jakub

Reply via email to