[Bug c++/71384] New: Global constructors (init_array) emitted for trivial initialisation depending on source code ordering

2016-06-02 Thread niels at penneman dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71384

Bug ID: 71384
   Summary: Global constructors (init_array) emitted for trivial
initialisation depending on source code ordering
   Product: gcc
   Version: 5.3.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: niels at penneman dot org
  Target Milestone: ---

GCC versions 4.7.2/5.3.0/5.3.1 are emitting a global constructor (to the
.init_array section) for the following piece of trivial code:

===

struct X
{
  constexpr X(int a);
  const int m_a;
};
X x(999);
inline constexpr X::X(int a):m_a(a) {}

===

Swapping the last two lines, i.e. placing the constructor implementation before
the declaration of 'x', causes 'x' to be emitted to the '.data' section with
value 999 instead. The latter is desirable as the generate binary is far
smaller and does not require global constructors.

How to reproduce:

g++ -std=c++11 -c -save-temps=obj global-constructor.cxx

Occurs regardless of whether you specify -O0, -O1, -O2, -O3. In a complete
program, -flto cannot resolve this. The issue occurs on both x86_64 and ARM, so
not in the backend. Also occurs with -std=c++14 and -std=c++17 on GCC 5.3.x.

Compiler versions used:

$ g++ -###
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/5.3.1/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap
--enable-languages=c,c++,objc,obj-c++,fortran,ada,go,lto --prefix=/usr
--mandir=/usr/share/man --infodir=/usr/share/info
--with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared
--enable-threads=posix --enable-checking=release --enable-multilib
--with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions
--enable-gnu-unique-object --enable-linker-build-id
--with-linker-hash-style=gnu --enable-plugin --enable-initfini-array
--disable-libgcj --with-isl --enable-libmpx --enable-gnu-indirect-function
--with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 5.3.1 20160406 (Red Hat 5.3.1-6) (GCC)

$ ${CROSS_COMPILE}g++ -###
Using built-in specs.
COLLECT_GCC=/home/niels/workspace/toolchains/build/arm-none-eabi/output/bin/arm-none-eabi-g++
COLLECT_LTO_WRAPPER=/home/niels/workspace/toolchains/build/arm-none-eabi/output/libexec/gcc/arm-none-eabi/5.3.0/lto-wrapper
Target: arm-none-eabi
Configured with:
/home/niels/workspace/toolchains/build/arm-none-eabi/work/src/gcc-5.3.0/configure
--build=x86_64-build_pc-linux-gnu --host=x86_64-build_pc-linux-gnu
--target=arm-none-eabi
--prefix=/home/niels/workspace/toolchains/build/arm-none-eabi/output
--with-local-prefix=/home/niels/workspace/toolchains/build/arm-none-eabi/output/arm-none-eabi/sysroot
--with-sysroot=/home/niels/workspace/toolchains/build/arm-none-eabi/output/arm-none-eabi/sysroot
--with-newlib --enable-threads=no --disable-shared --with-float=soft
--with-pkgversion='crosstool-NG crosstool-ng-1.22.0-134-ge1d494a'
--enable-__cxa_atexit --disable-libgomp --disable-libmudflap --disable-libssp
--disable-libquadmath --disable-libquadmath-support
--with-gmp=/home/niels/workspace/toolchains/build/arm-none-eabi/work/arm-none-eabi/buildtools
--with-mpfr=/home/niels/workspace/toolchains/build/arm-none-eabi/work/arm-none-eabi/buildtools
--with-mpc=/home/niels/workspace/toolchains/build/arm-none-eabi/work/arm-none-eabi/buildtools
--with-isl=/home/niels/workspace/toolchains/build/arm-none-eabi/work/arm-none-eabi/buildtools
--enable-lto --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++ -lm'
--enable-target-optspace --disable-nls --disable-multilib
--enable-languages=c,c++
Thread model: single
gcc version 5.3.0 (crosstool-NG crosstool-ng-1.22.0-134-ge1d494a)

