[Bug c++/93969] New: Static data member cannot be initialized in place, if it is of a nested class type with a default argument in its constructor.

2020-02-28 Thread igusarov at mail dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93969

Bug ID: 93969
   Summary: Static data member cannot be initialized in place, if
it is of a nested class type with a default argument
in its constructor.
   Product: gcc
   Version: 9.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: igusarov at mail dot ru
  Target Milestone: ---

Dear gcc developers,

x86_64-gcc-9.2 available online at godbolt.org, refuses to compile a sample
program which I believe is well-formed:

struct Outer
{
struct Inner
{
Inner(int arg = 23);
};
static inline Inner  x{};// (1)
};

If invoked with a sole "-std=c++17" command-line option, the compilation fails
at line marked (1) and the following error is reported:

error: call to 'Outer::Inner::Inner(int)'
uses the default argument for parameter 1,
which is not yet defined

The sample program looks well-formed to me because of the following reasoning:
(clause numbers are per N4659 C++17 draft at
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf )

1) Class Outer::Inner is fully defined at its closing brace (12.2/p6) and
therefore is already a complete-type before Outer::x data member is declared;

2) The declaration of static inline data member Outer::x comes with a
brace-initializer (12.2/p8) which means that it is also the definition
(12.2.3.2/p3), also initializing-declaration and defining declaration
(11.6/p21);

3) Outer::x is direct-list-initialized (11.6/p16, 11.6/p17); the initializer
list is empty;

4) Class Outer::Inner has a user-defined constructor Outer::Inner::Inner(int).
That constructor is the default constructor because every formal parameter has
a corresponding default argument (15.1/p4);

5) Combination of points 3) and 4) means that Outer::x should be
default-initialized (11.6.4/p3.4, 11.6/p8.1);

6) Default initialization of Outer::x should be performed by calling its
matching constructor with an empty argument list (11.6/p7.1);

7) Each time the constructor is called with no arguments, default argument
should be evaluated for the corresponding parameter (11.3.6/p9);

8) Default argument to that constructor is an integral constant expression
which is already defined. So it seems that evaluation of the said default
argument should cause no problem.


P.S. clang-9.0.0 also reports a similar error.

[Bug target/90622] New: Suboptimal code generated for __builtin_avr_insert_bits

2019-05-24 Thread igusarov at mail dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90622

Bug ID: 90622
   Summary: Suboptimal code generated for
__builtin_avr_insert_bits
   Product: gcc
   Version: 5.4.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: igusarov at mail dot ru
  Target Milestone: ---

Please consider the following function:

uint8_t copy_bit_5_to_bit_2(uint8_t dst, uint8_t src)
{
return __builtin_avr_insert_bits(0xF5FF, src, dst);
}

That particular map value (magic hex constant) is supposed to copy the 5-th bit
from argument 'src' to the 2-nd bit of argument 'dst' while leaving all other
bits of src unmodified.

In other words, given that
bit representation of src is [s7 s6 s5 s4 s3 s2 s1 s0], and
bit representation of dst is [d7 d6 d5 d4 d3 d2 d1 d0],
it should return [d7 d6 d5 d4 d3 s5 d1 d0].

The code generated for such function is perfect:

bst r22,5# Take the 5-th bit of r22
bld r24,2# Put it as the 2-nd bit in r24

Similar code is generated for copying any n-th bit to any m-th bit, provided
that n and m are different. Thus far everything is great.

However, the code generated for copying n-th bit to n-th bit is surprisingly
suboptimal. A similar function

uint8_t copy_bit_2_to_bit_2(uint8_t dst, uint8_t src)
{
return __builtin_avr_insert_bits(0xF2FF, src, dst);
}

gives:

eor r22,r24
andi r22,lo8(4)
eor r24,r22

which takes an extra word of program memory and an extra CPU cycle at runtime.
I wonder what's wrong with using the same bst/bld idiom which is successfully
used for n-to-m copy? I would expect that the following code is much better:

bst r22,2
bld r24,2

It would be great if the compiler can generate it.

[Bug target/90616] New: Suboptimal code generated for accessing an aligned array.

