[Bug c++/93870] New: User-defined conversion function not working in evaluation of template argument

2020-02-21 Thread o_kniemeyer at maxon dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93870

Bug ID: 93870
   Summary: User-defined conversion function not working in
evaluation of template argument
   Product: gcc
   Version: 7.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: o_kniemeyer at maxon dot net
  Target Milestone: ---

According to gcc.godbolt.org GCC 7.1 up to 9.2 fail to compile this piece of
code:


template  struct EnumWrapper
{
ENUM value;

constexpr operator ENUM() const
{
return value;
}
};

enum E : int
{
V
};

constexpr EnumWrapper operator ~(E a)
{
return {E(~int(a))};
}

template  struct R
{
static void Func();
};

template  struct S : R<~X>
{
};

void Test()
{
S::Func();
}


The can't evaluate the template argument ~X for R:

: In instantiation of 'struct S<(E)0>':
:32:12:   required from here
:26:31: error: taking address of temporary [-fpermissive]
 template  struct S : R<~X>
   ^
:26:31: error: no matching function for call to
'EnumWrapper::operator E(EnumWrapper*)'
:5:12: note: candidate: constexpr EnumWrapper::operator ENUM()
const [with ENUM = E]
  constexpr operator ENUM() const
^~~~
:5:12: note:   candidate expects 0 arguments, 1 provided
: In function 'void Test()':
:32:14: error: 'Func' is not a member of 'S<(E)0>'
 S::Func();
  ^~~~

All other compiler are fine. A workaround is to convert to E explicitly by
writing R.

[Bug c++/87841] Member of class template hides template parameter of another member

2018-12-19 Thread o_kniemeyer at maxon dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87841

--- Comment #5 from Ole Kniemeyer  ---
Thanks for asking the committee. I think the standard makes sense as it is,
because otherwise there is no chance to name the template parameter (that's
what I need in my specific situation where I found the bug). Also the standard
is what I would expect as the template parameter is "closer" to the function
template as a member type of the enclosing class.

[Bug c++/88221] New: Only restricted set of balanced token sequences allowed for attributes

2018-11-27 Thread o_kniemeyer at maxon dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88221

Bug ID: 88221
   Summary: Only restricted set of balanced token sequences
allowed for attributes
   Product: gcc
   Version: 8.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: o_kniemeyer at maxon dot net
  Target Milestone: ---

Attribute arguments may be arbitrary token sequences as long as they are
balanced regarding () [] {}. From C++17 10.6.1:

attribute-argument-clause :
( balanced-token-seq opt )

balanced-token-seq :
balanced-token
balanced-token-seq balanced-token

balanced-token :
( balanced-token-seqopt )
[ balanced-token-seqopt ]
{ balanced-token-seqopt }
any token other than a parenthesis, a bracket, or a brace

However GCC only allows a quite restricted set. For example the following
arguments are rejected:

[[myattribute(a)]] void Func();
[[myattribute(void)]] void Func();
[[myattribute(1 2)]] void Func();
[[myattribute(1:2)]] void Func();
[[myattribute([1])]] void Func();

[Bug c++/87841] Member of class template hides template parameter of another member

2018-11-01 Thread o_kniemeyer at maxon dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87841

--- Comment #3 from Ole Kniemeyer  ---
Yes, I also tried other compilers, and all of them fail. But in [temp.local] it
is explicitly stated that "the name of a member of the class template hides the
name of a template-parameter of any enclosing class templates (BUT NOT A
TEMPLATE-PARAMETER OF THE MEMBER IF THE MEMBER IS A CLASS OR FUNCTION
TEMPLATE)". (Bold by me, that's the case of this bug.)

[Bug c++/87841] New: Member of class template hides template parameter of another member

2018-11-01 Thread o_kniemeyer at maxon dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87841

Bug ID: 87841
   Summary: Member of class template hides template parameter of
another member
   Product: gcc
   Version: 8.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: o_kniemeyer at maxon dot net
  Target Milestone: ---

The following code example from C++17 standard 17.6.1.7 does not compile:

template struct A {
  struct B { /* ... */ };
  typedef void C;
  void f();
  template void g(U);
};

template void A::f() {
  B b; // A's B, not the template parameter
}

template template void A::g(C) {
  B b; // A's B, not the template parameter
  C c; // the template parameter C, not A's C
}

This is because GCC uses A's C instead of the template parameter C of A::g.

[Bug c++/87842] New: Member of class template hides template parameter of another member

2018-11-01 Thread o_kniemeyer at maxon dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87842

Bug ID: 87842
   Summary: Member of class template hides template parameter of
another member
   Product: gcc
   Version: 8.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: o_kniemeyer at maxon dot net
  Target Milestone: ---

The following code example from C++17 standard 17.6.1.7 does not compile:

template struct A {
  struct B { /* ... */ };
  typedef void C;
  void f();
  template void g(U);
};

template void A::f() {
  B b; // A's B, not the template parameter
}

template template void A::g(C) {
  B b; // A's B, not the template parameter
  C c; // the template parameter C, not A's C
}