$ ${CROSS_COMPILE}g++ -###
Using built-in specs.
COLLECT_GCC=/opt/OSELAS.Toolchain-2012.12.1/arm-v5te-linux-gnueabi/gcc-4.7.2-glibc-2.16.0-binutils-2.22-kernel-3.6-sanitized/bin/arm-v5te-linux-gnueabi-g++
COLLECT_LTO_WRAPPER=/opt/OSELAS.Toolchain-2012.12.1/arm-v5te-linux-gnueabi/gcc-4.7.2-glibc-2.16.0-binutils-2.22-kernel-3.6-sanitized/bin/../libexec/gcc/arm-v5te-linux-gnueabi/4.7.2/lto-wrapper
Target: arm-v5te-linux-gnueabi
Configured with:
/home/mol/dude/tmp/OSELAS.Toolchain-2012.12.1/platform-arm-v5te-linux-gnueabi-gcc-4.7.2-glibc-2.16.0-binutils-2.22-kernel-3.6-sanitized/build-cross/gcc-4.7.2/configure
--build=x86_64-host-linux-gnu --host=x86_64-host-linux-gnu
--target=arm-v5te-linux-gnueabi
--with-sysroot=/home/mol/dude/tmp/OSELAS.Toolchain-2012.12.1/inst/opt/OSELAS.Toolchain-2012.12.1/arm-v5te-linux-gnueabi/gcc-4.7.2-glibc-2.16.0-binutils-2.22-kernel-3.6-sanitized/sysroot-arm-v5te-linux-gnueabi
--disable-multilib --with-float=soft --with-fpu=vfp --with-cpu=arm926ej-s
--enable-__cxa_atexit --disable-sjlj-exceptions --disable-nls
--disable-decimal-float --disable-fixed-point --disable-win32-registry
--enable

[Bug tree-optimization/58727] New: Sub-optimal code for bit clear/set sequence

2013-10-14 Thread niels at penneman dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58727

Bug ID: 58727
   Summary: Sub-optimal code for bit clear/set sequence
   Product: gcc
   Version: 4.9.0
Status: UNCONFIRMED
  Severity: minor
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: niels at penneman dot org

GCC generates sub-optimal but functionally correct code when successively
clearing a bit and setting another bit in an integral value, as shown in the
clear_set and set_clear functions below. To be more specific, at all
O-levels except -O1, it emits code to clear the bit being set, prior to
setting it. When splitting the clear and set operations with exactly the same
bits, and calling them one after the other, the problem does not occur. It
looks like this behaviour is caused by an optimization pass prior to inlining.

On ARM this may cause a superfluous instruction to be emitted. In most
instructions, the 32-bit ARM ISA can only encode 8-bit immediate values. Most
of those instructions provide 4 extra bits in their encoding to specify a
rotation. This implies that when the bit being set (SET in the test case
below) is close enough to the bit being cleared (CLEAR), the code generation
phase merges the superflous clear for SET with the one for CLEAR. When the
bits are too far apart, however, an extra clear instruction is generated, even
when optimizing with -Os.

It looks like the root cause is a problem in the optimizer and not the code
generator, since the same behaviour can be observed on x86_64. However, in the
latter case this bug does not alter the number of instructions required. My
knowledge of the x86 architecture is limited so I have no clue whether it
causes any inefficiencies at all (instruction width, perhaps?).

The test case below contains six functions:
- clear_set and set_clear suffer from the problem described above: the
compiler usually emits a superfluous clear for the bit being set;
- clear and set perform the individual operations;
- clear_set_inline and set_clear_inline are used to demonstrate that the
problem does not occur when splitting and inlining the operations.

The tests were performed on a Gentoo x86_64 Linux system; GCC versions for both
native and cross-compiler are given below.

## testcase.c #

enum masks { CLEAR = 0x40, SET = 0x02 };
unsigned clear_set(unsigned a) { return (a  ~CLEAR) | SET; }
unsigned set_clear(unsigned a) { return (a | SET)  ~CLEAR; }
unsigned clear(unsigned a) { return a  ~CLEAR; }
unsigned set(unsigned a) { return a | SET; }
__attribute__((flatten)) unsigned clear_set_inline(unsigned a) { return
set(clear(a)); }
__attribute__((flatten)) unsigned set_clear_inline(unsigned a) { return
clear(set(a)); }

## GCC version (ARM) ##