2019-05-24 Thread igusarov at mail dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90616

Bug ID: 90616
   Summary: Suboptimal code generated for accessing an aligned
array.
   Product: gcc
   Version: 5.4.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: igusarov at mail dot ru
  Target Milestone: ---

Consider the following code:

#include 

uint8_t   globalArray[68]   __attribute__((aligned(256)));

uint8_t foo(uint8_t index)
{
return globalArray[index];
}

avr-gcc-5.4.0 generates the following code for the body of foo():

movr30,r24# r24 is where 'index' argument is stored
ldir31,0
subi   r30,lo8(-(globalArray))
sbci   r31,hi8(-(globalArray))
ld r24,Z

which is suboptimal because the lower byte of the address of globalArray is
always 0 due to the extended alignment enforced on that object.

Would it be possible to generate a better code for such specific indexing? For
example, the following snippet takes full advantage of the overalignment:

movr30,r24
ldir31,hi8(globalArray)
ld r24,Z

[Bug c++/90291] [8/9/10 Regression] Inline namespace erroneously extends another namespace

2019-05-03 Thread igusarov at mail dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90291

--- Comment #12 from Igor A. Goussarov  ---
Thank you for taking interest and for the efforts, Nathan!

[Bug c++/90291] [8/9/10 Regression] Inline namespace erroneously extends another namespace

2019-05-03 Thread igusarov at mail dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90291

--- Comment #10 from Igor A. Goussarov  ---
Having reflected on my feelings about the described scenario, I came up with a
slightly different wording for my complaints about the behaviour of gcc-8.x:

The fact that using an inline namespace at one point in source may alter the
interpretation of an unrelated, unaware and otherwise well-defined code at some
other point further down the same translation unit looks unsafe. That's
dangerous interference right there.

Given the following source text:

namespace B
{
namespace A
{
void foo() {}
}
}

I would expect the compiler to generate B::A::foo() no matter what header files
may have been included prior to these lines.

BTW, is that core working group forum public? Maybe I'm missing some important
reasoning why the behaviour exhibited by gcc 8.x is actually desired?

P.S. I'm having days off now; most likely, I'll not be able to reply before May
9.

[Bug c++/90291] [8/9/10 Regression] Inline namespace erroneously extends another namespace

2019-05-01 Thread igusarov at mail dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90291

--- Comment #8 from Igor A. Goussarov  ---
P.S. It seems that different compilers have different ideas about inline
namespaces. If godbolt.org can be trusted, clang-8.0 and msvc 2017 do not merge
namespaces in described scenario.

[Bug c++/90291] [8/9/10 Regression] Inline namespace erroneously extends another namespace

2019-05-01 Thread igusarov at mail dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90291

--- Comment #7 from Igor A. Goussarov  ---
The intent is to have a lot of services, each defined in its dedicated
namespace. The hierarchy of those namespaces can grow to arbitrary depth:

component
component::service_a
component::group_b::service_c
component::group_b::service_d
component::third_party::domain::service_e

Each service may have header-only public part and private part. Private part
must be placed in namespace `detail` under the namespace of its corresponding
service. So we have:

component::detail
component::service_a::detail
component::group_b::service_c::detail
component::group_b::service_d::detail
component::third_party::domain::service_e::detail

Now, if some team decided to put their service in an inline namespace (say, if
their service is common enough), the identity of detail namespaces is ruined
because they start merging with each other, subject to the order of header
files inclusion. And that leads to ODR violation and weird linker errors...

[Bug c++/90291] [8/9/10 Regression] Inline namespace erroneously extends another namespace

2019-05-01 Thread igusarov at mail dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90291

--- Comment #6 from Igor A. Goussarov  ---
Yes, this is a slightly modified excerpt from real code.
Perhaps a less abridged example would make more sense:

// Code in logger.h
namespace component
{
inline namespace utility
{
namespace detail // (1)
{
// Private implementation details
void LogImpl();
}

// Facade
inline void LogEvent()
{
detail::LogImpl();
}
}
}


