public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug other/107618] New: Incorrect diagnostics when using -Og, builtin_expect(), and function attribute "warning" or "error"
@ 2022-11-10 15:42 yann at droneaud dot fr
  2022-11-10 17:21 ` [Bug middle-end/107618] " yann at droneaud dot fr
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: yann at droneaud dot fr @ 2022-11-10 15:42 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107618

            Bug ID: 107618
           Summary: Incorrect diagnostics when using -Og,
                    builtin_expect(), and function attribute "warning" or
                    "error"
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: other
          Assignee: unassigned at gcc dot gnu.org
          Reporter: yann at droneaud dot fr
  Target Milestone: ---

Created attachment 53872
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53872&action=edit
reproducer for -Og, __builtin_expect(), and function
__attribute__((warning("")))

The code below compiled with -Og triggers a warning message that is not
mandated:

    $ gcc -Og  warning.c
    warning.c: In function ‘test_expect’:
    warning.c:26:17: warning: call to ‘size_mismatch_expect’ declared with
attribute warning: size mismatch (builtin_expect) [-Wattribute-warning]
       26 |                 size_mismatch_expect();
          |                 ^~~~~~~~~~~~~~~~~~~~~~


    $ cat warning.c
    #include <stdbool.h>
    #include <stddef.h>
    #include <stdlib.h>

    extern void size_mismatch_nonexpect(void)
    __attribute__((__warning__("size mismatch")));

    static bool
    test_nonexpect(const void *addr, size_t len)
    {
            size_t sz = __builtin_object_size(addr, 0);
            if (sz != (size_t)-1 && sz < len) {
                    size_mismatch_nonexpect();
                    return false;
            }

            return true;
    }

    extern void size_mismatch_expect(void)
    __attribute__((__warning__("size mismatch (builtin_expect)")));

    static bool
    test_expect(const void *addr, size_t len)
    {
            size_t sz = __builtin_object_size(addr, 0);
            if (__builtin_expect(sz != (size_t)-1 && sz < len, 0)) {
                    size_mismatch_expect();
                    return false;
            }

            return true;
    }

    int main(void)
    {
            int i = 0;

            if (!test_nonexpect(&i, sizeof(i)))
                    return EXIT_FAILURE;

            if (!test_expect(&i, sizeof(i)))
                    return EXIT_FAILURE;

            return EXIT_SUCCESS;
    }

The warning at -Og level is not expected because there's no call to the
size_mismatch_expect() in the generated assembler (for x86-64):

    $ head warning.s
            .file        "warning.c"
            .text
            .type        test_nonexpect, @function
    test_nonexpect:
            movl        $1, %eax
            ret
            .size        test_nonexpect, .-test_nonexpect
            .type        test_expect, @function
    test_expect:
            movl        $1, %eax
            ret
            .size        test_expect, .-test_expect
            .globl        main
            .type        main, @function
    main:
            endbr64
            subq        $24, %rsp
            movq        %fs:40, %rax
            movq        %rax, 8(%rsp)
            xorl        %eax, %eax
            movl        $0, 4(%rsp)
            leaq        4(%rsp), %rdi
            movl        $4, %esi
            call        test_nonexpect
            testb        %al, %al
            jne        .L11
            movl        $1, %eax
    .L5:
            movq        8(%rsp), %rdx
            subq        %fs:40, %rdx
            jne        .L12
            addq        $24, %rsp
            ret
    .L11:
            leaq        4(%rsp), %rdi
            movl        $4, %esi
            call        test_expect
            testb        %al, %al
            je        .L9
            movl        $0, %eax
            jmp        .L5
    .L9:
            movl        $1, %eax
            jmp        .L5


See also https://godbolt.org/z/KEsaavhvG

Compiling at optimization level s, z, 1, 2, or 3 doesn't produce that warning.
(but compiling with -O0 does produces two warnings, as expected, since calls to
the two functions are emitted).

Having the warning at debug optimization level makes using -Og in some complex
code base challenging for no good reason when __attribute__((error(""))) is
used (or -Werror=attribute-warning).

It should also be noted clang doesn't generate the warning for optimization
level above 0.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug middle-end/107618] Incorrect diagnostics when using -Og, builtin_expect(), and function attribute "warning" or "error"
  2022-11-10 15:42 [Bug other/107618] New: Incorrect diagnostics when using -Og, builtin_expect(), and function attribute "warning" or "error" yann at droneaud dot fr
@ 2022-11-10 17:21 ` yann at droneaud dot fr
  2022-11-10 17:45 ` yann at droneaud dot fr
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: yann at droneaud dot fr @ 2022-11-10 17:21 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107618

Yann Droneaud <yann at droneaud dot fr> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |yann at droneaud dot fr

--- Comment #1 from Yann Droneaud <yann at droneaud dot fr> ---
A smallest reproducer (generated with some help from C-reduce):

    void a(void) __attribute__((__warning__("")));
    int main(void) {
      unsigned long b = __builtin_object_size(0, 0);
      if (__builtin_expect(b < 1, 0))
        a();
    }

Works at all level above -00, except -Og:

    $ gcc -Og warning.c
    warning.c: In function ‘main’:
    warning.c:5:5: warning: call to ‘a’ declared with attribute warning: 
[-Wattribute-warning]
        5 |     a();
          |     ^~~

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug middle-end/107618] Incorrect diagnostics when using -Og, builtin_expect(), and function attribute "warning" or "error"
  2022-11-10 15:42 [Bug other/107618] New: Incorrect diagnostics when using -Og, builtin_expect(), and function attribute "warning" or "error" yann at droneaud dot fr
  2022-11-10 17:21 ` [Bug middle-end/107618] " yann at droneaud dot fr
