public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/61236] New: GCC 4.9 generates incorrect object code
@ 2014-05-19 17:39 muks at banu dot com
  2014-05-19 17:46 ` [Bug c/61236] " muks at banu dot com
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: muks at banu dot com @ 2014-05-19 17:39 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 61236
           Summary: GCC 4.9 generates incorrect object code
           Product: gcc
           Version: 4.9.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: muks at banu dot com

Hi all

This is a bug report from the BIND DNS project team at ISC.org. We have
a report to make of buggy code generated with GCC 4.9.0, and we request
a C compiler developer to take a look.

For the purpose of this ticket, you will have to look at source
code. All code mentioned here is under the ISC license (free software
license equivalent to MIT license). I have not been successful in making
an isolated testcase, but I'll instead describe our analysis.


The bug first was reported a few days ago on the Arch Linux bug tracker
against BIND 9.10.0: https://bugs.archlinux.org/task/40304

They had recently switched the system gcc compiler to:
gcc version 4.9.1 20140507 (prerelease) (GCC)

and built the BIND package with this compiler.

We had not seen such a crash on any of our builders or even our
development environments. When we looked at it, it was an assertion
being triggered in code that is similar to this:

----

void
crashing_function(void) {

   /* some code */

   if (some_condition) {
       goto free_and_exit;
   }

   /* some more code */

free_and_exit:
   if (ptr != NULL) {
       internal_mem_free(ptr, sizeof_ptr);
   }
}

void
internal_mem_free(void *ptr, size_t size) {
   assert(ptr != NULL);

   UNUSED(size);
   free(ptr);
}

----

>From the above, it is obvious that the assertion inside
internal_mem_free() cannot fail. Yet this is what is happening and is
the bug.

You can find the code in question here:
ftp://ftp.isc.org/isc/bind9/9.10.0-P1/bind-9.10.0-P1.tar.gz

Open dns_rdataslab_fromrdataset()'s definition in lib/dns/rdataslab.c.
It has the following code at the end of the function:

----

 free_rdatas:
        if (x != NULL)
                isc_mem_put(mctx, x, nalloc * sizeof(struct xrdata));
        return (result);
}

----

The isc__mem_put() function [called by isc_mem_put() macro] asserts that
x is not NULL as a prerequisite, and this assertion fails.

The bug has also been reported on other operating systems such as LFS
and also Fedora 20 with a locally built GCC 4.9.  If you need any help
in compiling the BIND tree, please ask us via email, or in #bind on
irc.freenode.net, but it should be as simple as ./configure && make.

Running the 'dnssec' system test will reproduce the assertion
failure. If you want help on running the test too, please ask.

To run the system test after successful configure and make, you'll have
to run (as root):

# sh bin/tests/system/ifconfig.sh up

to setup local interface addresses that the tests use.

Then (as a user):

$ cd bin/tests/system/
$ #ulimit -c unlimited # if necessary, to dump core
$ sh ./run.sh dnssec

Core files should be inside bin/tests/system/dnssec/ tree after the
assertion fails.

I'll follow up with an analysis of the generated x86_64 object code for
dns_rdataslab_fromrdataset() from our internal bug tracker that points
out the bug in generated object code.


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

* [Bug c/61236] GCC 4.9 generates incorrect object code
  2014-05-19 17:39 [Bug c/61236] New: GCC 4.9 generates incorrect object code muks at banu dot com
@ 2014-05-19 17:46 ` muks at banu dot com
  2014-05-19 17:49 ` muks at banu dot com
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: muks at banu dot com @ 2014-05-19 17:46 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Mukund Sivaraman <muks at banu dot com> ---
The following is _correct_ generated x8t_64 code for
dns_rdataslab_fromrdataset() as compiled with:

gcc version 4.8.2 20131212 (Red Hat 4.8.2-7) (GCC)

Under free_rdatas label, you can see that there is a 0 check for x
(%r14) as in the C code. It was not deleted by the compiler.

0000000000521450 <dns_rdataslab_fromrdataset>:

; find dns_rdata_set_first() call below:

  521450:       41 57                   push   %r15
  521452:       49 89 f7                mov    %rsi,%r15
  521455:       41 56                   push   %r14
  521457:       41 55                   push   %r13
  521459:       41 54                   push   %r12
  52145b:       49 89 fc                mov    %rdi,%r12
  52145e:       55                      push   %rbp
  52145f:       53                      push   %rbx
  521460:       48 83 ec 38             sub    $0x38,%rsp
  521464:       48 89 54 24 10          mov    %rdx,0x10(%rsp)
  521469:       89 4c 24 0c             mov    %ecx,0xc(%rsp)
  52146d:       e8 ce e7 ff ff          callq  51fc40 <dns_rdataset_count>
  521472:       41 89 c5                mov    %eax,%r13d
  521475:       45 85 ed                test   %r13d,%r13d
  521478:       75 26                   jne    5214a0
<dns_rdataslab_fromrdataset+0x50>
  52147a:       45 31 f6                xor    %r14d,%r14d
  52147d:       66 41 83 7c 24 22 00    cmpw   $0x0,0x22(%r12)
  521484:       b8 19 00 00 00          mov    $0x19,%eax
  521489:       74 4c                   je     5214d7
<dns_rdataslab_fromrdataset+0x87>
  52148b:       48 83 c4 38             add    $0x38,%rsp
  52148f:       5b                      pop    %rbx
  521490:       5d                      pop    %rbp
  521491:       41 5c                   pop    %r12
  521493:       41 5d                   pop    %r13
  521495:       41 5e                   pop    %r14
  521497:       41 5f                   pop    %r15
  521499:       c3                      retq   
  52149a:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
  5214a0:       41 81 fd ff ff 00 00    cmp    $0xffff,%r13d
  5214a7:       b8 13 00 00 00          mov    $0x13,%eax
  5214ac:       77 dd                   ja     52148b
<dns_rdataslab_fromrdataset+0x3b>
  5214ae:       44 89 e8                mov    %r13d,%eax
  5214b1:       b9 a1 00 00 00          mov    $0xa1,%ecx
  5214b6:       ba eb 20 64 00          mov    $0x6420eb,%edx
  5214bb:       48 8d 34 40             lea    (%rax,%rax,2),%rsi
  5214bf:       4c 89 ff                mov    %r15,%rdi
  5214c2:       48 c1 e6 04             shl    $0x4,%rsi
  5214c6:       e8 45 c2 0a 00          callq  5cd710 <isc__mem_get>
  5214cb:       48 85 c0                test   %rax,%rax
  5214ce:       49 89 c6                mov    %rax,%r14
  5214d1:       0f 84 a7 00 00 00       je     52157e
<dns_rdataslab_fromrdataset+0x12e>
  5214d7:       4c 89 e7                mov    %r12,%rdi

;       result = dns_rdataset_first(rdataset);

  5214da:       e8 41 e8 ff ff          callq  51fd20 <dns_rdataset_first>

;       if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE)
;               goto free_rdatas;

; 0x1d (ISC_R_NOMORE)

  5214df:       83 f8 1d                cmp    $0x1d,%eax
  5214e2:       74 04                   je     5214e8
<dns_rdataslab_fromrdataset+0x98>

; 0x0 (ISC_R_SUCCESS).  if (result != ISC_R_SUCCESS && result !=
; ISC_R_NOMORE), jmp to 52153f (free_rdatas) below.

;; test instruction does logical AND of operands and sets zero flag if
;; %eax is 0. jne (same as jnz) tests ZF and performs conditional jump
;; if ZF=0.

  5214e4:       85 c0                   test   %eax,%eax
  5214e6:       75 57                   jne    52153f
<dns_rdataslab_fromrdataset+0xef>

; go below to free_rdatas.

; ignore: for loop

  5214e8:       31 db                   xor    %ebx,%ebx
  5214ea:       85 c0                   test   %eax,%eax
  5214ec:       75 4c                   jne    52153a
<dns_rdataslab_fromrdataset+0xea>
  5214ee:       45 85 ed                test   %r13d,%r13d
  5214f1:       75 0a                   jne    5214fd
<dns_rdataslab_fromrdataset+0xad>
  5214f3:       eb 45                   jmp    52153a
<dns_rdataslab_fromrdataset+0xea>
  5214f5:       0f 1f 00                nopl   (%rax)

; ignore: for loop iterate (continue;)

  5214f8:       41 39 dd                cmp    %ebx,%r13d
  5214fb:       76 3d                   jbe    52153a
<dns_rdataslab_fromrdataset+0xea>
  5214fd:       89 d8                   mov    %ebx,%eax
  5214ff:       48 8d 2c 40             lea    (%rax,%rax,2),%rbp
  521503:       48 c1 e5 04             shl    $0x4,%rbp
  521507:       4c 01 f5                add    %r14,%rbp
  52150a:       48 89 ef                mov    %rbp,%rdi
  52150d:       e8 4e 9e fd ff          callq  4fb360 <dns_rdata_init>
  521512:       48 89 ee                mov    %rbp,%rsi
  521515:       4c 89 e7                mov    %r12,%rdi
  521518:       e8 a3 e8 ff ff          callq  51fdc0 <dns_rdataset_current>

; Second INSIST() inside for loop. First INSIST() is redundant.
  52151d:       48 81 7d 00 a8 c6 8b    cmpq   $0x8bc6a8,0x0(%rbp)
  521524:       00 
  521525:       0f 84 00 02 00 00       je     52172b
<dns_rdataslab_fromrdataset+0x2db>

  52152b:       4c 89 e7                mov    %r12,%rdi
  52152e:       83 c3 01                add    $0x1,%ebx
  521531:       e8 3a e8 ff ff          callq  51fd70 <dns_rdataset_next>
  521536:       85 c0                   test   %eax,%eax
  521538:       74 be                   je     5214f8
<dns_rdataslab_fromrdataset+0xa8>
  52153a:       83 f8 1d                cmp    $0x1d,%eax
  52153d:       74 49                   je     521588
<dns_rdataslab_fromrdataset+0x138>

;  free_rdatas:
;        if (x != NULL)
;                isc_mem_put(mctx, x, nalloc * sizeof(struct xrdata));
;        return (result);

  52153f:       4d 85 f6                test   %r14,%r14
  521542:       0f 84 43 ff ff ff       je     52148b
<dns_rdataslab_fromrdataset+0x3b>

; x is not NULL. Call isc__mem_put(), pop frame and return:

  521548:       4b 8d 54 6d 00          lea    0x0(%r13,%r13,2),%rdx
  52154d:       4c 89 f6                mov    %r14,%rsi
  521550:       4c 89 ff                mov    %r15,%rdi
  521553:       41 b8 4e 01 00 00       mov    $0x14e,%r8d
  521559:       b9 eb 20 64 00          mov    $0x6420eb,%ecx
  52155e:       89 44 24 0c             mov    %eax,0xc(%rsp)
  521562:       48 c1 e2 04             shl    $0x4,%rdx
  521566:       e8 85 d2 0a 00          callq  5ce7f0 <isc__mem_put>
  52156b:       8b 44 24 0c             mov    0xc(%rsp),%eax
  52156f:       48 83 c4 38             add    $0x38,%rsp
  521573:       5b                      pop    %rbx
  521574:       5d                      pop    %rbp
  521575:       41 5c                   pop    %r12
  521577:       41 5d                   pop    %r13
  521579:       41 5e                   pop    %r14
  52157b:       41 5f                   pop    %r15
  52157d:       c3                      retq   

; ... you can skip the rest of this comment.

  52157e:       b8 01 00 00 00          mov    $0x1,%eax
  521583:       e9 03 ff ff ff          jmpq   52148b
<dns_rdataslab_fromrdataset+0x3b>
  521588:       44 39 eb                cmp    %r13d,%ebx
  52158b:       b0 19                   mov    $0x19,%al
  52158d:       75 b0                   jne    52153f
<dns_rdataslab_fromrdataset+0xef>
  52158f:       8b 44 24 0c             mov    0xc(%rsp),%eax
  521593:       89 de                   mov    %ebx,%esi
  521595:       b9 c0 13 52 00          mov    $0x5213c0,%ecx
  52159a:       ba 30 00 00 00          mov    $0x30,%edx
  52159f:       4c 89 f7                mov    %r14,%rdi
  5215a2:       8d 68 02                lea    0x2(%rax),%ebp
  5215a5:       e8 86 57 ee ff          callq  406d30 <qsort@plt>
  5215aa:       83 fb 01                cmp    $0x1,%ebx
  5215ad:       0f 86 91 01 00 00       jbe    521744
<dns_rdataslab_fromrdataset+0x2f4>
  5215b3:       4c 89 f2                mov    %r14,%rdx
  5215b6:       89 5c 24 2c             mov    %ebx,0x2c(%rsp)
  5215ba:       b9 01 00 00 00          mov    $0x1,%ecx
  5215bf:       eb 16                   jmp    5215d7
<dns_rdataslab_fromrdataset+0x187>
  5215c1:       83 6c 24 2c 01          subl   $0x1,0x2c(%rsp)
  5215c6:       48 c7 02 a8 c6 8b 00    movq   $0x8bc6a8,(%rdx)
  5215cd:       83 c1 01                add    $0x1,%ecx
  5215d0:       39 d9                   cmp    %ebx,%ecx
  5215d2:       74 49                   je     52161d
<dns_rdataslab_fromrdataset+0x1cd>
  5215d4:       4c 89 c2                mov    %r8,%rdx
  5215d7:       4c 8d 42 30             lea    0x30(%rdx),%r8
  5215db:       48 89 d7                mov    %rdx,%rdi
  5215de:       89 4c 24 28             mov    %ecx,0x28(%rsp)
  5215e2:       48 89 54 24 18          mov    %rdx,0x18(%rsp)
  5215e7:       4c 89 c6                mov    %r8,%rsi
  5215ea:       4c 89 44 24 20          mov    %r8,0x20(%rsp)
  5215ef:       e8 8c d3 fd ff          callq  4fe980 <dns_rdata_compare>
  5215f4:       85 c0                   test   %eax,%eax
  5215f6:       48 8b 54 24 18          mov    0x18(%rsp),%rdx
  5215fb:       4c 8b 44 24 20          mov    0x20(%rsp),%r8
  521600:       8b 4c 24 28             mov    0x28(%rsp),%ecx
  521604:       74 bb                   je     5215c1
<dns_rdataslab_fromrdataset+0x171>
  521606:       8b 42 08                mov    0x8(%rdx),%eax
  521609:       01 e8                   add    %ebp,%eax
  52160b:       8d 68 02                lea    0x2(%rax),%ebp
  52160e:       83 c0 03                add    $0x3,%eax
  521611:       66 41 83 7c 24 22 2e    cmpw   $0x2e,0x22(%r12)
  521618:       0f 44 e8                cmove  %eax,%ebp
  52161b:       eb b0                   jmp    5215cd
<dns_rdataslab_fromrdataset+0x17d>
  52161d:       89 d8                   mov    %ebx,%eax
  52161f:       83 e8 01                sub    $0x1,%eax
  521622:       48 8d 04 40             lea    (%rax,%rax,2),%rax
  521626:       48 c1 e0 04             shl    $0x4,%rax
  52162a:       41 8b 44 06 08          mov    0x8(%r14,%rax,1),%eax
  52162f:       8d 6c 05 02             lea    0x2(%rbp,%rax,1),%ebp
  521633:       41 0f b7 44 24 22       movzwl 0x22(%r12),%eax
  521639:       31 d2                   xor    %edx,%edx
  52163b:       66 83 f8 2e             cmp    $0x2e,%ax
  52163f:       0f 94 c2                sete   %dl
  521642:       01 d5                   add    %edx,%ebp
  521644:       83 7c 24 2c 01          cmpl   $0x1,0x2c(%rsp)
  521649:       76 16                   jbe    521661
<dns_rdataslab_fromrdataset+0x211>
  52164b:       0f b7 f8                movzwl %ax,%edi
  52164e:       e8 3d d7 ff ff          callq  51ed90
<dns_rdatatype_issingleton>
  521653:       85 c0                   test   %eax,%eax
  521655:       74 0a                   je     521661
<dns_rdataslab_fromrdataset+0x211>
  521657:       b8 48 00 01 00          mov    $0x10048,%eax
  52165c:       e9 de fe ff ff          jmpq   52153f
<dns_rdataslab_fromrdataset+0xef>
  521661:       89 ee                   mov    %ebp,%esi
  521663:       b9 0a 01 00 00          mov    $0x10a,%ecx
  521668:       ba eb 20 64 00          mov    $0x6420eb,%edx
  52166d:       4c 89 ff                mov    %r15,%rdi
  521670:       e8 9b c0 0a 00          callq  5cd710 <isc__mem_get>
  521675:       48 85 c0                test   %rax,%rax
  521678:       0f 84 d7 00 00 00       je     521755
<dns_rdataslab_fromrdataset+0x305>
  52167e:       48 8b 4c 24 10          mov    0x10(%rsp),%rcx
  521683:       8b 54 24 0c             mov    0xc(%rsp),%edx
  521687:       8b 74 24 2c             mov    0x2c(%rsp),%esi
  52168b:       48 89 01                mov    %rax,(%rcx)
  52168e:       89 69 08                mov    %ebp,0x8(%rcx)
  521691:       48 89 f1                mov    %rsi,%rcx
  521694:       48 01 d0                add    %rdx,%rax
  521697:       85 db                   test   %ebx,%ebx
  521699:       0f b6 d5                movzbl %ch,%edx
  52169c:       40 88 70 01             mov    %sil,0x1(%rax)
  5216a0:       88 10                   mov    %dl,(%rax)
  5216a2:       48 8d 50 02             lea    0x2(%rax),%rdx
  5216a6:       74 7c                   je     521724
<dns_rdataslab_fromrdataset+0x2d4>
  5216a8:       83 eb 01                sub    $0x1,%ebx
  5216ab:       4c 89 f5                mov    %r14,%rbp
  5216ae:       48 8d 04 5b             lea    (%rbx,%rbx,2),%rax
  5216b2:       48 c1 e0 04             shl    $0x4,%rax
  5216b6:       49 8d 5c 06 30          lea    0x30(%r14,%rax,1),%rbx
  5216bb:       eb 21                   jmp    5216de
<dns_rdataslab_fromrdataset+0x28e>
  5216bd:       0f 1f 00                nopl   (%rax)
  5216c0:       8b 55 08                mov    0x8(%rbp),%edx
  5216c3:       48 8b 75 00             mov    0x0(%rbp),%rsi
  5216c7:       48 89 cf                mov    %rcx,%rdi
  5216ca:       e8 11 54 ee ff          callq  406ae0 <memmove@plt>
  5216cf:       8b 55 08                mov    0x8(%rbp),%edx
  5216d2:       48 01 c2                add    %rax,%rdx
  5216d5:       48 83 c5 30             add    $0x30,%rbp
  5216d9:       48 39 dd                cmp    %rbx,%rbp
  5216dc:       74 46                   je     521724
<dns_rdataslab_fromrdataset+0x2d4>
  5216de:       48 81 7d 00 a8 c6 8b    cmpq   $0x8bc6a8,0x0(%rbp)
  5216e5:       00 
  5216e6:       74 ed                   je     5216d5
<dns_rdataslab_fromrdataset+0x285>
  5216e8:       31 c0                   xor    %eax,%eax
  5216ea:       66 41 83 7c 24 22 2e    cmpw   $0x2e,0x22(%r12)
  5216f1:       0f 94 c0                sete   %al
  5216f4:       03 45 08                add    0x8(%rbp),%eax
  5216f7:       3d ff ff 00 00          cmp    $0xffff,%eax
  5216fc:       77 61                   ja     52175f
<dns_rdataslab_fromrdataset+0x30f>
  5216fe:       0f b6 cc                movzbl %ah,%ecx
  521701:       88 42 01                mov    %al,0x1(%rdx)
  521704:       88 0a                   mov    %cl,(%rdx)
  521706:       66 41 83 7c 24 22 2e    cmpw   $0x2e,0x22(%r12)
  52170d:       48 8d 4a 02             lea    0x2(%rdx),%rcx
  521711:       75 ad                   jne    5216c0
<dns_rdataslab_fromrdataset+0x270>
  521713:       8b 45 10                mov    0x10(%rbp),%eax
  521716:       48 8d 4a 03             lea    0x3(%rdx),%rcx
  52171a:       d1 e8                   shr    %eax
  52171c:       83 e0 01                and    $0x1,%eax
  52171f:       08 42 02                or     %al,0x2(%rdx)
  521722:       eb 9c                   jmp    5216c0
<dns_rdataslab_fromrdataset+0x270>
  521724:       31 c0                   xor    %eax,%eax
  521726:       e9 14 fe ff ff          jmpq   52153f
<dns_rdataslab_fromrdataset+0xef>
  52172b:       b9 f7 20 64 00          mov    $0x6420f7,%ecx
  521730:       ba 02 00 00 00          mov    $0x2,%edx
  521735:       be b1 00 00 00          mov    $0xb1,%esi
  52173a:       bf eb 20 64 00          mov    $0x6420eb,%edi
  52173f:       e8 dc 92 09 00          callq  5baa20 <isc_assertion_failed>
  521744:       85 db                   test   %ebx,%ebx
  521746:       75 30                   jne    521778
<dns_rdataslab_fromrdataset+0x328>
  521748:       c7 44 24 2c 00 00 00    movl   $0x0,0x2c(%rsp)
  52174f:       00 
  521750:       e9 de fe ff ff          jmpq   521633
<dns_rdataslab_fromrdataset+0x1e3>
  521755:       b8 01 00 00 00          mov    $0x1,%eax
  52175a:       e9 e0 fd ff ff          jmpq   52153f
<dns_rdataslab_fromrdataset+0xef>
  52175f:       b9 33 6c 5f 00          mov    $0x5f6c33,%ecx
  521764:       ba 02 00 00 00          mov    $0x2,%edx
  521769:       be 34 01 00 00          mov    $0x134,%esi
  52176e:       bf eb 20 64 00          mov    $0x6420eb,%edi
  521773:       e8 a8 92 09 00          callq  5baa20 <isc_assertion_failed>
  521778:       89 5c 24 2c             mov    %ebx,0x2c(%rsp)
  52177c:       b8 01 00 00 00          mov    $0x1,%eax
  521781:       e9 99 fe ff ff          jmpq   52161f
<dns_rdataslab_fromrdataset+0x1cf>
  521786:       66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
  52178d:       00 00 00


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

* [Bug c/61236] GCC 4.9 generates incorrect object code
  2014-05-19 17:39 [Bug c/61236] New: GCC 4.9 generates incorrect object code muks at banu dot com
  2014-05-19 17:46 ` [Bug c/61236] " muks at banu dot com