// Code in service.h
namespace component
{
namespace detail// (2)
{
// Private implementation details
void ServiceImpl();
}

// Facade
inline void DoService()
{
detail::ServiceImpl();
}
}


// Code in service_impl.cpp
#include "service.h"

namespace component
{
namespace detail
{
// This defines `component::detail::ServiceImpl()`.
void ServiceImpl()
{
}
}
}


// Code in other_source.cpp
#include "logger.h"
#include "service.h"

// When both headers are included, namespace (2) is
// merged with namespace (1), which results in
// inline function `component::DoService()` calling
// `component::utility::detail::ServiceImpl()`
// which obviously isn't defined.
// Not to say that ODR for component::DoService()
// is violated.

[Bug c++/90291] New: [7/8 Regression] Inline namespace erroneously extends another namespace

2019-04-30 Thread igusarov at mail dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90291

Bug ID: 90291
   Summary: [7/8 Regression] Inline namespace erroneously extends
another namespace
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: igusarov at mail dot ru
  Target Milestone: ---

Compilation of the following code with gcc 7.x and 8.x produces different
results:

inline namespace A
{
inline namesapce B // (1)
{
void foo() {}
}
}

inline namespace B // (2)
{
inline namesapce A
{
void foo() {}
}
}

If compiled with "gcc-7.4 -std=c++11 -c", the object file contains functions
A::B::foo()
B::A::foo()
which I believe is correct.

However, if the same source is compiled with "gcc-8.3 -std=c++11 -c", the
object file contains functions
A::B::foo()
A::B::A::foo()
which I believe is wrong.

It looks like gcc 8.x assumes that the namespace at line (2) doesn't start a
new top-level namespace, but extends the namespace defined at line (1).

[Bug rtl-optimization/68086] Expression explicitly defined outside the loop is moved inside the loop by the optimizer

2015-10-24 Thread igusarov at mail dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68086

--- Comment #1 from Igor A. Goussarov  ---
Created attachment 36579
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36579=edit
Performance test for the problem


[Bug rtl-optimization/68086] New: Expression explicitly defined outside the loop is moved inside the loop by the optimizer

2015-10-24 Thread igusarov at mail dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68086

Bug ID: 68086
   Summary: Expression explicitly defined outside the loop is
moved inside the loop by the optimizer
   Product: gcc
   Version: 5.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: rtl-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: igusarov at mail dot ru
  Target Milestone: ---

Created attachment 36578
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36578=edit
Single function to reproduce the results

Compileable C source in "ex324_core.c" does not include any header files. It
consists of a single function whose performance is spoiled by the optimizer.
Please read explanatory comments in that file.

"ex324.c" is a compileable test program build around the same core function. It
merely measures the amount of CPU clock ticks taken by that core function. It
includes system headers for printf and mmap, and is provided just for
convenience of testing.

The problem was first discovered in x86_64 gcc 5.2.0 compiler. Brief regression
research showed that 4.8.3 has this problem too. 4.7.4 seems to be good.

Problem in a nutshell. Let's start with this loop:

// Case 1
for (i = 0; i < size; ++i)
  accumulator += data[i];

and rewrite it in this equivalent form:

// Case 2
int*  rebased = data + size;
for (i = -size; i; ++i)
  accumulator += rebased[i];

It looks like the forward propagation pass decides not to allocate a register
for variable 'rebased', but rather compute its value every time it is used in
the loop. This results in assembly output which, if written in terms of C,
would look like this:

for (i = -size; i; ++i)
  accumulator += *(data + (size + i));

Extra operation inside the loop only slows the program down.
This happens at any optimization level above -O0.

Command line:
x86_64-unknown-freebsd9.0_5.2.0-gcc -O2 -S ex324_core.c