$ arm-none-eabi-gcc -###
Using built-in specs.
COLLECT_GCC=/path/to/toolchain/bin/arm-none-eabi-gcc
COLLECT_LTO_WRAPPER=/path/to/toolchain/libexec/gcc/arm-none-eabi/4.8.1/lto-wrapper
Target: arm-none-eabi
Configured with: /path/to/builddir/src/gcc-4.8.1/configure
--build=x86_64-build_unknown-linux-gnu --host=x86_64-build_unknown-linux-gnu
--target=arm-none-eabi --prefix=/path/to/toolchain
--with-local-prefix=/path/to/toolchain/arm-none-eabi/sysroot
--disable-libmudflap --with-sysroot=/path/to/toolchain/arm-none-eabi/sysroot
--with-newlib --enable-threads=no --disable-shared
--with-pkgversion='crosstool-NG 1.19.0' --with-float=hard
--disable-__cxa_atexit --with-gmp=/path/to/builddir/arm-none-eabi/buildtools
--with-mpfr=/path/to/builddir/arm-none-eabi/buildtools
--with-mpc=/path/to/builddir/arm-none-eabi/buildtools --with-ppl=no
--with-isl=no --with-cloog=no --with-libelf=no --disable-lto
--with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm'
--enable-target-optspace --disable-libgomp --disable-libmudflap --disable-nls
--disable-multilib --enable-languages=c
Thread model: single
gcc version 4.8.1 (crosstool-NG 1.19.0)

## GCC version (x86_64) ###

$ gcc -###
Using built-in specs.
COLLECT_GCC=/usr/x86_64-pc-linux-gnu/gcc-bin/4.9.0-alpha20131013/gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/4.9.0-alpha20131013/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with:
/var/tmp/portage/sys-devel/gcc-4.9.0_alpha20131013/work/gcc-4.9-20131013/configure
--prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/4.9.0-alpha20131013
--includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.0-alpha20131013/include
--datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.9.0-alpha20131013
--mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.9.0-alpha20131013/man
--infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.9.0-alpha20131013/info
--with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.0-alpha20131013/include/g++-v4
--host=x86_64-pc-linux-gnu

[Bug rtl-optimization/58727] Sub-optimal code for bit clear/set sequence

2013-10-14 Thread niels at penneman dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58727

--- Comment #2 from Niels Penneman niels at penneman dot org ---
You could be right about x86 being a different issue, since the superfluous
clear is there for every single optimization level that I have tested.

In that case, for the sake of completeness:
- ARM results have also been verified on 4.6.1 and 4.7.2;
- x86_64 results have also been verified on 4.8.1.

Looking at the list of GCC primary targets, I also see MIPS and PowerPC. Here
is what happens on MIPS.

## GCC version (MIPS) #

$ mips-none-elf-gcc -###
Using built-in specs.
COLLECT_GCC=mips-none-elf-gcc
COLLECT_LTO_WRAPPER=/path/to/toolchain/libexec/gcc/mips-none-elf/4.8.1/lto-wrapper
Target: mips-none-elf
Configured with: /path/to/builddir/src/gcc-4.8.1/configure
--build=x86_64-build_unknown-linux-gnu --host=x86_64-build_unknown-linux-gnu
--target=mips-none-elf --prefix=/path/to/toolchain
--with-local-prefix=/path/to/toolchain/mips-none-elf/sysroot
--disable-libmudflap --with-sysroot=/path/to/toolchain/mips-none-elf/sysroot
--with-newlib --enable-threads=no --disable-shared
--with-pkgversion='crosstool-NG 1.19.0' --with-abi=32 --with-float=soft
--disable-__cxa_atexit --with-gmp=/path/to/builddir/mips-none-elf/buildtools
--with-mpfr=/path/to/builddir/mips-none-elf/buildtools
--with-mpc=/path/to/builddir/mips-none-elf/buildtools --with-ppl=no
--with-isl=no --with-cloog=no --with-libelf=no --disable-lto
--with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm'
--enable-target-optspace --disable-libgomp --disable-libmudflap --disable-nls
--disable-multilib --enable-languages=c
Thread model: single
gcc version 4.8.1 (crosstool-NG 1.19.0) 