@ 2014-05-19 17:49 ` muks at banu dot com
  2014-05-19 17:53 ` muks at banu dot com
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: muks at banu dot com @ 2014-05-19 17:49 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Mukund Sivaraman <muks at banu dot com> ---
This is the C function (so you can compare notes from the next comment):

isc_result_t
dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
               isc_region_t *region, unsigned int reservelen)
{
    /*
     * Use &removed as a sentinal pointer for duplicate
     * rdata as rdata.data == NULL is valid.
     */
    static unsigned char removed;
    struct xrdata  *x;
    unsigned char  *rawbuf;
#if DNS_RDATASET_FIXED
    unsigned char  *offsetbase;
#endif
    unsigned int    buflen;
    isc_result_t    result;
    unsigned int    nitems;
    unsigned int    nalloc;
    unsigned int    i;
#if DNS_RDATASET_FIXED
    unsigned int   *offsettable;
#endif
    unsigned int    length;

    buflen = reservelen + 2;

    nalloc = dns_rdataset_count(rdataset);
    nitems = nalloc;
    if (nitems == 0 && rdataset->type != 0)
        return (ISC_R_FAILURE);

    if (nalloc > 0xffff)
        return (ISC_R_NOSPACE);


    if (nalloc != 0) {
        x = isc_mem_get(mctx, nalloc * sizeof(struct xrdata));
        if (x == NULL)
            return (ISC_R_NOMEMORY);
    } else
        x = NULL;

    /*
     * Save all of the rdata members into an array.
     */
    result = dns_rdataset_first(rdataset);
    if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE)
        goto free_rdatas;
    for (i = 0; i < nalloc && result == ISC_R_SUCCESS; i++) {
        INSIST(result == ISC_R_SUCCESS);
        dns_rdata_init(&x[i].rdata);
        dns_rdataset_current(rdataset, &x[i].rdata);
        INSIST(x[i].rdata.data != &removed);
#if DNS_RDATASET_FIXED
        x[i].order = i;
#endif
        result = dns_rdataset_next(rdataset);
    }
    if (result != ISC_R_NOMORE)
        goto free_rdatas;
    if (i != nalloc) {
        /*
         * Somehow we iterated over fewer rdatas than
         * dns_rdataset_count() said there were!
         */
        result = ISC_R_FAILURE;
        goto free_rdatas;
    }

    /*
     * Put into DNSSEC order.
     */
    qsort(x, nalloc, sizeof(struct xrdata), compare_rdata);

    /*
     * Remove duplicates and compute the total storage required.
     *
     * If an rdata is not a duplicate, accumulate the storage size
     * required for the rdata.  We do not store the class, type, etc,
     * just the rdata, so our overhead is 2 bytes for the number of
     * records, and 8 for each rdata, (length(2), offset(4) and order(2))
     * and then the rdata itself.
     */
    for (i = 1; i < nalloc; i++) {
        if (compare_rdata(&x[i-1].rdata, &x[i].rdata) == 0) {
            x[i-1].rdata.data = &removed;
#if DNS_RDATASET_FIXED
            /*
             * Preserve the least order so A, B, A -> A, B
             * after duplicate removal.
             */
            if (x[i-1].order < x[i].order)
                x[i].order = x[i-1].order;
#endif
            nitems--;
        } else {
#if DNS_RDATASET_FIXED
            buflen += (8 + x[i-1].rdata.length);
#else
            buflen += (2 + x[i-1].rdata.length);
#endif
            /*
             * Provide space to store the per RR meta data.
             */
            if (rdataset->type == dns_rdatatype_rrsig)
                buflen++;
        }
    }
    /*
     * Don't forget the last item!
     */
    if (nalloc != 0) {
#if DNS_RDATASET_FIXED
        buflen += (8 + x[i-1].rdata.length);
#else
        buflen += (2 + x[i-1].rdata.length);
#endif
    }

    /*
     * Provide space to store the per RR meta data.
     */
    if (rdataset->type == dns_rdatatype_rrsig)
        buflen++;

    /*
     * Ensure that singleton types are actually singletons.
     */
    if (nitems > 1 && dns_rdatatype_issingleton(rdataset->type)) {
        /*
         * We have a singleton type, but there's more than one
         * RR in the rdataset.
         */
        result = DNS_R_SINGLETON;
        goto free_rdatas;
    }

    /*
     * Allocate the memory, set up a buffer, start copying in
     * data.
     */
    rawbuf = isc_mem_get(mctx, buflen);
    if (rawbuf == NULL) {
        result = ISC_R_NOMEMORY;
        goto free_rdatas;
    }

