[Bug c++/70796] [DR 1030] Initialization order with braced-init-lists still broken

2021-11-03 Thread matthijsvanduin at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70796

Matthijs van Duin  changed:

   What|Removed |Added

 CC||matthijsvanduin at gmail dot 
com

--- Comment #3 from Matthijs van Duin  ---
This specifically appears to happen when the constructor has parameters of
trivially copyable non-reference types, e.g. this fails:

#include 
struct IntWrap {
int x = 0;
IntWrap  ++() { ++x; return *this; }
};
struct Pair {
IntWrap first, second;
Pair( IntWrap x, IntWrap y ) : first{ x }, second{ y } { }
};
int main() {
IntWrap i;
Pair p{ ++i, ++i };
assert( p.first.x == 1 && p.second.x == 2 );  // FAIL (p.first.x is 2)
}

but adding a destructor to IntWrap suffices to make it pass.


Interestingly, when using simple ints there also appear to be very narrow
constraints on the initializer arguments to trigger the bug:

#include 
struct IntPair {
int first, second;
IntPair( int x, int y ) : first{ x }, second{ y } { }
};
void testcase_fail() {
int i = 0;
IntPair p{ ++i, ++i };
assert( p.first == 1 && p.second == 2 );  // FAIL (p.first is 2)
}
void testcase_ok_1() {
int i = 0;
IntPair p{ ++i, ++i };
assert( p.first == 1 && p.second == 2 );  // ok
int  = i;
IntPair q{ ++j, ++j };
assert( q.first == 3 && q.second == 4 );  // ok
}
void testcase_ok_2() {
int i = 0;
IntPair p{ (int &)++i, (int &)++i };
assert( p.first == 1 && p.second == 2 );  // ok
}
int main() {
testcase_ok_1();
testcase_ok_2();
testcase_fail();
}

even though the analogous testcases for IntWrap all fail.


Related:
bug 51253  (was supposed to have fixed this but evidently missed some cases)
bug 65866  (incorrect -Wsequence-point diagnostic still being emitted)
bug 70792  (dup of bug 65866 but discussion in comments covered this case)

[Bug c++/65866] Wrong warning when using list-initialization: operation on 'b' may be undefined [-Wsequence-point]

2021-11-03 Thread matthijsvanduin at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65866

Matthijs van Duin  changed:

   What|Removed |Added

 CC||matthijsvanduin at gmail dot 
com

