[Bug c++/111419] New: Eager instantiation of function return type in concept causes compilation error

2023-09-14 Thread ldionne.2 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111419

Bug ID: 111419
   Summary: Eager instantiation of function return type in concept
causes compilation error
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code fails to compile on GCC:


  template 
  auto invoke(F f) -> decltype(f());

  template 
  concept invocable = requires(F&& f) {
::invoke(f);
  };

  struct Incomplete;
  template struct Holder { T t; };

  static_assert(invocable& ()>);


It produces the following error on GCC:

  : In instantiation of 'struct Holder':
  :6:11:   required from here
  :10:37: error: 'Holder::t' has incomplete type
10 | template struct Holder { T t; };
| ^
  :9:8: note: forward declaration of 'struct Incomplete'
  9 | struct Incomplete;
|^~
  Compiler returned: 1

My understanding is that this should be valid, because nothing actually
requires instantiating the return type of `f()` here, but I'm not sufficiently
well-versed in the details of concepts to know for sure.

Clang and MSVC accept the code.
Godbolt: https://godbolt.org/z/9G5zj47an

[Bug c++/103511] __builtin_bit_cast requires a constructor call

2023-07-07 Thread ldionne.2 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103511

--- Comment #5 from Louis Dionne  ---
Note that my claim about TriviallyCopyable is taken from the Standard here, for
reference (even though Jason probably knows this by heart :-).

https://eel.is/c++draft/class.prop#1:

> A trivially copyable class is a class:
> (1.1) that has at least one eligible copy constructor, move constructor, copy 
> assignment operator, or move assignment operator ([special], 
> [class.copy.ctor], [class.copy.assign]),
> (1.2) where each eligible copy constructor, move constructor, copy assignment 
> operator, and move assignment operator is trivial, and
> (1.3) that has a trivial, non-deleted destructor ([class.dtor]).

[Bug c++/103511] __builtin_bit_cast requires a constructor call

2023-07-07 Thread ldionne.2 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103511

Louis Dionne  changed:

   What|Removed |Added

 CC||ldionne.2 at gmail dot com

--- Comment #3 from Louis Dionne  ---
I concur with the reporter of this issue. `bit_cast` requires the types to be
TriviallyCopyable. In turn, TriviallyCopyable requires (for class types) that
there's at least one eligible copy constructor, move constructor, copy
assignment operator, or move assignment operator. It doesn't say which of those
has to be valid, but at least one of those has to be valid.

However, GCC's implementation of __builtin_bit_cast seems to always require at
least a copy or a move constructor, which seems like a bug to me.

For example, the following code should be valid IIUC, but it fails with GCC:

  struct CopyAssignable {
CopyAssignable() = default;
int value = 0;

CopyAssignable(const CopyAssignable&)= delete;
CopyAssignable(CopyAssignable&&) = delete;
CopyAssignable& operator=(const CopyAssignable&) = default;
CopyAssignable& operator=(CopyAssignable&&)  = delete;
  };

  struct MoveAssignable {
MoveAssignable() = default;
int value = 0;

MoveAssignable(const MoveAssignable&)= delete;
MoveAssignable(MoveAssignable&&) = delete;
MoveAssignable& operator=(const MoveAssignable&) = delete;
MoveAssignable& operator=(MoveAssignable&&)  = default;
  };

  int main(int, char**) {
CopyAssignable foo1;
(void)__builtin_bit_cast(CopyAssignable, foo1); // doesn't work
MoveAssignable foo2;
(void)__builtin_bit_cast(MoveAssignable, foo2); // doesn't work
  }

Full example on Godbolt showing that this is accepted by Clang and MSVC but
rejected by GCC: https://godbolt.org/z/548YKndrK
I am running into this issue while trying to fix something in libc++ here:
https://reviews.llvm.org/D154613

[Bug c++/110000] GCC should implement exclude_from_explicit_instantiation

2023-06-01 Thread ldionne.2 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=11

--- Comment #13 from Louis Dionne  ---
Nikolas already answered some, but just to expand on this:

> But on the topic of this enhancement request, I don't see why functions 
> should be excluded from explicit instantiation if they're already abi-tagged. 
> Do you want to be able to change these functions in ABI-incompatible ways 
> between major revisions of the library?

What we're trying to avoid here is that if a user has an explicit instantiation
*declaration*, we don't want their code to start depending on the fact that
some-implementation-detail-member-function exists in the class. So for example,
if we have:

  template 
  class vector {
  public:
iterator begin() { ... }
iterator end() { ... }

void __push_back_helper(T const&) { ... }
  };

If the user has something like this in their code:

  extern template class vector;

The compiler will then assume that the following methods are defined elsewhere
(presumably where the explicit instantiation actually happens):

iterator vector::begin();
iterator vector::end();
void vector::__push_back_helper(Foo const&);

Whether those methods are ABI-tagged or not doesn't matter, the compiler will
still emit code that contains external references to those methods. That's fine
if we're OK with committing to these methods in the long term, but if we want
to keep the flexibility of removing or changing these methods in arbitrary
ways, what we really want here is for the compiler not to assume that the
explicit instantiation includes these methods, and instead emit its own
linkonce_odr copy in the TU (which then gets deduplicated across TUs in case
the same function was defined elsewher too).

Does this make sense?

Regarding ABI tags, like Nikolas explained, the idea is that in most cases,
users actually have a single version of libc++ in their whole program, so all
the symbols from libc++ have the same ABI tag, and the linker will deduplicate
everything. In case a users happens to mix versions of libc++ in different TUs,
then the right thing will happen: functions with different ABI tags won't be
deduplicated as-if they were token-for-token equivalent and only the functions
that don't have an ABI tag will be deduplicated cause they're the same across
all TUs (but we do commit to stability for those symbols).

[Bug c++/110000] GCC should implement exclude_from_explicit_instantiation

2023-05-31 Thread ldionne.2 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=11

--- Comment #9 from Louis Dionne  ---
(In reply to Andrew Pinski from comment #3)
> I am getting a feeling this attribute is well defined enough.
> 
> Is it really just supposed to block explicit instantiation of templates?
> Is there a decent set of testcases that can be used to match up the
> implementations here? Because I suspect without those it will be implemented
> slightly different.

Is there anything specific you're thinking about that would be insufficiently
defined? It's possible that that's the case, and if so then we can define it
properly and make sure Clang/GCC are aligned on the semantics.

This is quite a painful issue for libc++ on GCC since the current solution is
to use `always_inline`, which has too many downsides. It used to be just an
annoyance, but with the addition of libraries like `std::format`, using
`always_inline` leads to a library that is literally unusable in some cases
(compile times and code size just skyrockets). So yeah, we're much willing to
collaborate in order to make this work.

[Bug c++/110000] GCC should implement exclude_from_explicit_instantiation

2023-05-26 Thread ldionne.2 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=11

Louis Dionne  changed:

   What|Removed |Added

 CC||ldionne.2 at gmail dot com

--- Comment #1 from Louis Dionne  ---
I implemented the attribute in Clang and it was pretty easy for me even as a
novice compiler person, so I expect it wouldn't be too hard to implement in GCC
either.

Removing always_inline does not only lead to better compile times, but also to
better code generation and obviously a better debugging experience. We
investigated various other alternatives that wouldn't require using the
attribute but we concluded that we really had to if we wanted to keep a tight
grip on our ABI surface while still allowing users to explicitly instantiate
stdlib classes (which they are allowed to as long as they provide at least one
user-defined type).

[Bug bootstrap/107795] recursion through breaks non-GNU implementations of the C++ stdlib

2022-11-21 Thread ldionne.2 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107795

--- Comment #13 from Louis Dionne  ---
Let me rephrase my whole request here.

I understand that what GCC does work for GCC and GCC-adjacent projects. This
report is about making the behavior of  more friendly to
implementations that are not GCC-adjacent and that need to build on top of the
GCC machinery. Those implementations expect that they can include_next GCC
headers and that no crazy magic is required to make that work, an expectation
that is not met at the moment.

Is GCC interested in doing that? If not, you can close this bug as "not to be
fixed".

Frankly, I do hope there's such a desire, since on our side we (Clang and
libc++) do try to be "friendly" to GCC/libstdc++. For example, Clang is careful
to implement attributes and match GCC behavior, and libc++ similarly tries to
match libstdc++ behavior and ensures that it works on GCC. This results in a
better ecosystem for everyone, but it can't be a one-way street.

If you don't want to even consider fixing this "because it's not a problem
within the GCC stack", there's nothing I can do about it, but I think that
would be a poor decision. If there's a technical reason why this can't or
shouldn't be done, I'm all ears.

[Bug bootstrap/107795] recursion through breaks non-GNU implementations of the C++ stdlib

2022-11-21 Thread ldionne.2 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107795