#if DNS_RDATASET_FIXED
    /* Allocate temporary offset table. */
    offsettable = isc_mem_get(mctx, nalloc * sizeof(unsigned int));
    if (offsettable == NULL) {
        isc_mem_put(mctx, rawbuf, buflen);
        result = ISC_R_NOMEMORY;
        goto free_rdatas;
    }
    memset(offsettable, 0, nalloc * sizeof(unsigned int));
#endif

    region->base = rawbuf;
    region->length = buflen;

    rawbuf += reservelen;
#if DNS_RDATASET_FIXED
    offsetbase = rawbuf;
#endif

    *rawbuf++ = (nitems & 0xff00) >> 8;
    *rawbuf++ = (nitems & 0x00ff);

#if DNS_RDATASET_FIXED
    /* Skip load order table.  Filled in later. */
    rawbuf += nitems * 4;
#endif

    for (i = 0; i < nalloc; i++) {
        if (x[i].rdata.data == &removed)
            continue;
#if DNS_RDATASET_FIXED
        offsettable[x[i].order] = rawbuf - offsetbase;
#endif
        length = x[i].rdata.length;
        if (rdataset->type == dns_rdatatype_rrsig)
            length++;
        INSIST(length <= 0xffff);
        *rawbuf++ = (length & 0xff00) >> 8;
        *rawbuf++ = (length & 0x00ff);
#if DNS_RDATASET_FIXED
        rawbuf += 2;    /* filled in later */
#endif
        /*
         * Store the per RR meta data.
         */
        if (rdataset->type == dns_rdatatype_rrsig) {
            *rawbuf++ |= (x[i].rdata.flags & DNS_RDATA_OFFLINE) ?
                        DNS_RDATASLAB_OFFLINE : 0;
        }
        memmove(rawbuf, x[i].rdata.data, x[i].rdata.length);
        rawbuf += x[i].rdata.length;
    }

#if DNS_RDATASET_FIXED
    fillin_offsets(offsetbase, offsettable, nalloc);
    isc_mem_put(mctx, offsettable, nalloc * sizeof(unsigned int));
#endif

    result = ISC_R_SUCCESS;

 free_rdatas:
    if (x != NULL)
        isc_mem_put(mctx, x, nalloc * sizeof(struct xrdata));
    return (result);
}


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

* [Bug c/61236] GCC 4.9 generates incorrect object code
  2014-05-19 17:39 [Bug c/61236] New: GCC 4.9 generates incorrect object code muks at banu dot com
  2014-05-19 17:46 ` [Bug c/61236] " muks at banu dot com
  2014-05-19 17:49 ` muks at banu dot com
@ 2014-05-19 17:53 ` muks at banu dot com
  2014-05-19 18:13 ` trippels at gcc dot gnu.org
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: muks at banu dot com @ 2014-05-19 17:53 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Mukund Sivaraman <muks at banu dot com> ---
The following is _incorrect_ generated x86_64 code for
dns_rdataslab_fromrdataset() as compiled with:

gcc version 4.9.1 20140507 (prerelease) (GCC).

(the current version of GCC on Arch Linux).

NOTE that there are two copies of generated code for this
function. Either the first or second copy of code is called based on
whether (nalloc == 0) implying (nitems == 0) too.

In the (nitems == 0) case, the entire free_rdatas block is deleted by
GCC as x is inferred to be NULL.

In the (nitems != 0) case, the "if (x != NULL)" check is deleted as x is
inferred to NOT be NULL, and isc_mem_put() is always called.

The failed assertion obviously happens when (x == NULL), i.e.,
(nitems == 0). And the fact that the "if (x != NULL)" check was deleted
is an obvious sign that code flow is through that path to cause the
assertion failure.

Because the code is like noodles, I've added STEP# comments in the code
to take you through the (nitems == 0) case. Go from STEP #0 to STEP #13.

The bug happens because the (nitems == 0) case branches into code for
(nitems != 0) where checks have been removed.