Compiler:
x86_64-unknown-freebsd9.0_5.2.0-gcc -v
Using built-in specs.
COLLECT_GCC=x86_64-unknown-freebsd9.0_5.2.0-gcc
COLLECT_LTO_WRAPPER=/usr/toolchain/x86_64-unknown-freebsd9.0_5.2.0/libexec/gcc/x86_64-unknown-freebsd9.0/5.2.0/lto-wrapper
Target: x86_64-unknown-freebsd9.0
Configured with:
/mnt/hdd/usr/home/toolbuilder/build_scripts/x86_64-unknown-freebsd9.0_5.2.0/build_scripts/../tools_build/x86_64-unknown-freebsd9.0_5.2.0/gcc-5.2.0/configure
--target=x86_64-unknown-freebsd9.0
--prefix=/usr/toolchain/x86_64-unknown-freebsd9.0_5.2.0
--with-local-prefix=/usr/local
--with-sysroot=/usr/toolchain/x86_64-unknown-freebsd9.0_5.2.0/sysroot
--program-prefix=x86_64-unknown-freebsd9.0_5.2.0- --with-gnu-as --with-gnu-ld
--with-as=/usr/toolchain/x86_64-unknown-freebsd9.0_5.2.0/bin/x86_64-unknown-freebsd9.0_5.2.0-as
--with-ld=/usr/toolchain/x86_64-unknown-freebsd9.0_5.2.0/bin/x86_64-unknown-freebsd9.0_5.2.0-ld
--with-nm=/usr/toolchain/x86_64-unknown-freebsd9.0_5.2.0/bin/x86_64-unknown-freebsd9.0_5.2.0-nm
--with-objdump=/usr/toolchain/x86_64-unknown-freebsd9.0_5.2.0/bin/x86_64-unknown-freebsd9.0_5.2.0-objdump
--with-gmp=/mnt/hdd/usr/home/toolbuilder/build_scripts/x86_64-unknown-freebsd9.0_5.2.0/build_scripts/../tools_build/x86_64-unknown-freebsd9.0_5.2.0/gmp-root
--with-mpfr=/mnt/hdd/usr/home/toolbuilder/build_scripts/x86_64-unknown-freebsd9.0_5.2.0/build_scripts/../tools_build/x86_64-unknown-freebsd9.0_5.2.0/mpfr-root
--with-mpc=/mnt/hdd/usr/home/toolbuilder/build_scripts/x86_64-unknown-freebsd9.0_5.2.0/build_scripts/../tools_build/x86_64-unknown-freebsd9.0_5.2.0/mpc-root
--disable-__cxa_atexit --enable-languages=c,c++ --disable-multilib
--disable-nls --enable-shared=libstdc++ --enable-static --enable-threads
Thread model: posix
gcc version 5.2.0 (GCC)

Operating system:
amd64 FreeBSD 9.0-RELEASE

CPU:
Intel(R) Core(TM) i7-2700K CPU @ 3.50GHz (3500.10-MHz K8-class CPU)
  Origin = "GenuineIntel"  Id = 0x206a7  Family = 6  Model = 2a Stepping = 7
Features=0xbfebfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CLFLUSH,DTS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE>
Features2=0x179ae3bf<SSE3,PCLMULQDQ,DTES64,MON,DS_CPL,VMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,POPCNT,TSCDLT,AESNI,XSAVE,AVX>
  AMD Features=0x28100800<SYSCALL,NX,RDTSCP,LM>
  AMD Features2=0x1


[Bug c++/42692] New: Invalid member lookup when member template class is involved

2010-01-11 Thread igusarov at mail dot ru
The bug is: if a class definition has a nested template class, then whenever a
code refers to a name in the nested class, gcc searches it not in the nested
template class, but it the outer class.

The bug results in gcc accepting a source text that should not be compiled, and
incorrectly compiling a valid source text. Complete compilable example is
included at the end of this report. I was able to reproduce this behaviour back
to gcc 4.2.1, 3.3.2 and 2.95.3.

Explanation. Please consider the following class definition:

struct root
{
  template typename Y
  struct chain
  {
  };
};

As you see, the structure root::chainany_type has no members. However, gcc
accepts and compiles type declarations like

typedef  root::chaintype_1::chaintype_2::chaintype_3   my_type;

, where my_type becomes root::chaintype_3, asif each chain template were
looked up in the root class.

You can use the following example to reproduce the bug. The example is
compilable, which is wrong.