$ mips64-none-elf-gcc -###
Using built-in specs.
COLLECT_GCC=./mips64-none-elf-gcc
COLLECT_LTO_WRAPPER=/path/to/toolchain/libexec/gcc/mips64-none-elf/4.8.1/lto-wrapper
Target: mips64-none-elf
Configured with: /path/to/builddir/src/gcc-4.8.1/configure
--build=x86_64-build_unknown-linux-gnu --host=x86_64-build_unknown-linux-gnu
--target=mips64-none-elf --prefix=/path/to/toolchain
--with-local-prefix=/path/to/toolchain/mips64-none-elf/sysroot
--disable-libmudflap --with-sysroot=/path/to/toolchain/mips64-none-elf/sysroot
--with-newlib --enable-threads=no --disable-shared
--with-pkgversion='crosstool-NG 1.19.0' --with-abi=64 --with-float=soft
--disable-__cxa_atexit --with-gmp=/path/to/builddir/mips64-none-elf/buildtools
--with-mpfr=/path/to/builddir/mips64-none-elf/buildtools
--with-mpc=/path/to/builddir/mips64-none-elf/buildtools --with-ppl=no
--with-isl=no --with-cloog=no --with-libelf=no --disable-lto
--with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm'
--enable-target-optspace --disable-libgomp --disable-libmudflap --disable-nls
--disable-multilib --enable-languages=c
Thread model: single
gcc version 4.8.1 (crosstool-NG 1.19.0) 

## Compiler invocation / steps to reproduce ###

mips-none-elf-gcc -O1 -S -o - -c testcase.c | grep -vE '^\s*\.'
mips64-none-elf-gcc -O1 -S -o - -c testcase.c | grep -vE '^\s*\.'

## Observations  expected results 

The instructions generated for the clear_set and set_clear functions are
identical:

MIPS32 (o32 ABI):
li  $2,-4259840 # 0xffbf
ori $2,$2,0xfffd
and $2,$4,$2
j   $31
ori $2,$2,0x2

MIPS64 (n64 ABI):
li  $2,-4259840 # 0xffbf
ori $2,$2,0xfffd
and $4,$4,$2
j   $31
ori $2,$4,0x2

Just to compare to the *_inline variants (also both identical):

MIPS32:
li  $2,-4259840 # 0xffbf
ori $2,$2,0x
and $2,$4,$2
j   $31
ori $2,$2,0x2

MIPS64:
li  $2,-4259840 # 0xffbf
ori $2,$2,0x
and $4,$4,$2
j   $31
ori $2,$4,0x2

Compare non-inlined the mask used to clear bits is 0xffbd while with
inlined split operations the mask is 0xffbf. The SET bit also appears in
the mask to be cleared when using -O0, -O2, -O3 and -Os, much like on
x86. Once again, from the looks of the clear function I doubt any superfluous
instruction is emitted here, so there are probably no run-time effects. I only
have limited knowledge of MIPS so correct me if I am wrong.

For your reference, here is the clear function (same code at all optimization
levels different from -O0):

MIPS32/64:
li  $2,-4259840 # 0xffbf
ori $2,$2,0x
j   $31
and $2,$4,$2

It apparently needs the extra ori instruction regardless of whether SET
appears in the mask or not.

In the end, the problem with ARM does look different since it does not occur
with -O1; perhaps some

[Bug c++/55311] Cannot specialize template parameter of type 'const char *const' in 'using' alias

2012-12-05 Thread niels at penneman dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55311



--- Comment #2 from Niels Penneman niels at penneman dot org 2012-12-05 
08:32:42 UTC ---

Workaround for GCC 4.8.0-alpha20121202 (full version details see earlier post)

for case #2: replace STRING_PTR template parameter with static_castconst char

*const(STRING_PTR).



Example code below with same invocation arguments is accepted by the compiler.



===



extern constexpr char STRING_PTR[] = test;



template const char *const C, typename T

struct A {};



template typename T

struct B: Astatic_castconst char *const(STRING_PTR), T {};



===



This workaround does not work for case #1 (with 'using') and does not seem to

work on 4.7.2 in general.


[Bug c++/55311] Cannot specialize template parameter of type 'const char *const' in 'using' alias

2012-12-04 Thread niels at penneman dot org

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55311

Niels Penneman niels at penneman dot org changed:

   What|Removed |Added

   Keywords||rejects-valid
  Known to fail||4.6.3, 4.7.2, 4.8.0

--- Comment #1 from Niels Penneman niels at penneman dot org 2012-12-04 
21:00:50 UTC ---
Exact same thing in a slightly different shape: with a derived struct instead
of a 'using' alias

===