@ 2022-11-10 17:45 ` yann at droneaud dot fr
  2022-11-11  7:47 ` [Bug tree-optimization/107618] " rguenth at gcc dot gnu.org
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: yann at droneaud dot fr @ 2022-11-10 17:45 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107618

--- Comment #2 from Yann Droneaud <yann at droneaud dot fr> ---
I was wondering what GCC expects __builtin_object_size(0, 0) to be, and used
the following:

    void a_1 (void) __attribute__((__warning__("-1")));
    void a0 (void) __attribute__((__warning__("0")));
    void a1 (void) __attribute__((__warning__("1")));
    void a2 (void) __attribute__((__warning__("2")));
    void a3 (void) __attribute__((__warning__("3")));
    void a4 (void) __attribute__((__warning__("4")));

    int main(void) {
      unsigned long b = __builtin_object_size(0, 0);
      if (__builtin_expect(b == (unsigned long)-1, 0))
        a_1();
      if (__builtin_expect(b == 0, 0))
        a0();
      if (__builtin_expect(b == 1, 0))
        a1();
      if (__builtin_expect(b == 2, 0))
        a2();
      if (__builtin_expect(b == 3, 0))
        a3();
      if (__builtin_expect(b == 4, 0))
        a4();
    }

It works as expected for any level above 0, except -Og:

    $ gcc -O1 -S warning.c
    warning.c: In function ‘main’:
    warning.c:11:5: warning: call to ‘a_1’ declared with attribute warning: -1
[-Wattribute-warning]
       11 |     a_1();
          |     ^~~~~

It's quite reassuring that __builtin_object_size(0, 0) returns -1, hence the
emitted call to a_1():

    $ cat warning.s
            .file        "warning.c"
            .text
            .globl        main
            .type        main, @function
    main:
            endbr64
            subq        $8, %rsp
            call        a_1@PLT
            movl        $0, %eax
            addq        $8, %rsp
            ret

For -Og, there's a firework of warnings (shockingly they're the same than -O0
level):

    $ gcc -Og -S warning.c
    warning.c: In function ‘main’:
    warning.c:11:5: warning: call to ‘a_1’ declared with attribute warning: -1
[-Wattribute-warning]
       11 |     a_1();
          |     ^~~~~
    warning.c:13:5: warning: call to ‘a0’ declared with attribute warning: 0
[-Wattribute-warning]
       13 |     a0();
          |     ^~~~
    warning.c:15:5: warning: call to ‘a1’ declared with attribute warning: 1
