[Bug c/66970] Add __has_builtin() macro

2016-01-04 Thread luto at mit dot edu
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

2015-10-06 Thread luto at mit dot edu
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

2015-10-05 Thread luto at mit dot edu
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

2015-10-05 Thread luto at mit dot edu
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

2015-08-12 Thread luto at mit dot edu
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

2015-07-07 Thread luto at mit dot edu
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

2015-07-05 Thread luto at mit dot edu
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

2015-07-05 Thread luto at mit dot edu
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

2014-12-02 Thread luto at mit dot edu
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

2014-09-12 Thread luto at mit dot edu
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

2014-09-12 Thread luto at mit dot edu
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

2014-06-06 Thread luto at mit dot edu
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

2014-06-05 Thread luto at mit dot edu
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

2014-05-09 Thread luto at mit dot edu
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

2014-03-28 Thread luto at mit dot edu
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

2014-01-23 Thread luto at mit dot edu
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

2014-01-20 Thread luto at mit dot edu
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

2014-01-14 Thread luto at mit dot edu
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

2013-12-13 Thread luto at mit dot edu
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

2013-11-19 Thread luto at mit dot edu
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)

2013-11-18 Thread luto at mit dot edu
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)

2013-11-18 Thread luto at mit dot edu
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)

2013-11-18 Thread luto at mit dot edu
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)

2013-11-18 Thread luto at mit dot edu
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)

2013-11-18 Thread luto at mit dot edu
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)

2013-11-18 Thread luto at mit dot edu
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

2013-08-09 Thread luto at mit dot edu
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

2013-08-09 Thread luto at mit dot edu
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

2013-07-26 Thread luto at mit dot edu
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

2013-07-03 Thread luto at mit dot edu
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)

2013-07-02 Thread luto at mit dot edu
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

2013-07-02 Thread luto at mit dot edu
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)

2013-07-01 Thread luto at mit dot edu
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)

2013-06-27 Thread luto at mit dot edu
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++

2013-05-15 Thread luto at mit dot edu
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)))

2013-03-04 Thread luto at mit dot edu


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

2013-03-04 Thread luto at mit dot edu


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

2012-11-29 Thread luto at mit dot edu

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

2012-11-29 Thread luto at mit dot edu


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

2012-11-29 Thread luto at mit dot edu


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

2012-11-28 Thread luto at mit dot edu


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

2012-11-28 Thread luto at mit dot edu


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

2012-11-15 Thread luto at mit dot edu


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

2012-11-12 Thread luto at mit dot edu


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?

2012-10-22 Thread luto at mit dot edu

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

2012-09-09 Thread luto at mit dot edu
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

2012-09-08 Thread luto at mit dot edu
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

2012-08-20 Thread luto at mit dot edu
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

2012-08-20 Thread luto at mit dot edu
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

2012-07-19 Thread luto at mit dot edu
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

2012-07-18 Thread luto at mit dot edu
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

2012-07-18 Thread luto at mit dot edu
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

2012-06-05 Thread luto at mit dot edu
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

2012-06-01 Thread luto at mit dot edu
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

2012-06-01 Thread luto at mit dot edu
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

2012-05-23 Thread luto at mit dot edu
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

2012-05-04 Thread luto at mit dot edu
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

2012-05-03 Thread luto at mit dot edu
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

2012-05-03 Thread luto at mit dot edu
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

2012-05-03 Thread luto at mit dot edu
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

2012-05-03 Thread luto at mit dot edu
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

2012-04-23 Thread luto at mit dot edu
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

2012-01-06 Thread luto at mit dot edu
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

2011-12-14 Thread luto at mit dot edu
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

2011-12-14 Thread luto at mit dot edu
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

2011-12-14 Thread luto at mit dot edu
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

2011-12-14 Thread luto at mit dot edu
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

2011-11-29 Thread luto at mit dot edu
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

2011-10-07 Thread luto at mit dot edu
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

2011-10-06 Thread luto at mit dot edu
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

2011-09-12 Thread luto at mit dot edu
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

2011-05-04 Thread luto at mit dot edu
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

2010-11-16 Thread luto at mit dot edu
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.)