$ g++ -###
Using built-in specs.
COLLECT_GCC=/usr/x86_64-pc-linux-gnu/gcc-bin/4.8.0-alpha20121202/g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/4.8.0-alpha20121202/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with:
/var/tmp/portage/sys-devel/gcc-4.8.0_alpha20121202/work/gcc-4.8-20121202/configure
--prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/4.8.0-alpha20121202
--includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.0-alpha20121202/include
--datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.8.0-alpha20121202
--mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.8.0-alpha20121202/man
--infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.8.0-alpha20121202/info
--with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.0-alpha20121202/include/g++-v4
--host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --disable-altivec
--disable-fixed-point --with-ppl --with-cloog --disable-ppl-version-check
--with-cloog-include=/usr/include/cloog-ppl --enable-lto --enable-nls
--without-included-gettext --with-system-zlib --enable-obsolete
--disable-werror --enable-secureplt --enable-multilib
--with-multilib-list=m32,m64 --enable-libmudflap --disable-libssp
--enable-libgomp
--with-python-dir=/share/gcc-data/x86_64-pc-linux-gnu/4.8.0-alpha20121202/python
--enable-checking=release --disable-libgcj --disable-libquadmath
--enable-languages=c,c++ --enable-shared --enable-threads=posix
--enable-__cxa_atexit --enable-clocale=gnu --enable-targets=all
--with-bugurl=http://bugs.gentoo.org/ --with-pkgversion='Gentoo
4.8.0_alpha20121202'
Thread model: posix
gcc version 4.8.0-alpha20121202 20121202 (experimental) (Gentoo
4.8.0_alpha20121202) 

===

extern constexpr char STRING_PTR[] = test;

template const char *const C, typename T
struct A {};

template typename T
struct B: ASTRING_PTR, T {};

===

$ g++ -fsyntax-only -std=c++11 test2.cxx 
test2.cxx:7:26: error: ‘test’ is not a valid template argument of type ‘const
char*’ because ‘test’ is not a variable
 struct B: ASTRING_PTR, T {};
  ^

===


[Bug c++/55535] New: Call to default constructor with overloaded subscript operator is interpreted as declaring/using array

2012-11-29 Thread niels at penneman dot org

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55535

 Bug #: 55535
   Summary: Call to default constructor with overloaded subscript
operator is interpreted as declaring/using array
Classification: Unclassified
   Product: gcc
   Version: 4.8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: ni...@penneman.org


gcc version:

Using built-in specs.
COLLECT_GCC=/usr/x86_64-pc-linux-gnu/gcc-bin/4.8.0-alpha20121125/g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/4.8.0-alpha20121125/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with:
/var/tmp/portage/sys-devel/gcc-4.8.0_alpha20121125/work/gcc-4.8-20121125/configure
--prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/4.8.0-alpha20121125
--includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.0-alpha20121125/include
--datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.8.0-alpha20121125
--mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.8.0-alpha20121125/man
--infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.8.0-alpha20121125/info
--with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.0-alpha20121125/include/g++-v4
--host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --disable-altivec
--disable-fixed-point --with-ppl --with-cloog --disable-ppl-version-check
--with-cloog-include=/usr/include/cloog-ppl --enable-lto --enable-nls
--without-included-gettext --with-system-zlib --enable-obsolete
--disable-werror --enable-secureplt --enable-multilib
--with-multilib-list=m32,m64 --enable-libmudflap --disable-libssp
--enable-libgomp
--with-python-dir=/share/gcc-data/x86_64-pc-linux-gnu/4.8.0-alpha20121125/python
--enable-checking=release --disable-libgcj --disable-libquadmath
--enable-languages=c,c++ --enable-shared --enable-threads=posix
--enable-__cxa_atexit --enable-clocale=gnu --enable-targets=all
--with-bugurl=http://bugs.gentoo.org/ --with-pkgversion='Gentoo
4.8.0_alpha20121125'
Thread model: posix
gcc version 4.8.0-alpha20121125 20121125 (experimental) (Gentoo
4.8.0_alpha20121125) 



Command and output:
$ g++ -fsyntax-only -Wall -Wextra voodoo.cxx 
voodoo.cxx: In function ‘void func()’:
voodoo.cxx:12:20: error: size of array has non-integral type ‘Empty’
   (Voodoo()[Empty()]) | Empty();
^
voodoo.cxx:12:20: error: ‘type name’ declared as function returning an array
voodoo.cxx:12:20: error: size of array has non-integral type ‘Empty’
voodoo.cxx:12:20: error: ‘type name’ declared as function returning an array



Full source code of 'voodoo.cxx':

struct Empty {};
struct Voodoo
{
  Empty operator [](Empty);
};
void func()
{
  (Voodoo()[Empty()]);
}