//---
struct root
{
  template typename Y
  struct chain
  {
  };
};

struct o1;
struct o2;
struct o3;

typedef   root::chaino1 p1;
typedef   root::chaino2::chaino1  p2;  /* - should be error */
typedef   root::chaino3::chaino2::chaino1   p3;  /* - should be error */

int main()
{
  p1 x1;
  p2 x2;
  p3 x3;

  x1 = x2 = x3; /* gcc thinks that they are of the same type! */

  return 0;
}


-- 
   Summary: Invalid member lookup when member template class is
involved
   Product: gcc
   Version: 4.4.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: igusarov at mail dot ru
 GCC build triplet: amd64-unknown-freebsd7.1
  GCC host triplet: amd64-unknown-freebsd7.1
GCC target triplet: amd64-unknown-freebsd7.1


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



[Bug c++/33909] New: Error reported on a legal source: invalid use of non-lvalue array when array name is used in initializer

2007-10-26 Thread igusarov at mail dot ru
Compiling the following code with g++ result in error. Command line to
reproduce the error is arm-linux-gnueabi-g++ -c test.cpp, where test.cpp is
the file comprising the following lines:

struct T
{
   const void* ptr;
};

const struct T my_arr[] =
{
  { 0 },
  { my_arr+1 }// Error at this line
};

Error is: invalid use of non-lvalue array

This error is reported only when compiling as C++ code. Compilation with gcc or
with -xc is successful.

I think that the code above perfectly meet C++ standard because:

1. According to 3.3.1p1, the point of declaration of my_arr is immediately
before =. Thus, the name my_arr is properly introduced and can be used in
the initializer.

2. Expression my_arr+1 should be treated as: Array-to-pointer conversion
(4.2p1), additive operator + (5.7p1). Resulting pointer does not exceed array
boundaries, so the expression is well-formed and it has legal result.

3. Whether my_arr is an lvalue or an rvalue expression is not important,
because array-to-pointer conversion is defined for lvalue and rvalue arrays
(4.2p1). Which makes error message irrelevant, because such use is valid.

4. However, I believe that expression my_arr is an lvalue expression because
it refers to an object (3.10p2). The fact that the object is const (i.e.
non-modifiable) doesn't make it non-lvalue.

Output of arm-linux-gnueabi-g++ -v is:

Using built-in specs.
Target: arm-none-linux-gnueabi
Configured with:
/home/toolbuilder/tools_build/build.arm-linux-gnueabi/gcc-4.1.1/configure
--target=arm-none-linux-gnueabi
--prefix=/usr/toolchain/arm-linux-gnueabi/gcc-4.1.1
--with-local-prefix=/usr/toolchain/arm-linux-gnueabi/gcc-4.1.1/local
--with-sysroot=/usr/toolchain/arm-linux-gnueabi/sysroot-arm11-linux-2.6.17.8-glibc-2.4
--enable-languages=c,c++ --enable-c99
--program-transform-name=s/.*/arm-linux-gnueabi--4.1.1/ --enable-shared
--enable-__cxa_atexit --disable-libunwind-exceptions --enable-threads=posix
--enable-symvers=gnu --enable-long-long --disable-cpp --with-gnu-as
--with-gnu-ld
--with-as=/usr/toolchain/arm-linux-gnueabi/bin/arm-linux-gnueabi-as
--with-ld=/usr/toolchain/arm-linux-gnueabi/bin/arm-linux-gnueabi-ld
--with-nm=/usr/toolchain/arm-linux-gnueabi/bin/arm-linux-gnueabi-nm
--with-objdump=/usr/toolchain/arm-linux-gnueabi/bin/arm-linux-gnueabi-objdump
--disable-nls --disable-multilib
Thread model: posix
gcc version 4.1.1


-- 
   Summary: Error reported on a legal source: invalid use of non-
lvalue array when array name is used in initializer
   Product: gcc
   Version: 4.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: igusarov at mail dot ru
 GCC build triplet: i386-unknown-freebsd5.4
  GCC host triplet: i386-unknown-freebsd5.4
GCC target triplet: arm-none-linux-gnueabi


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