--- Comment #11 from Louis Dionne  ---
(In reply to Andrew Pinski from comment #9)
> 
> GCC version specific includes > GCC version specific fixincludes > C library
> includes
> 
> That is for C.
> C++ is:
> libstdc++ library includes > ... (rest same as C).

Okay, that's great. That's exactly what I want! I want to be able to do:

libc++ library includes > ... (rest same as C)

What I'm trying to say is precisely that this doesn't work as intended today,
because somewhere inside "rest same as C", a header is taking for granted that
libstdc++ does NOT implement a  header. If it did, then libstdc++
would get the same issue that we are having.

Is there a reason why GCC needs to indirect through  and
recursively include , telling it to recurse using _GCC_NEXT_LIMITS_H?

[Bug bootstrap/107795] recursion through breaks non-GNU implementations of the C++ stdlib

2022-11-21 Thread ldionne.2 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107795

--- Comment #8 from Louis Dionne  ---
(In reply to Andrew Pinski from comment #5)
> (In reply to Louis Dionne from comment #4)
> > (In reply to Andrew Pinski from comment #2)
> > > You should not be building on top of GCC's limits.h header at all really.
> > > Rather implementations should have their own.
> > 
> > What do you mean by "implementations"? Do you mean implementations of the C
> > library or compiler implementations, or what?
> 
> GCC limits.h is the implementation detail of GCC.
> Yes I know it gets fuzzy. This is why GCC even has fixincludes to make sure
> target headers are always correct. See the comment I posted.

When compiling pure C with GCC, what's the order of includes? Is it "C Library
includes > GCC builtin includes", or "GCC builtin includes > C Library
includes"?

> If clang/libc++ wants built on top of GCC's implementation of GCC's C
> implementation, then it will need to similar tricks as GCC does for other
> targets. GCC does fixincludes trick to support other targets besides Linux
> even.

That's exactly my point -- this bug report is about removing the need to do
tricks just to build on top of GCC's . None of the other headers
require it AFAICT, so why does this header require it? Is there a reason not to
make GCC's  friendly to #include_next?

[Bug bootstrap/107795] recursion through breaks non-GNU implementations of the C++ stdlib

2022-11-21 Thread ldionne.2 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107795

--- Comment #4 from Louis Dionne  ---
(In reply to Andrew Pinski from comment #2)
> You should not be building on top of GCC's limits.h header at all really.
> Rather implementations should have their own.

What do you mean by "implementations"? Do you mean implementations of the C
library or compiler implementations, or what?


(In reply to Jonathan Wakely from comment #3)
> (In reply to Andrew Pinski from comment #2)
> > Rather implementations should have their own.
> 
> Or just use GCC's one without change, which is what libstdc++ does. We don't
> provide any  in libstdc++, only . When you #include
>  with G++ you just get GCC's own  as-is.

Yeah but we may need to add stuff to  on some platforms, so we may
need to have such a header. Also, I assume you only do that for a subset of
headers, because you must have  headers in libstdc++ for a few headers
that require adding const-correct overloads of e.g. `memchr`?

[Bug libstdc++/107795] New: recursion through breaks non-GNU implementations of the C++ stdlib

2022-11-21 Thread ldionne.2 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107795

Bug ID: 107795
   Summary:  recursion through  breaks
non-GNU implementations of the C++ stdlib
   Product: gcc
   Version: 12.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The  header currently includes "syslimits.h", which then recursively
includes  after defining the _GCC_NEXT_LIMITS_H macro. The 
header seems to be generated from a bunch of stuff, including `gcc/limitx.h`,
which seems to be responsible for that recursive inclusion. Incidentally, this
seems to not have been modified in the last 30 years.

This recursive inclusion with a macro is hostile to implementations that want
to build on top of GCC's  header, since they need to know about that
recursive inclusion trick and the _GCC_NEXT_LIMITS_H macro. For example, libc++
currently needs to know about this wrinkle and implement its own 
header differently depending on whether it's built with GCC or another
compiler.

System headers should work such that they can be layered on top of each other
without needing this sort of trick. To reproduce the issue we're seeing with a
minimal example:

#!/usr/bin/env bash

rm -rf __fake_cxx_include && mkdir -p __fake_cxx_include
cat < __fake_cxx_include/limits.h
#ifndef __MY_LIMITS_H
#define __MY_LIMITS_H
#   include_next 
#endif
EOF

cat <
#include 
EOF

When running this script, the output is (on our Docker image):

. /llvm/__fake_cxx_include/limits.h
.. /usr/lib/gcc/x86_64-linux-gnu/12/include/limits.h
... /usr/lib/gcc/x86_64-linux-gnu/12/include/syslimits.h
 /llvm/__fake_cxx_include/limits.h
. /usr/include/wchar.h
[...]
.. /usr/include/x86_64-linux-gnu/bits/wchar.h
[...]
.. /usr/include/x86_64-linux-gnu/bits/wchar2.h
In file included from /usr/include/wchar.h:867,
from :2:
/usr/include/x86_64-linux-gnu/bits/wchar2.h:398:3: error: #error "Assumed
value of MB_LEN_MAX wrong"
398 | # error "Assumed value of MB_LEN_MAX wrong"
|   ^

Because this  header does not know about the GCC-internal macro
_GCC_NEXT_LIMITS_H, we fail to recursively re-include  and then
including  fails in a rather obscure way. Also note that this only
fails if we're using -O2 to compile, since -O2 seems to turn on some __fortify
stuff which leads to including .

Long story short, it would be great if GCC's  header could be
simplified to avoid recursively including itself through .

[Bug libstdc++/48101] obscure error message with std::set

2022-03-10 Thread ldionne.2 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48101

Louis Dionne  changed:

   What|Removed |Added

 CC||ldionne.2 at gmail dot com

--- Comment #12 from Louis Dionne  ---
FWIW, we now consider it a bug in libc++ that we accept std::allocator, and we're trying to remove that "extension".

[Bug c++/104760] Attribute [[deprecated]] causes diagnostic in never-instantiated template

2022-03-02 Thread ldionne.2 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104760

--- Comment #3 from Louis Dionne  ---
(In reply to Marek Polacek from comment #2)
> And I think this is the same problem as in
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=33911#c18.  Not sure if we want
> to change anything.

Yup, I agree this is the same problem. However, see my recent comment on that
bug report -- I think we should still fix this, and the resolution of PR33911
was IMO incomplete.

[Bug c++/33911] attribute deprecated vs. templates

2022-03-02 Thread ldionne.2 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=33911

Louis Dionne  changed:

   What|Removed |Added

 CC||ldionne.2 at gmail dot com

--- Comment #21 from Louis Dionne  ---
(In reply to Martin Sebor from comment #20)
> (In reply to Jonathan Wakely from comment #16)
> 
> Although Clang doesn't, warning for uses of a deprecated primary seems
> correct/useful to me because there's no way to define a specialization of
> the primary that's not deprecated.  In your test case, there is no
> specialization of  b() that would not use some specialization of the primary
> class template, and since every specialization is a use of the primary, that
> would not be subject to its deprecated attribute.  (It seems analogous to
> warning for an unused constexpr function that can never be used in a core
> constant expression.)

I believe it is important to *not* diagnose when the template is never
instantiated. Indeed, imagine a library is providing these declarations. It
needs to keep them around for backwards compatibility, but it also wants to
mark them as deprecated to make sure that no users actually use them.

With the current state of affairs, GCC will issue a warning just because the
declarations exist and are marked as deprecated, even if the user doesn't
actually use these declarations. This is not useful behavior -- it ends up
being so noisy that the only reasonable solution is to remove deprecation
warnings altogether, which defeats the whole thing. This is exactly what we're
hitting with libc++ on GCC right now. I think it would be worth reconsidering
the resolution of this issue to make GCC's behavior match Clang's behavior more
closely.

> If you feel it's important to only warn for code that's instantiated, rather
> than reopening this bug I suggest opening a separate bug just for that.

See https://gcc.gnu.org/PR104760.

[Bug c++/104760] New: Attribute [[deprecated]] causes diagnostic in never-instantiated template

2022-03-02 Thread ldionne.2 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104760

Bug ID: 104760
   Summary: Attribute [[deprecated]] causes diagnostic in
never-instantiated template
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

When using the [[deprecated]] attribute on a class template, a diagnostic is
produced even if that class template is never actually instantiated. For
example, if that class template is only mentioned from another function
template (which is never actually instantiated), we get a diagnostic:

template 
struct [[deprecated]] unary_negate {
explicit unary_negate(const Pred&);
};

template 
[[deprecated]]
unary_negate not1(const Pred& p) { return unary_negate(p); }

We get:

:8:1: warning: 'template struct unary_negate' is
deprecated [-Wdeprecated-declarations]
8 | unary_negate not1(const Pred& p) { return
unary_negate(p); }
| ^~~~
:2:23: note: declared here
2 | struct [[deprecated]] unary_negate {
|   ^~~~
: In function 'unary_negate not1(const Pred&)':
:8:49: warning: 'template struct unary_negate' is
deprecated [-Wdeprecated-declarations]
8 | unary_negate not1(const Pred& p) { return
unary_negate(p); }
| ^~~~
:2:23: note: declared here
2 | struct [[deprecated]] unary_negate {
|   ^~~~

We are encountering this issue in libc++, where we do mark several things as
[[deprecated]] (per the Standard), and those warnings fire off when the headers
are used not as system headers. Any other non-system header library would have
the same problem.

Note that in comparison, Clang does not issue a warning in this case. It only
issues a warning if we actually instantiate `not1` or `unary_negate`.

Godbolt: https://godbolt.org/z/559EfKn9K

[Bug c++/70816] bogus error __builtin_strcmp is not a constant expression in a constexpr function

2021-12-15 Thread ldionne.2 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70816

Louis Dionne  changed:

   What|Removed |Added

 CC||ldionne.2 at gmail dot com

--- Comment #3 from Louis Dionne  ---
We are having to add a workaround in libc++ to implement constexpr std::string:
https://reviews.llvm.org/D115795

It would be awesome if this could be fixed! (if so, please drop us a line and
we'll remove our workaround)

[Bug c++/102247] New: Overload resolution with brace-init is ambiguous when it shouldn't be

2021-09-08 Thread ldionne.2 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102247

Bug ID: 102247
   Summary: Overload resolution with brace-init is ambiguous when
it shouldn't be
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code fails to compile when I believe it should succeed
(https://godbolt.org/z/z9aved8Wb):

#include 

template 
struct pair {
template
constexpr pair(U1&&, U2&&) { }
};

struct BraceInit { BraceInit() = default; };
struct ExplicitBraceInit { explicit ExplicitBraceInit() = default; };

constexpr int f(pair) { return 1; }
constexpr int f(pair) { return 2; }

static_assert(f({{}, {}}) == 2, "");

Indeed, the error is

:15:16: error: call of overloaded 'f()' is ambiguous
15 | static_assert(f({{}, {}}) == 2, "");
|   ~^~
:12:15: note: candidate: 'constexpr int f(pair)'
12 | constexpr int f(pair) { return
1; }
|   ^
:13:15: note: candidate: 'constexpr int f(pair)'
13 | constexpr int f(pair) { return 2; }
|   ^
Compiler returned: 1

I think it should succeed because `f(pair)` can never be selected, since selecting it would require
using the explicit constructor of `ExplicitBraceInit`. And indeed, if we try to
call `f(pair)` alone, we get
(https://godbolt.org/z/W33Pvnnoe):

:15:16: error: converting to 'ExplicitBraceInit' from initializer
list would use explicit constructor 'constexpr
ExplicitBraceInit::ExplicitBraceInit()'
15 | static_assert(f({{}, {}}) == 2, "");
|   ~^~
Compiler returned: 1

So I'm not sure why that overload is considered valid for overload resolution
(leading to the ambiguity), but it seems like GCC itself doesn't think it's
valid when there are no other candidates. Also note that Clang compiles this
code without issue, calling the non-explicit BraceInit version as expected.

This issue was uncovered while implementing http://wg21.link/P1951 in libc++.

[Bug c++/97675] GCC does not allow turning off the warning for exceptions being caught by an earlier handler

2020-11-06 Thread ldionne.2 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97675

--- Comment #3 from Louis Dionne  ---
Thanks a lot!

[Bug c++/97675] New: GCC does not allow turning off the warning for exceptions being caught by an earlier handler

2020-11-02 Thread ldionne.2 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97675

Bug ID: 97675
   Summary: GCC does not allow turning off the warning for
exceptions being caught by an earlier handler
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

In the LLVM libc++abi test suite, we test that an exception of type 'Child' is
being caught by an earlier handler of type 'Base'. As a result, GCC (and Clang)
produce a warning saying that the later catch clause (of type 'Child') will
never 
be used. This is fine.

However, Clang allows turning off that specific warning using -Wno-exceptions
(or the appropriate warning pragma). GCC doesn't provide that option, which is
problematic because we compile our test suite with -Werror. The options that
are left are:

- To disable these tests with GCC altogether
- To disable -Werror on these tests

Instead, it would be nice if GCC allowed controlling that warning (and perhaps 
other related warnings I'm not aware of) using a compiler flag.

Reproducer:
cat <: In function 'int main()':
:6:5: warning: exception of type 'Child' will be caught
:5:5: warning:by earlier handler for 'Base'


Expectation:
Some warning flag (e.g. -Wno-exceptions) allows turning off that warning.

[Bug c++/94745] No error emitted for unknown -Wno-meow argument

2020-05-04 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94745

--- Comment #4 from Louis Dionne  ---
Thanks for your replies, all. We resolved the problem on our side by not trying
to workaround the lack of error, which means that we might end up passing
`-Wno-foo` to GCC when it's not supported. I think that follows the design
intent explained by Jonathan.

Thanks again!

[Bug c++/94745] New: No error emitted for unknown -Wno-meow argument

2020-04-24 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94745

Bug ID: 94745
   Summary: No error emitted for unknown -Wno-meow argument
   Product: gcc
   Version: 10.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

GCC does not diagnose unsupported -Wno-meow command line flags unless another
error happens during compilation.

For example, the following compiles just fine even though -Wno-foo doesn't
exist:

$ echo | g++ -xc++ - -Werror -fsyntax-only -Wno-foo



If, however, another error happens during compilation, the unsupported
command-line flag is reported:

$ echo '#error' | g++ -xc++ - -Werror -fsyntax-only -Wno-foo

:1:2: error: #error
cc1plus: error: unrecognized command line option '-Wno-foo' [-Werror]
cc1plus: all warnings being treated as errors


This makes detecting whether GCC supports a given warning flag very challenging
in build systems. This issue popped up while trying to support GCC when running
the libc++ Standard Library conformance test suite.

[Bug driver/94198] New: Placement of source file in GCC command line has impact on whether the link succeeds

2020-03-16 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94198

Bug ID: 94198
   Summary: Placement of source file in GCC command line has
impact on whether the link succeeds
   Product: gcc
   Version: 9.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: driver
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

It seems that the position where the source file is specified to GCC has an
impact on how it is linked when other `-l` options are passed.

For example, the following command (with the source file specified last) fails
to link:

$ /usr/bin/g++-9 -L/llvm/build-linux/lib -Wl,-rpath,/llvm/build-linux/lib
-nodefaultlibs -lc++ -lm -lgcc_s -lgcc -lpthread -lc -lgcc_s -lgcc go.cpp
/tmp/ccusVxoZ.o: In function `main':
go.cpp:(.text+0xa): undefined reference to `__cxa_allocate_exception'
go.cpp:(.text+0x1a): undefined reference to `typeinfo for int'
go.cpp:(.text+0x22): undefined reference to `__cxa_throw'
go.cpp:(.text+0x2a): undefined reference to `__cxa_begin_catch'
go.cpp:(.text+0x2f): undefined reference to `__cxa_end_catch'
/tmp/ccusVxoZ.o:(.eh_frame+0x13): undefined reference to
`__gxx_personality_v0'
collect2: error: ld returned 1 exit status

However, the same command-line with the source file specified first links
successfully:

$ /usr/bin/g++-9 go.cpp -L/llvm/build-linux/lib
-Wl,-rpath,/llvm/build-linux/lib -nodefaultlibs -lc++ -lm -lgcc_s -lgcc
-lpthread -lc -lgcc_s -lgcc


I've tracked it down to a difference in how `collect2` is called after the
assembler. When the source file appears first (which works), `collect2` is
called as:

$ collect2 [...] /tmp/X.o -rpath /llvm/build-linux/lib -lc++ -lm
-lgcc_s -lgcc -lpthread -lc -lgcc_s -lgcc [...]

However, when the source file appears last (which fails), `collect2` is called
as follows:

$ collect2 [...] -rpath /llvm/build-linux/lib -lc++ -lm -lgcc_s -lgcc
-lpthread -lc -lgcc_s -lgcc /tmp/X.o [...]

You can notice how in the former, the temporary object file `/tmp/X.o`
appears _before_ the various libraries to link, and in the latter it appears
after. Because of how most linkers operate, the latter can't possibly link.

Since the way GCC calls the linker with a temporary object file is an
implementation detail, I believe the correct behavior here should be that in
both cases, GCC passes the object file before the various libraries to link.

This issue was discovered while running the libc++ conformance test suite with
GCC.

[Bug c++/88453] New: GCC pretends that constexpr default-constructible type is nothrow constructible

2018-12-11 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88453

Bug ID: 88453
   Summary: GCC pretends that constexpr default-constructible type
is nothrow constructible
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code does not compile with GCC trunk:


#include 

struct Throwing {
  constexpr Throwing() {}
};

static_assert(!std::is_nothrow_default_constructible::value, "");


It seems like GCC assumes that the default constructor is noexcept since it is
constexpr. Clang does not have this behaviour, and I believe Clang to be
correct in this case.

Live example: https://wandbox.org/permlink/1z1qYQSUDWsYJda1

[Bug c++/67164] ICE: tree check: expected class ‘expression’, have ‘exceptional’ (argument_pack_select) in tree_operand_check, at tree.h:3356

2018-11-19 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67164

--- Comment #14 from Louis Dionne  ---
I think so -- all the reproducers posted in this bug report can compile with
GCC trunk.

[Bug c++/85659] New: ICE with inline assembly inside virtual function

2018-05-04 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85659

Bug ID: 85659
   Summary: ICE with inline assembly inside virtual function
   Product: gcc
   Version: 6.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following program causes an ICE with GCC 6.1.0 and up. GCC 5.5.0 compiles
this fine.

==
#include 

template 
void DoNotOptimize(Tp& value) {
  asm volatile("" : "+m,r"(value) : : "memory");
}

struct base {
  virtual void f1() = 0;
};

template 
struct derived : base {
  void f1() override { ::DoNotOptimize(value_); }
  T value_;
};

template struct derived;

int main() { }
==

The exact error given by GCC trunk is:

==
during RTL pass: expand
prog.cc: In function 'void DoNotOptimize(Tp&) [with Tp =
std::__cxx11::basic_string]':
prog.cc:5:48: internal compiler error: in assign_temp, at function.c:977
   asm volatile("" : "+m,r"(value) : : "memory");
^
0x59887a assign_temp(tree_node*, int, int)
  ../../source/gcc/function.c:977
0x7a5bde expand_asm_stmt
  ../../source/gcc/cfgexpand.c:3083
0x7aa007 expand_gimple_stmt_1
  ../../source/gcc/cfgexpand.c:3621
0x7aa007 expand_gimple_stmt
  ../../source/gcc/cfgexpand.c:3790
0x7ab7af expand_gimple_basic_block
  ../../source/gcc/cfgexpand.c:5819
0x7b0866 execute
  ../../source/gcc/cfgexpand.c:6425
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
==

This is especially problematic as this code was reduced from a benchmark
written using the widely used GoogleBenchmark library. This is where
DoNotOptimize comes from -- I don't write inline assembly myself.

Live examples:
GCC 5.5.0 (works): https://wandbox.org/permlink/bVzSwbSlkoDy5vBt
GCC 6.1.0 (fails): https://wandbox.org/permlink/hgUJL0aEH8MDQgI1
GCC 6.3.0 (fails): https://wandbox.org/permlink/5qhSFDvLzsrmsVrT
GCC 7.3.0 (fails): https://wandbox.org/permlink/uNdVyOlaPUWhxPec
GCC 8.1.0 (fails): https://wandbox.org/permlink/qburemRl1AcqmaVl
GCC trunk (fails): https://wandbox.org/permlink/WcDrgDL9g4YLKsGN

[Bug libstdc++/82156] New: [7/8 regression] Atomic is_lock_free is not true for 16 byte type

2017-09-08 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82156

Bug ID: 82156
   Summary: [7/8 regression] Atomic is_lock_free is not true for
16 byte type
   Product: gcc
   Version: 7.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code prints true on GCC 4.x, 5.x and 6.x, but not on GCC 7.x and
trunk:

#include 
#include 
#include 


using T = std::aligned_storage_t<16>; // just a 16 bytes type
std::atomic atomic;

int main() {
  std::cout << std::boolalpha << atomic.is_lock_free() << std::endl;
  std::cout << std::boolalpha << std::atomic::is_always_lock_free <<
std::endl;
}

I'd like to know whether this is a regression, or me misunderstanding the
meaning of `is_lock_free()`.

Live examples:
GCC 4.9 (true): https://wandbox.org/permlink/gg0HoiAofJXXxHzh
GCC 5 (true):   https://wandbox.org/permlink/vofEUemsQSpIROOR
GCC 6 (true):   https://wandbox.org/permlink/jH8spWex3KDKVT0a
GCC 7 (false):  https://wandbox.org/permlink/M1SG1B6StNtBjlxH
GCC 8 (false):  https://wandbox.org/permlink/4vmBcSph2Pvy4tye

Thanks!

[Bug c++/82047] non-existent variable template used to initialize variable

2017-08-31 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82047

--- Comment #7 from Louis Dionne  ---
Then, I think there's another bug in GCC (or maybe just a QOI issue), since the
following code compiles (wandbox[1]):

  template  constexpr T v;
  template  constexpr T v(888);

  struct S {
constexpr S() : value(999) { }
constexpr S(int x) : value(x) { }
int value;
  };

  static_assert(v.value == 888);


Instead, I would expect to get some error saying that I'm redefining `v` on the
second line. FWIW, Clang does think it's only a declaration [2].


[1]: https://wandbox.org/permlink/c5An5PbMbJdxa9Hj
[2]: https://wandbox.org/permlink/m9VSksjjtFhiQSab

[Bug c++/82047] non-existent variable template used to initialize variable

2017-08-31 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82047

Louis Dionne  changed:

   What|Removed |Added

 CC||ldionne.2 at gmail dot com

--- Comment #5 from Louis Dionne  ---
I don't understand why the standard mandates that

  template  constexpr T v;

though it is only a declaration, would actually default-initialize the object
if you try to use it (am I understanding this properly?). I understand that
this is consistent with

  constexpr T x;

which default-initializes `x`, but that is a definition, not a declaration. In
this case, maybe it doesn't make sense to pretend that

  template  constexpr T v;

is only a declaration?

[Bug c++/82000] Missed optimization of char_traits::length() on constant string

2017-08-28 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82000

--- Comment #2 from Louis Dionne  ---
> The example you wrote in the bug report makes no sense: missing includes, and 
> with the includes added it optimizes to return 0.

Sorry, I did not mean the example I pasted here to be a complete reproduction;
I just wanted explain the gist of what the godbolt link does.

> Downloading the one from godbolt, we simplify it to: [...]

I have no idea what this is and how you feed that to GCC, but I'm curious.

> (btw, why do you use "g" for clang and not for gcc?)

I copy pasted from
https://github.com/google/benchmark/blob/a271c36/include/benchmark/benchmark.h#L302.

[Bug c++/82000] New: Missed optimization of char_traits::length() on constant string

2017-08-27 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82000

Bug ID: 82000
   Summary: Missed optimization of char_traits::length() on
constant string
   Product: gcc
   Version: 8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

In the following code, the calculation of the string length is not folded,
despite the input string being visible to the compiler:

  template 
  struct string_constant {
static constexpr char internal_buffer[sizeof...(c)+1] = {c..., '\0'};
constexpr char const* c_str() const { return internal_buffer; }
constexpr std::size_t size() const { return sizeof...(c); }
  };

  auto const text = string_constant<'s', 'o', 'm', 'e', 'c', 'o', 'm', 'p',
'i', 'l', 'e', 't', 'i', 'm', 'e', 't', 'e', 'x', 't'>{};

  int main() {
std::string_view sv1{text.c_str()}; // calculation of length not folded

std::string_view sv2{text.c_str(), text.size()}; // no work required
  }

I tracked it down to `char_traits::length()` not being folded. Note that
Clang folds that without problem. Here's a link on Godbolt so you can reproduce
the issue easily and look at the assembly: https://godbolt.org/g/sF3enh

[Bug c++/81933] New: [7 Regression] Invalid "constexpr call flows off the end of the function" error

2017-08-22 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81933

Bug ID: 81933
   Summary: [7 Regression] Invalid "constexpr call flows off the
end of the function" error
   Product: gcc
   Version: 7.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code does not compile with GCC 7, std=c++14:


#include 

struct any_udt { };

template 
constexpr auto flatten(Tuples ...tuples) {
  auto all = std::make_tuple(tuples...);
  auto flat = std::make_tuple(
std::get<0>(std::get<1>(all)),
std::get<0>(std::get<2>(all))
  );
  return flat;
}

constexpr auto fail = ::flatten(std::make_tuple(),
std::make_tuple(any_udt{}),
std::make_tuple(any_udt{}));

int main() { }


It triggers the following error:

foo.cpp:17:59:   in constexpr expansion of 'flatten(Tuples ...) 
  [with Tuples = {std::tuple<>, std::tuple, std::tuple}]
(std::make_tuple(_Elements&& ...) [with _Elements = {any_udt}](), 
 std::make_tuple(_Elements&& ...) [with _Elements = {any_udt}]())'

foo.cpp:17:59: error: constexpr call flows off the end of the function
 std::make_tuple(any_udt{}));
   ^


Note that the code compiles just fine with GCC 6 and all Clang versions I've
tried, so this looks like a 7 regression.

Working example (GCC 6.3.0, -std=c++14):
https://wandbox.org/permlink/5AjQ50OSxNjJPP8r
Working example (GCC 6.3.0, -std=c++1z):
https://wandbox.org/permlink/dKegxu0QeVXtzObB

Failing example (GCC 7.2.0, -std=c++14):
https://wandbox.org/permlink/hfbI0Ndg5UyCIF9W
Working example (GCC 7.2.0, -std=c++1z):
https://wandbox.org/permlink/Hz1gm6EipU5Ej5jy

Failing example (GCC 8.0.0, -std=c++14):
https://wandbox.org/permlink/jSHOPt8zXosccp8a
Working example (GCC 8.0.0, -std=c++1z):
https://wandbox.org/permlink/Nj7tNIYWu8Ueury7

[Bug c++/81525] New: [7 Regression] Invalid codegen with constexpr variable template

2017-07-23 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81525

Bug ID: 81525
   Summary: [7 Regression] Invalid codegen with constexpr variable
template
   Product: gcc
   Version: 7.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code prints

i = 0
N = 0

when it should print

i = 0
N = 1

This seems to be a regression since GCC 7, although I am not sure exactly
which minor version introduced it. The problem only triggers when 'N' is
constexpr, when it is assigned from a variable template, and when we go
through enough templates (randomly making functions not templates seems
to fix the issue). The code is (sorry, I reduced a lot but could not
reduce further):

#include 

template 
struct integral_constant {
  constexpr operator int() const { return i; }
};

template 
constexpr integral_constant int_{};

template 
void with_index(F f) {
  f(integral_constant<0>{});
}

template 
void print(Dummy) {
  constexpr auto N = ::int_<1>;
  (void)N; // otherwise we get [warning: variable 'N' set but not used]
   // this may be a hint that something is wrong

  auto f = [&](auto i) {
std::cout << "i = " << static_cast(i) << std::endl;
std::cout << "N = " << static_cast(N) << std::endl;
  };

  with_index(f);
}

int main() {
  ::print(0);
}


Live example with GCC 6.3.0: https://wandbox.org/permlink/lclToxN6mnRAS3ol
Live example with GCC 7.1.0: https://wandbox.org/permlink/AUqaHBYlsfwHLUrU
Live example with GCC trunk: https://wandbox.org/permlink/8wxi8MqrS03MbujE

This bug report was lifted from a failure in Boost.Hana's test suite [1],
with the relevant original code being [2]. This is quite worrisome as this
breaks mundane constexpr-utilizing code in a nasty way.

[1]: https://travis-ci.org/boostorg/hana/jobs/256518824#L7663
[2]:
https://github.com/boostorg/hana/blob/e50749/example/tutorial/tag_dispatching.cpp#L72-L85

[Bug c++/81299] New: Spurious "set but not used" warning with constexpr variable

2017-07-03 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81299

Bug ID: 81299
   Summary: Spurious "set but not used" warning with constexpr
variable
   Product: gcc
   Version: 8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code triggers a spurious warning on GCC trunk (8.0 ish):

  struct function_t {
  template 
  void operator()(Xs&& ...) const { }
  };
  constexpr function_t function{};

  int main() {
  constexpr auto fun = ::function;
  auto call = [=](auto ...x) { fun(x...); };
  call();
  }

The output is:

  prog.cc: In function 'int main()':
  prog.cc:8:20: warning: variable 'fun' set but not used
[-Wunused-but-set-variable]
   constexpr auto fun = ::function;
  ^~~

Live example: https://godbolt.org/g/jNhNJV

This is an incredibly annoying bug that was also present in GCC 7 and causes
trivial constexpr code to fail to compile (when -Werror is used) :-(.

Sorry for using Godbolt (which does not clearly show the warning message)
instead of Wandbox, but Wandbox's shareable links feature are not working right
now.

[Bug c++/79189] New: Poor code generation when using stateless lambda instead of normal function

2017-01-22 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79189

Bug ID: 79189
   Summary: Poor code generation when using stateless lambda
instead of normal function
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

When doing an indirect call (through a function pointer), GCC generates
different code depending on whether the function pointer was obtained by
converting a stateless lambda or a normal function. The code generated for a
normal function is vastly superior, and in fact the call can sometimes be
elided.

Code:

  #if 1
template 
static auto const increment = [](void* self) { ++*static_cast<T*>(self); };
  #else
template 
void increment(void* self) { ++*static_cast<T*>(self); }
  #endif

  struct VTable { void (*increment)(void*); };
  template  static VTable const vtable{increment};

  struct any_iterator {
template 
explicit any_iterator(Iterator it)
  : vptr_{}, self_{new Iterator(it)}
{ }
VTable const* vptr_;
void* self_;
  };

  int main() {
int input[100] = {0};
any_iterator first{[0]};
first.vptr_->increment(first.self_);
  }


Codegen with the lambda:

  increment<int*>::{lambda(void*)#1}::_FUN(void*):
  add QWORD PTR [rdi], 4
  ret
  main:
  sub rsp, 408
  xor eax, eax
  mov ecx, 50
  mov rdi, rsp
  rep stosq
  mov edi, 8
  calloperator new(unsigned long)
  mov QWORD PTR [rax], rsp
  mov rdi, rax
  call[QWORD PTR vtable<int*>[rip]]
  xor eax, eax
  add rsp, 408
  ret
  _GLOBAL__sub_I_main:
  mov QWORD PTR vtable<int*>[rip], OFFSET
FLAT:increment<int*>::{lambda(void*)#1}::_FUN(void*)
  ret


Codegen with the function:

  main:
  sub rsp, 8
  mov edi, 8
  calloperator new(unsigned long)
  xor eax, eax
  add rsp, 8
  ret


Note that Clang (trunk) makes a much better job at optimizing this. Also see
[1] for this example on compiler explorer. See [2] for a larger example that
exhibits the same behavior, and where this results in a ~10x speed difference
because the call is done in a loop.

[1]: https://godbolt.org/g/HQb5Y5
[2]: http://melpon.org/wandbox/permlink/Gs3njR3STPLk2Ecr

[Bug c++/59498] [DR 1430][4.9/5/6/7 Regression] Pack expansion error in template alias

2016-07-04 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59498

--- Comment #12 from Louis Dionne  ---
Not sure, as I've been off pure-type computations for a while now. Looking at
how Meta does it might be useful:
https://github.com/ericniebler/meta/blob/master/include/meta/meta.hpp#L819

[Bug c++/67364] [5/6 Regression] "accessing uninitialized member" error in constexpr context

2016-03-05 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67364

--- Comment #13 from Louis Dionne  ---
Actually, the problem is much worse than I thought. It turns out that with -O1,
the following code does not pass the assertion:

#include 

template 
struct tuple {
Xn storage_;

constexpr tuple(Xn const& xn)
: storage_(xn)
{ }

template 
constexpr tuple(tuple const& other)
: storage_(other.storage_)
{ }

template 
constexpr tuple(tuple& other)
: tuple(const_cast(other))
{ }
};

template 
struct wrapper { T value; };

template 
constexpr wrapper wrap(T t) { return {t}; }

int main() {
wrapper t = wrap(tuple{2});
assert(t.value.storage_ == 2);
}


Live example: http://melpon.org/wandbox/permlink/nRGrPcbvqYWhzCDt

This is the same code as above, except the `t` variable is not constexpr
anymore.
This seems like a case of invalid codegen. If I make the `wrap` function
non-constexpr,
the problem goes away. Should I create a separate bug report for this?

[Bug c++/70097] New: Cannot assign ref-qualified non-static member function

2016-03-05 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70097

Bug ID: 70097
   Summary: Cannot assign ref-qualified non-static member function
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code fails to compile on GCC trunk:

struct F { void member() & { } };
using Member = void()&;
Member F::* fptr = ::member;

The error is:

[...]: error: cannot convert ‘void (F::*)() &’ to ‘void (F::*)()’ in
initialization
 Member F::* fptr = ::member;
^~

Live example: http://melpon.org/wandbox/permlink/kizV7mkIaHTnMTkd

[Bug c++/70096] New: [Invalid codegen] Read of uninitialized value in ref-qualified pointer to member function

2016-03-05 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70096

Bug ID: 70096
   Summary: [Invalid codegen] Read of uninitialized value in
ref-qualified pointer to member function
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: major
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code has a codegen issue that causes the read of an uninitialized 
value, which can lead to a segfault in some circumstances:

struct Holder {
void operator()() & { int read = data; }
int data;
};

template 
void test() {
Holder h{42};
F Holder::* fptr = ::operator();
(h.*fptr)();
}

int main() {
test();
}

> g++ -std=c++11 test/worksheet.cpp
> valgrind --leak-check=full --track-origins=yes ./a.out

==44102== Memcheck, a memory error detector
[...]
==44102== Use of uninitialised value of size 8
==44102==at 0x10EE6: Holder::operator()() & (in ./a.out)
==44102==by 0x10F26: void test() (in ./a.out)
==44102==by 0x10ED2: main (in ./a.out)
==44102==  Uninitialised value was created by a stack allocation
==44102==at 0x10F2A: void test() (in ./a.out)

I'm not sure, but I think it has something to do with the fact that we're 
using `F = void() &` (note the ref-qualifier) and the reading of the `this`
pointer. I'm not sure at all, but just pointing out a possible direction.

Live example: http://melpon.org/wandbox/permlink/kzRh8PNguwrP11lB

[Bug c++/67364] [5/6 Regression] "accessing uninitialized member" error in constexpr context

2016-03-05 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67364

--- Comment #12 from Louis Dionne  ---
The following code still fails to compile on GCC trunk:

template 
struct tuple {
Xn storage_;

constexpr tuple(Xn const& xn)
: storage_(xn)
{ }

template 
constexpr tuple(tuple const& other)
: storage_(other.storage_)
{ }

template 
constexpr tuple(tuple& other)
: tuple(const_cast(other))
{ }
};

template 
struct wrapper { T value; };

template 
constexpr wrapper wrap(T t) { return {t}; }

constexpr wrapper t = wrap(tuple{2});
static_assert(t.value.storage_ == 2, "");


The error is

prog.cc:27:5: error: non-constant condition for static assertion
 static_assert(t.value.storage_ == 2, "");
 ^
prog.cc:27:5: error: accessing uninitialized member 'tuple::storage_'


Note that if the `static_assert` is changed to a runtime assertion, and if `t`
is not made `constexpr`, this code will trigger a runtime error. I'm pretty
sure
the above is triggered by the current bug.

[Bug c++/70095] New: [C++14] Link error on partially specialized variable template

2016-03-05 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70095

Bug ID: 70095
   Summary: [C++14] Link error on partially specialized variable
template
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code fails to link on GCC trunk:

template  struct Foo;
template  int variable_template = 0;
template  int variable_template<Foo> = 0;
template  int get_variable_template() { return
variable_template; }

int main() {
get_variable_template<Foo>();
}


> ~/code/gcc/prefix/bin/g++ -std=c++14 test/worksheet.cpp

Undefined symbols for architecture x86_64:
  "_variable_template", referenced from:
  int get_variable_template<Foo >() in ccPzxGMc.o
 (maybe you meant: int get_variable_template<Foo >())
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status


Live example: http://melpon.org/wandbox/permlink/eFOhrTWIfIeelZnu


Curiously, explicitly specializing `variable_template<Foo>` fixes the
issue.

[Bug c++/69995] [5/6 Regression] [C++14] Invalid result when evaluating constexpr function

2016-02-28 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69995

--- Comment #2 from Louis Dionne  ---
I know but using a runtime assert allows showing that with/without constexpr
have different results. Also, I wanted to emphasize the fact that it could
result into a runtime error, since these are much more insidious than
compile-time errors. With the constexpr-ification of part of the standard
library proposed in [P0202R0], this could be a major problem.

[P0202R0]: http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0202r0.html

[Bug c++/69995] New: [C++14] Invalid result when evaluating constexpr function

2016-02-27 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69995

Bug ID: 69995
   Summary: [C++14] Invalid result when evaluating constexpr
function
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: major
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code triggers a runtime assertion:

--
#include 

#define CONSTEXPR constexpr

template 
struct array {
T elems_[Size];

constexpr T const& operator[](unsigned long n) const
{ return elems_[n]; }

constexpr T& operator[](unsigned long n)
{ return elems_[n]; }
};

template 
CONSTEXPR void my_swap(T& a, T& b) {
T tmp = a;
a = b;
b = tmp;
}

CONSTEXPR auto rotate2() {
array<array<int, 2>, 2> result{};
array<int, 2> a{{0, 1}};

result[0] = a;
my_swap(a[0], a[1]);
result[1] = a;

return result;
}

int main() {
CONSTEXPR auto indices = rotate2();
assert(indices[0][0] == 0);
assert(indices[0][1] == 1);
assert(indices[1][0] == 1);
assert(indices[1][1] == 0);
}
--

The fun thing is that #defining CONSTEXPR to nothing makes the code work again.
So GCC's constexpr evaluation seems to be broken in this case, in a way that
can lead to _runtime_ errors.

Live example: http://melpon.org/wandbox/permlink/PPpwDHbk5tYVlNWI

[Bug c++/67164] ICE: tree check: expected class ‘expression’, have ‘exceptional’ (argument_pack_select) in tree_operand_check, at tree.h:3356

2016-02-27 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67164

--- Comment #6 from Louis Dionne  ---
The code I posted above does not seem to trigger the bug anymore on GCC trunk. 
However, the following code still produces an ICE on trunk:

> ~/code/gcc/prefix/bin/g++ --version
> g++ (GCC) 6.0.0 20160226 (experimental)

--
#include 

namespace detail {
template 
struct fast_and
: std::is_same>
{ };
}

template 
struct tuple {
tuple() { }

template ::value...>::value
>::type>
tuple(Yn&& ...yn) { }

template ::value...>::value
>::type>
tuple(tuple const& other) { }
};

tuple> t{};
tuple> copy = t;
--

[Bug c++/69059] New: [C++14] Invalid rejection of expression as not-a-constant-expression

2015-12-26 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69059

Bug ID: 69059
   Summary: [C++14] Invalid rejection of expression as
not-a-constant-expression
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code does not compile with GCC trunk (g++ 6.0.0 20151226
experimental):

template 
struct holder { T value; };

template 
constexpr holder make_holder_impl(T&& t) {
return {static_cast<T&&>(t)};
}

template 
constexpr auto make_holder(T&& t) {
return make_holder_impl(static_cast<T&&>(t));
}


constexpr int my_strlen(char const* s) {
int n = 0;
while (*s++ != '\0')
++n;
return n;
}

constexpr int len = my_strlen(make_holder("name").value);


The error is 

[snip]/bin/g++ -pedantic -std=c++1y -W -Wall -Wextra -c ../test/worksheet.cpp
../test/worksheet.cpp:1221:30:   in constexpr expansion of 
  ‘my_strlen(make_holder("name").holder::value)’
../test/worksheet.cpp:1216:12: error: ‘t’ is not a constant expression
 while (*s++ != '\0')
^~~~


Live example: http://melpon.org/wandbox/permlink/77rNCLjwmz1P1xG2

[Bug c++/69060] New: Invalid 'cannot bind lvalue to rvalue' error

2015-12-26 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69060

Bug ID: 69060
   Summary: Invalid 'cannot bind lvalue to rvalue' error
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code does not compile on GCC trunk (g++ 6.0.0 20151226
experimental):

template 
struct hold {
T value;
T&& operator()() && {
return static_cast<T&&>(value);
}
};

bool result = hold<bool&&>{true}();


The error is 

[snip]/bin/g++ -pedantic -std=c++1y -W -Wall -Wextra -c ../test/worksheet.cpp
../test/worksheet.cpp: In instantiation of ‘T&& hold::operator()() && [with
T = bool&&]’:
../test/worksheet.cpp:1209:34:   required from here
../test/worksheet.cpp:1205:38: error: cannot bind ‘bool’ lvalue to ‘bool&&’
 return static_cast<T&&>(value);
  ^


Live example: http://melpon.org/wandbox/permlink/m9qGlrfGJLm218uh

[Bug c++/67050] [C++14] ICE when calling a template member function from a lambda with implicit "this" capture

2015-12-16 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67050

--- Comment #5 from Louis Dionne  ---
Agreed, the ICE seems to be fixed on trunk. However, the error you're getting
is still a bug, right? The code compiles if I use `this->X()`,
but not `X()` alone.

[Bug c++/67050] [C++14] ICE when calling a template member function from a lambda with implicit "this" capture

2015-12-16 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67050

--- Comment #7 from Louis Dionne  ---
Yes, it seems like a dup. However, it would still be nice to know when this bug
was fixed, because it seems unlikely to have been fixed by chance... It could
be that something's still wrong, but the compiler simply doesn't ICE anymore.

At any rate, this can be closed as a duplicate of PR61636.

[Bug c++/68754] New: Explicitly defaulted constexpr assignment operator fails to compile

2015-12-06 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68754

Bug ID: 68754
   Summary: Explicitly defaulted constexpr assignment operator
fails to compile
   Product: gcc
   Version: 5.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code fails to compile on GCC 5.3.0:

struct base { };
struct derived : base {
constexpr derived& operator=(derived const&) = default;
};

The error message is

[...]: error: explicitly defaulted function 
'constexpr derived& derived::operator=(const derived&)' cannot 
be declared as constexpr because the implicit declaration is 
not constexpr:
 constexpr derived& operator=(derived const&) = default;
^
[...]: note: defaulted constructor calls non-constexpr 
'base& base::operator=(const base&)'
 struct base { };
^
[...]: note: 'base& base::operator=(const base&)' is not usable as a 
constexpr function because:


However, the default-generated assignment operator of `base` is constexpr.
Live example: http://melpon.org/wandbox/permlink/GUJHQDuVaWOkwObj

[Bug c++/67364] "accessing uninitialized member" error in constexpr context

2015-09-17 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67364

--- Comment #1 from Louis Dionne  ---
Ping. This is one of the last bugs preventing Boost.Hana [1] to work with GCC.
I would be eternally grateful if someone could fix this!

[1]: https://github.com/ldionne/hana


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

2015-08-27 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67371

Bug ID: 67371
   Summary: Never executed throw in constexpr function fails to
compile
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code fails to compile on GCC trunk:

constexpr void f() {
if (false)
throw;
}


The error is:

[snip]: In function 'constexpr void f()':
[snip]: error: expression 'throw-expression' is not a constant-expression
 }
 ^


The code should compile because the throw expression is never executed inside a
constexpr context. Clang indeed compiles this just fine.

Live example: http://melpon.org/wandbox/permlink/V0g96xpWdO2eWGNx


[Bug c++/67164] ICE: tree check: expected class ‘expression’, have ‘exceptional’ (argument_pack_select) in tree_operand_check, at tree.h:3356

2015-08-27 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67164

--- Comment #4 from Louis Dionne ldionne.2 at gmail dot com ---
Still fails on trunk. Out of curiosity Markus, do you use software to reduce 
test cases? Did you generate these A, B, ... structs yourself?

Anyway, I was able to reduce to the following:

--
template typename T
T declval();

template typename ...
struct expand;

template typename ...Xn
struct closure {
closure();

template typename ...Yn, typename = expand
decltype(Xn(declvalYn()))...

closure(Yn ...);

template typename ...Yn
closure(closureYn...);
};

int main() {
closureclosure empty{};
closureclosure copy(empty);
}
--


The command line and output (formatted to fit the report) are:

--
 ~/code/gcc/prefix/bin/g++ --version
g++ (GCC) 6.0.0 20150827 (experimental)

 ~/code/gcc/prefix/bin/g++ -std=c++14 test/worksheet.cpp
test/worksheet.cpp: In substitution of ‘
templateclass ... Yn 
closureXn::closure(closureYn ...) [with Yn = missing]’:

test/worksheet.cpp:1573:31:   required by substitution of ‘
templateclass ... Yn, class 
closureXn::closure(Yn ...) [with Yn = closureclosure ; 
   template-parameter-1-2 = missing]’

test/worksheet.cpp:1584:34:   required from here
test/worksheet.cpp:1573:31: internal compiler error: 
tree check: expected class ‘expression’, have ‘exceptional’ 
(argument_pack_select) in tree_operand_check, at tree.h:3356

 template typename ...Yn, typename = expand
   ^
--

[Bug c++/56958] Spurious set but not used variable warning in empty pack expansion

2015-08-27 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56958

Louis Dionne ldionne.2 at gmail dot com changed:

   What|Removed |Added

 CC||ldionne.2 at gmail dot com

--- Comment #4 from Louis Dionne ldionne.2 at gmail dot com ---
The following code triggers the same warning on GCC trunk:

--
struct Object { int method(int) const { return 0; } };

template typename ...T void expand(T...);
template int ... struct index_sequence { };

template typename ...
struct TemplateStruct {
static constexpr Object get_object() { return {}; }

template int ...i
static void f(index_sequencei...) {
constexpr auto object = get_object(); // only fires with 'auto'
expand(object.method(i)...);
}
};

template void TemplateStruct::f(index_sequence);
--

The warning is:

[snip]: In instantiation of ‘
static void TemplateStruct template-parameter-1-1
::f(index_sequencei ...) [with int ...i = {};
  template-parameter-1-1 = {}]’:
[snip]:   required from here
[snip]: warning: variable ‘object’ set but not used
[-Wunused-but-set-variable]
 constexpr auto object = get_object(); // only fires with 'auto'
^


This is very annoying because that will cause perfectly fine code to emit 
warnings when used with empty parameter packs. Also surprising is that the 
warning goes away if either

(1) A non-template struct is used instead of TemplateStruct
(2) One uses `Object object = ...` instead of `auto object = ...`

which makes it obvious that this is a bug, not a feature. Please fix your
compiler, or metaprogrammers all around the world will hate you for forcing
them to write

constexpr auto object = get_object();
(void)object; // workaround GCC false positive
expand(object.method(i)...);

in every place where a variable may be 'unused' when a parameter pack is empty.

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

2015-08-27 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67371

--- Comment #1 from Louis Dionne ldionne.2 at gmail dot com ---
This is almost certainly a duplicate of #66026, yet it is still unconfirmed.


[Bug c++/67376] New: Comparison with pointer to past-the-end of array fails inside constant expression

2015-08-27 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67376

Bug ID: 67376
   Summary: Comparison with pointer to past-the-end of array fails
inside constant expression
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code fails to compile on GCC trunk:

struct array {
int elems_[1];
};

constexpr array a{{0}};
static_assert(a.elems_ != a.elems_ + 1, );

The error (formatted to fit the report) is

[snip]: error: non-constant condition for static assertion
 static_assert(a.elems_ != a.elems_ + 1, );
 ^
[snip]: error: ‘(((const int*)( a.array::elems_)) != 
(((const int*)( a.array::elems_)) + 4u))’ 
is not a constant expression
 static_assert(a.elems_ != a.elems_ + 1, );
^

It seems like GCC does not like the fact that we're comparing a past-the-end
pointer. But then again, that's weird because the following code works fine:

constexpr int a[1] = {0};
static_assert(a != a + 1, );

Live example: http://melpon.org/wandbox/permlink/4QKMVN5vm3ePJcpY

[Bug c++/66135] trailing return type error for generic lambda

2015-08-27 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66135

Louis Dionne ldionne.2 at gmail dot com changed:

   What|Removed |Added

 CC||ldionne.2 at gmail dot com

--- Comment #2 from Louis Dionne ldionne.2 at gmail dot com ---
Another test case:

template typename T
void f(T) {
[](auto x) - decltype(x.foo()) { };
}

template void f(int);

And a variation, which also yields an invalid x has incomplete type error:

template typename T
void f(T) {
[](auto x) - decltype(x.foo()) { };
}

template void f(int);


[Bug c++/67370] New: Invalid parameter packs not expanded error in lambda capture

2015-08-27 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67370

Bug ID: 67370
   Summary: Invalid parameter packs not expanded error in lambda
capture
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code does not compile with GCC trunk:

template typename ...T
void expand(T const ...);

template typename ...T
void f(T ...t) {
expand([t]{ }...);
}


The error is

[snip]: In function 'void f(T ...)':
[snip]: error: parameter packs not expanded with '...':
 expand([t]{ }...);
 ^
[snip]: note: 't'
[snip]: error: parameter packs not expanded with '...':
 expand([t]{ }...);
  ^


Live example: http://melpon.org/wandbox/permlink/uKHsTOctM4EbNTpi


[Bug c++/67041] [C++14] Variable template initialized by call to lambda does not compile

2015-08-26 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67041

--- Comment #1 from Louis Dionne ldionne.2 at gmail dot com ---
Can be simplified to:

template typename ...Anything
auto variable_template = [] { };

int main() {
variable_template;
}

Still fails on GCC trunk.


[Bug c++/67364] New: accessing uninitialized member error in constexpr context

2015-08-26 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67364

Bug ID: 67364
   Summary: accessing uninitialized member error in constexpr
context
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code triggers a compilation error on GCC trunk:

template typename Xn
struct element : Xn {
constexpr element() : Xn() { }
};

template typename Xn
struct closure {
elementXn member;
constexpr closure() { }
};

struct empty { };
constexpr closureempty tup{};
constexpr empty first = tup.member;


The error given is:

[snip]: error: accessing uninitialized member 'closureempty::member'
 constexpr empty first = tup.member;
 ^

Note that writing the default constructor of `closure` as

constexpr closure() : member{} { }

also triggers the failure. However, writing it as 

constexpr closure() : member() { }

seems to do the trick.


Live example: http://melpon.org/wandbox/permlink/vPjfVOpuauYDkatT

Seems very similar to #65896.


[Bug c++/67050] [C++14] ICE when calling a template member function from a lambda with implicit this capture

2015-07-29 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67050

Louis Dionne ldionne.2 at gmail dot com changed:

   What|Removed |Added

 CC||ldionne.2 at gmail dot com

--- Comment #1 from Louis Dionne ldionne.2 at gmail dot com ---
Created attachment 36084
  -- https://gcc.gnu.org/bugzilla/attachment.cgi?id=36084action=edit
Test case

Promised test case


[Bug c++/67050] New: [C++14] ICE when calling a template member function from a lambda with implicit this capture

2015-07-29 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67050

Bug ID: 67050
   Summary: [C++14] ICE when calling a template member function
from a lambda with implicit this capture
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

Hi,

The following code triggers an ICE (segmentation fault) on GCC trunk:
-
struct Foo {
template typename
void X() { }

void test() {
auto by_ref = [](auto arg) {
// anything that makes X... dependent will do
Xdecltype(arg)();
};
by_ref(1);

auto by_val = [=](auto arg) {
Xdecltype(arg)();
};
by_val(1);
}
};


int main() {
Foo foo;
foo.test();
}
-


Formatted to fit the report, the error is:
-
prog.cc: In lambda function:
prog.cc:8:29: internal compiler error: Segmentation fault
 Xdecltype(arg)();
 ^
0xae69af crash_signal
/home/heads/gcc/gcc-source/gcc/toplev.c:352
0x854887 size_binop_loc(unsigned int, tree_code, tree_node*, tree_node*)
/home/heads/gcc/gcc-source/gcc/fold-const.c:1732
0x9308fd gimplify_compound_lval
/home/heads/gcc/gcc-source/gcc/gimplify.c:2014
0x92bb93 gimplify_expr(tree_node**, gimple_statement_base**, 
gimple_statement_base**, 
bool (*)(tree_node*), int)
/home/heads/gcc/gcc-source/gcc/gimplify.c:8021
0x9314bb gimplify_call_expr
/home/heads/gcc/gcc-source/gcc/gimplify.c:2452
0x92d26d gimplify_expr(tree_node**, gimple_statement_base**, 
gimple_statement_base**, 
bool (*)(tree_node*), int)
/home/heads/gcc/gcc-source/gcc/gimplify.c:8040
0x92ea06 gimplify_stmt(tree_node**, gimple_statement_base**)
/home/heads/gcc/gcc-source/gcc/gimplify.c:5525
0x92cf5d gimplify_cleanup_point_expr
/home/heads/gcc/gcc-source/gcc/gimplify.c:5301
0x92cf5d gimplify_expr(tree_node**, gimple_statement_base**, 
gimple_statement_base**, 
bool (*)(tree_node*), int)
/home/heads/gcc/gcc-source/gcc/gimplify.c:8432
0x92ea06 gimplify_stmt(tree_node**, gimple_statement_base**)
/home/heads/gcc/gcc-source/gcc/gimplify.c:5525
0x92f7af gimplify_bind_expr
/home/heads/gcc/gcc-source/gcc/gimplify.c:
0x92d24c gimplify_expr(tree_node**, gimple_statement_base**, 
gimple_statement_base**, 
bool (*)(tree_node*), int)
/home/heads/gcc/gcc-source/gcc/gimplify.c:8266
0x92ea06 gimplify_stmt(tree_node**, gimple_statement_base**)
/home/heads/gcc/gcc-source/gcc/gimplify.c:5525
0x93491e gimplify_body(tree_node*, bool)
/home/heads/gcc/gcc-source/gcc/gimplify.c:9203
0x934c47 gimplify_function_tree(tree_node*)
/home/heads/gcc/gcc-source/gcc/gimplify.c:9361
0x782da7 cgraph_node::analyze()
/home/heads/gcc/gcc-source/gcc/cgraphunit.c:636
0x785447 analyze_functions
/home/heads/gcc/gcc-source/gcc/cgraphunit.c:1028
0x785cf0 symbol_table::finalize_compilation_unit()
/home/heads/gcc/gcc-source/gcc/cgraphunit.c:2477
--

Live example: http://melpon.org/wandbox/permlink/eN6sRg5AacE50CrZ
Note that Clang compiles this code just fine.

Curiously enough, using any of the following lambdas will 
not trigger the ICE:

(1)
[this](auto arg) {
Xdecltype(arg)();
};

(2)
[this](auto arg) {
this-Xdecltype(arg)();
};

(3)
[=](auto arg) {
this-Xdecltype(arg)();
};

(4)
[](auto arg) {
this-Xdecltype(arg)();
};

I will also attach a test case checking for all of the above patterns.
You might want to add this to GCC's unit tests.


Related to 53741 and 54604
Maybe a duplicate of 61636


Regards,
Louis Dionne


[Bug c++/67041] New: [C++14] Variable template initialized by call to lambda does not compile

2015-07-27 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67041

Bug ID: 67041
   Summary: [C++14] Variable template initialized by call to
lambda does not compile
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code does not compile on GCC trunk:

---
template typename ...Anything
auto variable_template = [] { return 1; }();

int main() {
variable_template;
}
---

The error is 

-
prog.cc: In instantiation of 'auto variable_template':
prog.cc:5:5:   required from here
prog.cc:2:42: error: use of 'variable_template' before deduction of 'auto'
 auto variable_template = [] { return 1; }();
  ^
prog.cc:2:42: error: use of 'lambda() [with Anything = {}]' before deduction
of 'auto'
-

Live example: http://melpon.org/wandbox/permlink/srH8coYkvigwJSkb

Note that Clang compiles this code fine.


[Bug c++/66693] New: [C++17] std::tuple_size fails with const std::array

2015-06-28 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66693

Bug ID: 66693
   Summary: [C++17] std::tuple_size fails with const std::array
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code fails on GCC trunk:

--
#include array

int main() {
std::tuple_sizestd::arrayint, 10 const::value;
}
--

The failure is

error: implicit instantiation of undefined template 
'std::tuple_sizeconst std::arrayint, 10 '
std::tuple_sizestd::arrayint, 10 const::value;
 ^
note: template is declared here
class tuple_size;
  ^

This is because the specializations of tuple_size for const and volatile
types is in the tuple header, but they ought to be available when including
utility and array in C++17.

Strictly speaking, this isn't a bug since C++14 does not require utility and
array to have these specializations AFAIK. However, it would be a trivial
fix.


[Bug c++/66543] New: False positive warning variable set but not used

2015-06-15 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66543

Bug ID: 66543
   Summary: False positive warning variable set but not used
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code triggers a unused but set variable warning on GCC trunk:

int main() {
auto f = []() { };
[=](auto) {
using Foo = decltype(f());
};
}

I think it is a false positive, since `f` is obviously used.

 g++ --version
g++ (GCC) 6.0.0 20150613 (experimental)

 g++ -std=c++14 worksheet.cpp -fsyntax-only -Wall -Wno-unused-local-typedefs

In function ‘int main()’:
warning: variable ‘f’ set but not used [-Wunused-but-set-variable]
 auto f = []() { };
  ^

Regards,
Louis Dionne

[Bug c++/65719] Link error with constexpr variable template

2015-06-14 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65719

--- Comment #9 from Louis Dionne ldionne.2 at gmail dot com ---
I can confirm that my original use case now works. Thanks a bunch!


[Bug c++/66538] New: Parameter not in scope of generic lambda trailing decltype

2015-06-14 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66538

Bug ID: 66538
   Summary: Parameter not in scope of generic lambda trailing
decltype
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code does not compile on GCC trunk:

auto f = [](auto x) - decltype((void)x) { };

The failure is

 error: ‘x’ was not declared in this scope


Removing the  gives an internal compiler error as a bonus:

auto f = [](auto x) - decltype((void)x) { };

The failure is

error: ‘x’ was not declared in this scope
 auto f = [](auto x) - decltype((void)x) { };
   ^
In lambda function:
internal compiler error: in dependent_type_p, at cp/pt.c:21073
 auto f = [](auto x) - decltype((void)x) { };
^


Finally, please note that the following code compiles fine:

auto f = [](auto x) - decltype(static_castvoid(x)) { };


Regards,
Louis Dionne

[Bug c++/65719] Link error with constexpr variable template

2015-06-03 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65719

--- Comment #4 from Louis Dionne ldionne.2 at gmail dot com ---
I added Jason to the CC list since he's the one who committed r213641. Jason,
any clue about how to fix this?


[Bug c++/65719] Link error with constexpr variable template

2015-06-03 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65719

--- Comment #3 from Louis Dionne ldionne.2 at gmail dot com ---
This bug is a real, real pain. I'm willing to help fixing it and/or to provide
test cases, but it'll take me forever if someone on your side does not assist,
since I don't know the GCC code base. I've looked at the changes introduced in
r213641 and I wasn't able to see an obvious cause for the bug, but then again I
don't know GCC.

What I can tell is this: If you look at the produced assembly
(https://goo.gl/Uxc8Dl), you can clearly see that no symbol is ever emitted for
`fint`. When you explicitly instantiate `fint`, however, the symbol is
emitted. If `fint` is not constexpr, the symbol is also emitted.


[Bug c++/66281] New: [C++14][Variable templates] internal compiler error: in tsubst, at cp/pt.c:12022

2015-05-25 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66281

Bug ID: 66281
   Summary: [C++14][Variable templates] internal compiler error:
in tsubst, at cp/pt.c:12022
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

Hi,

The following code causes an ICE on GCC trunk (couple of weeks old):


template typename ... auto f() { return 1; }

template char
auto variable_template2 = f();

template char c
auto variable_template1 = variable_template2c;

template int variable_template1'c';



Sample command line (lines trimmed):

› ~/code/gcc5/bin/g++ --version
g++ (GCC) 6.0.0 20150423 (experimental)
Copyright (C) 2015 Free Software Foundation, Inc.


› ~/code/gcc5/bin/g++ -std=c++1y ~/Desktop/bug.cpp
~/Desktop/bug.cpp: In instantiation of ‘auto variable_template1'c'’:
~/Desktop/bug.cpp:9:14:   required from here
~/Desktop/bug.cpp:4:6: internal compiler error: in tsubst, at cp/pt.c:11973
 auto variable_template2 = f();
  ^

~/Desktop/bug.cpp:4:6: internal compiler error: Abort trap: 6
g++: internal compiler error: Abort trap: 6 (program cc1plus)
Please submit a full bug report,
with preprocessed source if appropriate.
See http://gcc.gnu.org/bugs.html for instructions.


Regards,
Louis Dionne

[Bug c++/65719] New: Link error with constexpr variable template

2015-04-09 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65719

Bug ID: 65719
   Summary: Link error with constexpr variable template
   Product: gcc
   Version: 5.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com

The following code triggers a link error on GCC trunk:

--
struct FunctionObject {
void operator()() const { }
};

template typename T
constexpr FunctionObject f{};

// template FunctionObject fint;

int main() {
fint();
}
--

Curiously, uncommenting the explicit instantiation of f fixes the problem.
Similarly, making the variable template non-constexpr fixes the problem too.

My version of GCC:
› ~/code/gcc5/bin/g++ --version
g++ (GCC) 5.0.0 20150409 (experimental)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

The exact output:
› ~/code/gcc5/bin/g++ -std=c++1y ~/code/hana/test/worksheet.cpp
Undefined symbols for architecture x86_64:
  fint, referenced from:
  _main in cc7xJZsT.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status

[Bug libstdc++/65473] Including ciso646 does not define __GLIBCXX__

2015-04-09 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65473

--- Comment #4 from Louis Dionne ldionne.2 at gmail dot com ---
(In reply to Jonathan Wakely from comment #3)
 (In reply to Louis Dionne from comment #2)
  Does the standard specify which headers should define those macros?
 
 Of course not, __GLIBCXX__ is not specified by the standard at all.

The standard _could_ have said something like: 

Detection macros must be defined when including the x header
at the very least.

From your comment, I understand it doesn't.


 [...]
 
 But the unhelpful answer is include anything that includes
 bits/c++config.h

Thanks, I now include cstddef. I still think it would be a nice improvement
to include whatever your configuration header is in ciso646 and to 
document that, especially since it is super easy to do. Also, ciso646 seems 
well suited for that job since it is said to be empty by the standard, and so 
this gives us a way to include the least amount of stuff while still getting 
the detection macros.


[Bug c++/65708] New: Non-type template argument not visible causes substitution failure

2015-04-08 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65708

Bug ID: 65708
   Summary: Non-type template argument not visible causes
substitution failure
   Product: gcc
   Version: 5.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com

The following code produces an error on GCC trunk. The error says that there
is no matching `f` to call:

--
template typename T, T v
struct integral_constant { };

template typename T, T v
decltype(~v) f(integral_constantT, v);

int main() {
f(integral_constantint, 6{});
}
--

Even more curious is that the problem goes away if I replace `decltype(~v)`
by `decltype(v)` or even `decltype(+v)`.


The exact error is:
› ~/code/gcc5/bin/g++ ~/code/hana/test/worksheet.cpp -std=c++11
[...]: In function ‘int main()’:
[...]: error: no matching function for call to ‘f(integral_constantint, 6)’
 f(integral_constantint, 6{});
  ^
[...]: note: candidate: templateclass T, T v decltype (~ v)
f(integral_constantT, v)
 decltype(~v) f(integral_constantT, v);
  ^
[...]: note:   template argument deduction/substitution failed:
[...]: In substitution of ‘templateclass T, T v decltype (~ v)
f(integral_constantT, v) [with T = int; T v = 6]’:
[...]:   required from here
[...]: error: ‘v’ was not declared in this scope


My GCC version:
› ~/code/gcc5/bin/g++ --version
g++ (GCC) 5.0.0 20150326 (experimental)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[Bug c++/59766] c++1y: declaring friend function with 'auto' return type deduction is rejected with bogus reason

2015-04-08 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59766

Louis Dionne ldionne.2 at gmail dot com changed:

   What|Removed |Added

 CC||ldionne.2 at gmail dot com

--- Comment #7 from Louis Dionne ldionne.2 at gmail dot com ---
The following still fails on GCC trunk:

struct T {
friend auto f() { }
};


Sample command line:

› ~/code/gcc5/bin/g++ --version
g++ (GCC) 5.0.0 20150326 (experimental)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

› ~/code/gcc5/bin/g++ ~/code/hana/test/worksheet.cpp -std=c++1y
[...]: error: non-static data member declared ‘auto’
 friend auto f() { }
   ^

[Bug c++/65707] New: internal compiler error: in unify, at cp/pt.c:18577

2015-04-08 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65707

Bug ID: 65707
   Summary: internal compiler error: in unify, at cp/pt.c:18577
   Product: gcc
   Version: 5.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com

The following code triggers an ICE on GCC trunk:

--
#include type_traits

template bool
struct when;

template typename T
struct always_true : std::true_type { };


template typename T, typename = whentrue
struct f;

template typename T
struct fT, whenalways_trueT{} { };

template struct fint;
--

The exact command line is:

› ~/code/gcc5/bin/g++ ~/code/hana/test/worksheet.cpp -std=c++1y
[...]: internal compiler error: in unify, at cp/pt.c:18577
 template struct fint;
 ^

Note that changing

whenpredicateT{}

to

whenpredicateT{}()

fixes the problem.

[Bug c++/65706] New: [c++14] Pack expansion with variable template incorrectly marked as invalid

2015-04-08 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65706

Bug ID: 65706
   Summary: [c++14] Pack expansion with variable template
incorrectly marked as invalid
   Product: gcc
   Version: 5.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com

The following code produces an error on GCC trunk:

--
void allow_expansion(...);

template int i
int vtemplate = i;

template int ...i
void f() {
allow_expansion(vtemplatei...);
}

template void f();
template void f1();
template void f1, 2();
--

Note that the three above statements trigger the same error. 
The exact output is 

› ~/code/gcc5/bin/g++ ~/code/hana/test/worksheet.cpp -std=c++1y
[...]: In function ‘void f()’:
[...]: error: expansion pattern ‘vtemplatei’ contains no argument packs
 allow_expansion(vtemplatei...);
 ^

[Bug libstdc++/65473] Including ciso646 does not define __GLIBCXX__

2015-03-23 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65473

--- Comment #2 from Louis Dionne ldionne.2 at gmail dot com ---
Does the standard specify which headers should define those macros? If not,
then it's a QOI issue that could easily be solved. In all cases, does stdcxx
document which headers must be included in order to get those definitions? I
couldn't find it.


[Bug c++/65498] [5 Regression] ICE in cxx_eval_call_expression when using __func__ inside dependent context

2015-03-22 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65498

--- Comment #5 from Louis Dionne ldionne.2 at gmail dot com ---
[Just a quick comment: thank you for being so responsive. Most of my bug
reports on Clang are left hanging for a long while before anyone ever considers
them, and I appreciate it not being the case here.]


[Bug c++/65498] New: ICE in cxx_eval_call_expression when using __func__ inside dependent context

2015-03-20 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65498

Bug ID: 65498
   Summary: ICE in cxx_eval_call_expression when using __func__
inside dependent context
   Product: gcc
   Version: 5.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com

The following code triggers an ICE on GCC trunk:
--
#include type_traits

struct T;

template typename, typename = void
struct F { };

template typename X
struct FX, std::enable_if_tstd::is_sameX, T{}() {
template typename MakeDependent
F(MakeDependent) {
auto ICE_HERE = __func__;
(void)ICE_HERE; // avoid -Wunused-variable
}
};

int main() {
FT{1};
}
--


Example run:
--
› ~/code/gcc5/bin/g++ -std=c++1y ~/code/hana/test/worksheet.cpp
/Users/ldionne/code/hana/test/worksheet.cpp: In substitution of ‘templatebool
_Cond, class _Tp using enable_if_t = typename std::enable_if::type [with bool
_Cond = std::is_sameT, T{}(); _Tp = void]’:
/Users/ldionne/code/hana/test/worksheet.cpp:1411:25:   required from here
/Users/ldionne/code/hana/test/worksheet.cpp:1408:50:   in constexpr expansion
of ‘((std::integral_constantbool, true*)( std::is_sameT,
T()))-std::integral_constant_Tp, __v::operator()bool, true()’
/Users/ldionne/code/hana/test/worksheet.cpp:1411:25: internal compiler error:
in cxx_eval_call_expression, at cp/constexpr.c:1358
 auto ICE_HERE = __func__;
 ^

/Users/ldionne/code/hana/test/worksheet.cpp:1411:25: internal compiler error:
Abort trap: 6
g++: internal compiler error: Abort trap: 6 (program cc1plus)
Please submit a full bug report,
with preprocessed source if appropriate.
See http://gcc.gnu.org/bugs.html for instructions.
--

Note that using 

std::is_sameX, T::value

instead of 

std::is_sameX, T{}()

seems to fix the issue.


Regards,
Louis Dionne

[Bug c++/65498] ICE in cxx_eval_call_expression when using __func__ inside dependent context

2015-03-20 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65498

--- Comment #1 from Louis Dionne ldionne.2 at gmail dot com ---
Apologies; the lines of the example run were wrapped and it's unreadable from
here. Here's what it looks like:

https://gist.github.com/ldionne/054e276caf90f16e3223


[Bug libstdc++/65473] New: Including ciso646 does not define __GLIBCXX__

2015-03-19 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65473

Bug ID: 65473
   Summary: Including ciso646 does not define __GLIBCXX__
   Product: gcc
   Version: 5.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com

Hi,

One would expect that including _any_ header from the standard library defines
the relevant detection macros. For example, I usually include the ciso646
header to check for libc++ (per http://goo.gl/eXNYJH). However, libstdc++'s
headers do not always define those detection macros.

Regards,
Louis Dionne


[Bug c++/59498] [DR 1430][4.9/4.10 Regression] Pack expansion error in template alias

2014-07-27 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59498

--- Comment #7 from Louis Dionne ldionne.2 at gmail dot com ---
I ran into this problem in another context, and I think it justifies some
thinking about how this issue is going to be handled by the language. I
_really_ think the following should be valid C++. This is a C++11
implementation of the `quote` utility of the Boost.MPL. Unfortunately,
it won't compile when given an alias:

#include type_traits

template template typename ... class f
struct quote {
template typename ...x
using apply = fx...;
};

using test = quotestd::add_pointer_t::applyint;

It is very important for this kind of code to be valid to enable a generic
handling of aliases in metaprograms. Without this, I see two solutions:
1. Use metafunctions instead of aliases, i.e.
   `quotestd::add_pointer::applyint::type`.
2. Do not use variadic templates and have numbered forms for `quote` for
   each number of arguments up to some number. This is basically returning
   to C++03.

Tested on gcc 4.9.1 and clang 3.5.0 (trunk).


[Bug c++/59498] [DR 1430][4.9/4.10 Regression] Pack expansion error in template alias

2014-07-27 Thread ldionne.2 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59498

--- Comment #8 from Louis Dionne ldionne.2 at gmail dot com ---
I made further experiments to try and workaround this (I need it badly!) and
I found some things that might be of interest to you. The following test case
compiles on GCC 4.9.1 but not on Clang 3.5.0 (trunk):

template template typename ... class f
struct make {
template typename ...x
static constexpr auto apply(x...)
- decltype(fx...{}) // - compiles on both when this is
commented
{
return fx...{};
}
};

template typename struct f { }; // - fails on GCC when this is variadic
template typename x using alias = fx;


int main() {
makealias::apply(1);
}


Now, if I change the definition of f to:

template typename... struct f { };

then it fails to compile on both compilers. Finally, if I remove the
decltype(fx...{}) part of the apply function above, then it compiles
on both compilers regardless of f's definition.


[Bug c++/59498] New: Pack expansion error in template alias

2013-12-13 Thread ldionne.2 at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59498

Bug ID: 59498
   Summary: Pack expansion error in template alias
   Product: gcc
   Version: 4.9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ldionne.2 at gmail dot com

GCC Version
---
gcc-4.9 (GCC) 4.9.0 20131201 (experimental)
Installed with Homebrew.


System
--
OS X 10.8.5


Command line to trigger the bug
---
gcc-4.9 -std=c++11 -Wall -Wextra -pedantic -o /dev/null -c
template_alias_bug.cpp


Minimal code to reproduce
-

template typename T, typename ...
using alias = T;

template typename ...T
using variadic_alias = aliasT...;

using Fail = variadic_aliasint;

int main() { }


Error message
-
template_alias_bug.cpp:9:34: error: pack expansion argument for non-pack
parameter 'T' of alias template 'templateclass T, class ... using alias = T'
 using variadic_alias = aliasT...;
  ^
template_alias_bug.cpp:5:11: note: declared here
 template typename T, typename ...
   ^
template_alias_bug.cpp:11:14: error: expected type-specifier before
'variadic_alias'
 using Fail = variadic_aliasint;
  ^

Possibly related

Bug 58856


Comments

Clang compiles the code just fine and I don't see any obvious reason why that
would be invalid C++11 (I could be mistaken), so I think that's a GCC bug.