[-Wattribute-warning]
       15 |     a1();
          |     ^~~~
    warning.c:17:5: warning: call to ‘a2’ declared with attribute warning: 2
[-Wattribute-warning]
       17 |     a2();
          |     ^~~~
    warning.c:19:5: warning: call to ‘a3’ declared with attribute warning: 3
[-Wattribute-warning]
       19 |     a3();
          |     ^~~~
    warning.c:21:5: warning: call to ‘a4’ declared with attribute warning: 4
[-Wattribute-warning]
       21 |     a4();
          |     ^~~~

Generated assembly for -Og is the same than for levels above 0: a call to a_1()
function is emitted, which mean GCC, at some point, knows
__builtin_object_size(0, 0) is -1 here. Thus most of the warnings are not very
useful.

    $ cat warning.s
            .file        "warning.c"
            .text
            .globl        main
            .type        main, @function
    main:
            endbr64
            subq        $8, %rsp
            call        a_1@PLT
            movl        $0, %eax
            addq        $8, %rsp
            ret

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug tree-optimization/107618] Incorrect diagnostics when using -Og, builtin_expect(), and function attribute "warning" or "error"
  2022-11-10 15:42 [Bug other/107618] New: Incorrect diagnostics when using -Og, builtin_expect(), and function attribute "warning" or "error" yann at droneaud dot fr
  2022-11-10 17:21 ` [Bug middle-end/107618] " yann at droneaud dot fr
  2022-11-10 17:45 ` yann at droneaud dot fr
@ 2022-11-11  7:47 ` rguenth at gcc dot gnu.org
  2022-11-11 13:32 ` cvs-commit at gcc dot gnu.org
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-11-11  7:47 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107618

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |ASSIGNED
            Version|unknown                     |13.0
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot gnu.org
   Last reconfirmed|                            |2022-11-11
           Keywords|                            |diagnostic
          Component|middle-end                  |tree-optimization
     Ever confirmed|0                           |1

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
We diagnose because we see

int main ()
{
  long int _2;

  <bb 2> [local count: 1073741824]:
  _2 = 0;
  if (_2 != 0)
    goto <bb 3>; [10.00%]
  else
    goto <bb 4>; [90.00%]

  <bb 3> [local count: 107374184]:
  a ();

  <bb 4> [local count: 1073741824]:
  return 0;

}

and the reason is that for some reason

      /* Copy propagation also copy-propagates constants, this is necessary
         to forward object-size and builtin folding results properly.  */
      NEXT_PASS (pass_copy_prop);

doesn't work:

--- a-t2.c.224t.strlen2 2022-11-11 08:44:14.044322291 +0100
+++ a-t2.c.225t.copyprop5       2022-11-11 08:44:14.044322291 +0100
...
   <bb 2> [local count: 1073741824]:
   b_5 = __builtin_object_size (0B, 0);
-  _1 = 0;
-  _2 = (long int) _1;
+  _2 = 0;
   if (_2 != 0)
     goto <bb 3>; [10.00%]
   else

I will have a look.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug tree-optimization/107618] Incorrect diagnostics when using -Og, builtin_expect(), and function attribute "warning" or "error"
  2022-11-10 15:42 [Bug other/107618] New: Incorrect diagnostics when using -Og, builtin_expect(), and function attribute "warning" or "error" yann at droneaud dot fr
                   ` (2 preceding siblings ...)
  2022-11-11  7:47 ` [Bug tree-optimization/107618] " rguenth at gcc dot gnu.org
@ 2022-11-11 13:32 ` cvs-commit at gcc dot gnu.org
  2022-11-11 13:33 ` rguenth at gcc dot gnu.org
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2022-11-11 13:32 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107618

--- Comment #4 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Richard Biener <rguenth@gcc.gnu.org>:

https://gcc.gnu.org/g:af96500eea72c674a5686b35c66202ef2bd9688f