--- Comment #6 from Matthijs van Duin  ---
(In reply to Jonathan Wakely from comment #4)

Note that this testcase, where the constructor takes trivially copyable prvalue
arguments, actually still generates wrong code (so the diagnostic is
technically still appropriate), while the original testcase in this bug
generates correct code but emits a wrong diagnostic.

[Bug c++/70792] Incorrect sequence point warning with uniform initializer syntax

2021-11-03 Thread matthijsvanduin at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70792

--- Comment #12 from Matthijs van Duin  ---
(In reply to Jonathan Wakely from comment #11)
> (In reply to Matthijs van Duin from comment #10)
> > I'm assuming this means a new bug should be opened
> > about the wrong code generation?
> 
> Yes please. This one is too confusing now.

Found an existing one, bug 70796.

[Bug c++/70792] Incorrect sequence point warning with uniform initializer syntax

2021-11-03 Thread matthijsvanduin at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70792

--- Comment #10 from Matthijs van Duin  ---
(In reply to Jonathan Wakely from comment #9)
> (In reply to Matthijs van Duin from comment #4)
> > Also bug 65866 exists for the warning itself.
> 
> I think this is an exact dup.
> 
> *** This bug has been marked as a duplicate of bug 65866 ***

Well, this bug was amended to be about incorrect code generation (although the
reporter did not update the title), while bug 65866 is purely about incorrect
diagnostics. I'm assuming this means a new bug should be opened about the wrong
code generation? (assuming one hasn't been created for it yet)

[Bug c++/89695] unexpected copying of trivially copyable prvalue arguments

2021-10-28 Thread matthijsvanduin at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89695

--- Comment #5 from Matthijs van Duin  ---
So for reference, the Itanium C++ ABI says:

"A type which is trivial for the purposes of the ABI will be passed and
returned according to the rules of the base C ABI, e.g. in registers; often
this has the effect of performing a trivial copy of the type."

It is not clear to me what the justification is for that last remark, can
someone quote what's in the base C ABI that forbids this optimization?

Eliding the trivial copy should be permitted under the as-if rule anyway,
there's no way to detect its elision that doesn't involve undefined behaviour.

[Bug c++/102942] Implicit copy constructor not elided

2021-10-28 Thread matthijsvanduin at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102942

Matthijs van Duin  changed:

   What|Removed |Added

 CC||matthijsvanduin at gmail dot 
com

--- Comment #4 from Matthijs van Duin  ---
This is indeed a duplicate of 89695. The copy constructor isn't being "elided",
there's no semantic expectation of it being invoked at all, you're simply
initializing the parameter of take(T) with a prvalue T(). As special exception
however C++ permits parameters and return values of trivially-copyable types
(such as int and StructWithImplicitCpyCtr) to be copied superfluously, which is
what you're observing. This exception exists to allow C++ ABIs to pass such
types in a C-ABI-compatible way, which may sometimes require copying (notably
when passing small types in register for efficiency), though gcc seems to make
a superfluous copy whenever it is _allowed_ rather than whenever it is
_needed_.

[Bug tree-optimization/83234] Aggressive loop optim warning for loop iteration that cannot happen

2021-07-30 Thread matthijsvanduin at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83234

Matthijs van Duin  changed:

   What|Removed |Added

 CC||matthijsvanduin at gmail dot 
com

--- Comment #2 from Matthijs van Duin  ---
Probably same as bug 100801 ?

[Bug tree-optimization/100801] Aggressive loop optimizations cause incorrect warning

2021-07-30 Thread matthijsvanduin at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100801

Matthijs van Duin  changed:

   What|Removed |Added

 CC||matthijsvanduin at gmail dot 
com

--- Comment #3 from Matthijs van Duin  ---
Simpler testcase:

/* compiler flags required to trigger warning: -O1 -ftree-vrp  */

static void foo(int *x, long n)
{
long i = 0;
for (; i + 4 <= n; i += 4) {
}
for (; i < n; i++) {
x[i]++;
}
}

void bar(int *x)
{
foo(x, 128);
}


A workaround with no runtime overhead is adding the following check between the
loops:

if (__builtin_constant_p(n % 4 == 0) && n % 4 == 0)
return;

[Bug target/92075] New: extracting element from NEON float-vector moves to/from integer register

2019-10-12 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92075

Bug ID: 92075
   Summary: extracting element from NEON float-vector moves
to/from integer register
   Product: gcc
   Version: 9.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: matthijsvanduin at gmail dot com
  Target Milestone: ---

On ARM, when extracting an element from a float32x2_t expression, i.e.:

   float32x2_t v = (...);
   float v0 = v[0];

In most cases, gcc moves the element to an general-purpose register and back to
a VFP/Neon register, even at -Ofast. It doesn't seem to happen when v is an
argument or the return value of a non-inline function, but it does happen e.g.
when v is an arithmetic expression or produced by a NEON intrinsic or inline
asm. It doesn't seem to matter how v0 is consumed (i.e. by returning it,
passing it as argument to a function, or consuming it by inline asm).

Some test-cases:

#include 

float test1( float32x2_t v ) {
return (v + v)[0];
}

void test2() {
float32x2_t v;
asm( "" : "=w"(v) );
float v0 = v[0];
asm( "" :: "w"(v0) );
}

void foo( float );
void test3( uint32x2_t v ) {
foo( vcvt_n_f32_u32( v, 32 )[0] );
}

output produced by "arm-linux-gnueabihf-gcc-9 (Debian 9.2.1-8) 9.2.1 20190909"
with -Ofast -mcpu=cortex-a8 -mfpu=neon, reformatted for readability:

test1:
vadd.f32  d0, d0, d0
vmov.32   r3, d0[0]
vmov  s0, r3
bxlr
test2:
vmov.32  r3, d16[0]
vmov s15, r3
bx   lr
test3:
vcvt.f32.u32  d0, d0, #32
vmov.32   r3, d0[0]
vmov  s0, r3
b foo(PLT)

This is especially bad on the cortex-A8, where moving from a VFP/Neon register
to an general purpose register causes a severe pipeline stall.

Note btw how in test1 and test3 no move is needed at all: the final move
destination is the register it originally came from, and a different choice of
register allocation can make this also true in test2.

[Bug c++/89695] unexpected copying of trivially copyable prvalue arguments

2019-10-03 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89695

--- Comment #4 from Matthijs van Duin  ---
(In reply to Jonathan Wakely from comment #3)
> I believe this is required by the ABI for trivially copyable types.

I don't see how that's possible, the callee can't tell the difference.

[Bug c++/89695] unexpected copying of trivially copyable prvalue arguments

2019-03-13 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89695

Matthijs van Duin  changed:

   What|Removed |Added

Summary|inappropriate copying of|unexpected copying of
   |trivially copyable prvalue  |trivially copyable prvalue
   |arguments   |arguments

--- Comment #2 from Matthijs van Duin  ---
(In reply to Richard Biener from comment #1)
> So not really inappropriate but fails to optimize it?

Yes. Changing title to avoid implying the copying is not permitted.

[Bug c++/89695] New: inappropriate copying of trivially copyable prvalue arguments

2019-03-12 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89695

Bug ID: 89695
   Summary: inappropriate copying of trivially copyable prvalue
arguments
   Product: gcc
   Version: 8.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: matthijsvanduin at gmail dot com
  Target Milestone: ---

When a function that has a non-reference parameter of a trivially copyable
class-type is invoked with a prvalue expression as argument, e.g.:

#include 

struct Foo {
int data[32];
Foo() { printf( "%p (constructor)\n", this ); }
};

Foo make_foo() {  return Foo{};  }

void f( Foo x ) {  printf( "%p (parameter)\n",  );  }

int main() {
f( Foo{} );
f( make_foo() );
return 0;
}

g++ initializes a temporary from this expression and then copy-constructs the
parameter from it:

0x7fffce1caa80 (constructor)
0x7fffce1cab00 (parameter)
0x7fffce1caa80 (constructor)
0x7fffce1cab00 (parameter)

This appears to happen whenever C++17 permits it and at any optimization level,
even though Foo is large and expensive to copy. For example on armhf at -O2,
g++ produces this particularly silly-looking output:

mov r1, r5
mov r0, r7
bl  printf(PLT)
mov r2, r8
mov r1, r5
mov r0, r4
bl  memcpy(PLT)
mov r1, r4
mov r0, r6
bl  printf(PLT)
mov r1, r5
mov r0, r7
bl  printf(PLT)
mov r2, r8
mov r1, r5
mov r0, r4
bl  memcpy(PLT)
mov r1, r4
mov r0, r6
bl  printf(PLT)

If a user-provided destructor, copy-constructor, or move-constructor is added
to the class, no copying is done even at -O0 (as expected due to C++17
requirements):

mov r3, r7
mov r0, r3
bl  _ZN3FooC1Ev(PLT)
mov r3, r7
mov r0, r3
bl  _Z1f3Foo(PLT)
add r3, r7, #128
mov r0, r3
bl  _Z8make_foov(PLT)
add r3, r7, #128
mov r0, r3
bl  _Z1f3Foo(PLT)

[Bug c++/86521] [8/9 Regression] GCC 8 selects incorrect overload of ref-qualified conversion operator template

2019-03-11 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86521

Matthijs van Duin  changed:

   What|Removed |Added

 CC||matthijsvanduin at gmail dot 
com

--- Comment #3 from Matthijs van Duin  ---
First off, your example is more complicated than it needs to be. A more minimal
test case would be:

#include 

struct Dest {
Dest() = default;
Dest( Dest && ) = default;
Dest( Dest const & ) = delete;
};

struct Source {
Dest val;
operator Dest () && {
return std::move( val );
}
operator Dest const & () const & {
return val;
}
};

int main() {
Source x;
static_cast( std::move( x ) );
}


Second, notice that the two conversions are not really directly comparable
since one converts to directly Dest while the other converts to an expression
used to invoke a constructor of Dest. While it seems desirable for the former
to take preference over the latter, I'm not enough of a language lawyer to be
able to figure out what the C++ standard actually requires overload resolution
to do in this situation.

Replacing
operator Dest () && {
by
operator Dest && () && {
fixes the problem, and has the additional benefit of avoiding unnecessary
temporary materialization in situations like:

void foo( Dest && );
int main() {
Source x;
foo( std::move( x ) );
}

[Bug c++/51253] [C++11][DR 1030] Evaluation order (sequenced-before relation) among initializer-clauses in braced-init-list

2019-01-25 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253

--- Comment #25 from Matthijs van Duin  ---
I wasn't referring to the warnings though but incorrect code generation. Since
is exhibited by pretty trivial test cases (testsuite/g++.dg/cpp0x/initlist86.C
confirms that { i++, i++ } works but the analogous test for { ++i, ++i } fails)
yet was first reported long after this bug was marked "FIXED" I kind of assumed
it was a regression, but apparently it was just never really fixed to begin
with.

[Bug c++/70792] Incorrect sequence point warning with uniform initializer syntax

2019-01-25 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70792

--- Comment #8 from Matthijs van Duin  ---
(In reply to Matthijs van Duin from comment #4)
>   return std::pair{ ++i, ++i }.first;

My bad! This isn't an exhibit of the bug. I simply forgot that std::pair is not
really a struct, and this isn't aggregate initialization: the constructor takes
references, so correct code is generated in this case.

And in fact, if you do use an aggregate, the test works correctly.

However, if you replace std::pair by a class whose constructor takes (int,
int), similar to the one used in the existing testcase
(g++.dg/cpp0x/initlist86.C) then it fails again.

Looking at the disassembly (on ARM since I don't know x86 asm) shows that gcc
loads both arguments from the storage allocated for i, after both increments
have been done. Effectively it's copy-constructing the first argument too late.

The more general issue appears to be that if the arguments are trivially
copyable lvalues, then gcc keeps these as lvalues and copy-constructs the
actual arguments way too late. If I look at this disassembly of this code:

  struct Foo {
char x[64]; // too big to pass in register
Foo( Foo const  ) = default; // but still trivially copyable
Foo ();
  };

  struct Pair {
Pair( Foo x, Foo y );
  };

  void test( Foo  ) {
Pair{ foo.mutate(), foo.mutate() };
  }

Then test() effectively does:

  Foo  = foo.mutate();
  Foo  = foo.mutate();
  Pair{ temp1, temp2 }  // copy-construct arguments and call Pair constructor

(Also, interestingly, temp2 is copy-constructed before temp1 is!)

If Foo is not trivially copyable, even if merely due to the presence of a
destructor, then the problem disappears.

[Bug c++/83028] Incorrect -Wsequence-point warning in correct C++17 code with new evaluation order rules

2018-10-28 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83028

Matthijs van Duin  changed:

   What|Removed |Added

 CC||matthijsvanduin at gmail dot 
com

--- Comment #1 from Matthijs van Duin  ---
There are many such cases which are well-defined in C++17 yet trigger a
sequence-point warning in g++ 8.2, such as:

(x+i)[i++]
i = i++
(funcs[i++])(i)

This incorrect behaviour is actually documented: "The C++17 standard will
define the order of evaluation of operands in more cases: in particular it
requires that the right-hand side of an assignment be evaluated before the
left-hand side, so the above examples are no longer undefined. But this warning
will still warn about them, to help people avoid writing code that is undefined
in C and earlier revisions of C++."

This reasoning here is of course complete garbage. Plenty of valid C++17 code
is invalid in earlier revisions of the standard. When compiling code with
-std=c++17 or -std=gnu++17, the compiler should only concern itself with
whether the code is valid C++17 code.

Since I think habitually ignoring warnings is very bad practice and compile
with -Werror to ensure this won't happen, I consider these warnings to be
nearly as bad as miscompilation, as the end result is the same: I still cannot
rely on this feature of the C++17 standard.

[Bug c++/70792] Incorrect sequence point warning with uniform initializer syntax

2018-10-01 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70792

--- Comment #7 from Matthijs van Duin  ---
Ah! I should have checked the actual tests of 51253 before calling it a
regression, apologies. I just kinda assumed that these simple cases would be
covered by the work done back then.

[Bug c++/51253] [C++11][DR 1030] Evaluation order (sequenced-before relation) among initializer-clauses in braced-init-list

2018-09-30 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253

Matthijs van Duin  changed:

   What|Removed |Added

 CC||matthijsvanduin at gmail dot 
com

--- Comment #23 from Matthijs van Duin  ---
There appears to be a regression of this bug. See bug 70792.

[Bug c++/70792] Incorrect sequence point warning with uniform initializer syntax

2018-09-30 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70792

Matthijs van Duin  changed:

   What|Removed |Added

 CC||matthijsvanduin at gmail dot 
com

--- Comment #4 from Matthijs van Duin  ---
It seems bug 51253 previously addressed this, which means this is a regression.
Also bug 65866 exists for the warning itself.

I can confirm incorrect code generation using g++ 8.2.0 on this simpler
testcase:


#include 

int main() {
int i = -1;
return std::pair{ ++i, ++i }.first;
}


$ g++ -Wall -std=c++17 -o list-init-sequence{,.cc}
list-init-sequence.cc: In function ‘int main()’:
list-init-sequence.cc:6:20: warning: operation on ‘i’ may be undefined
[-Wsequence-point]
  return std::pair{ ++i, ++i }.first;
^~~
$ ./list-init-sequence || echo fail
fail


Interestingly, this variation does not produce a warning but still produces
incorrect code:

#include 

int main() {
int i = 0;
return std::pair{ i, ++i }.first;
}

$ g++ -Wall -std=c++17 -o list-init-sequence{,.cc}
$ ./list-init-sequence || echo fail
fail

[Bug target/82989] [7/8 regression] Inexplicable use of NEON for 64-bit math

2018-02-19 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82989

--- Comment #15 from Matthijs van Duin  ---
(In reply to Wilco from comment #14)
> Yes on older cores it can be a bad idea to allow accidental use of Neon
> instructions. The simplest workaround is to switch off Neon, just use
> -mfpu=vfp.

Sure, though that's not exactly ideal since it is very desirable for the Neon
unit to be used for single-precision floats. (9-10 cycles for add/sub in VFP,
10-12 cycles for mul in VFP, 1 cycle for two add/sub/mul ops in Neon)

[Bug target/82989] [7/8 regression] Inexplicable use of NEON for 64-bit math

2018-02-19 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82989

--- Comment #13 from Matthijs van Duin  ---
In case it's of interest, I did a quick benchmark of my testcase executed in a
loop on a cortex-a8:

Without neon:
12 instructions/iteration
14 cycles/iteration

With neon:
14 instructions/iteration
35.2-35.3 cycles/iteration

(This includes 4 instructions for the loop itself.)

When using neon, the majority of the time is spent in a nasty pipeline stall
for moving data from neon registers to arm registers, which takes a minimum of
20 cycles according to the cortex-a8 TRM.

[Bug target/82989] [7/8 regression ] Inexplicable use of NEON for 64-bit math

2018-02-15 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82989

--- Comment #9 from Matthijs van Duin  ---
I can still reproduce the same test case with:  arm-linux-gnueabihf-gcc-8
(Debian 8-20180207-2) 8.0.1 20180207 (experimental) [trunk revision 257435]


-mfloat-abi=hard is implicit for arm-linux-gnueabihf, although overriding that
to -mfloat-abi=softfp produces exactly the same result for me.

(-mfloat-abi=soft completely disables all use of VFP/Neon hence obviously
suppresses this problem.)

[Bug target/49526] extra move instruction for smmul

2017-11-17 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49526

Matthijs van Duin  changed:

   What|Removed |Added

 CC||matthijsvanduin at gmail dot 
com

--- Comment #5 from Matthijs van Duin  ---
So... what happened to this patch? Why was it never applied?

[Bug target/82989] New: Inexplicable use of NEON for 64-bit math

2017-11-14 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82989

Bug ID: 82989
   Summary: Inexplicable use of NEON for 64-bit math
   Product: gcc
   Version: 7.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: matthijsvanduin at gmail dot com
  Target Milestone: ---

The following function:

void foo( uint64_t *a ) {
*a += *a >> 32;
}

compiled with  arm-linux-gnueabihf-gcc -mcpu=cortex-a8 -mfpu=neon -O2
produces the following code:

  push  {r4, r5}
  ldrd  r4, [r0]
  vmov  d16, r4, r5
  vshr.u64  d16, d16, #32
  vmov  r2, r3, d16
  adds  r2, r2, r4
  adcs  r3, r3, r5
  strd  r2, [r0]
  pop   {r4, r5}
  bxlr

Since -mneon-for-64bits is not enabled (I double-checked using -Q just to be
sure), the use of neon instructions here is highly unexpected.

(Moreover, shifting right by 32 bits should of course not involve any actual
arithmetic whatsoever.  Ideally this function would compile to

  ldrd  r2, [r0]
  adds  r2, r2, r3
  adcs  r3, r3, #0
  strd  r2, [r0]
  bxlr

)

[Bug c++/80061] error on constexpr function with an unevaluated throw

2017-07-21 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80061

--- Comment #2 from Matthijs van Duin  ---
> void foo( bool ok ) {
 ^constexpr

[Bug c++/80061] error on constexpr function with an unevaluated throw

2017-07-21 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80061

Matthijs van Duin  changed:

   What|Removed |Added

 CC||matthijsvanduin at gmail dot 
com

--- Comment #1 from Matthijs van Duin  ---
Simpler test case:

void foo( bool ok ) {
if( ok )
return;
throw;
}

fails to compile with g++ 6.3.0 and g++ 7.1.0

[Bug c++/67371] Never executed "throw" in constexpr function fails to compile

2017-07-21 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67371

Matthijs van Duin  changed:

   What|Removed |Added

 CC||matthijsvanduin at gmail dot 
com

--- Comment #13 from Matthijs van Duin  ---
This is still not working for me in g++ 6 and 7:

constexpr void foo( bool ok ) {
if( ok )
return;
throw;
}

In function ‘constexpr void foo(bool)’:
error: expression ‘’ is not a constant-expression


Rewriting the code as:

constexpr void foo( bool ok ) {
if( ok )
return;
else
throw;
}

gets rid of the error, but this can be really awkward to do in more complicated
functions.

[Bug c++/59832] [c++11] ICE in reshape_init_class with initializer list

2016-12-15 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59832

Matthijs van Duin  changed:

   What|Removed |Added

 CC||matthijsvanduin at gmail dot 
com

--- Comment #13 from Matthijs van Duin  ---
I also just ran into this one with g++ 6.2.1.

Here are some interesting cases:

union Foo {
union { int x; char y; } u;
union { int x; char y; } v;
int n;
};
std::vector foo = {
{}, // ok
{ .u = {} },// ok
{ .u = { .x = {} } },   // ok
{ .u = { .x = 0 } },// ok
{ .u = { .y = {} } },   // ICE in reshape_init_class
{ .u = { .y = 0 } },// ICE in reshape_init_class
{ .v = {} },// ok
{ .v = { .x = {} } },   // ICE in reshape_init_class
{ .v = { .x = 0 } },// ICE in reshape_init_class
{ .v = { .y = {} } },   // ICE in reshape_init_class
{ .v = { .y = 0 } },// ICE in reshape_init_class
{ .n = {} },// ok
{ .n = 0 }, // error: could not convert
};

Some more observations:
- Replacing the inner unions by structs results in the same errors (in addition
to some warnings for missing initializers)
- No errors occur if a C-style array is initialized instead of std::vector
- It doesn't matter if the inner aggregates are anonymous or not.

Similar things with an outer struct:

struct Bar {
union { int x; char y; } u;
union { int x; char y; } v;
};
std::vector bar = {
{ .u = {}, .v = {} },   // ok
{ .u = {}, .v = { .x = 0 } },   // ok
//  { .u = {}, .v = { .y = 0 } },   // ICE in reshape_init_class
{ .u = { .x = 0 }, .v = {} },   // ok
//  { .u = { .y = 0 }, .v = {} },   // ICE in reshape_init_class
//  { .v = { .x = 0 }, .u = {} },   // ICE in reshape_init_class
//  { .v = {}, .u = { .x = 0 } },   // ICE in reshape_init_class
//  { .v = {}, .u = {} },   // sorry, unimplemented
};

[Bug middle-end/50481] builtin to reverse the bit order

2016-12-08 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50481

Matthijs van Duin  changed:

   What|Removed |Added

 CC||matthijsvanduin at gmail dot 
com

--- Comment #3 from Matthijs van Duin  ---
Bump!  Proper intrinsics for bitreverse would be much appreciated!  A plain C
implementation is ugly and results in equally awful code output, while using
inline asm breaks portability and can't be constant-folded or used in
constexpr.

What makes the continued lack of a __builtin_arm_rbit() in gcc a bit bizarre is
that the (identically named) Neon versions of this instruction on AArch64
actually *did* receive proper intrinsics! [1]

It's worth mentioning that clang does support __builtin_arm_rbit(), and they've
actually generalized this to a full set of target-independent bitreverse
builtins [2].

[1] https://gcc.gnu.org/ml/gcc-patches/2014-08/msg01913.html
[2] http://clang.llvm.org/docs/LanguageExtensions.html#builtin-bitreverse

[Bug c++/67625] New: some constexpr expressions rejected as enumerator value

2015-09-18 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67625

Bug ID: 67625
   Summary: some constexpr expressions rejected as enumerator
value
   Product: gcc
   Version: 5.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: matthijsvanduin at gmail dot com
  Target Milestone: ---

GCC 5.2.1 rejects the following code (with -std=gnu++11 or later):

constexpr uint16_t bswap16( uint16_t x ) {
return __builtin_bswap16( x );
}
constexpr int foo_1 = bswap16(1);
enum { foo_2 = foo_1 };
enum { foo_3 = __builtin_bswap16(1) };
enum { foo_4 = bswap16(1) };

with the error message "enumerator value for ‘foo_4’ is not an integer
constant", while the other three definitions of the same constant are accepted.


This is a regression w.r.t. 4.9.3