; STEP #0
000000000051fc10 <dns_rdataslab_fromrdataset>:
  51fc10:       41 57                   push   %r15
  51fc12:       41 56                   push   %r14
  51fc14:       49 89 f7                mov    %rsi,%r15
  51fc17:       41 55                   push   %r13
  51fc19:       41 54                   push   %r12
  51fc1b:       49 89 fc                mov    %rdi,%r12
  51fc1e:       55                      push   %rbp
  51fc1f:       53                      push   %rbx
  51fc20:       48 83 ec 38             sub    $0x38,%rsp
  51fc24:       48 89 54 24 08          mov    %rdx,0x8(%rsp)
  51fc29:       89 4c 24 20             mov    %ecx,0x20(%rsp)
  51fc2d:       e8 9e e7 ff ff          callq  51e3d0 <dns_rdataset_count>
  51fc32:       41 89 c5                mov    %eax,%r13d

;; STEP #1
;; Is (nitems == 0)? If not, go to 51fc60. It is 0 in our case.

  51fc35:       45 85 ed                test   %r13d,%r13d
  51fc38:       75 26                   jne    51fc60
<dns_rdataslab_fromrdataset+0x50>

;; STEP #2
;;     if (nitems == 0 && rdataset->type != 0)
;;        return (ISC_R_FAILURE);
;;
;; Here, let's take it that (rdataset->type != 0) so that we can
;;   continue execution. Jump to 51fd20 (STEP #3).

  51fc3a:       66 41 83 7c 24 22 00    cmpw   $0x0,0x22(%r12)
  51fc41:       ba 19 00 00 00          mov    $0x19,%edx
  51fc46:       0f 84 d4 00 00 00       je     51fd20
<dns_rdataslab_fromrdataset+0x110>

; out:
;
; control comes back here as part of a "return;" statement's code from
; below.

  51fc4c:       48 83 c4 38             add    $0x38,%rsp
  51fc50:       89 d0                   mov    %edx,%eax
  51fc52:       5b                      pop    %rbx
  51fc53:       5d                      pop    %rbp
  51fc54:       41 5c                   pop    %r12
  51fc56:       41 5d                   pop    %r13
  51fc58:       41 5e                   pop    %r14
  51fc5a:       41 5f                   pop    %r15
  51fc5c:       c3                      retq   


  51fc5d:       0f 1f 00                nopl   (%rax)

; (nitems != 0) case.

  51fc60:       41 81 fd ff ff 00 00    cmp    $0xffff,%r13d
  51fc67:       ba 13 00 00 00          mov    $0x13,%edx
  51fc6c:       77 de                   ja     51fc4c
<dns_rdataslab_fromrdataset+0x3c>
  51fc6e:       44 89 e8                mov    %r13d,%eax
  51fc71:       b9 a1 00 00 00          mov    $0xa1,%ecx
  51fc76:       ba 6b e1 63 00          mov    $0x63e16b,%edx
  51fc7b:       48 8d 1c 40             lea    (%rax,%rax,2),%rbx
  51fc7f:       4c 89 ff                mov    %r15,%rdi
  51fc82:       48 c1 e3 04             shl    $0x4,%rbx
  51fc86:       48 89 de                mov    %rbx,%rsi
  51fc89:       e8 d2 a9 0a 00          callq  5ca660 <isc__mem_get>
  51fc8e:       48 85 c0                test   %rax,%rax
  51fc91:       49 89 c6                mov    %rax,%r14
  51fc94:       0f 84 7d 01 00 00       je     51fe17
<dns_rdataslab_fromrdataset+0x207>
  51fc9a:       4c 89 e7                mov    %r12,%rdi

; /* FIRST COPY OF GENERATED CODE (nalloc > 0) */
;
;       result = dns_rdataset_first(rdataset);

  51fc9d:       e8 0e e8 ff ff          callq  51e4b0 <dns_rdataset_first>

;       if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE)
;               goto free_rdatas;

; 0x1d (ISC_R_NOMORE)

  51fca2:       83 f8 1d                cmp    $0x1d,%eax
  51fca5:       74 08                   je     51fcaf
<dns_rdataslab_fromrdataset+0x9f>

; 0x0 (ISC_R_SUCCESS).  if (result != ISC_R_SUCCESS && result !=
; ISC_R_NOMORE), jmp to 51fd53 (free_rdatas) below.

  51fca7:       85 c0                   test   %eax,%eax
  51fca9:       0f 85 a4 00 00 00       jne    51fd53
<dns_rdataslab_fromrdataset+0x143>

; go below to free_rdatas.

; ignore: for loop

  51fcaf:       31 ed                   xor    %ebp,%ebp
  51fcb1:       85 c0                   test   %eax,%eax
  51fcb3:       74 1f                   je     51fcd4
<dns_rdataslab_fromrdataset+0xc4>
  51fcb5:       e9 82 00 00 00          jmpq   51fd3c
<dns_rdataslab_fromrdataset+0x12c>
  51fcba:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)

; ignore: for loop iterate (continue;)

  51fcc0:       4c 89 e7                mov    %r12,%rdi
  51fcc3:       83 c5 01                add    $0x1,%ebp
  51fcc6:       e8 35 e8 ff ff          callq  51e500 <dns_rdataset_next>
  51fccb:       85 c0                   test   %eax,%eax
  51fccd:       75 6d                   jne    51fd3c
<dns_rdataslab_fromrdataset+0x12c>
  51fccf:       41 39 ed                cmp    %ebp,%r13d
  51fcd2:       76 68                   jbe    51fd3c
<dns_rdataslab_fromrdataset+0x12c>
  51fcd4:       89 e8                   mov    %ebp,%eax
  51fcd6:       48 8d 1c 40             lea    (%rax,%rax,2),%rbx
  51fcda:       48 c1 e3 04             shl    $0x4,%rbx
  51fcde:       4c 01 f3                add    %r14,%rbx
  51fce1:       48 89 df                mov    %rbx,%rdi
  51fce4:       e8 37 ad fd ff          callq  4faa20 <dns_rdata_init>
  51fce9:       48 89 de                mov    %rbx,%rsi
  51fcec:       4c 89 e7                mov    %r12,%rdi
  51fcef:       e8 5c e8 ff ff          callq  51e550 <dns_rdataset_current>

; Second INSIST() inside for loop. First INSIST() is redundant. In this
; compiler's output, the assertion call is inlined here.

  51fcf4:       48 81 3b 28 f2 8b 00    cmpq   $0x8bf228,(%rbx)
  51fcfb:       75 c3                   jne    51fcc0
<dns_rdataslab_fromrdataset+0xb0>
  51fcfd:       b9 77 e1 63 00          mov    $0x63e177,%ecx
  51fd02:       ba 02 00 00 00          mov    $0x2,%edx
  51fd07:       be b1 00 00 00          mov    $0xb1,%esi
  51fd0c:       bf 6b e1 63 00          mov    $0x63e16b,%edi
  51fd11:       e8 1a 81 09 00          callq  5b7e30 <isc_assertion_failed>
  51fd16:       66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
  51fd1d:       00 00 00 

; STEP #3

  51fd20:       4c 89 e7                mov    %r12,%rdi

; /* SECOND COPY OF GENERATED CODE (nalloc == 0) */
;
;       result = dns_rdataset_first(rdataset);

  51fd23:       e8 88 e7 ff ff          callq  51e4b0 <dns_rdataset_first>

;       if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE)
;               goto free_rdatas;

; 0x1d (ISC_R_NOMORE)

;; Let's assume result is ISC_R_NOMORE here. So jump to 51fd37 (STEP #4).

  51fd28:       83 f8 1d                cmp    $0x1d,%eax
  51fd2b:       74 0a                   je     51fd37
<dns_rdataslab_fromrdataset+0x127>

; 0x0 (ISC_R_SUCCESS).  if (result != ISC_R_SUCCESS && result !=
; ISC_R_NOMORE), jmp to 51fc4c (out) at the start of the function.

; If this jump is taken, isc__mem_put() is not called before return, but
; x is NULL here in this copy of call to dns_rdataset_first()
; (nalloc = dns_rdataset_count(rdataset) returned 0).

;; The mov between test and jne below won't affect ZF.

  51fd2d:       85 c0                   test   %eax,%eax
  51fd2f:       89 c2                   mov    %eax,%edx
  51fd31:       0f 85 15 ff ff ff       jne    51fc4c
<dns_rdataslab_fromrdataset+0x3c>