It looks like gcc sees the type name (call to default constructor) followed by
the subscript operator as using or declaring an array. Without the parentheses
around Voodoo()[Empty()] makes the error go away. I don't see why the
parentheses should cause functionally different behaviour.

Because of that, and because the code passes syntax checking with clang 3.1,
icc 13 and armcc, I assume it's just something odd in g++. I am however not
100% sure that the above code conforms to the C++ standard, simply because I'm
not sure where to start looking.

While the above example looks useless the code has been extracted and
simplified from a 100k LOC boost/spirit-based parser where it did make sense.

Compiling this code also fails on 4.5.4, 4.6.3 and 4.7.2.

Note: (ancient) bug #13503 came up in 'possible duplicates' and looks slightly
related
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13503


[Bug c++/55535] Call to default constructor with overloaded subscript operator is interpreted as declaring/using array

2012-11-29 Thread niels at penneman dot org

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55535

--- Comment #1 from Niels Penneman niels at penneman dot org 2012-11-29 
21:07:07 UTC ---
Wrong copy/paste for output. Below is the correct compiler output.

$ g++ -fsyntax-only -Wall -Wextra voodoo.cxx 
voodoo.cxx: In function ‘void func()’:
voodoo.cxx:10:20: error: size of array has non-integral type ‘Empty’
   (Voodoo()[Empty()]);
^
voodoo.cxx:10:20: error: ‘type name’ declared as function returning an array
voodoo.cxx:10:20: error: size of array has non-integral type ‘Empty’
voodoo.cxx:10:20: error: ‘type name’ declared as function returning an array


[Bug c++/55311] New: Cannot specialize template parameter of type 'const char *const' in 'using' alias

2012-11-13 Thread niels at penneman dot org

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55311

 Bug #: 55311
   Summary: Cannot specialize template parameter of type 'const
char *const' in 'using' alias
Classification: Unclassified
   Product: gcc
   Version: 4.8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: ni...@penneman.org


When providing arguments for a template class in a 'using' alias, specifying
arguments of type 'const char *const' doesn't work. It does work for an 'int'
pointer.

==

GCC version:

$ gcc -###
Using built-in specs.
COLLECT_GCC=/usr/x86_64-pc-linux-gnu/gcc-bin/4.8.0-alpha2012/gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/4.8.0-alpha2012/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with:
/var/tmp/portage/sys-devel/gcc-4.8.0_alpha2012/work/gcc-4.8-2012/configure
--prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/4.8.0-alpha2012
--includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.0-alpha2012/include
--datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.8.0-alpha2012
--mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.8.0-alpha2012/man
--infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.8.0-alpha2012/info
--with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.0-alpha2012/include/g++-v4
--host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --disable-altivec
--disable-fixed-point --with-ppl --with-cloog --disable-ppl-version-check
--with-cloog-include=/usr/include/cloog-ppl --enable-lto --enable-nls
--without-included-gettext --with-system-zlib --enable-obsolete
--disable-werror --enable-secureplt --enable-multilib
--with-multilib-list=m32,m64 --enable-libmudflap --disable-libssp
--enable-libgomp
--with-python-dir=/share/gcc-data/x86_64-pc-linux-gnu/4.8.0-alpha2012/python
--enable-checking=release --disable-libgcj --disable-libquadmath
--enable-languages=c,c++ --enable-shared --enable-threads=posix
--enable-__cxa_atexit --enable-clocale=gnu --enable-targets=all
--with-bugurl=http://bugs.gentoo.org/ --with-pkgversion='Gentoo
4.8.0_alpha2012'
Thread model: posix
gcc version 4.8.0-alpha2012 2012 (experimental) (Gentoo
4.8.0_alpha2012)

==

Code that fails to compile:

==

template const char *const C, typename T
struct A
{};

extern constexpr char HELLO_WORLD[] = hello world;

template typename T
using PartiallySpecialized = AHELLO_WORLD, T;

int main(int, char **)
{
AHELLO_WORLD, int original;
PartiallySpecializedint ps;
}

==

Compiler invocation/output:

$ g++ -std=c++11 -Wall -Wextra strbug.cxx 
strbug.cxx:8:46: error: ‘hello world’ is not a valid template argument of
type ‘const char*’ because ‘hello world’ is not a variable
 using PartiallySpecialized = AHELLO_WORLD, T;
  ^
