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 ï¬nds 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 ï¬nds 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-modiï¬able storage when the corresponding
parameter is not const-qualiï¬ed) or a type (after promotion) not expected by a
function
with variable number of arguments, the behavior is undeï¬ned.
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).