commit r13-3898-gaf96500eea72c674a5686b35c66202ef2bd9688f
Author: Richard Biener <rguenther@suse.de>
Date:   Fri Nov 11 10:12:28 2022 +0100

    tree-optimization/107618 - enhance copy propagation of constants

    The following enhances copy propagation of constants to also see
    through simple operations like conversions but also operations with
    otherwise constant operands.  That's required to fulfill the promise

          /* Copy propagation also copy-propagates constants, this is necessary
             to forward object-size and builtin folding results properly.  */
          NEXT_PASS (pass_copy_prop);

    and avoid false diagnostics as shown in the testcase.  We're
    using gimple_fold_stmt_to_constant_1 with not following SSA edges
    and accordingly adjust what stmts we simulate during SSA propagation.

            PR tree-optimization/107618
            * tree-ssa-copy.cc (stmt_may_generate_copy): Simulate all
            assignments with a single SSA use.
            (copy_prop_visit_assignment): Use gimple_fold_stmt_to_constant_1
            to perform simple constant folding.
            (copy_prop::visit_stmt): Visit all assignments.

            * gcc.dg/pr107618.c: New testcase.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug tree-optimization/107618] Incorrect diagnostics when using -Og, builtin_expect(), and function attribute "warning" or "error"
  2022-11-10 15:42 [Bug other/107618] New: Incorrect diagnostics when using -Og, builtin_expect(), and function attribute "warning" or "error" yann at droneaud dot fr
                   ` (3 preceding siblings ...)
  2022-11-11 13:32 ` cvs-commit at gcc dot gnu.org
@ 2022-11-11 13:33 ` rguenth at gcc dot gnu.org
  2022-11-11 14:37 ` yann at droneaud dot fr
  2022-11-28 22:19 ` pinskia at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-11-11 13:33 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107618

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
      Known to work|                            |13.0
             Status|ASSIGNED                    |RESOLVED
         Resolution|---                         |FIXED
      Known to fail|                            |12.2.0, 4.8.5, 7.5.0

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
Should be fixed for GCC 13, it doesn't seem to be a regression.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug tree-optimization/107618] Incorrect diagnostics when using -Og, builtin_expect(), and function attribute "warning" or "error"
  2022-11-10 15:42 [Bug other/107618] New: Incorrect diagnostics when using -Og, builtin_expect(), and function attribute "warning" or "error" yann at droneaud dot fr
                   ` (4 preceding siblings ...)
  2022-11-11 13:33 ` rguenth at gcc dot gnu.org
@ 2022-11-11 14:37 ` yann at droneaud dot fr
  2022-11-28 22:19 ` pinskia at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: yann at droneaud dot fr @ 2022-11-11 14:37 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107618

--- Comment #6 from Yann Droneaud <yann at droneaud dot fr> ---
(In reply to Richard Biener from comment #5)
> Should be fixed for GCC 13, it doesn't seem to be a regression.

I've tested with a fresh rebuild of GCC's trunk, and the warning is no more
reported at -Og level.

Thanks.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug tree-optimization/107618] Incorrect diagnostics when using -Og, builtin_expect(), and function attribute "warning" or "error"
  2022-11-10 15:42 [Bug other/107618] New: Incorrect diagnostics when using -Og, builtin_expect(), and function attribute "warning" or "error" yann at droneaud dot fr
                   ` (5 preceding siblings ...)
  2022-11-11 14:37 ` yann at droneaud dot fr
@ 2022-11-28 22:19 ` pinskia at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-11-28 22:19 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107618

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|---                         |13.0

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2022-11-28 22:19 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-10 15:42 [Bug other/107618] New: Incorrect diagnostics when using -Og, builtin_expect(), and function attribute "warning" or "error" yann at droneaud dot fr
2022-11-10 17:21 ` [Bug middle-end/107618] " yann at droneaud dot fr
2022-11-10 17:45 ` yann at droneaud dot fr
2022-11-11  7:47 ` [Bug tree-optimization/107618] " rguenth at gcc dot gnu.org
2022-11-11 13:32 ` cvs-commit at gcc dot gnu.org
2022-11-11 13:33 ` rguenth at gcc dot gnu.org
2022-11-11 14:37 ` yann at droneaud dot fr
2022-11-28 22:19 ` pinskia at gcc dot gnu.org

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