This is because GCC uses A's C instead of the template parameter C of A::g.

[Bug c++/79101] New: Registers aren't used for passing and returning objects when there is a move constructor

2017-01-16 Thread o_kniemeyer at maxon dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79101

Bug ID: 79101
   Summary: Registers aren't used for passing and returning
objects when there is a move constructor
   Product: gcc
   Version: 6.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: o_kniemeyer at maxon dot net
  Target Milestone: ---

According to the calling conventions of System V AMD64 ABI (e.g.
https://www.uclibc.org/docs/psABI-x86_64.pdf) a simple class with trivial copy
constructor and trivial destructor is passed and returned in a register, no
matter if there is a non-trivial move constructor or not. However this code:

struct X
{
  X(char* p = nullptr) : ptr(p) { }
  X(const X& src) = default;
  X(X&& src) : ptr(src.ptr) { src.ptr = nullptr; }
  X& operator=(const X&) = default;
  char* ptr;
};

X Test(X x)
{
  return x.ptr+1;
}

is (wrongly) compiled to

Test(X):
mov rdx, QWORD PTR [rsi]
mov rax, rdi
add rdx, 1
mov QWORD PTR [rdi], rdx
ret

whereas the code without move constructor is correctly compiled to

Test(X):
lea rax, [rdi+1]
ret

I checked this with all GCC versions on http://gcc.godbolt.org. Clang correctly
compiles the code to the two-liner with or without the move constructor.

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

2015-04-23 Thread o_kniemeyer at maxon dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65866

Bug ID: 65866
   Summary: Wrong warning when using list-initialization:
operation on 'b' may be undefined [-Wsequence-point]
   Product: gcc
   Version: 5.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: o_kniemeyer at maxon dot net

This is related to Bug 51253: While that bug was about wrong compiled code and
is reported to be fixed, GCC 5.1.0 still produces a warning in code like

struct X
{
  template typename... ARGS X(ARGS...);
};

void test()
{
  bool b = false;
  X{b = true, b = true};
}

warning: operation on 'b' may be undefined [-Wsequence-point]

Because list-initialization has to be done from left to right, the warning is
wrong.


[Bug c++/57610] New: Result of conversion

2013-06-14 Thread o_kniemeyer at maxon dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57610

Bug ID: 57610
   Summary: Result of conversion
   Product: gcc
   Version: 4.8.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: o_kniemeyer at maxon dot net


[Bug c++/57610] Result of conversion

2013-06-14 Thread o_kniemeyer at maxon dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57610

--- Comment #2 from Ole Kniemeyer o_kniemeyer at maxon dot net ---
Created attachment 30301
  -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=30301action=edit
cpp file (without any #includes) which shows the bug


[Bug c++/57610] Reference initialized with temporary instead of sub-object of conversion result

2013-06-14 Thread o_kniemeyer at maxon dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57610

Ole Kniemeyer o_kniemeyer at maxon dot net changed:

   What|Removed |Added

 Status|RESOLVED|UNCONFIRMED
 Resolution|INVALID |---

--- Comment #3 from Ole Kniemeyer o_kniemeyer at maxon dot net ---
In the example X can be converted to B which is a derived class of A. When an A
reference is initialized with an X object, the result of the X::operator B()
should be used directly for the A reference, but GCC creates a temporary A
object and initializes this by copy-construction from the conversion result.

At least if the classes use virtual functions, this leads to wrong results.


[Bug c++/57610] Reference initialized with temporary instead of sub-object of conversion result

2013-06-14 Thread o_kniemeyer at maxon dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57610

--- Comment #4 from Ole Kniemeyer o_kniemeyer at maxon dot net ---
As I commented in the cpp example, the C++11 standard shows exactly this
example in sections 8.5.3. So this is definitely a bug according to C++11. I
think the GCC behaviour is correct according to older C++11 standards.


[Bug c++/57610] Reference initialized with temporary instead of sub-object of conversion result

2013-06-14 Thread o_kniemeyer at maxon dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57610

--- Comment #5 from Ole Kniemeyer o_kniemeyer at maxon dot net ---
Ops, sorry, of course I meant ... to older C++ standards.


[Bug c++/57610] Reference initialized with temporary instead of sub-object of conversion result

2013-06-14 Thread o_kniemeyer at maxon dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57610

--- Comment #7 from Ole Kniemeyer o_kniemeyer at maxon dot net ---
OK, thanks for your comments. I wasn't aware of the ongoing discussion about
this issue (I was referring to the the draft version N3376 of the C++11
standard).

A B-copy would be OK, but as I said copying B into A is not a good idea if
those classes have virtual functions. The N3376 wording would be much better
for such cases.

In my case A is an interface (with dummy implementations of the virtual
functions), B an implementation of A and X an unrelated class with conversion
operator to B. Now if a function has a const A parameter (so it works with the
interface), N3376 allows me to pass an X object to this function by implicitly
creating a temporary B object which makes X look like an A. With the variant
discussed in the links you posted this wouldn't work (copying B into A makes no
sense).