[Bug c++/111419] New: Eager instantiation of function return type in concept causes compilation error
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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() { wrappert = 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
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
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
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 wrappert = 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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__
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
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
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
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
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__
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
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
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
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__
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
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
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
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.