strbug.cxx: In function ‘int main(int, char**)’:
strbug.cxx:12:22: warning: unused variable ‘original’ [-Wunused-variable]
  AHELLO_WORLD, int original;
  ^
strbug.cxx:13:28: warning: unused variable ‘ps’ [-Wunused-variable]
  PartiallySpecializedint ps;
^

==

Notice the first instantiation ('original') does not generate any errors or
warnings. The second instantiation ('ps') should be identical to the second.
Above code compiles without warnings and without errors on Clang 3.1.


[Bug c++/53531] ,,,, accepted as template arguments for variadic template

2012-07-10 Thread niels at penneman dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53531

Niels Penneman niels at penneman dot org changed:

   What|Removed |Added

 CC||niels at penneman dot org

--- Comment #1 from Niels Penneman niels at penneman dot org 2012-07-10 
10:37:34 UTC ---
Exactly the same behavior with both 4.6.3 and 4.7.1

Similar test case below. Adding a trailing comma to a list of template
arguments breaks the code but compiles successfully and without warnings. A
trailing comma in a template list of for instance boost::mpl::vector will make
the vector empty.

#
template typename ... Ts
struct S;

template typename T, typename ... Ts
struct ST, Ts ... { static constexpr int count = STs ...::count + 1; };

template typename T
struct ST { static constexpr int count = 1; };

int main()
{
  return Schar, int, long,::count;
}
#
$ g++ -v
Using built-in specs.
COLLECT_GCC=/usr/x86_64-pc-linux-gnu/gcc-bin/4.6.3/g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/4.6.3/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /var/tmp/portage/sys-devel/gcc-4.6.3/work/gcc-4.6.3/configure
--prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/4.6.3
--includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.3/include
--datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.6.3
--mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.6.3/man
--infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.6.3/info
--with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.3/include/g++-v4
--host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --disable-altivec
--disable-fixed-point --with-ppl --with-cloog --disable-ppl-version-check
--with-cloog-include=/usr/include/cloog-ppl --enable-lto --enable-nls
--without-included-gettext --with-system-zlib --enable-obsolete
--disable-werror --enable-secureplt --enable-multilib --disable-libmudflap
--disable-libssp --enable-libgomp
--with-python-dir=/share/gcc-data/x86_64-pc-linux-gnu/4.6.3/python
--enable-checking=release --disable-libgcj --disable-libquadmath
--enable-languages=c,c++ --enable-shared --enable-threads=posix
--enable-__cxa_atexit --enable-clocale=gnu --enable-targets=all
--with-bugurl=http://bugs.gentoo.org/ --with-pkgversion='Gentoo 4.6.3 p1.3,
pie-0.5.2'
Thread model: posix
gcc version 4.6.3 (Gentoo 4.6.3 p1.3, pie-0.5.2) 

$ g++ -v
Using built-in specs.
COLLECT_GCC=/usr/x86_64-pc-linux-gnu/gcc-bin/4.7.1/g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/4.7.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /var/tmp/portage/sys-devel/gcc-4.7.1/work/gcc-4.7.1/configure
--prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/4.7.1
--includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.1/include
--datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.7.1
--mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.7.1/man
--infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.7.1/info
--with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.1/include/g++-v4
--host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --disable-altivec
--disable-fixed-point --with-ppl --with-cloog --disable-ppl-version-check
--with-cloog-include=/usr/include/cloog-ppl --enable-lto --enable-nls
--without-included-gettext --with-system-zlib --enable-obsolete
--disable-werror --enable-secureplt --enable-multilib
--with-multilib-list=m32,m64 --disable-libmudflap --disable-libssp
--enable-libgomp
--with-python-dir=/share/gcc-data/x86_64-pc-linux-gnu/4.7.1/python
--enable-checking=release --disable-libgcj --disable-libquadmath
--enable-languages=c,c++ --enable-shared --enable-threads=posix
--enable-__cxa_atexit --enable-clocale=gnu --enable-targets=all
--with-bugurl=http://bugs.gentoo.org/ --with-pkgversion='Gentoo 4.7.1 p1.0,
pie-0.5.3'
Thread model: posix
gcc version 4.7.1 (Gentoo 4.7.1 p1.0, pie-0.5.3) 
#

Command: g++ -Wall -Wextra -std=c++0x undef.cpp
Output: none, completes succesfully

Command: ./a.out ; echo $?
Output: 0

When omitting the trailing comma, return status of compiled application is 3 as
expected.