; STEP #4
;
; This just zeros some more variables and because %eax is still
; ISC_R_NOMORE, jumps to 51fd7b (STEP #5).

  51fd37:       31 ed                   xor    %ebp,%ebp
  51fd39:       45 31 f6                xor    %r14d,%r14d

  51fd3c:       83 f8 1d                cmp    $0x1d,%eax
  51fd3f:       74 3a                   je     51fd7b
<dns_rdataslab_fromrdataset+0x16b>

; before_free_rdatas:
; if (x == NULL), skip calling isc_mem_put()
  51fd41:       4d 85 f6                test   %r14,%r14
  51fd44:       0f 84 12 02 00 00       je     51ff5c
<dns_rdataslab_fromrdataset+0x34c>
  51fd4a:       4b 8d 5c 6d 00          lea    0x0(%r13,%r13,2),%rbx
  51fd4f:       48 c1 e3 04             shl    $0x4,%rbx

; STEP #13:
;
; free_rdatas: (nitems != 0) variant
;
;        /* When a jmp is made to this location directly, this check is
missing,
;           causing the assertion! */
;
;        /* if (x != NULL) */
;                isc_mem_put(mctx, x, nalloc * sizeof(struct xrdata));
;        return (result);
;
;

  51fd53:       48 89 da                mov    %rbx,%rdx
  51fd56:       41 b8 4e 01 00 00       mov    $0x14e,%r8d
  51fd5c:       b9 6b e1 63 00          mov    $0x63e16b,%ecx
  51fd61:       4c 89 f6                mov    %r14,%rsi
  51fd64:       4c 89 ff                mov    %r15,%rdi
  51fd67:       89 44 24 20             mov    %eax,0x20(%rsp)
  51fd6b:       e8 d0 ba 0a 00          callq  5cb840 <isc__mem_put>
  51fd70:       8b 44 24 20             mov    0x20(%rsp),%eax
  51fd74:       89 c2                   mov    %eax,%edx
  51fd76:       e9 d1 fe ff ff          jmpq   51fc4c
<dns_rdataslab_fromrdataset+0x3c>

; the jmpq instruction above jumps above to "out:" label at the start of
; this function.

; STEP #5
;
; nalloc is 0 here, so the for (i = 0; i < nalloc... is skipped.
;
;       if (i != nalloc) {
;               /*
;                * Somehow we iterated over fewer rdatas than
;                * dns_rdataset_count() said there were!
;                */
;               result = ISC_R_FAILURE;
;               goto free_rdatas;
;       }

; In the following, the jne jumps to before_free_rdatas (above) where x
; is checked for NULL before calling isc_mem_put(). But (i == nalloc)
; here as the for loop was not entered. So keep going below to STEP #6.

  51fd7b:       44 39 ed                cmp    %r13d,%ebp
  51fd7e:       b0 19                   mov    $0x19,%al
  51fd80:       75 bf                   jne    51fd41
<dns_rdataslab_fromrdataset+0x131>

; STEP #6
;
;       qsort(x, nalloc, sizeof(struct xrdata), compare_rdata);

  51fd82:       8b 44 24 20             mov    0x20(%rsp),%eax
  51fd86:       b9 80 fb 51 00          mov    $0x51fb80,%ecx
  51fd8b:       ba 30 00 00 00          mov    $0x30,%edx
  51fd90:       4c 89 f7                mov    %r14,%rdi
  51fd93:       8d 58 02                lea    0x2(%rax),%ebx
  51fd96:       89 e8                   mov    %ebp,%eax
  51fd98:       48 89 c6                mov    %rax,%rsi
  51fd9b:       48 89 44 24 28          mov    %rax,0x28(%rsp)
  51fda0:       e8 8b 6f ee ff          callq  406d30 <qsort@plt>

;    for (i = 1; i < nalloc; i++) {
;       Here, nalloc is 0, so we jump to 51ff3c (STEP #7).

  51fda5:       83 fd 01                cmp    $0x1,%ebp
  51fda8:       0f 86 8e 01 00 00       jbe    51ff3c
<dns_rdataslab_fromrdataset+0x32c>

  51fdae:       8d 45 fe                lea    -0x2(%rbp),%eax
  51fdb1:       4d 89 f5                mov    %r14,%r13
  51fdb4:       89 6c 24 24             mov    %ebp,0x24(%rsp)
  51fdb8:       48 8d 44 40 03          lea    0x3(%rax,%rax,2),%rax
  51fdbd:       48 c1 e0 04             shl    $0x4,%rax
  51fdc1:       4c 01 f0                add    %r14,%rax
  51fdc4:       48 89 44 24 18          mov    %rax,0x18(%rsp)
  51fdc9:       eb 17                   jmp    51fde2
<dns_rdataslab_fromrdataset+0x1d2>
  51fdcb:       83 6c 24 24 01          subl   $0x1,0x24(%rsp)
  51fdd0:       49 c7 45 00 28 f2 8b    movq   $0x8bf228,0x0(%r13)
  51fdd7:       00 
  51fdd8:       48 3b 4c 24 18          cmp    0x18(%rsp),%rcx
  51fddd:       49 89 cd                mov    %rcx,%r13
  51fde0:       74 3f                   je     51fe21
<dns_rdataslab_fromrdataset+0x211>
  51fde2:       49 8d 4d 30             lea    0x30(%r13),%rcx
  51fde6:       4c 89 ef                mov    %r13,%rdi
  51fde9:       48 89 ce                mov    %rcx,%rsi
  51fdec:       48 89 4c 24 10          mov    %rcx,0x10(%rsp)
  51fdf1:       e8 2a e2 fd ff          callq  4fe020 <dns_rdata_compare>
  51fdf6:       85 c0                   test   %eax,%eax
  51fdf8:       48 8b 4c 24 10          mov    0x10(%rsp),%rcx
  51fdfd:       74 cc                   je     51fdcb
<dns_rdataslab_fromrdataset+0x1bb>
  51fdff:       41 8b 45 08             mov    0x8(%r13),%eax
  51fe03:       01 d8                   add    %ebx,%eax
  51fe05:       8d 58 02                lea    0x2(%rax),%ebx
  51fe08:       83 c0 03                add    $0x3,%eax
  51fe0b:       66 41 83 7c 24 22 2e    cmpw   $0x2e,0x22(%r12)
  51fe12:       0f 44 d8                cmove  %eax,%ebx
  51fe15:       eb c1                   jmp    51fdd8
<dns_rdataslab_fromrdataset+0x1c8>
  51fe17:       ba 01 00 00 00          mov    $0x1,%edx
  51fe1c:       e9 2b fe ff ff          jmpq   51fc4c
<dns_rdataslab_fromrdataset+0x3c>
  51fe21:       89 e8                   mov    %ebp,%eax
  51fe23:       83 e8 01                sub    $0x1,%eax
  51fe26:       48 8d 04 40             lea    (%rax,%rax,2),%rax
  51fe2a:       48 c1 e0 04             shl    $0x4,%rax
  51fe2e:       41 8b 44 06 08          mov    0x8(%r14,%rax,1),%eax
  51fe33:       8d 5c 03 02             lea    0x2(%rbx,%rax,1),%ebx

; STEP #8

  51fe37:       41 0f b7 44 24 22       movzwl 0x22(%r12),%eax
  51fe3d:       31 d2                   xor    %edx,%edx
  51fe3f:       66 83 f8 2e             cmp    $0x2e,%ax
  51fe43:       0f 94 c2                sete   %dl
  51fe46:       01 d3                   add    %edx,%ebx

;     if (nitems > 1 && dns_rdatatype_issingleton(rdataset->type)) {
;
;   here, nitems = 0. so jmp to 51fe72 (STEP #9)

  51fe48:       83 7c 24 24 01          cmpl   $0x1,0x24(%rsp)
  51fe4d:       76 23                   jbe    51fe72
<dns_rdataslab_fromrdataset+0x262>

  51fe4f:       0f b7 f8                movzwl %ax,%edi
  51fe52:       e8 c9 d6 ff ff          callq  51d520
<dns_rdatatype_issingleton>
  51fe57:       85 c0                   test   %eax,%eax
  51fe59:       74 17                   je     51fe72
<dns_rdataslab_fromrdataset+0x262>
  51fe5b:       b8 48 00 01 00          mov    $0x10048,%eax

; STEP #12
;
; Jump to 51fd53 (STEP #13)

  51fe60:       48 8b 4c 24 28          mov    0x28(%rsp),%rcx
  51fe65:       48 8d 1c 49             lea    (%rcx,%rcx,2),%rbx
  51fe69:       48 c1 e3 04             shl    $0x4,%rbx
  51fe6d:       e9 e1 fe ff ff          jmpq   51fd53
<dns_rdataslab_fromrdataset+0x143>

; STEP #9
;
;     rawbuf = isc_mem_get(mctx, buflen);

  51fe72:       89 de                   mov    %ebx,%esi
  51fe74:       b9 0a 01 00 00          mov    $0x10a,%ecx
  51fe79:       ba 6b e1 63 00          mov    $0x63e16b,%edx
  51fe7e:       4c 89 ff                mov    %r15,%rdi
  51fe81:       e8 da a7 0a 00          callq  5ca660 <isc__mem_get>

;    if (rawbuf == NULL) {
;        result = ISC_R_NOMEMORY;
;        goto free_rdatas;
;    }
;
;
; Here, things are already falling apart. if rawbuf is NULL, jump to 51ff52
which is the
; free_rdatas variant for (nalloc != 0) where the (x != NULL) check is
; deleted. But let's assume that rawbuf is not NULL here (likely case).

  51fe86:       48 85 c0                test   %rax,%rax
  51fe89:       0f 84 c3 00 00 00       je     51ff52
<dns_rdataslab_fromrdataset+0x342>

; STEP #10
;
;    for (i = 0; i < nalloc; i++) {
;        if (x[i].rdata.data == &removed)
;            continue;
;
;
; Here we test first that nalloc (%ebp) is 0. If it is (true in our
; case), jmp to 51ff35 (STEP #11). This also takes us to the free_rdatas
; variant for (nalloc != 0) where the (x != NULL) is deleted.

  51fe8f:       48 8b 4c 24 08          mov    0x8(%rsp),%rcx
  51fe94:       8b 54 24 20             mov    0x20(%rsp),%edx
  51fe98:       48 89 01                mov    %rax,(%rcx)
  51fe9b:       89 59 08                mov    %ebx,0x8(%rcx)
  51fe9e:       8b 4c 24 24             mov    0x24(%rsp),%ecx
  51fea2:       48 01 c2                add    %rax,%rdx
  51fea5:       85 ed                   test   %ebp,%ebp
  51fea7:       48 89 c8                mov    %rcx,%rax
  51feaa:       88 4a 01                mov    %cl,0x1(%rdx)
  51fead:       0f b6 c4                movzbl %ah,%eax
  51feb0:       88 02                   mov    %al,(%rdx)
  51feb2:       48 8d 42 02             lea    0x2(%rdx),%rax
  51feb6:       74 7d                   je     51ff35
<dns_rdataslab_fromrdataset+0x325>




  51feb8:       83 ed 01                sub    $0x1,%ebp
  51febb:       49 8d 5e 08             lea    0x8(%r14),%rbx
  51febf:       48 8d 54 6d 00          lea    0x0(%rbp,%rbp,2),%rdx
  51fec4:       48 c1 e2 04             shl    $0x4,%rdx
  51fec8:       49 8d 6c 16 38          lea    0x38(%r14,%rdx,1),%rbp
  51fecd:       eb 20                   jmp    51feef
<dns_rdataslab_fromrdataset+0x2df>
  51fecf:       90                      nop

  51fed0:       8b 13                   mov    (%rbx),%edx
  51fed2:       48 8b 73 f8             mov    -0x8(%rbx),%rsi
  51fed6:       48 89 cf                mov    %rcx,%rdi
  51fed9:       e8 02 6c ee ff          callq  406ae0 <memmove@plt>
  51fede:       48 89 c1                mov    %rax,%rcx
  51fee1:       8b 03                   mov    (%rbx),%eax
  51fee3:       48 01 c8                add    %rcx,%rax
  51fee6:       48 83 c3 30             add    $0x30,%rbx
  51feea:       48 39 eb                cmp    %rbp,%rbx
  51feed:       74 46                   je     51ff35
<dns_rdataslab_fromrdataset+0x325>
  51feef:       48 81 7b f8 28 f2 8b    cmpq   $0x8bf228,-0x8(%rbx)
  51fef6:       00 
  51fef7:       74 ed                   je     51fee6
<dns_rdataslab_fromrdataset+0x2d6>
  51fef9:       31 d2                   xor    %edx,%edx
  51fefb:       66 41 83 7c 24 22 2e    cmpw   $0x2e,0x22(%r12)
  51ff02:       0f 94 c2                sete   %dl
  51ff05:       03 13                   add    (%rbx),%edx
  51ff07:       81 fa ff ff 00 00       cmp    $0xffff,%edx
  51ff0d:       77 54                   ja     51ff63
<dns_rdataslab_fromrdataset+0x353>
  51ff0f:       0f b6 ce                movzbl %dh,%ecx
  51ff12:       88 50 01                mov    %dl,0x1(%rax)
  51ff15:       88 08                   mov    %cl,(%rax)
  51ff17:       66 41 83 7c 24 22 2e    cmpw   $0x2e,0x22(%r12)
  51ff1e:       48 8d 48 02             lea    0x2(%rax),%rcx
  51ff22:       75 ac                   jne    51fed0
<dns_rdataslab_fromrdataset+0x2c0>
  51ff24:       8b 53 08                mov    0x8(%rbx),%edx
  51ff27:       48 8d 48 03             lea    0x3(%rax),%rcx
  51ff2b:       d1 ea                   shr    %edx
  51ff2d:       83 e2 01                and    $0x1,%edx
  51ff30:       08 50 02                or     %dl,0x2(%rax)
  51ff33:       eb 9b                   jmp    51fed0
<dns_rdataslab_fromrdataset+0x2c0>

; STEP #11
;
; Jump to 51fe60 (STEP #12)

  51ff35:       31 c0                   xor    %eax,%eax
  51ff37:       e9 24 ff ff ff          jmpq   51fe60
<dns_rdataslab_fromrdataset+0x250>

; STEP #7
;
; check if nalloc is 0 (it is). jmp to 51fe37 (STEP #8).

  51ff3c:       85 ed                   test   %ebp,%ebp
  51ff3e:       89 6c 24 24             mov    %ebp,0x24(%rsp)
  51ff42:       b8 01 00 00 00          mov    $0x1,%eax
  51ff47:       0f 84 ea fe ff ff       je     51fe37
<dns_rdataslab_fromrdataset+0x227>

  51ff4d:       e9 d1 fe ff ff          jmpq   51fe23
<dns_rdataslab_fromrdataset+0x213>
  51ff52:       b8 01 00 00 00          mov    $0x1,%eax
  51ff57:       e9 04 ff ff ff          jmpq   51fe60
<dns_rdataslab_fromrdataset+0x250>
  51ff5c:       89 c2                   mov    %eax,%edx
  51ff5e:       e9 e9 fc ff ff          jmpq   51fc4c
<dns_rdataslab_fromrdataset+0x3c>
  51ff63:       b9 33 2c 5f 00          mov    $0x5f2c33,%ecx
  51ff68:       ba 02 00 00 00          mov    $0x2,%edx
  51ff6d:       be 34 01 00 00          mov    $0x134,%esi
  51ff72:       bf 6b e1 63 00          mov    $0x63e16b,%edi
  51ff77:       e8 b4 7e 09 00          callq  5b7e30 <isc_assertion_failed>
  51ff7c:       0f 1f 40 00             nopl   0x0(%rax)


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

* [Bug c/61236] GCC 4.9 generates incorrect object code
  2014-05-19 17:39 [Bug c/61236] New: GCC 4.9 generates incorrect object code muks at banu dot com
                   ` (2 preceding siblings ...)
  2014-05-19 17:53 ` muks at banu dot com
@ 2014-05-19 18:13 ` trippels at gcc dot gnu.org
  2014-05-19 18:15 ` trippels at gcc dot gnu.org
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: trippels at gcc dot gnu.org @ 2014-05-19 18:13 UTC (permalink / raw)
  To: gcc-bugs

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

Markus Trippelsdorf <trippels at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |WAITING
   Last reconfirmed|                            |2014-05-19
                 CC|                            |trippels at gcc dot gnu.org
     Ever confirmed|0                           |1

--- Comment #4 from Markus Trippelsdorf <trippels at gcc dot gnu.org> ---
Could you please try to reproduce the issue with a more recent snapshot:
 ftp://gcc.gnu.org/pub/gcc/snapshots/4.10-20140518/ 

There were several bug fixes for tree-ssa-threadedge.c that went
in after "gcc version 4.9.1 20140507".


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

* [Bug c/61236] GCC 4.9 generates incorrect object code
  2014-05-19 17:39 [Bug c/61236] New: GCC 4.9 generates incorrect object code muks at banu dot com
                   ` (3 preceding siblings ...)
  2014-05-19 18:13 ` trippels at gcc dot gnu.org
@ 2014-05-19 18:15 ` trippels at gcc dot gnu.org
  2014-05-19 19:05 ` trippels at gcc dot gnu.org
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: trippels at gcc dot gnu.org @ 2014-05-19 18:15 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Markus Trippelsdorf <trippels at gcc dot gnu.org> ---
(In reply to Markus Trippelsdorf from comment #4)
> Could you please try to reproduce the issue with a more recent snapshot:
>  ftp://gcc.gnu.org/pub/gcc/snapshots/4.10-20140518/ 

Sorry wrong address. This one is correct:
 ftp://gcc.gnu.org/pub/gcc/snapshots/4.9-20140514/


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

* [Bug c/61236] GCC 4.9 generates incorrect object code
  2014-05-19 17:39 [Bug c/61236] New: GCC 4.9 generates incorrect object code muks at banu dot com
                   ` (4 preceding siblings ...)
  2014-05-19 18:15 ` trippels at gcc dot gnu.org
@ 2014-05-19 19:05 ` trippels at gcc dot gnu.org
  2014-05-19 21:07 ` jakub at gcc dot gnu.org
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: trippels at gcc dot gnu.org @ 2014-05-19 19:05 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #6 from Markus Trippelsdorf <trippels at gcc dot gnu.org> ---
(In reply to Markus Trippelsdorf from comment #4)
> Could you please try to reproduce the issue with a more recent snapshot:

No need. I can reproduce the issue and will look deeper tomorrow.


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

* [Bug c/61236] GCC 4.9 generates incorrect object code
  2014-05-19 17:39 [Bug c/61236] New: GCC 4.9 generates incorrect object code muks at banu dot com
                   ` (5 preceding siblings ...)
  2014-05-19 19:05 ` trippels at gcc dot gnu.org
@ 2014-05-19 21:07 ` jakub at gcc dot gnu.org
  2014-05-20  7:16 ` jakub at gcc dot gnu.org
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: jakub at gcc dot gnu.org @ 2014-05-19 21:07 UTC (permalink / raw)
  To: gcc-bugs

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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The glibc prototype for qsort is:
extern void qsort (void *__base, size_t __nmemb, size_t __size,
                   __compar_fn_t __compar) __nonnull ((1, 4));
therefore when you pass x to it, gcc derives from that that x must not be NULL.
As ISO C99 says that qsort sorts an array of nmemb objects, I'd say the glibc
prototype is correct and therefore BIND is buggy, because NULL is not an
address of any object.


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

* [Bug c/61236] GCC 4.9 generates incorrect object code
  2014-05-19 17:39 [Bug c/61236] New: GCC 4.9 generates incorrect object code muks at banu dot com
                   ` (6 preceding siblings ...)
  2014-05-19 21:07 ` jakub at gcc dot gnu.org
@ 2014-05-20  7:16 ` jakub at gcc dot gnu.org
  2014-05-20  8:07 ` pinskia at gcc dot gnu.org
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: jakub at gcc dot gnu.org @ 2014-05-20  7:16 UTC (permalink / raw)
  To: gcc-bugs

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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|WAITING                     |RESOLVED
         Resolution|---                         |INVALID

--- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
If you believe the nonnull attribute on qsort is incorrect, then you should
report that as glibc bug, not gcc bug, the prototype is provided by glibc.
The more aggressive GCC optimization is documented e.g. in
https://gcc.gnu.org/gcc-4.9/porting_to.html
plus we hope to add -fsanitize=undefined instrumentation for this in the
upcoming GCC version, so you find it out more easily.

> When the compiler knows at that point that base (=x) is NULL as an
> argument to qsort(), why isn't it warning when the attribute expects it
> to be non-NULL, esp. as it is using this inferred decision to optimize
> code down below?

But the compiler doesn't know there that x is NULL.  The compiler sees a call
to a function which must not be called with NULL, and from that derives the
value range of x to be anything but NULL.  Instead of qsort consider here some
less controversial function, e.g. memcpy, where the standard is very clear that
memcpy (NULL, "", 0); or memcpy ("", NULL, 0); is invalid despite the length 0.


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

* [Bug c/61236] GCC 4.9 generates incorrect object code
  2014-05-19 17:39 [Bug c/61236] New: GCC 4.9 generates incorrect object code muks at banu dot com
                   ` (7 preceding siblings ...)
  2014-05-20  7:16 ` jakub at gcc dot gnu.org
@ 2014-05-20  8:07 ` pinskia at gcc dot gnu.org
  2014-05-20  8:51 ` jakub at gcc dot gnu.org
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: pinskia at gcc dot gnu.org @ 2014-05-20  8:07 UTC (permalink / raw)
  To: gcc-bugs

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="UTF-8", Size: 6974 bytes --]

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

--- Comment #11 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #10)
> If you believe the nonnull attribute on qsort is incorrect, then you should
> report that as glibc bug, not gcc bug, the prototype is provided by glibc.
> The more aggressive GCC optimization is documented e.g. in
> https://gcc.gnu.org/gcc-4.9/porting_to.html
> plus we hope to add -fsanitize=undefined instrumentation for this in the
> upcoming GCC version, so you find it out more easily.

It is not incorrect as the C standard says this about qsort:
nmemb can have the value zero on a call to that function; the comparison
function is not called, a search finds no matching element, and sorting performs
no rearrangement. Pointer arguments on such a call shall still have valid
values, as described in 7.1.4.

POSIX 2008 defers to the C standard now so this is neither a glibc or a GCC bug
in the end.
>From gcc-bugs-return-452001-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org Tue May 20 08:09:10 2014
Return-Path: <gcc-bugs-return-452001-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org>
Delivered-To: listarch-gcc-bugs@gcc.gnu.org
Received: (qmail 23909 invoked by alias); 20 May 2014 08:09:10 -0000
Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm
Precedence: bulk
List-Id: <gcc-bugs.gcc.gnu.org>
List-Archive: <http://gcc.gnu.org/ml/gcc-bugs/>
List-Post: <mailto:gcc-bugs@gcc.gnu.org>
List-Help: <mailto:gcc-bugs-help@gcc.gnu.org>
Sender: gcc-bugs-owner@gcc.gnu.org
Delivered-To: mailing list gcc-bugs@gcc.gnu.org
Received: (qmail 23356 invoked by uid 48); 20 May 2014 08:09:04 -0000
From: "pinskia at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug c/61236] GCC 4.9 generates incorrect object code
Date: Tue, 20 May 2014 08:09:00 -0000
X-Bugzilla-Reason: CC
X-Bugzilla-Type: changed
X-Bugzilla-Watch-Reason: None
X-Bugzilla-Product: gcc
X-Bugzilla-Component: c
X-Bugzilla-Version: 4.9.1
X-Bugzilla-Keywords:
X-Bugzilla-Severity: normal
X-Bugzilla-Who: pinskia at gcc dot gnu.org
X-Bugzilla-Status: RESOLVED
X-Bugzilla-Priority: P3
X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org
X-Bugzilla-Target-Milestone: ---
X-Bugzilla-Flags:
X-Bugzilla-Changed-Fields:
Message-ID: <bug-61236-4-Z79pJdKCQC@http.gcc.gnu.org/bugzilla/>
In-Reply-To: <bug-61236-4@http.gcc.gnu.org/bugzilla/>
References: <bug-61236-4@http.gcc.gnu.org/bugzilla/>
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/
Auto-Submitted: auto-generated
MIME-Version: 1.0
X-SW-Source: 2014-05/txt/msg01693.txt.bz2
Content-length: 1176

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

--- Comment #12 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #11) 
> It is not incorrect as the C standard says this about qsort:
> nmemb can have the value zero on a call to that function; the comparison
> function is not called, a search finds no matching element, and sorting
> performs no rearrangement. Pointer arguments on such a call shall still have
> valid values, as described in 7.1.4.

7.1.4 says this:
Each of the following statements applies unless explicitly stated otherwise in
the detailed
descriptions that follow: If an argument to a function has an invalid value
(such as a value
outside the domain of the function, or a pointer outside the address space of
the program,
or a null pointer, or a pointer to non-modifiable storage when the corresponding
parameter is not const-qualified) or a type (after promotion) not expected by a
function
with variable number of arguments, the behavior is undefined.

So there is not need to say it was detected to be non-null as the null pointer
case is mentioned in 7.1.4.
>From gcc-bugs-return-452002-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org Tue May 20 08:11:25 2014
Return-Path: <gcc-bugs-return-452002-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org>
Delivered-To: listarch-gcc-bugs@gcc.gnu.org
Received: (qmail 25526 invoked by alias); 20 May 2014 08:11:25 -0000
Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm
Precedence: bulk
List-Id: <gcc-bugs.gcc.gnu.org>
List-Archive: <http://gcc.gnu.org/ml/gcc-bugs/>
List-Post: <mailto:gcc-bugs@gcc.gnu.org>
List-Help: <mailto:gcc-bugs-help@gcc.gnu.org>
Sender: gcc-bugs-owner@gcc.gnu.org
Delivered-To: mailing list gcc-bugs@gcc.gnu.org
Received: (qmail 25462 invoked by uid 48); 20 May 2014 08:11:22 -0000
From: "bugdal at aerifal dot cx" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug ipa/61144] [4.9/4.10 Regression] Invalid optimizations for extern vars with local weak definitions
Date: Tue, 20 May 2014 08:11:00 -0000
X-Bugzilla-Reason: CC
X-Bugzilla-Type: changed
X-Bugzilla-Watch-Reason: None
X-Bugzilla-Product: gcc
X-Bugzilla-Component: ipa
X-Bugzilla-Version: 4.9.0
X-Bugzilla-Keywords: wrong-code
X-Bugzilla-Severity: normal
X-Bugzilla-Who: bugdal at aerifal dot cx
X-Bugzilla-Status: NEW
X-Bugzilla-Priority: P3
X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org
X-Bugzilla-Target-Milestone: 4.9.1
X-Bugzilla-Flags:
X-Bugzilla-Changed-Fields:
Message-ID: <bug-61144-4-jZVZUvpOl1@http.gcc.gnu.org/bugzilla/>
In-Reply-To: <bug-61144-4@http.gcc.gnu.org/bugzilla/>
References: <bug-61144-4@http.gcc.gnu.org/bugzilla/>
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit
X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/
Auto-Submitted: auto-generated
MIME-Version: 1.0
X-SW-Source: 2014-05/txt/msg01694.txt.bz2
Content-length: 1239

https://gcc.gnu.org/bugzilla/show_bug.cgi?ida144

--- Comment #19 from Rich Felker <bugdal at aerifal dot cx> ---
Here is the commit that seems to have introduced the bug:

https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;hß8d3e8981a99e264b49876f0f5064bdb30ac981

In the function ctor_for_folding, the following erroneous logic appears:

+  /* Non-readonly alias of readonly variable is also de-facto readonly,
+     because the variable itself is in readonly section.
+     We also honnor READONLY flag on alias assuming that user knows
+     what he is doing.  */
+  if (!TREE_READONLY (decl) && !TREE_READONLY (real_decl))
+    return error_mark_node;

This treats the value of an alias as a compile-time constant if either the
alias itself or the alias target has TREE_READONLY being true. Replacing the &&
with || seems to make the problem go away in my test case, and makes a bit more
sense (perhaps that was the original intent?), but it's only sufficient if
TREE_READONLY is always false for weak aliases (since they can always be
overridden by a strong symbol from another translation unit, even if the alias
is const-qualified). I'm not sure where the value of TREE_READONLY is set for
aliases yet but I'll keep looking...


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

* [Bug c/61236] GCC 4.9 generates incorrect object code
  2014-05-19 17:39 [Bug c/61236] New: GCC 4.9 generates incorrect object code muks at banu dot com
                   ` (8 preceding siblings ...)
  2014-05-20  8:07 ` pinskia at gcc dot gnu.org
@ 2014-05-20  8:51 ` jakub at gcc dot gnu.org
  2014-05-20  9:02 ` pinskia at gcc dot gnu.org
  2014-05-20  9:31 ` muks at banu dot com
  11 siblings, 0 replies; 13+ messages in thread
From: jakub at gcc dot gnu.org @ 2014-05-20  8:51 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #13 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #11)
> It is not incorrect as the C standard says this about qsort:
> nmemb can have the value zero on a call to that function; the comparison
> function is not called, a search finds no matching element, and sorting
> performs no rearrangement. Pointer arguments on such a call shall still have
> valid values, as described in 7.1.4.
> 
> POSIX 2008 defers to the C standard now so this is neither a glibc or a GCC
> bug in the end.

I've missed the "Pointer arguments on such a call shall still have
valid values, as described in 7.1.4." sentence in C99 7.20.5 (was looking for
that in 7.20.5.2), with that it is exactly the same thing in this regard as
memcpy etc.
>From gcc-bugs-return-452016-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org Tue May 20 08:57:53 2014
Return-Path: <gcc-bugs-return-452016-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org>
Delivered-To: listarch-gcc-bugs@gcc.gnu.org
Received: (qmail 14036 invoked by alias); 20 May 2014 08:57:53 -0000
Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm
Precedence: bulk
List-Id: <gcc-bugs.gcc.gnu.org>
List-Archive: <http://gcc.gnu.org/ml/gcc-bugs/>
List-Post: <mailto:gcc-bugs@gcc.gnu.org>
List-Help: <mailto:gcc-bugs-help@gcc.gnu.org>
Sender: gcc-bugs-owner@gcc.gnu.org
Delivered-To: mailing list gcc-bugs@gcc.gnu.org
Received: (qmail 13686 invoked by uid 48); 20 May 2014 08:57:49 -0000
From: "muks at banu dot com" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug c/61236] GCC 4.9 generates incorrect object code
Date: Tue, 20 May 2014 08:57:00 -0000
X-Bugzilla-Reason: CC
X-Bugzilla-Type: changed
X-Bugzilla-Watch-Reason: None
X-Bugzilla-Product: gcc
X-Bugzilla-Component: c
X-Bugzilla-Version: 4.9.1
X-Bugzilla-Keywords:
X-Bugzilla-Severity: normal
X-Bugzilla-Who: muks at banu dot com
X-Bugzilla-Status: RESOLVED
X-Bugzilla-Priority: P3
X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org
X-Bugzilla-Target-Milestone: ---
X-Bugzilla-Flags:
X-Bugzilla-Changed-Fields:
Message-ID: <bug-61236-4-3U6dM3hWlb@http.gcc.gnu.org/bugzilla/>
In-Reply-To: <bug-61236-4@http.gcc.gnu.org/bugzilla/>
References: <bug-61236-4@http.gcc.gnu.org/bugzilla/>
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit
X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/
Auto-Submitted: auto-generated
MIME-Version: 1.0
X-SW-Source: 2014-05/txt/msg01708.txt.bz2
Content-length: 1720

https://gcc.gnu.org/bugzilla/show_bug.cgi?ida236

--- Comment #14 from Mukund Sivaraman <muks at banu dot com> ---
(In reply to Jakub Jelinek from comment #10)
> But the compiler doesn't know there that x is NULL.  The compiler sees a

See comment #3. It generates 2 codepaths, one where (nalloc == 0) and another
where (nalloc != 0). For the former, it deletes the if statement and
isc_mem_put() call at the free_rdatas label completely:

 free_rdatas:
        if (x != NULL)
                isc_mem_put(mctx, x, nalloc * sizeof(struct xrdata));
    return (result);
}

and instead reduces free_rdata's definition to:

 free_rdatas:
    return (result);
}

How does the compiler do that if it has not inferred that x is NULL there?

OTOH, you're the compiler developers, so if you say it doesn't know that x is
NULL, then that is that. :) Maybe the part of compiler code that does this
doesn't know it.

Note that despite all this discussion of correctness, this optimization is
counter intuitive and will bite developers. There should at least be warnings
where they could be generated.

The point about correctness with C standards is taken and agreed.

See what is happening from a programmer's point of view: an explicit NULL check
is deleted. There are no warnings about qsort() used with NULL arguments where
it seems the compiler could warn (see above). Also consider the use of notnull
as an API annotation change by 3rd party libraries, which can make caller code
buggy without any way to notice it.

At the very least, if it is possible to detect that the pointer is NULL by
static analysis and it is being passed to a function that has the notnull
attribute, please warn mentioning inferences being made.


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

* [Bug c/61236] GCC 4.9 generates incorrect object code
  2014-05-19 17:39 [Bug c/61236] New: GCC 4.9 generates incorrect object code muks at banu dot com
                   ` (9 preceding siblings ...)
  2014-05-20  8:51 ` jakub at gcc dot gnu.org
@ 2014-05-20  9:02 ` pinskia at gcc dot gnu.org
  2014-05-20  9:31 ` muks at banu dot com
  11 siblings, 0 replies; 13+ messages in thread
From: pinskia at gcc dot gnu.org @ 2014-05-20  9:02 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #15 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Mukund Sivaraman from comment #14)
> (In reply to Jakub Jelinek from comment #10)
> > But the compiler doesn't know there that x is NULL.  The compiler sees a
> 
> See comment #3. It generates 2 codepaths, one where (nalloc == 0) and
> another where (nalloc != 0). For the former, it deletes the if statement and
> isc_mem_put() call at the free_rdatas label completely:
> 
>  free_rdatas:
>         if (x != NULL)
>                 isc_mem_put(mctx, x, nalloc * sizeof(struct xrdata));
> 	return (result);
> }
> 
> and instead reduces free_rdata's definition to:
> 
>  free_rdatas:
> 	return (result);
> }
> 
> How does the compiler do that if it has not inferred that x is NULL there?
> 
> OTOH, you're the compiler developers, so if you say it doesn't know that x
> is NULL, then that is that. :) Maybe the part of compiler code that does
> this doesn't know it.
> 
> Note that despite all this discussion of correctness, this optimization is
> counter intuitive and will bite developers. There should at least be
> warnings where they could be generated.
> 
> The point about correctness with C standards is taken and agreed.
> 
> See what is happening from a programmer's point of view: an explicit NULL
> check is deleted. There are no warnings about qsort() used with NULL
> arguments where it seems the compiler could warn (see above). Also consider
> the use of notnull as an API annotation change by 3rd party libraries, which
> can make caller code buggy without any way to notice it.
> 
> At the very least, if it is possible to detect that the pointer is NULL by
> static analysis and it is being passed to a function that has the notnull
> attribute, please warn mentioning inferences being made.
The warning did not make it into gcc 4.9 due to the patches to do the warning
were not ready. Gcc 4.10 should warn about it. If it does not then that is a
bug.
>From gcc-bugs-return-452018-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org Tue May 20 09:20:53 2014
Return-Path: <gcc-bugs-return-452018-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org>
Delivered-To: listarch-gcc-bugs@gcc.gnu.org
Received: (qmail 30490 invoked by alias); 20 May 2014 09:20:51 -0000
Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm
Precedence: bulk
List-Id: <gcc-bugs.gcc.gnu.org>
List-Archive: <http://gcc.gnu.org/ml/gcc-bugs/>
List-Post: <mailto:gcc-bugs@gcc.gnu.org>
List-Help: <mailto:gcc-bugs-help@gcc.gnu.org>
Sender: gcc-bugs-owner@gcc.gnu.org
Delivered-To: mailing list gcc-bugs@gcc.gnu.org
Received: (qmail 30467 invoked by uid 48); 20 May 2014 09:20:47 -0000
From: "mt at debian dot org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug target/61249] New: _mm_frcz_ss, _mm_frcz_sd: __builtin_ia32_vfrczss, __builtin_ia32_vfrczsd require 2 arguments
Date: Tue, 20 May 2014 09:20:00 -0000
X-Bugzilla-Reason: CC
X-Bugzilla-Type: new
X-Bugzilla-Watch-Reason: None
X-Bugzilla-Product: gcc
X-Bugzilla-Component: target
X-Bugzilla-Version: 4.8.3
X-Bugzilla-Keywords:
X-Bugzilla-Severity: normal
X-Bugzilla-Who: mt at debian dot org
X-Bugzilla-Status: UNCONFIRMED
X-Bugzilla-Priority: P3
X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org
X-Bugzilla-Target-Milestone: ---
X-Bugzilla-Flags:
X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter
Message-ID: <bug-61249-4@http.gcc.gnu.org/bugzilla/>
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/
Auto-Submitted: auto-generated
MIME-Version: 1.0
X-SW-Source: 2014-05/txt/msg01710.txt.bz2
Content-length: 1150

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

            Bug ID: 61249
           Summary: _mm_frcz_ss, _mm_frcz_sd: __builtin_ia32_vfrczss,
                    __builtin_ia32_vfrczsd require 2 arguments
           Product: gcc
           Version: 4.8.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mt at debian dot org

Looking at https://gcc.gnu.org/onlinedocs/gcc/X86-Built-in-Functions.html on
the one hand and AMD's "AMD64 Architecture Programmer’s Manual
Volume 6: 128-Bit and 256-Bit XOP and FMA4 Instructions" on the other hand,
vfrczss/vfrczsd require a second argument to specify the destination.

Yet r205495 changed _mm_frcz_ss/_mm_frcz_sd so that only a single argument is
passed to the __builtin_ia32_vfrczss/vfrczsd calls.

This was detected at language level (inconsistent types), I can only speculate
that this may cause invalid code to be generated (or null operands).

Best,
Michael

PS.: The problem persists in the 4.9 branch as xopintrin.h hasn't been touched
since 4.8.
>From gcc-bugs-return-452019-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org Tue May 20 09:25:03 2014
Return-Path: <gcc-bugs-return-452019-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org>
Delivered-To: listarch-gcc-bugs@gcc.gnu.org
Received: (qmail 2406 invoked by alias); 20 May 2014 09:25:02 -0000
Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm
Precedence: bulk
List-Id: <gcc-bugs.gcc.gnu.org>
List-Archive: <http://gcc.gnu.org/ml/gcc-bugs/>
List-Post: <mailto:gcc-bugs@gcc.gnu.org>
List-Help: <mailto:gcc-bugs-help@gcc.gnu.org>
Sender: gcc-bugs-owner@gcc.gnu.org
Delivered-To: mailing list gcc-bugs@gcc.gnu.org
Received: (qmail 1953 invoked by uid 48); 20 May 2014 09:24:57 -0000
From: "dominiq at lps dot ens.fr" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug fortran/61126] [4.10 Regression] gfortran does not enable -Wununused-parameter with -Wextra
Date: Tue, 20 May 2014 09:25:00 -0000
X-Bugzilla-Reason: CC
X-Bugzilla-Type: changed
X-Bugzilla-Watch-Reason: None
X-Bugzilla-Product: gcc
X-Bugzilla-Component: fortran
X-Bugzilla-Version: 4.10.0
X-Bugzilla-Keywords:
X-Bugzilla-Severity: normal
X-Bugzilla-Who: dominiq at lps dot ens.fr
X-Bugzilla-Status: NEW
X-Bugzilla-Priority: P3
X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org
X-Bugzilla-Target-Milestone: ---
X-Bugzilla-Flags:
X-Bugzilla-Changed-Fields:
Message-ID: <bug-61126-4-pPYpTdKgoe@http.gcc.gnu.org/bugzilla/>
In-Reply-To: <bug-61126-4@http.gcc.gnu.org/bugzilla/>
References: <bug-61126-4@http.gcc.gnu.org/bugzilla/>
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit
X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/
Auto-Submitted: auto-generated
MIME-Version: 1.0
X-SW-Source: 2014-05/txt/msg01711.txt.bz2
Content-length: 669

https://gcc.gnu.org/bugzilla/show_bug.cgi?ida126

--- Comment #23 from Dominique d'Humieres <dominiq at lps dot ens.fr> ---
Adding -Wall to the dg-options let the test succeed (in line with the gfortran
manual, see comment 21):

--- ../_clean/gcc/testsuite/gfortran.dg/wextra_1.f    2012-10-21
13:06:18.000000000 +0200
+++ gcc/testsuite/gfortran.dg/wextra_1.f    2014-05-15 12:05:56.000000000 +0200
@@ -1,5 +1,5 @@
 ! { dg-do compile }
-! { dg-options "-Wextra" }
+! { dg-options "-Wall -Wextra" }
       program main
       integer, parameter :: x=3 ! { dg-warning "Unused parameter" }
       real :: a

Indeed the questions asked in comment 22 should be answered.


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

* [Bug c/61236] GCC 4.9 generates incorrect object code
  2014-05-19 17:39 [Bug c/61236] New: GCC 4.9 generates incorrect object code muks at banu dot com
                   ` (10 preceding siblings ...)
  2014-05-20  9:02 ` pinskia at gcc dot gnu.org
@ 2014-05-20  9:31 ` muks at banu dot com
  11 siblings, 0 replies; 13+ messages in thread
From: muks at banu dot com @ 2014-05-20  9:31 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #16 from Mukund Sivaraman <muks at banu dot com> ---
(In reply to Andrew Pinski from comment #15)
> > At the very least, if it is possible to detect that the pointer is NULL by
> > static analysis and it is being passed to a function that has the notnull
> > attribute, please warn mentioning inferences being made.
> The warning did not make it into gcc 4.9 due to the patches to do the
> warning were not ready. Gcc 4.10 should warn about it. If it does not then
> that is a bug.

Thank you for this. :) It should detect at least some cases in that case.

If qsort() can cause this sort of disruption to a caller if NULL is passed, I
guess a change in glibc to add an assert(base != NULL) or similar abort is also
in order given that the caller code becomes buggy otherwise. Do you agree? This
would catch remaining cases before any inferred decisions are executed after
the qsort().


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

end of thread, other threads:[~2014-05-20  9:31 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-19 17:39 [Bug c/61236] New: GCC 4.9 generates incorrect object code muks at banu dot com
2014-05-19 17:46 ` [Bug c/61236] " muks at banu dot com
2014-05-19 17:49 ` muks at banu dot com
2014-05-19 17:53 ` muks at banu dot com
2014-05-19 18:13 ` trippels at gcc dot gnu.org
2014-05-19 18:15 ` trippels at gcc dot gnu.org
2014-05-19 19:05 ` trippels at gcc dot gnu.org
2014-05-19 21:07 ` jakub at gcc dot gnu.org
2014-05-20  7:16 ` jakub at gcc dot gnu.org
2014-05-20  8:07 ` pinskia at gcc dot gnu.org
2014-05-20  8:51 ` jakub at gcc dot gnu.org
2014-05-20  9:02 ` pinskia at gcc dot gnu.org
2014-05-20  9:31 ` muks at banu dot com

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