[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 Andy Lutomirski changed: What|Removed |Added CC||luto at mit dot edu --- Comment #2 from Andy Lutomirski --- I'd also like this feature. Not all standard open source projects use autoconf. For example, the Linux kernel doesn't. The Linux kernel *is* capable of probing for the existence of builtins, but it's a pain in the neck: it needs to write out a test .c file and try compiling it. This is slow, and it scales terribly: the configuration step wastes time proportional to the number of probed builtins probing for builtins, and the constant factor is pretty bad. It also means that the amount of work needed to use a new builtin is rather high: add a new config step and remember to use the result correctly in the code that uses the builtin. The name of the resulting macro can't really be standardized. Sure, with __has_builtin, users would still need to probe for __has_builtin itself, but that would be a single check. For builtins that are newer than __has_builtin, there would be no need to have a fallback and, for older builtins, a fallback could be added if needed. (Alternatively, the C code could simply not use the builtin on older gcc versions.)
[Bug rtl-optimization/67856] callee-saved register saves should be shrink-wrapped
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67856 --- Comment #4 from Andy Lutomirski --- I don't want to comment on how code generation works in GCC, but in terms of what works in the output: x86_64 generally has a 16-byte stack alignment in user code, which is two slots. (In the kernel, we use 8-byte alignment, since we don't use SSE/AVX.) This means that the stack is always aligned appropriately. For builds with frame pointers on, merely pushing %rbp aligns the stack, so splitting out the 'push %rbp' from the rest of the pushes doesn't leave an unaligned window. With frame pointers off, doing any odd number of pushes will similarly align the stack. For functions in which there's a control flow path from the beginning to the end that call nothing, then the alignment is irrelevant unless there's a 16-byte or higher aligned live variable on the stack.
[Bug rtl-optimization/67856] New: callee-saved register saves should be shrink-wrapped
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67856 Bug ID: 67856 Summary: callee-saved register saves should be shrink-wrapped Product: gcc Version: 5.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: luto at mit dot edu Target Milestone: --- This code: typedef _Bool bool; extern int a(void); /* used as a proxy for real code. */ volatile int x; bool func(void *regs) { int t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11; while (1) { int cached_flags = a(); if (!__builtin_expect(cached_flags & 31, 0)) break; t1 = x; t2 = x; t3 = x; t4 = x; t5 = x; t6 = x; t7 = x; t8 = x; t9 = x; t10 = x; t11 = x; x = t1; x = t2; x = t3; x = t4; x = t5; x = t6; x = t7; x = t8; x = t9; x = t10; x = t11; } return 0; } generates (gcc -O2 -S): .file "ra.c" .section.text.unlikely,"ax",@progbits .LCOLDB0: .text .LHOTB0: .p2align 4,,15 .globl func .type func, @function func: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 pushq %rbx .cfi_def_cfa_offset 24 .cfi_offset 3, -24 subq$8, %rsp .cfi_def_cfa_offset 32 .L3: calla testb $31, %al jne .L6 addq$8, %rsp .cfi_remember_state .cfi_def_cfa_offset 24 xorl%eax, %eax popq%rbx .cfi_def_cfa_offset 16 popq%rbp .cfi_def_cfa_offset 8 ret .p2align 4,,10 .p2align 3 .L6: .cfi_restore_state movlx(%rip), %ebp movlx(%rip), %ebx movlx(%rip), %r11d movlx(%rip), %r10d movlx(%rip), %r9d movlx(%rip), %r8d movlx(%rip), %edi movlx(%rip), %esi movlx(%rip), %ecx movlx(%rip), %edx movlx(%rip), %eax movl%ebp, x(%rip) movl%ebx, x(%rip) movl%r11d, x(%rip) movl%r10d, x(%rip) movl%r9d, x(%rip) movl%r8d, x(%rip) movl%edi, x(%rip) movl%esi, x(%rip) movl%ecx, x(%rip) movl%edx, x(%rip) movl%eax, x(%rip) jmp .L3 .cfi_endproc .LFE0: .size func, .-func .section.text.unlikely .LCOLDE0: .text .LHOTE0: .comm x,4,4 .ident "GCC: (GNU) 5.1.1 20150618 (Red Hat 5.1.1-4)" .section.note.GNU-stack,"",@progbits The unconditional pushes of rbp and rbx are missed optimizations: they should be sunk into the cold code that needs them pushed.
[Bug rtl-optimization/67856] callee-saved register saves should be shrink-wrapped
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67856 --- Comment #2 from Andy Lutomirski --- (In reply to Segher Boessenkool from comment #1) > The call to "a" needs the prologue, maybe to align the stack? The "subq $8, %rsp" is for stack alignment, and whether it's emitted depends on the parity of the number of pushes. I have no problem with it. The problem is that rbx and rbp are pushed. They shouldn't be. In a real function, it's worse: rbx, rbp, r12, r13, r14, and r15 all get pushed unnecessarily. I just had a bunch of fun refactoring my big Linux entry code rewrite to minimize the amount of pain that this issue causes.
[Bug inline-asm/66631] inability to clobber segment regs makes tls problematic
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66631 Andy Lutomirski luto at mit dot edu changed: What|Removed |Added CC||luto at mit dot edu --- Comment #17 from Andy Lutomirski luto at mit dot edu --- I'll chime in, possibly uselessly. Before Linux 4.1, only CS was saved. (Unless you go *way* back.) In 4.1 or newer, SS is saved, too. In 64-bit code, DS and ES have no effect*, so I don't think it should affect code gen. FS and GS are weird, and they may get weirder when WRGSBASE and friends are enabled, which will happen at some point. Anyway, I tend to agree with Andrew here, I think: if you want to fiddle with FS and GS, write a little asm wrapper around the C code. * Except in an odd case on AMD processors that is mostly invisible to userspace. On new enough kernels, it's completely invisible to userspace, and I don't think it was ever visible without long jumps or such.
[Bug c/66795] New: Incorrect and missed optimizations of __builtin_frame_address
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66795 Bug ID: 66795 Summary: Incorrect and missed optimizations of __builtin_frame_address Product: gcc Version: 5.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: luto at mit dot edu Target Milestone: --- Here's an evil little program (x86_64-specific, although I suspect that a trivial change would have the same effect on x86_32): #include stdio.h #include unistd.h void target(void) { printf(Here\n); _exit(0); } __attribute__((noinline,noclone)) void escape(void *x) { /* Weird: this is needed to cause the call to escape to be emitted. */ asm volatile (); } int main() { unsigned long *frame = __builtin_frame_address(0); frame[1] = (unsigned long)target; /* Uncommenting this fixes it: asm volatile (nopq %0 : : m (frame[1])); */ /* Oddly, this does *not* fix it. */ asm volatile (nopq %0 : : r (frame)); /* Uncommenting this also fixes it: escape(frame); */ return 0; } Compiled without -O2, this program prints Here and exits. Compiled with -O2, it does nothing. Examining the asm indicates that the assignment to frame[1] never happens. I think this means that, somehow, that assignment is considered a dead store, despite the fact that it's very much not dead. For one thing, it's an assignment to the return frame. It has an effect. (Yes, this is evil, but I actually want to do something like this in Linux to access the caller's frame where the caller is written in assembly.) My best guess is that the return value from __builtin_frame_address is treated as a pointer to a local, non-escaped array. But this makes no sense to me (even if it were a reasonable assumption), as the r (frame) constraint should cause the compiler to realize that it has escaped. I think there's also a missed optimization here. Using __builtin_frame_address(0) appears to force the creation of a frame pointer. Why should it need to do that? Gcc should be able to figure out where the frame starts without having to refer to the base pointer.
[Bug target/53383] Allow -mpreferred-stack-boundary=3 on x86-64
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53383 Andy Lutomirski luto at mit dot edu changed: What|Removed |Added CC||luto at mit dot edu --- Comment #19 from Andy Lutomirski luto at mit dot edu --- I don't think the fix is correct. This works: gcc -mno-sse -mpreferred-stack-boundary=3 ... This does not: gcc -mno-sse -mpreferred-stack-boundary=3 -mincoming-stack-boundary=3 ... This makes no sense, since they should be equivalent. Also, I find the docs to be unclear as to what different values of the incoming and preferred stack boundaries mean. Finally, why is -mno-sse required in order to set a low stack boundary? Couldn't gcc figure out that the existence of a stack variable (SSE, alignas, __attribute__((aligned(32))), etc) should force dynamic stack alignment? In fact, that should be necessary, and already appears to work, for __attribute__((aligned(32))), as gcc generates correct code for this: typedef int __attribute__((aligned(32))) int_aligned_32; extern void func2(int_aligned_32 *x); void func(void) { int_aligned_32 x; func2(x); }
[Bug target/53383] Allow -mpreferred-stack-boundary=3 on x86-64
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53383 --- Comment #21 from Andy Lutomirski luto at mit dot edu --- (In reply to H.J. Lu from comment #20) (In reply to Andy Lutomirski from comment #19) I don't think the fix is correct. This works: gcc -mno-sse -mpreferred-stack-boundary=3 ... This does not: gcc -mno-sse -mpreferred-stack-boundary=3 -mincoming-stack-boundary=3 ... Please provide a testcase. No code needed: $ touch foo.c $ gcc -c -mno-sse -mpreferred-stack-boundary=3 -mincoming-stack-boundary=3 foo.c foo.c:1:0: error: -mincoming-stack-boundary=3 is not between 4 and 12 $ gcc -c -mno-sse -mpreferred-stack-boundary=3 foo.c This makes no sense, since they should be equivalent. Also, I find the docs to be unclear as to what different values of the incoming and preferred stack boundaries mean. Finally, why is -mno-sse required in order to set a low stack boundary? Couldn't gcc figure out that the existence of a stack variable (SSE, alignas, __attribute__((aligned(32))), etc) should force dynamic stack alignment? Since the x86-86 psABI says that stack must be 16 byte aligned, if the stack isn't 16-byte aligned, the code with SSE insn, which follows the psABI, will crash when called with 8-byte aligned stack. I'm confused here. I agree in principle, but I don't actually think that gcc works this way, or, if it does, it shouldn't. If I compile with -mpreferred-stack-boundary=3 and create an aligned(32) local variable, then gcc will dynamically align the stack and the variable will have correct alignment even if the incoming stack was not 16-byte aligned. Shouldn't an SSE variable work exactly the same way? That is, if gcc is generating an SSE instruction with a memory reference to an on-stack variable that requires 16-byte alignment (movdqa, for example), wouldn't that variable be effectively aligned(16) or greater and thus trigger dynamic stack alignment. Sure, the generated SSE code will be less efficient with -mpreferred-stack-boundary=3 (because neither and $-16,%rsp nor the required frame pointer is free), but it should still work, right?
[Bug c/61129] Feature request: integer-overflow-detecting arithmetic intrinsics
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61129 Andy Lutomirski luto at mit dot edu changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #5 from Andy Lutomirski luto at mit dot edu --- According to https://gcc.gnu.org/gcc-5/changes.html, this is now implemented. Thanks!
[Bug c++/59500] Bogus maybe-uninitialized warning due to optimizations
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59500 --- Comment #3 from Andy Lutomirski luto at mit dot edu --- Created attachment 33484 -- https://gcc.gnu.org/bugzilla/attachment.cgi?id=33484action=edit Headerless reproducer (c++ only)
[Bug c++/59500] Bogus maybe-uninitialized warning due to optimizations
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59500 --- Comment #4 from Andy Lutomirski luto at mit dot edu --- Created attachment 33485 -- https://gcc.gnu.org/bugzilla/attachment.cgi?id=33485action=edit Output from g++ -O2 -Wall -fdump-tree-all-all-lineno pr59500.cc
[Bug middle-end/56574] False possibly uninitialized variable warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56574 --- Comment #10 from Andy Lutomirski luto at mit dot edu --- See PR59500 for another example without . I think I can reduce another test case with only if and else.
[Bug middle-end/56574] False possibly uninitialized variable warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56574 Andy Lutomirski luto at mit dot edu changed: What|Removed |Added CC||luto at mit dot edu --- Comment #7 from Andy Lutomirski luto at mit dot edu --- I think this has gotten worse in newer GCC versions. I'm up to six independent triggers of this bug in my tree.
[Bug c/61129] New: Feature request: integer-overflow-detecting arithmetic intrinsics
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61129 Bug ID: 61129 Summary: Feature request: integer-overflow-detecting arithmetic intrinsics Product: gcc Version: unknown Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: luto at mit dot edu Clang has a fairly complete family of intrinsics to do integer arithmetic with overflow detection. They include function like __builtin_uadd_overflow, and they are described here: http://clang.llvm.org/docs/LanguageExtensions.html#checked-arithmetic-builtins Please consider supporting these in GCC as well.
[Bug c/60693] New: ICE on funny memcpy
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60693 Bug ID: 60693 Summary: ICE on funny memcpy Product: gcc Version: 4.8.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: luto at mit dot edu This little program: int main() { char buf[4096]; memcpy(buf, (void *)0xff60, 4096); return 0; } does this: $ gcc ice.c ice.c: In function ‘main’: ice.c:4:3: warning: incompatible implicit declaration of built-in function ‘memcpy’ [enabled by default] memcpy(buf, (void *)0xff60, 4096); ^ ice.c:4:9: internal compiler error: in ix86_copy_addr_to_reg, at config/i386/i386.c:21886 memcpy(buf, (void *)0xff60, 4096); ^ Please submit a full bug report, with preprocessed source if appropriate. See http://bugzilla.redhat.com/bugzilla for instructions. Preprocessed source stored into /tmp/ccJqACry.out file, please attach this to your bugreport. This is gcc (GCC) 4.8.2 20131212 (Red Hat 4.8.2-7).
[Bug c++/59930] New: template friend declarations, namespaces, and explicit instantiations don't mix
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59930 Bug ID: 59930 Summary: template friend declarations, namespaces, and explicit instantiations don't mix Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: luto at mit dot edu namespace NS { templatetypename T class Holder { private: void func(); templatetypename friend class User; }; template class Holderlong; templatetypename T class User { public: void method() const { HolderT x; x.func(); } }; } // namespace // This one is okay, oddly. // template class NS::Holderlong; void Foo() { NS::Userlong decl; decl.method(); } says (in trunk r207012): $ g++-trunk -Wall -c template_friend.cc template_friend.cc: In instantiation of ‘void NS::UserT::method() const [with T = long int]’: template_friend.cc:34:14: required from here template_friend.cc:7:7: error: ‘void NS::HolderT::func() [with T = long int]’ is private void func(); ^ template_friend.cc:22:3: error: within this context x.func(); ^ The 4.8 branch can't compile this either, but clang is okay with it. Oddly, removing the namespace, removing the explicit instantiation, or moving the explicit instantiation outside the namespace causes g++ to accept this code.
[Bug c++/58116] missed-optimization: const temporaries could be promoted to static
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58116 --- Comment #4 from Andy Lutomirski luto at mit dot edu --- Sorry -- I forgot about the recursive / threaded case. (I keep meaning to propose something like [[non_unique_address]] to enable optimizations like this and things zero-byte struct members.)
[Bug c++/59500] Bogus maybe-unintialized warning due to optimizations
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59500 --- Comment #1 from Andy Lutomirski luto at mit dot edu --- This might be a duplicate of PR56574
[Bug c++/59500] New: Bogus maybe-unintialized warning due to optimizations
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59500 Bug ID: 59500 Summary: Bogus maybe-unintialized warning due to optimizations Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: luto at mit dot edu I would have sworn that there was a bug open about this, but I can't find it, and this bug has been annoying me for years. Compiling this code with g++ -O2 -Wall: #ifndef __cplusplus #include stdbool.h #endif extern int intval(); extern bool cond(); int main() { bool valid = false; int value; if (cond()) { valid = true; value = intval(); } while (!valid || intval() value) ; return 0; } says: trivial_uninit_warning.cc: In function ‘int main()’: trivial_uninit_warning.cc:18:17: warning: ‘value’ may be used uninitialized in this function [-Wmaybe-uninitialized] while (!valid || intval() value) Oddly, compiling exactly the same code in C (instead of C++) does not warn. This seems quite sensitive to exactly what the code is doing. IIRC the issue is that the load of value is moved ahead of the check of valid by the optimizer (which is entirely valid), but then that load appears to access an uninitialized value and warns.
[Bug c/59197] New: An alias from an always_inline function causes inconsistent behavior
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59197 Bug ID: 59197 Summary: An alias from an always_inline function causes inconsistent behavior Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: luto at mit dot edu This program: extern void func(void); extern __inline __attribute__((__always_inline__)) __attribute__((__gnu_inline__)) void func(void) { } extern void alias_target_func(void) {} extern void func(void) __attribute__((alias(alias_target_func))); extern void caller(void) { func(); } fails to compile on 4.7, 4.8, and trunk with -c -fPIC -O2, saying: inline_alias.c: In function ‘caller’: inline_alias.c:5:13: error: inlining failed in call to always_inline ‘func’: function body can be overwritten at link time extern void func(void) __attribute__((alias(alias_target_func))); ^ inline_alias.c:9:7: error: called from here func(); ^ It compiles on an old copy of gcc 4.5 I have lying around, although I don't think I agree with the generated code. gcc 4.5.1 (and gcc 4.8.2 with -O0) emit the call to func. With the alias removed, the call to func is not emitted, even at -O0. Oddly, without -fPIC, gcc 4.8 and trunk inline the call to func. trunk's behavior with -O0 (w/o -fPIC) is even stranger: it emits a call to alias_target_func. I can't reproduce that with other flags or on gcc 4.8. I think that the correct behavior would be to either (a) reject the alias as a redefinition of func or (b) accept this code as valid and inline func. Given the documented behavior for extern __attribute__((gnu_inline)), the inline version of func should be used (or this code should be rejected outright). This may be related to PR33763 or PR46596, but I don't think it's the same issue as either one, although the respective fixes could be involved in the behavior changes. It came up in practice when openonload-201310 failed to build with _FORTIFY_SOURCE=2.
[Bug libstdc++/59177] New: steady_clock::now() and system_clock::now do not use the vdso (and are therefore very slow)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59177 Bug ID: 59177 Summary: steady_clock::now() and system_clock::now do not use the vdso (and are therefore very slow) Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: luto at mit dot edu std::chrono::steady_clock::now() does this: #ifdef _GLIBCXX_USE_CLOCK_GETTIME_SYSCALL syscall(SYS_clock_gettime, CLOCK_MONOTONIC, tp); #else clock_gettime(CLOCK_MONOTONIC, tp); #endif I'm not sure what the intent of this condition is, but the effect is that glibc's clock_gettime (which is very carefully optimized and avoids using syscalls) is ignored in favor of using syscall(2) (which is very slow). This appears to have been introduced by this commit: http://gcc.gnu.org/ml/libstdc++/2013-05/txtfX2KusGj9C.txt It's a serious slowdown: steady_clock::now(): 0.0933114µs per iteration clock_gettime: 0.0230129µs per iteration as measured by: #include chrono #include iostream #include time.h using namespace std; constexpr int iters = 1; typedef chrono::durationdouble dsecs; int main() { auto start = chrono::steady_clock::now(); for (int i = 0; i iters; i++) chrono::steady_clock::now(); auto end = chrono::steady_clock::now(); std::cout steady_clock::now(): 1e6 * chrono::duration_castdsecs(end-start).count() / iters µs per iteration\n; start = chrono::steady_clock::now(); timespec ts; for (int i = 0; i iters; i++) clock_gettime(CLOCK_MONOTONIC, ts); end = chrono::steady_clock::now(); std::cout clock_gettime: 1e6 * chrono::duration_castdsecs(end-start).count() / iters µs per iteration\n; } system_clock appears to behave identically.
[Bug libstdc++/59177] steady_clock::now() and system_clock::now do not use the vdso (and are therefore very slow)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59177 --- Comment #3 from Andy Lutomirski luto at mit dot edu --- I can't get gcc trunk to build right now, but I just distcleaned and rebuilt the 4.8 branch truck on Fedora 19, which has glibc-2.17-19.fc19.x86_64. It defines _GLIBCXX_USE_CLOCK_GETTIME_SYSCALL. This happens because: configure:19349: checking for clock_gettime, nanosleep and sched_yield configure:19378: result: no I think that the underlying problem is that --enable-libstdcxx-time defaults to no. Shouldn't it default to yes (and hence run the fancy configure checks)? Configuring with ./configure --enable-libstdcxx-time does the right thing.
[Bug libstdc++/59177] steady_clock::now() and system_clock::now do not use the vdso (and are therefore very slow)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59177 Andy Lutomirski luto at mit dot edu changed: What|Removed |Added Version|4.9.0 |4.8.3 --- Comment #5 from Andy Lutomirski luto at mit dot edu --- Aha. I think the issue is only in 4.8. libstdc++-v3/configure.ac says: # For clock_gettime, nanosleep and sched_yield support. # NB: The default is [no], because otherwise it requires linking. GLIBCXX_ENABLE_LIBSTDCXX_TIME([no]) Aside from the typo in the comment (the end of the sentence seems to have disappeared), I'm still confused. Even in the 4.8 branch, enable_libstdcxx_time=yes doesn't appear to link in librt; only enable_libstdcxx_time=rt seems to have that effect. (Please accept my apologies if I'm just completely confused about how autoconf works here.)
[Bug libstdc++/59177] steady_clock::now() and system_clock::now do not use the vdso (and are therefore very slow)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59177 --- Comment #7 from Andy Lutomirski luto at mit dot edu --- I guess what I'm saying is: what's wrong with yes in 4.8? From looking at the code, it still seems like it does the right thing (i.e. not using clock_gettime if it's not in [posix4]).
[Bug libstdc++/59177] steady_clock::now() and system_clock::now do not use the vdso (and are therefore very slow)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59177 --- Comment #9 from Andy Lutomirski luto at mit dot edu --- Given that this is C++11-only, it's already fixed on trunk, it's only a performance issue (as opposed to correctness), and it's more complicated than just changing the default, I won't argue for a backport. From my perspective, feel free to close this.
[Bug libstdc++/59177] steady_clock::now() and system_clock::now do not use the vdso (and are therefore very slow)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59177 --- Comment #12 from Andy Lutomirski luto at mit dot edu --- D'oh! I assumed that it was the resulting library (and thus that it would require linking *against librt*), not that it was the configure test.
[Bug c++/58116] New: missed-optimization: const temporaries could be promoted to static
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58116 Bug ID: 58116 Summary: missed-optimization: const temporaries could be promoted to static Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: luto at mit dot edu This code: struct S { int a, b, c; }; extern void callee(const S s); void test() { const S s{1,2,3}; callee(s); callee((const S){1,2,3}); } would be shorter and faster if both S instances were promoted to statics. This would be correct because it's undefined behavior to modify a non-mutable member of an object declared const in C++. (I'm not sure about C.)
[Bug rtl-optimization/10837] noreturn attribute causes no sibling calling optimization
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10837 Andy Lutomirski luto at mit dot edu changed: What|Removed |Added CC||luto at mit dot edu --- Comment #9 from Andy Lutomirski luto at mit dot edu --- In this case, perhaps sibling call optimization is the wrong thing here. The caller of a noreturn function shouldn't pop the stack, but it also shouldn't save registers (and, if it doesn't need to save registers, it shouldn't create a stack frame in the first place).
[Bug c++/57998] New: Unhelpful error message when a class has no move constructor
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57998 Bug ID: 57998 Summary: Unhelpful error message when a class has no move constructor Product: gcc Version: 4.8.1 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: luto at mit dot edu When trying and failing to move an object because the move constructor is deleted, the error message tells you so. When there is no move constructor at all, however, the error message is unhelpful. For example, this: #include utility struct move_only { move_only() = default; move_only(move_only) = default; move_only operator = (move_only) = default; }; struct broken : move_only { move_only mo; ~broken() {} }; void test() { broken a; broken b(std::move(a)); } is correctly rejected with this error: move_base.cc: In function ‘void test()’: move_base.cc:19:24: error: use of deleted function ‘broken::broken(const broken)’ broken b(std::move(a)); ^ move_base.cc:10:8: note: ‘broken::broken(const broken)’ is implicitly deleted because the default definition would be ill-formed: struct broken : move_only ^ move_base.cc:10:8: error: use of deleted function ‘constexpr move_only::move_only(const move_only)’ move_base.cc:3:8: note: ‘constexpr move_only::move_only(const move_only)’ is implicitly declared as deleted because ‘move_only’ declares a move constructor or move assignment operator struct move_only ^ move_base.cc:10:8: error: use of deleted function ‘constexpr move_only::move_only(const move_only)’ struct broken : move_only ^ It would be much more helpful if there was another line saying something like broken::broken(broken) is suppressed because broken has a user-defined destructor.
[Bug c++/57815] New: [c++11] Error spew on misspelled initializer lists
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57815 Bug ID: 57815 Summary: [c++11] Error spew on misspelled initializer lists Product: gcc Version: 4.7.4 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: luto at mit dot edu [This is fixed in trunk. If the stable branch policy means it can't get backported, then so be it. I'm filing the bug because this issue is *really* annoying.] This erroneous code: // Adding 'struct misspelled {int a, bc[2];};' makes this compile void func() { misspelled object{1, {2, 3}}; } Seems to throw the parser into an awful state. The 4.7 branch says: brace_problem.cc: In function ‘void func()’: brace_problem.cc:4:3: error: ‘misspelled’ was not declared in this scope brace_problem.cc:4:14: error: expected ‘;’ before ‘object’ brace_problem.cc:5:1: error: expected ‘}’ at end of input This isn't so bad in a program this short, but in a bigger program I'm getting multiple pages of errors scattered around the file, so finding the actual problem is a needle-in-a-haystack problem. If the offending code is inside a class definition, then a bunch of the bogus errors are *before* the correct one. Trunk from today gets this right: brace_problem.cc: In function ‘void func()’: brace_problem.cc:4:3: error: ‘misspelled’ was not declared in this scope misspelled object{1, {2, 3}}; ^
[Bug c++/57746] rejected valid specialization of member function of class template (I think)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57746 --- Comment #6 from Andy Lutomirski luto at mit dot edu --- Jonathan Wakely wrote in comment #4: (In reply to Andy Lutomirski from comment #4) [temp.explicit].4 says A declaration of [list including member function] ... A definition of [list not including member function]. If definitions were intended to be declarations in this context, then the second part would be redundant, I think. That doesn't follow at all. The second part describes different types of entities that have different requirements. For the first list an explicit instantiation must follow a declaration (and a definition also counts as a declaration) but for the second list an explicit instantiation must follow a definition, a declaration is not sufficient. Ugh. In that case, [temp.explicit].4 is irrelevant. I guess it means that, if you explicitly instantiate something, then a declaration and/or definition must happen before that instantiation, and it probably doesn't mean that a declaration and/or definition can't follow that explicit instantiation. Regardless, the interesting case is: templatetypename T struct X { static int val; static void func(); }; // optionally: extern template struct Xint; void something() { Xint::func(); } in one file and struct X { static int val; static void func(); }; template void Xint::func() {} in another. I don't think this is an odr violation, since there is only one definition of anything that could be confused with Xint::func. g++ will happily compile and link it (without the extern template bit) and it will work. It is supposed to? Could a conforming compiler mangle the specialized version of func differently? Isn't this ill-formed, with no diagnostic required, by both [temp] p6 and [temp.expl.spec] p6? ...so this proves that I know considerably less about C++ templates than I thought I did. Apparently even a translation unit containing exactly: templatetypename T void func(); void caller() { funcint(); } is ill-formed. I wonder why. g++ and clang++ both accept it, I think (from memory) that MSVC accepts it as well, and I wouldn't be surprised if there are quite a few libraries that rely on this behavior.
[Bug c++/57746] Invalid specializations of member objects are accepted, unlike member functions
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57746 Andy Lutomirski luto at mit dot edu changed: What|Removed |Added Summary|rejected valid |Invalid specializations of |specialization of member|member objects are |function of class template |accepted, unlike member |(I think) |functions --- Comment #8 from Andy Lutomirski luto at mit dot edu --- OK, I'm convinced. I renamed the bug accordingly.
[Bug c++/57746] rejected valid specialization of member function of class template (I think)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57746 --- Comment #4 from Andy Lutomirski luto at mit dot edu --- Daniel, I'm unconvinced that your interpretation is the intended one. [temp.explicit].4 says A declaration of [list including member function] ... A definition of [list not including member function]. If definitions were intended to be declarations in this context, then the second part would be redundant, I think. Regardless, the interesting case is: templatetypename T struct X { static int val; static void func(); }; // optionally: extern template struct Xint; void something() { Xint::func(); } in one file and struct X { static int val; static void func(); }; template void Xint::func() {} in another. I don't think this is an odr violation, since there is only one definition of anything that could be confused with Xint::func. g++ will happily compile and link it (without the extern template bit) and it will work. It is supposed to? Could a conforming compiler mangle the specialized version of func differently?
[Bug c++/57746] New: rejected valid specialization of member function of class template (I think)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57746 Bug ID: 57746 Summary: rejected valid specialization of member function of class template (I think) Product: gcc Version: 4.7.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: luto at mit dot edu Note: I could easily be wrong here... templatetypename T struct X { static int val; static void func(); }; extern template struct Xint; template int Xint::val = 5; // OK template void Xint::func() {} // Error g++ 4.7.2 and some pre-4.8 build say error: specialization of ‘static void XT::func() [with T = int]’ after instantiation. Oddly, both accept the specialization of val. clang++ rejects both. The relevant part of the standard is probably [temp.explicit.4], which says: A declaration of a function template, a member function or static data member of a class template, or a member function template of a class or class template shall precede an explicit instantiation of that entity. A definition of a class template, a member class of a class template, or a member class template of a class or class template shall precede an explicit instantiation of that entity unless the explicit instantiation is preceded by an explicit specialization of the entity with the same template arguments. If the declaration of the explicit instantiation names an implicitly-declared special member function (Clause 12), the program is ill-formed. The two specializations are definitions, not declarations, as far as I know. Therefore, [temp.explicit.4] shouldn't apply.
[Bug c++/57301] New: bit rotation is not optimized in c but not c++
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57301 Bug ID: 57301 Summary: bit rotation is not optimized in c but not c++ Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: luto at mit dot edu It's well known [citation needed] that modern compilers are excellent at optimizing simple bit twiddling. Unfortunately, while gcc is, g++ is not. (See PR29749 for where gcc gained this ability.) Here's a trivial example borrowed from gcc/testsuite/gcc.dg/fold-rotate-1.c: unsigned short f1 (unsigned short a) { return a 8 | a 8; } gcc -O2 (4.7 and some random 4.8 build) generates: f1: .LFB0: .cfi_startproc movl%edi, %eax rolw$8, %ax ret .cfi_endproc clang -O2 generates: f1: # @f1 .cfi_startproc # BB#0: rolw$8, %di movzwl %di, %eax ret (I suspect that these are equally good.) clang++ -O2 generates: _Z2f1t: # @_Z2f1t .cfi_startproc # BB#0: rolw$8, %di movzwl %di, %eax ret All unsurprising. But g++ -O2 generates: _Z2f1t: .LFB0: .cfi_startproc movzwl %di, %edi movl%edi, %eax sarl$8, %edi sall$8, %eax orl %edi, %eax ret .cfi_endproc Perhaps some decent subset of the gcc testsuite should also be built with the c++ frontend to make sure it still passes...
[Bug c/56527] New: Provide an import counterpart to attribute((visibility(protected)))
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56527 Bug #: 56527 Summary: Provide an import counterpart to attribute((visibility(protected))) Classification: Unclassified Product: gcc Version: unknown Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu This is a common idiom: #ifdef BUILDING_LIBWHATEVER #define LIBWHATEVER_API __attribute__((visibility(protected))) #else #define LIBWHATEVER_API ??? #endif Protected can be replaced with default without changing anything. The issue is: what to specify for imports (the ??? above). The common approach seems to be __attribute__((visibility(default))), since hidden is asking for trouble and protected won't link due to undefined protected symbols. Neither one is good. I want an attribute (which could be a new visibility) that acts like default visibility for undefined symbols, like default visibility [1] for inline defined symbols, and fails to compile for non-inline symbols. (In this definition, inline should probably include implicitly instantiated templates as well.) This will catch errors when a non-inline function is defined in the right place. [1] This isn't quite ideal. To avoid interposing a possible protected instantiation of an inline function, these should probably end up as default visibility but weak. P.S. It would be neat if calls to functions with this attribute generated explicit GOT references rather than going to the PLT. (IMO Windows gets this right.)
[Bug c/56527] Provide an import counterpart to attribute((visibility(protected)))
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56527 --- Comment #1 from Andy Lutomirski luto at mit dot edu 2013-03-05 00:37:20 UTC --- In fact, without an improvement like this, protected visibility is unusable on objects -- anything linking against a protected object will generate a copy relocation. The fact that the resulting binary is even loadable is IMO a bug (whether in binutils for generating it or in glibc for loading it is debatable.)
[Bug c++/55540] New: The C++ literal -9223372036854775808 is misinterpreted
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55540 Bug #: 55540 Summary: The C++ literal -9223372036854775808 is misinterpreted Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu The literal -9223372036854775808LL has type __int128 and says warning: integer constant is so large that it is unsigned [enabled by default]. Both of these properties of that literal are incorrect, and, for good measure, they are inconsistent with each other. This is demonstrated in this C++11 code (for clarity -- a similar test in C++98 would show similar results): #include type_traits #include limits // Using -9223372036854775807 instead works. constexpr auto n = -9223372036854775808; static_assert(n == std::numeric_limitslong long::min(), This test passes); // This line assumes that long is 64-bit. static_assert(std::is_samedecltype(n), const long::value, n has the wrong type); templatetypename T struct what_is_t { static_assert(sizeof(T) != sizeof(T), This is n's type); }; what_is_tdecltype(n) x; which produces this output: $ g++-trunk -std=gnu++0x big_negative_literal.cc big_negative_literal.cc:6:21: warning: integer constant is so large that it is unsigned [enabled by default] constexpr auto n = -9223372036854775808; ^ big_negative_literal.cc:10:1: error: static assertion failed: n has the wrong type static_assert(std::is_samedecltype(n), const long::value, n has the wrong type); ^ big_negative_literal.cc: In instantiation of ‘struct what_is_tconst __int128’: big_negative_literal.cc:18:24: required from here big_negative_literal.cc:15:3: error: static assertion failed: This is n's type static_assert(sizeof(T) != sizeof(T), This is n's type); ^ Quoting from [lex.icon]: The type of an integer literal is the first of the corresponding list in Table 6 in which its value can be represented. The first type with this property is long int (if 64-bits) or long long int (otherwise). The warning is totally incorrect: the literal may be large, but it both is and should be *signed*.
[Bug c++/55540] The C++ literal -9223372036854775808 is misinterpreted
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55540 --- Comment #2 from Andy Lutomirski luto at mit dot edu 2012-11-29 22:58:44 UTC --- Gack. I'm still at a loss as to where __int128 is coming from. I don't think it's an integral promotion.
[Bug target/55522] -funsafe-math-optimizations is unexpectedly harmful, especially w/ -shared
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55522 --- Comment #3 from Andy Lutomirski luto at mit dot edu 2012-11-30 01:41:14 UTC --- I'm still unconvinced that it makes sense as part of -funsafe-math-optimizations at all. It's not an optimization in the sense that people usually think of when looking at compiler flags.
[Bug c++/55522] New: -funsafe-math-optimizations is unexpectedly harmful, especially w/ -shared
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55522 Bug #: 55522 Summary: -funsafe-math-optimizations is unexpectedly harmful, especially w/ -shared Classification: Unclassified Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu The docs for -funsafe-math-optimizations say: When used at link-time, it may include libraries or startup files that change the default FPU control word or other similar optimizations. This is, IMO, really bad. One might naively assume (if you haven't thought about that) that -ffast-math and -funsafe-math-optimizations merely affect code generation. This is true if you *compile* with -ffast-math, but if you *link* with it, then you end up breaking IEEE758 semantics program-wide. This causes real-life problems. Please consider some combination of: 1. Making -funsafe-math-optimizations illegal when combined with -shared. 2. Splitting the inclusion of crtfastmath.o into its own option (-funsafe-math-mode-at-startup, perhaps) and make -ffast-math (and -Ofast) not set that one. 3. Mention in the docs just how bad this is in shared libraries.
[Bug c++/55522] -funsafe-math-optimizations is unexpectedly harmful, especially w/ -shared
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55522 --- Comment #1 from Andy Lutomirski luto at mit dot edu 2012-11-29 01:48:53 UTC --- I mean IEEE754, of course.
[Bug c++/55347] New: Specialized member of class template prevents visibility setting
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55347 Bug #: 55347 Summary: Specialized member of class template prevents visibility setting Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu Compiling this code: --- cut here --- templatetypename T class A { void func() {} }; //#pragma GCC visibility push(default) -- no effect template void Aint::func() {} // This causes a problem template class __attribute__((visibility(default))) Aint; //#pragma GCC visibility pop --- cut here --- results in: template_visibility.cc:10:55: warning: type attributes ignored after type is already defined [-Wattributes] The emitted code ends up hidden. This is a minor issue in C++98 (I'm not sure why you'd want to do this), but it's an actual problem in C++11: extern templates behave the same way. I think that gcc's behavior is consistent, but there should be a way to override the visibility of a particular class template specialization *without instantiating/defining it*, then specialize a member, then instantiate the template.
[Bug other/55307] New: libgcc's __cpu_indicator_init does not check for avx correctly
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55307 Bug #: 55307 Summary: libgcc's __cpu_indicator_init does not check for avx correctly Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: other AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu [this is a libgcc bug, and I haven't tested it -- the test is a PITA.] One might expect that __builtin_cpu_supports(avx) would only return true if avx is usable. Unfortunately, it returns true iff avx is implemented by the cpu, regardless of whether it should be expected to work. The code should check for osxsave and then use xgetbv to see if ymm state is available. This is more or less the same bug as glibc bug 13007 [1]. There's an intel blog post on the subject at [2]. It's likely to result in crashes if old kernels are run on new hardware. Curiously, the code in gcc/testsuite/gcc.target/i386/avx-check.h appears correct. I suspect it's never been run with ymm state disabled. [1] http://sourceware.org/bugzilla/show_bug.cgi?id=13007 [2] http://software.intel.com/en-us/blogs/2011/04/14/is-avx-enabled/
[Bug c++/55029] New: constexpr bug: lvalue required?
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55029 Bug #: 55029 Summary: constexpr bug: lvalue required? Classification: Unclassified Product: gcc Version: 4.6.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu This code: - templateint x class A { public: constexpr A() : val_(0) {} static constexpr A Func(int units) { return A(); } templateint y explicit operator Ay() const; private: int val_; A(double); }; struct Foo { static constexpr A2 z = A2::Func(0); }; - fails on gcc 4.6 with 20:41: error: lvalue required as unary ‘’ operand gcc 4.7 and trunk is okay.
[Bug c++/54021] [c++0x] __builtin_constant_p should be constexpr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54021 --- Comment #8 from Andy Lutomirski luto at mit dot edu 2012-09-09 06:05:34 UTC --- Did you mean constexpr bool a instead of book const a? If so, I agree. But consider: bool const a = something complicated Is a a constant?
[Bug c++/54021] [c++0x] __builtin_constant_p should be constexpr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54021 --- Comment #6 from Andy Lutomirski luto at mit dot edu 2012-09-08 22:29:17 UTC --- I think that's correct. x isn't a standards-mandated constant expression, so __builtin_constant_p depends on optimization level and probably shouldn't be allowed as a constexpr.
[Bug c++/54336] New: [c++0x] diagnostics for functions with arg-dependent return types have bad signatures
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54336 Bug #: 54336 Summary: [c++0x] diagnostics for functions with arg-dependent return types have bad signatures Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: minor Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu This code: templatetypename T auto func(T x) - decltype(x.method()) { static_assert(false, test); } fails to compile with: decltype_return.cc: In function 'decltype (x.method()) func(T)': decltype_return.cc:3:3: error: static assertion failed: test static_assert(false, test); ^ What's 'decltype (x.method()) func(T)'? x isn't defined. 'auto func(T x) - decltype(x.method())' or even 'decltype (x.method()) func (T x)' would be better.
[Bug c++/54336] [c++0x] diagnostics for functions with arg-dependent return types have bad signatures
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54336 --- Comment #2 from Andy Lutomirski luto at mit dot edu 2012-08-20 23:21:32 UTC --- Fair enough. Here's a better example: struct A { int method(); }; templatetypename T auto func(T x) - decltype(x.method()) { bogus(x); } int main() { func(A()); } The error is: decltype_return.cc: In instantiation of 'decltype (x.method()) func(T) [with T = A; decltype (x.method()) = int]': decltype_return.cc:8:22: required from here decltype_return.cc:5:3: error: 'bogus' was not declared in this scope bogus(x); ^ 'decltype (x.method())' is still meaningless in that context. Even just 'auto func(T) [with ...; auto = int]' might be less puzzling. (This is a very minor issue -- I just found it puzzling when I hit it earlier today in an STL error message.)
[Bug c++/54020] [c++0x] incorrectly accepted constexpr functions
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54020 --- Comment #2 from Andy Lutomirski luto at mit dot edu 2012-07-19 15:41:51 UTC --- I clearly failed at reading comprehension yesterday. Maybe this should be considered as more of an enhancement request (like PR54021): it would be nicer for the user if constexpr worked the same with an without optimization. Otherwise there'll probably be reports of code that builds at -O2 but not -O0.
[Bug c++/54020] New: [c++0x] incorrectly accepted constexpr functions
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54020 Bug #: 54020 Summary: [c++0x] incorrectly accepted constexpr functions Classification: Unclassified Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu Tested on a somewhat recent trunk build as well as 4.7-some branch version. // Preliminaries. extern int nonconst_func(int); constexpr int identity(int x) { return x; } constexpr int zero() { return identity(0); } constexpr int one() { return identity(1); } // Correctly accepted. constexpr int three = one() ? 3 : nonconst_func(0); // Incorrectly accepted. See [dcl.constexpr] #5: // For a constexpr function, if no function argument values exist // such that the function invocation sub-stitution would produce a // constant expression (5.19), the program is ill-formed; no diagnostic // required. constexpr int bogus() { return zero () ? 3 : nonconst_func(0); } // Correctly rejected (not sure why). constexpr int correct_error() { return nonconst_func(0); } // Correctly rejected. constexpr int z = bogus(); // This is also correctly rejected. constexpr int correct_failure() { return 0 ? 3 : nonconst_func(0); }
[Bug c++/54021] New: [c++0x] __builtin_constant_p should be constexpr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54021 Bug #: 54021 Summary: [c++0x] __builtin_constant_p should be constexpr Classification: Unclassified Product: gcc Version: unknown Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu It's hard to tell how __builtin_constant_p works right now, due to PR54020. // Preliminaries. extern int nonconst_func(int); constexpr int identity(int x) { return x; } constexpr int zero() { return identity(0); } constexpr int one() { return identity(1); } // These are the same. Only the latter is accepted, though. // I suspect that the acceptance of the latter is due to the bug above. constexpr int rejected_const_4(int x) { return __builtin_constant_p(x) ? 4 : nonconst_func(x); } constexpr int accepted_const_4(int x) { return identity(__builtin_constant_p(x)) ? 4 : nonconst_func(x); } // This is rejected. I would like it to work. constexpr int four = accepted_const_4(1); The ability to use the construction __builtin_constant_p(x) ? const_func(x) : nonconst_func(x) in constexpr context would be quite powerful.
[Bug c++/53582] New: [4.6 regression, fixed in 4.7, I think] ICE on valid code
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53582 Bug #: 53582 Summary: [4.6 regression, fixed in 4.7, I think] ICE on valid code Classification: Unclassified Product: gcc Version: 4.6.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu g++ -O2 segfaults on this code. Tested on gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2). 4.7 and trunk work. 4.5 seems okay as well. struct A { A(); }; unsigned f1(); void f2() { while(true) { unsigned x; try { f1(); } catch(char) { x = (unsigned)-1; } if (x != 1) { new A; continue; } } }
[Bug libstdc++/53561] New: [c++0x] regex_replace is missing overloads
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53561 Bug #: 53561 Summary: [c++0x] regex_replace is missing overloads Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu [re.alg.replace] says: template class traits, class charT, class ST, class SA basic_stringcharT, ST, SA regex_replace(const basic_stringcharT, ST, SA s, const basic_regexcharT, traits e, const charT* fmt, regex_constants::match_flag_type flags = regex_constants::match_default); This doesn't compile, though: #include string #include regex int main() { std::regex_replacestd::regex_traitschar, char(std::string(x), std::regex(x), y); // works std::regex_replace(std::string(x), std::regex(x), y); // fails return 0; } The string,regex,string,flags overload doesn't work because the arguments aren't an exact match.
[Bug libstdc++/53561] [c++0x] regex_replace is missing overloads
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53561 Andy Lutomirski luto at mit dot edu changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution||INVALID --- Comment #1 from Andy Lutomirski luto at mit dot edu 2012-06-02 02:09:16 UTC --- Never mind. I just saw that the implementation isn't supposed to be done.
[Bug tree-optimization/53465] New: [4.7 regression] wrong code with -O1 -ftree-vrp
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53465 Bug #: 53465 Summary: [4.7 regression] wrong code with -O1 -ftree-vrp Classification: Unclassified Product: gcc Version: 4.7.1 Status: UNCONFIRMED Severity: major Priority: P3 Component: tree-optimization AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu This code aborts with -O1 -ftree-vrp. It shouldn't. gcc 4.6 is okay; 4_7-branch from today and trunk are both bad. extern void abort(); static const char input[] = {1,2}; void test(char const *data, int len) { int i; int found_x = 0; char prev_x; for(i = 0; i len; i++) { char x = data[i]; if (x == 0) break; if (found_x x = prev_x) abort(); prev_x = x; found_x = 1; } } int main() { test(input, 2); return 1; } Changing char x to volatile char x or initializing prev_x before the loop will prevent the crash.
[Bug c++/53234] New: [c++0x] unfriendly error message for missing move constructor
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53234 Bug #: 53234 Summary: [c++0x] unfriendly error message for missing move constructor Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu This code is correctly rejected by gcc 4.7 and up (4.6 incorrectly accepted it). The error message confused me for a while, though. struct move_only { move_only() = default; move_only(move_only) = default; move_only operator = (move_only) = default; }; struct is_it_moveable { //is_it_moveable() = default; //is_it_moveable(is_it_moveable ) = default; ~is_it_moveable(); move_only mo; }; int main() { is_it_moveable j; is_it_moveable k = (is_it_moveable)j; } A recent trunk build says: move.cc: In function ‘int main()’: move.cc:20:40: error: use of deleted function ‘is_it_moveable::is_it_moveable(const is_it_moveable)’ is_it_moveable k = (is_it_moveable)j; ^ move.cc:8:8: note: ‘is_it_moveable::is_it_moveable(const is_it_moveable)’ is implicitly deleted because the default definition would be ill-formed: struct is_it_moveable ^ move.cc:8:8: error: use of deleted function ‘constexpr move_only::move_only(const move_only)’ struct is_it_moveable ^ move.cc:1:8: note: ‘constexpr move_only::move_only(const move_only)’ is implicitly declared as deleted because ‘move_only’ declares a move constructor or move assignment operator struct move_only ^ This is, according to the standard, exactly correct. [class.copy] paragraph 9 says If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only if [condition that does not apply here]. The note says When the move constructor is not implicitly declared or explicitly supplied, expressions that otherwise would have invoked the move constructor may instead invoke a copy constructor. I think the error message could be improved to help C++11 newbies like myself, though. An extra line like: note: is_it_moveable has no move constructor because it has a user-declared destructor would be quite friendly. I spent a while staring at the error, thinking of course the copy constructor would be ill-formed. That's way I called the *move* constructor, you dummy! (FWIW, this change is missing from the 4.7 release notes. I think it, or something related, breaks boost 1.47's shared_ptr quite thoroughly.)
[Bug c++/51494] Legal program rejection - capturing this when using static method inside lambda
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51494 Andy Lutomirski luto at mit dot edu changed: What|Removed |Added CC||luto at mit dot edu --- Comment #2 from Andy Lutomirski luto at mit dot edu 2012-05-03 21:53:18 UTC --- This seems to have gotten worse in gcc 4.7. This code is now rejected as well: This code: struct A { static void func1() {} }; templatetypename T struct B : public A { void func2() const { func3([]{ func1(); }); } templatetypename Func void func3(Func f) const { } }; template class Bint; The error is: template_bug.cc: In instantiation of ‘BT::func2() const [with T = int]::lambda()’: template_bug.cc:11:22: required from ‘struct BT::func2() const [with T = int]::lambda()’ template_bug.cc:11:5: required from ‘void BT::func2() const [with T = int]’ template_bug.cc:20:16: required from here template_bug.cc:11:16: error: redeclaration of ‘const Bint* const BT::func2() const [with T = int]::lambda()::__this’ template_bug.cc:11:22: note: previous declaration ‘const Bint* const BT::func2() const [with T = int]::lambda()::__this’ template_bug.cc:11:16: error: redeclaration of ‘const Bint* const this’ template_bug.cc:11:22: error: ‘const Bint* const this’ previously declared here template_bug.cc:15:8: error: ‘void BT::func3(Func) const [with Func = BT::func2() const [with T = int]::lambda(); T = int]’, declared using local type ‘BT::func2() const [with T = int]::lambda()’, is used but never defined [-fpermissive] Your patch fixes this test case, too.
[Bug c++/53223] New: [c++0x] auto and operator* don't mix inside templates
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53223 Bug #: 53223 Summary: [c++0x] auto and operator* don't mix inside templates Classification: Unclassified Product: gcc Version: 4.7.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu This is truly bizarre: struct A { int good() const; int operator *() const; }; templatetypename T void func(T t) { A x; auto g1 = x.good(); // OK auto g2 = x.operator*(); // OK auto error = *x; // error here } void func2(int) { A x; auto g = *x; // OK } int main() { func(0); func2(0); } gcc 4.6 and 4.7 can't compile the line marked error here. The error looks like: auto-rvalue.cc: In instantiation of ‘void func(T) [with T = int]’: auto-rvalue.cc:24:9: required from here auto-rvalue.cc:13:19: error: invalid initialization of non-const reference of type ‘int’ from an rvalue of type ‘int’ I suppose this could be correct, but I'd be very surprised. clang++ 2.9 accepts this code.
[Bug c++/53223] [c++0x] auto and operator* don't mix inside templates
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53223 --- Comment #2 from Andy Lutomirski luto at mit dot edu 2012-05-03 23:21:10 UTC --- (In reply to comment #1) Don't we have something in Bugzilla about auto ? There's PR 52851, but that's supposedly fixed in 4_7-branch, and (unless I messed up) this bug is present in 4_7-branch updated today (r187118). The test case from that bug works on my compiler.
[Bug c++/53223] [c++0x] auto and operator* don't mix inside templates
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53223 --- Comment #4 from Andy Lutomirski luto at mit dot edu 2012-05-03 23:25:54 UTC --- PR51547 could be the same thing. I'll build and test trunk.
[Bug c++/53097] New: [c++0x] Missed optimization: lambda closure object could be smaller
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53097 Bug #: 53097 Summary: [c++0x] Missed optimization: lambda closure object could be smaller Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu This code: include stdio.h int main(int argc, char **argv) { int a, b; auto foo = [](){return a + b;}; printf(%d\n, (int)sizeof(foo)); return 0; } prints 16 (on x86-64) on gcc 4.6 and something quite close to 4.7 at -O2 and -Ofast. This is as expected if the closure object is implemented as imagined in the spec. In this particular case, accessing a from the lambda is defined behavior iff accessing b is defined (because either a and b are both in scope or both out of scope, so the lambda could be optimized based on the knowledge that a and b are at a fixed offset from each other. This would give size 8. (It sounds like this could be rather difficult. clang++ 2.9 works the same way as g++. I don't really expect to see this optimization implemented anytime soon.)
[Bug c++/51777] New: Errors message show unsigned long template parameters as signed
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51777 Bug #: 51777 Summary: Errors message show unsigned long template parameters as signed Classification: Unclassified Product: gcc Version: 4.6.2 Status: UNCONFIRMED Severity: minor Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu On x86_64, with g++ (GCC) 4.6.2 20111027 (Red Hat 4.6.2-1) and some trunk build or other, this test: templateunsigned long long struct A { }; int main() { return A0xf000ul(); } gives this error: type_err_test.cc: In function ‘int main()’: type_err_test.cc:8:34: error: cannot convert ‘A-1152921504606846976ull’ to ‘int’ in return That's wrong -- the constant is positive. (With just 'unsigned long' instead of 'unsigned long long', it still gets it wrong on x86_64 but it gets it right with -m32. With 'unsigned long long' it fails both ways.) I'm marking this minor because it's unlikely to cause significant confusion.
[Bug c++/51556] New: Bizarre member template protection errors
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51556 Bug #: 51556 Summary: Bizarre member template protection errors Classification: Unclassified Product: gcc Version: 4.6.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu Created attachment 26086 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=26086 Failing test I'm not really sure what's going on here, so this test case isn't very well reduced. multiindex_success.cc compiles (as IMO it should). multiindex_failure.cc fails to compile (which is IMO wrong) with this error: /usr/include/boost/multi_index/detail/index_base.hpp: In member function ‘void A::Test2(const Irrelevant) [with Irrelevant = int]’: /usr/include/boost/multi_index/detail/index_base.hpp:49:44: error: ‘typedef struct boost::multi_index::detail::index_node_baseEntry, std::allocatorEntry boost::multi_index::detail::index_baseEntry, boost::multi_index::indexed_byboost::multi_index::ordered_uniqueboost::multi_index::tagA::ById, boost::multi_index::memberEntry, int, Entry::id , std::allocatorEntry ::node_type’ is protected multiindex_failure.cc:42:11: error: within this context The error is garbage, since there is no reference to node_type in that context. The two test cases are identical except that I've reversed the order of two member functions. Preprocessed source attached, because I haven't yet reproduced this without using boost libraries. Seen on g++ (GCC) 4.6.2 20111027 (Red Hat 4.6.2-1) and an old-ish 4.7 trunk build.
[Bug c++/51556] Bizarre member template protection errors
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51556 --- Comment #1 from Andy Lutomirski luto at mit dot edu 2011-12-14 20:28:28 UTC --- Created attachment 26087 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=26087 Working test
[Bug c++/51556] Bizarre member template protection errors
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51556 --- Comment #2 from Andy Lutomirski luto at mit dot edu 2011-12-14 20:30:01 UTC --- Created attachment 26088 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=26088 Preprocessed test cases
[Bug c++/51556] Bizarre member template protection errors
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51556 --- Comment #4 from Andy Lutomirski luto at mit dot edu 2011-12-15 00:00:18 UTC --- Created attachment 26095 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=26095 Partially reduced test case This is reduced by a combination of fiddling by hand and automated reduction. It's still not pretty, but it's considerably shorter than the original version. I still haven't been able to reproduce the bug from scratch.
[Bug c++/51348] New: [c++0x] ICE in finish_class_member_access_expr with bogus(?) enum class use
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51348 Bug #: 51348 Summary: [c++0x] ICE in finish_class_member_access_expr with bogus(?) enum class use Classification: Unclassified Product: gcc Version: 4.6.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu I haven't checked whether this is legal C++, but it certainly looks fishy: struct A { enum class EC { VAL, }; }; int main() { A a; a.EC::VAL; } An old-ish build from trunk (g++-trunk (GCC) 4.7.0 20111006 (experimental)) says: test_ice.cc: In function ‘int main()’: test_ice.cc:11:9: internal compiler error: in finish_class_member_access_expr, at cp/typeck.c:2555 Fedora 16's gcc (g++ (GCC) 4.6.2 20111027 (Red Hat 4.6.2-1)) says: test_ice.cc: In function ‘int main()’: test_ice.cc:11:9: internal compiler error: in finish_class_member_access_expr, at cp/typeck.c:2546 In both cases, I've compiled with g++ -c -std=c++0x.
[Bug libstdc++/50641] [c++0x] is_convertible and is_constructible incorrectly require copy constructibility
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50641 --- Comment #4 from Andy Lutomirski luto at mit dot edu 2011-10-07 06:57:01 UTC --- The problem I encountered that inspired this was: #include type_traits #include map struct From { }; struct To { To(const From ) {} To(const To ) = delete; void operator = (const To ) = delete; }; int main() { std::mapint, To m; m.insert(std::pairint, From(1, From())); } This works in 4.6.0 due to a different bug. IMO it deserves to work -- the implementation of map could move-construct the To object in place. The standard says explicitly that it's OK for To not to be CopyConstructible and, indeed, this example works if I add: To(const To ) {} I defer to the experts (and the people who have a copy of the FDIS) to figure out whether it's supposed to work. N3242 says that From needs to be convertible to To, but I'm not at all convinced that convertible means the same thing as is_convertible. Maybe if it's illegal I'll file a DR some day. (N3242's section on map modifiers is woefully incomplete -- quite a few functions are simply not there. I hope the FDIS is better.)
[Bug libstdc++/50641] New: [c++0x] is_convertible and is_constructible incorrectly require copy constructibility
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50641 Bug #: 50641 Summary: [c++0x] is_convertible and is_constructible incorrectly require copy constructibility Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu is_convertible and is_constructible seem to either spew errors or return false when the To type is not CopyConstructible. (errors happen if the copy constructor is private; false happens if it's deleted.) Here's a test case: #include type_traits struct From { }; struct To { To(const From ); To(const To ) = delete; }; template class T typename std::add_rvalue_referenceT::type create(); void test() { /* From N3242 [meta.unary.prop], with the ... removed, in reference to is_constructible. */ To t(createFrom()); } static_assert(std::is_constructibleFrom, To::value, not constructible); static_assert(std::is_convertibleFrom, To::value, not convertible); From my reading of N3242, is_constructible should certainly return true, and I'm having a hard time understanding the definition of is_convertible. This causes the fancy new map::insert function to be less useful if the mapped_type is not CopyConstructible. That usage seems to be the whole point, according to [map.modifiers], which says: If P is instantiated as a reference type, then the argument x is copied from. Otherwise x is con-sidered to be an rvalue as it is converted to value_type and inserted into the map. Specifically, in such cases CopyConstructible is not required of key_type or mapped_type unless the conversion from P specifically requires it (e.g., if P is a tupleconst key_type, mapped_type, then key_type must be CopyConstructible). The signature taking InputIterator parameters does not require CopyConstructible of either key_type or mapped_type if the dereferenced InputIterator returns a non-const rvalue pairkey_type,mapped_type. Otherwise CopyConstructible is required for both key_type and mapped_type.
[Bug c++/50372] New: c++11: pointers to static functions should be valid template parameters
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50372 Bug #: 50372 Summary: c++11: pointers to static functions should be valid template parameters Classification: Unclassified Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu Created attachment 25253 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=25253 Test case In n3242 [temp.arg.nontype]: A template-argument for a non-type, non-template template-parameter shall be one of: ... - a constant expression (5.19) that designates the address of an object with static storage duration and external or internal linkage or a function with external *or internal* linkage, ... [emphasis added] Nonetheless, the attached test case fails to compile with: foo.cc: In function ‘void test()’: foo.cc:8:21: error: ‘static_func’ is not a valid template argument for type ‘void (*)()’ because function ‘void static_func()’ has not external linkage foo.cc:8:21: error: no matching function for call to ‘foo()’ foo.cc:8:21: note: candidate is: foo.cc:2:6: note: templatevoid (* fptr)() void foo() foo.cc:2:6: note: substitution of deduced template arguments resulted in errors seen above even with -std=gnu++0x. Tested on 4.6.0 and trunk r178795. AFAICT the error is correct in c++98 mode.
[Bug rtl-optimization/48877] New: Inline asm for rdtsc generates silly code
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48877 Summary: Inline asm for rdtsc generates silly code Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu gcc -O2 -S on this input: typedef unsigned long long u64; u64 test() { u64 low, high; asm volatile (rdtsc : =a (low), =d (high)); return low | (high 32); } generates this: test: .LFB0: .cfi_startproc #APP # 6 rax_rdx.c 1 rdtsc # 0 2 #NO_APP movq%rax, %rcx movq%rdx, %rax salq$32, %rax orq %rcx, %rax ret .cfi_endproc which is silly -- both movq instructions are unnecessary. clang -O3 -fomit-frame-pointer does much better: test: .Leh_func_begin0: #APP rdtsc #NO_APP shlq$32, %rdx orq %rdx, %rax ret Getting rid of the 32 makes gcc generate the obvious code. FWIW, this code: unsigned long long rdtsc (void) { unsigned int tickl, tickh; __asm__ __volatile__(rdtsc:=a(tickl),=d(tickh)); return ((unsigned long long)tickh 32)|tickl; } is copied verbatim from the manual in the Machine Constraints (http://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constraints) and generates the same silly code.
[Bug rtl-optimization/46514] New: 128-bit shifts on x86_64 generate silly code unless the shift amount is constant
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46514 Summary: 128-bit shifts on x86_64 generate silly code unless the shift amount is constant Product: gcc Version: 4.5.1 Status: UNCONFIRMED Severity: minor Priority: P3 Component: rtl-optimization AssignedTo: unassig...@gcc.gnu.org ReportedBy: l...@mit.edu Created attachment 22428 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=22428 Preprocessed source I'm using 4.5.1 (Fedora 14) with -O3, but -O2 does the same thing. This really easy case: uint64_t shift_test_31(__uint128_t x, uint32_t shift) { if (shift != 31) __builtin_unreachable(); return (uint64_t)(x shift); } generates: 0050 shift_test_31: 50: 48 89 f8mov%rdi,%rax 53: 48 0f ac f0 1f shrd $0x1f,%rsi,%rax 58: c3 retq 59: 0f 1f 80 00 00 00 00nopl 0x0(%rax) which is entirely sensible. But this: uint64_t shift_test_le_31(__uint128_t x, uint32_t shift) { if (shift = 32) __builtin_unreachable(); return (uint64_t)(x shift); } generates this: 0060 shift_test_le_31: 60: 89 d1 mov%edx,%ecx 62: 48 89 6c 24 f8 mov%rbp,-0x8(%rsp) 67: 48 89 f5mov%rsi,%rbp 6a: 48 0f ad f7 shrd %cl,%rsi,%rdi 6e: 48 d3 edshr%cl,%rbp 71: f6 c2 40test $0x40,%dl 74: 48 89 5c 24 f0 mov%rbx,-0x10(%rsp) 79: 48 0f 45 fd cmovne %rbp,%rdi 7d: 48 8b 5c 24 f0 mov-0x10(%rsp),%rbx 82: 48 8b 6c 24 f8 mov-0x8(%rsp),%rbp 87: 48 89 f8mov%rdi,%rax 8a: c3 retq which contains a pointless shr, test, and cmovne. (Even if I change the __builtin_unreachable() into a real branch, I get the same code.)