[Bug libstdc++/111357] New: __integer_pack fails to work with values of dependent type convertible to integers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111357 Bug ID: 111357 Summary: __integer_pack fails to work with values of dependent type convertible to integers Product: gcc Version: 13.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- Case: #include #include #include using std::size_t; #if __cpp_lib_integer_sequence >= 201304L using std::index_sequence; using std::make_index_sequence; #else template struct index_sequence {}; template struct succ; template struct succ> { using type = index_sequence; }; template struct iseq { using type = typename succ::type>::type; }; template<> struct iseq<0> { using type = index_sequence<>; }; template using make_index_sequence = typename iseq::type; #endif template void g(index_sequence) {} template struct R { using S = make_index_sequence>{}>; R() noexcept(noexcept(g(S( {} }; int main() { R(); } Output of x86-64 gcc 13.2 (Compiler #1) : In instantiation of 'R::R() [with T = int]': :55:9: required from here :49:33: error: argument to '__integer_pack' must be between 0 and 268435452 49 | R() noexcept(noexcept(g(S( | ^~~ This should work as -std=c++11 which uses a naive implementation of make_index_sequence here. I mark it as a libstdc++ bug of conformance for the case. The root cause seems a bug of the implementation in the frontend, but I'm not that sure, because the document of __integer_pack does not mention such cases explicitly. (The error message here is obviously confusing, though.)
[Bug lto/110844] New: LTO sometimes fail with -save-temp -dumpdir options
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110844 Bug ID: 110844 Summary: LTO sometimes fail with -save-temp -dumpdir options Product: gcc Version: 13.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: lto Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com CC: marxin at gcc dot gnu.org Target Milestone: --- Cases: $ cd /tmp $ g++ --version g++ (GCC) 13.1.1 20230714 Copyright (C) 2023 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. $ echo 'int main(){}' > a.cc $ g++ -flto -c a.cc -o a.o $ g++ -flto -save-temps -dumpdir . a.o $ g++ -flto -c a.cc -o a.o -save-temps -dumpdir . $ g++ -flto -save-temps -dumpdir . a.o $ g++ -flto -save-temps -dumpdir /tmp/ a.o /usr/sbin/ld: error: could not open arguments file collect2: error: ld returned 1 exit status The error message is from lto-plugin.c. Setting the environment variables (indicated by 'g++ -v' and then 'collect2 -v' from the result) properly, by "b fopen if *(char*)$rsi == 'w'" for ld running in gdb a few times, it shows something goes wrong in 'link_output_name' which forms 'arguments_file_name': the variable incorrectly contains all the remain characters in the command line. (This is also reproduced in MSYS2 ld which has no debug symbols distributed together, after changing $rsi to $rdx.) The parsing implementation of '-dumpdir' arguments introduced in 1dedc12d186a110854537e1279b4e6c29f2df35a then looks quite suspicious.
[Bug libstdc++/103240] std::type_info::before gives wrong answer for ARM EABI
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103240 --- Comment #9 from frankhb1989 at gmail dot com --- (In reply to Jonathan Wakely from comment #8) > I don't think that's true. If __GXX_MERGED_TYPEINFO_NAMES is true then the > out-of-line definition is correct. You can't just redefine that macro to 1 > in your code and expect it to affect the out-of-line definition in the > library. Even if you recompile the library with > -D__GXX_MERGED_TYPEINFO_NAMES=1 that doesn't magically make it true. If the > platform ABI and compiler and linker really do guarantee that all typeinfo > names are unique, then address comparison works correctly. > Yes, -D__GXX_MERGED_TYPEINFO_NAMES=1 is harmful and unnecessary to work around the issue. As illustrated, it just works for some of my cases accidentally, and fails for some other cases. Further, I want to make sure no out-of-line definition of type_info::before is called in the system libraries (which I can't rebuild). Does libstdc++ have calls to type_info::before internally? > You can't expect that to give meaningful results though, you would need to > rebuild the entire compiler for meaningful results with redefined macros, > and even then it would fail when you use RTTI across dynamic library > boundaries. > > You can't just redefine those macros and expect the compiler and OS to > change how they work. > I don't quite get this point about the compiler. Do you mean not only libstdc++ and the linker, but also the compiler's codegen of the mangled names works differently depending on the macro definitions, besides the possible duplicate (but having identical mangled names) definitions of the internal objects providing the mangle names? Will it affect the section layout of the object code? Are there existing optimizations relying on the assumptions? I know it will not be formally supported to have consistent behavior just by rebuilding the user programs, and it will be plain wrong without things like ICF or in cases dynamic loading is relied on, but I'm curious: what are the actual consequences from the compiler's view, when (1) all TUs of the program code eventually use these macro definitions consistently, (2) definitions of RTTI information for identical types are totally merged; and, (3) each instance of the call to the out-of-line definition of type_info::before is avoided? I am interesting in such questions because there are cases where rebuiding the toolchain is impossible. It is not even possible to rebuilt libstdc++ for production system unless more than one instance can be deployed side by side (e.g. by static linking), because I cannot make sure no other part of the environment have relied on the bug-to-bug compatibility to the existing system libraries. In my case, I have to make sure which parts of the deployed code are actually affected before the toolchain update (either system-wide or not) is possible. And before that, the redefinition of macros seems the only viable workaround (with certain limitations). > > Accidentally the > > inline definition of std::type_info::before does the right thing > > I don't think it's an accident. > Good news to me. > > (hopefully), so __GXX_TYPEINFO_EQUALITY_INLINE == 1 just works. Otherwise > > there would be no easy workaround without the modification on the standard > > headers. > > > > Forcing address comparisons is wrong in general, but with some additional > > assumptions to rule out all potential offending features, then all type_info > > objects follow ODR in the strict sense, so this just works. When this is an > > issue, __GXX_TYPEINFO_EQUALITY_INLINE == 1 && __GXX_MERGED_TYPEINFO_NAMES == > > 0 should be safe for all names not from unnamed namespaces. This is a real > > problem for MinGW (at least with GNU ld which does not perform ICF on > > PE/COFF AFAIK), where __GXX_TYPEINFO_EQUALITY_INLINE == 1 && > > __GXX_MERGED_TYPEINFO_NAMES == 1 causes something like > > (shared_ptr<...>) not unique across module boundaries, and my code > > fails elsewhere due to this reason. > > So stop redefining those macros then, you're lying to the compiler. > Sadly, we *have to* lie for some degrees... ODR in ISO C++ is already conceptually violated in cases when dynamic libraries are taken into account. There is no such strong guarantee (like ICF) for all implementations, so implementation-specific details are already kicked in. > __GXX_MERGED_TYPEINFO_NAMES=1 is a lie on your target. Don't do that. Agreed for the current case, though.
[Bug libstdc++/103240] std::type_info::before gives wrong answer for ARM EABI
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103240 --- Comment #7 from frankhb1989 at gmail dot com --- (In reply to Jonathan Wakely from comment #6) > What are the mangled type names that are unordered? (that's all you need to > describe, everything about flat_map and partition_point is irrelevant; just > tell us which names are unordered). Here are the pair of the unordered names in the actual case: 1. St5_BindIFPFN3NPL15ReductionStatusERNS0_8TermNodeERNS0_11ContextNodeEESt17reference_wrapperIS2_ESt12_PlaceholderILi1 2. St5_BindIFZN3NPL2A112_GLOBAL__N_113DoDefineOrSetILb0EE4CallIJEEENS0_15ReductionStatusERNS0_8TermNodeERNS0_11ContextNodeESt10shared_ptrINS0_11EnvironmentEES8_DpOT_EUlRKS7_RKSD_E_S7_SD_EE Here is the reduced program (exactly from the actual case) to show the sequence and the ordering: #include #include #include #include #include #include #include std::vector v; namespace ystdex { template struct expanded_caller {}; } namespace NPL { enum class ReductionStatus { Clean }; struct TermNode {}; struct ContextNode {}; struct Environment {}; namespace A1 { template void bar() { static struct Init { Init() { // std::cout << typeid(T).name() << std::endl; v.push_back(typeid(T)); } } init; } template void foo(C&&) { bar>(); } template void foo2(C&&) { bar(); } namespace { struct EvalSequence {}; } namespace { template struct DoDefineOrSet { template static ReductionStatus Call(TermNode& term, ContextNode& ctx, std::shared_ptr p, TermNode& t, A&&... args) { foo2(std::bind([&](const TermNode& saved, const std::shared_ptr& p_e, const A&...){ return ReductionStatus::Clean; }, std::move(t), std::move(p), std::move(args)...)); return ReductionStatus::Clean; } }; template ReductionStatus LambdaVauWithEnvironment(TermNode&, ContextNode&, bool) { []{}; foo([]{}); return ReductionStatus::Clean; } } } ReductionStatus f1(TermNode&, ContextNode&) { return ReductionStatus::Clean; } } int main() { using namespace std; using namespace placeholders; using namespace NPL; using namespace A1; TermNode t; ContextNode c; cout << "__GXX_TYPEINFO_EQUALITY_INLINE = " << __GXX_TYPEINFO_EQUALITY_INLINE << endl; cout << "__GXX_MERGED_TYPEINFO_NAMES = " << __GXX_MERGED_TYPEINFO_NAMES << endl; foo2(bind(f1, ref(t), _1)); foo2(EvalSequence{}); DoDefineOrSet::Call(t, c, {}, t); LambdaVauWithEnvironment<1, 1>(t, c, true); for(auto& id : v) cout << "i = " << ( - [0]) << ", v[i] = " << id.name() << endl; for(std::size_t i = 0; i < v.size(); ++i) for(auto j = i; j < v.size(); ++j) if(i != j) cout << "i = " << i << ", " << "j = " << j << ", v[i] < v[j] = " << (v[i] < v[j]) << ", v[j] < v[i] = " << (v[j] < v[i]) << endl; } // g++ -std=c++11 -U__GXX_TYPEINFO_EQUALITY_INLINE -D__GXX_TYPEINFO_EQUALITY_INLINE=0 -U__GXX_MERGED_TYPEINFO_NAMES -D__GXX_MERGED_TYPEINFO_NAMES=0 a.cc This is tested with x86_64-w64-mingw32-g++. Linking may fail on platforms where libstdc++ is configured without the out-of-line definition of std::type_info::before. Here is the output: __GXX_TYPEINFO_EQUALITY_INLINE = 0 __GXX_MERGED_TYPEINFO_NAMES = 0 i = 0, v[i] = St5_BindIFPFN3NPL15ReductionStatusERNS0_8TermNodeERNS0_11ContextNodeEESt17reference_wrapperIS2_ESt12_PlaceholderILi1 i = 1, v[i] = N3NPL2A112_GLOBAL__N_112EvalSequenceE i = 2, v[i] = St5_BindIFZN3NPL2A112_GLOBAL__N_113DoDefineOrSetILb0EE4CallIJEEENS0_15ReductionStatusERNS0_8TermNodeERNS0_11ContextNodeESt10shared_ptrINS0_11EnvironmentEES8_DpOT_EUlRKS7_RKSD_E_S7_SD_EE i = 3, v[i] = N6ystdex15expanded_callerIFN3NPL15ReductionStatusERNS1_11ContextNodeEEZNS1_2A112_GLOBAL__N_124LambdaVauWithEnvironmentILy1ELy1EEES2_RNS1_8TermNodeES4_bEUlvE0_EE i = 0, j = 1, v[i] < v[j] = 0, v[j] < v[i] = 1 i = 0, j = 2, v[i] < v[j] = 1, v[j] < v[i] = 1 i = 0, j = 3, v[i] < v[j] = 0, v[j] < v[i] = 1 i = 1, j = 2, v[i] < v[j] = 0, v[j] < v[i] = 1 i = 1, j = 3, v[i] < v[j] = 0, v[j] < v[i] = 1 i = 2, j = 3, v[i] < v[j] = 0, v[j] < v[i] = 1 The unordered pair occurs iff. __GXX_TYPEINFO_EQUALITY_INLINE == 0, i.e. the out-of-line definition is used, and regardless to the value of __GXX_MERG
[Bug libstdc++/103240] std::type_info::before gives wrong answer for ARM EABI
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103240 --- Comment #5 from frankhb1989 at gmail dot com --- There are multiple issues. 1. The out-of-line definition and the inline definition of std::type_info::before do different things. Specifically, only one name is detected against to '*' in the former, but two in the latter. It seems the latter is more correct. ("More", because it is still not quite correct, see below.) 2. As stated in https://reviews.llvm.org/D100134, mixture of different methods of comparisons breaks the ordering. I've actually encountered the problem with std::type_index as the key type when using flat_map::emplace (like https://github.com/WG21-SG14/SG14/blob/master/SG14/flat_map.h, which uses std::partition_point to find the position of insertion). The insertion suddenly fails when std::partition_point meets two std::type_info objects x and y which are unordered. It works with the workaround '-U__GXX_MERGED_TYPEINFO_NAMES -D__GXX_MERGED_TYPEINFO_NAMES=1' in the compiler command line, but it seems not enough in general without fixing the issue 2 here. (Although the same sequence of key on std::map does not fail, occasionally, due to less comparisons are made.) 3. Not sure the original change in r179236 is correct. 4. '||' in the condition of the inline definition of std::type_info::before seems an overkill. '&&' may be enough. Assuming string comparison is more expensive, this is a simple optimization. But once the issue 2 is fixed, the change would look quite different.
[Bug libstdc++/103240] std::type_info::before gives wrong answer for ARM EABI
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103240 frankhb1989 at gmail dot com changed: What|Removed |Added CC||frankhb1989 at gmail dot com --- Comment #4 from frankhb1989 at gmail dot com --- This should affect all targets without __GXX_MERGED_TYPEINFO_NAMES enabled. Actually the test case also fails on (some old versions of) MinGW GCC in MSYS2.
[Bug libstdc++/108771] New: Incorrect noexcept for merging in
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108771 Bug ID: 108771 Summary: Incorrect noexcept for merging in Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- _M_merge_unique and _M_merge_equal in _Rb_tree have noexcept. This is problematic because the call to _M_insert_node is potentially throwing, by the call to the comparison object. The subclause [associative.reqmts.general] also suggest it can throw: a.merge(a2) Throws: Nothing unless the comparison object throws. There is no such issue in _Hashtable.
[Bug libstdc++/107189] New: Inconsistent range insertion implementations in std::_Rb_tree in
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107189 Bug ID: 107189 Summary: Inconsistent range insertion implementations in std::_Rb_tree in Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- //#if __cplusplus >= 201103L template __enable_if_t<__same_value_type<_InputIterator>::value> _M_insert_range_unique(_InputIterator __first, _InputIterator __last) { _Alloc_node __an(*this); for (; __first != __last; ++__first) _M_insert_unique_(end(), *__first, __an); } template __enable_if_t::value> _M_insert_range_unique(_InputIterator __first, _InputIterator __last) { for (; __first != __last; ++__first) _M_emplace_unique(*__first); } template __enable_if_t<__same_value_type<_InputIterator>::value> _M_insert_range_equal(_InputIterator __first, _InputIterator __last) { _Alloc_node __an(*this); for (; __first != __last; ++__first) _M_insert_equal_(end(), *__first, __an); } template __enable_if_t::value> _M_insert_range_equal(_InputIterator __first, _InputIterator __last) { _Alloc_node __an(*this); for (; __first != __last; ++__first) _M_emplace_equal(*__first); } __an is not used in the 2nd overload of _M_insert_range_equal. And is there any reason about not using _M_emplace_hint_{unique,equal} for !__same_value_type cases?
[Bug ipa/101279] Function attributes often block inlining
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101279 frankhb1989 at gmail dot com changed: What|Removed |Added CC||frankhb1989 at gmail dot com --- Comment #3 from frankhb1989 at gmail dot com --- There is a more specific instance here: can_inline_edge_by_limits_p in ipa-inline.cc treats flags and "optimize" attributes differently. While it is reasonable to reject inlining for semantic mismatch from different global flags, "opts_for_fn (caller->decl) != opts_for_fn (callee->decl)" looks quite unnatural. In practice it means missing of valid opportunity of inlining, unless the programmer knows what should go under the hood and decides to propagate "always_inline" plus the "optimize" attributes manually in the declarations of *all* callees (including lambda-expressions in C++), *recursively*. Adding "__attribute__((flatten))" can be a workaround sometimes, but it does not always generated desired code, and often too slow. This is somewhat worse than the case of "-fwrapv" whose semantic is easier to reason in the generated code.
[Bug libstdc++/104191] Incorrect max_size() for node-based containers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104191 --- Comment #4 from frankhb1989 at gmail dot com --- Well, surrendering at the possibility of huge amount of node allocations, because there is LWG 2794. (I'd complain this is over-restrictive and pure loss of functionality for allocators used on containers which do not expose contiguous memory access interface like data(), but this would be another story.) Moreover, PR 57272 is still not fixed. Despite the change in LWG 2794, without the fix of that bug, I'd admit there is indeed no reasonable way to create such many nodes...
[Bug libstdc++/104191] Incorrect max_size() for node-based containers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104191 --- Comment #2 from frankhb1989 at gmail dot com --- (In reply to Jonathan Wakely from comment #1) > (In reply to frankhb1989 from comment #0) > > and it should be solely determined by the internal node count type. > > What is the internal node count type? You mean the size_type? That would be > wrong, because there's no way you can create > numeric_limits::max() nodes, as each node requires tens of bytes. > For the current std::list implementation with _GLIBCXX_USE_CXX11_ABI enabled, it is the type of _List_node_header::_M_size, which is explicitly declared as std::size_t. Otherwise, it is the size_type. Both are effectively size_t. Allocating such many nodes are generally impossible to succeed with usual allocators, but what if allocators with fancy pointers which can point to objects allocated out of the main memory in the usual flat address space (e.g. via Microsoft Windows's address windowing extensions)? There is one more related problem: can the allocator's size_type greater than size_t? If so, the implementations of max_size() are immediately more flawed due to the truncation of allocator's size_type to container's size_type (size_t), e.g. when the allocator's max_size() is implemented by default in the allocator traits (since the fix of LWG 2466). As per https://stackoverflow.com/a/12499353, the standard used to allow such size_type. But I then found the referenced wording are invalidated by the side effects of the changes in LWG 2384 and P0593R6. I'm not confident they are intentional. > I agree using the allocator's max_size() is wrong, but it doesn't really > matter because all max_size() functions on containers and allocators are > useless in practice. This is true for most user code. But it still seems too easy to break, as the case shows. Further, it exposes some internal consistency in the implementation. MSVC's std::list checks the size and throw std::length_error in the insertion to avoid the inconsistency. I don't think such cost should be introduced here. The simplest fix is just to return numeric_limits::max() in container's max_size()... well, only if PR 78448 is not taken into account. It catastrophically blocks the way of this simple fix. Perhaps there could be an LWG issue to propose changes on the definitions of size() and max_size() to get rid of the range limit of difference_type at least for containers not requiring contiguous memory (and [container.requirements.general]/5 kicks in instead)... then the simple fix can be applied.
[Bug libstdc++/104191] New: Incorrect max_size() for node-based containers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104191 Bug ID: 104191 Summary: Incorrect max_size() for node-based containers Product: gcc Version: 11.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- Case: #include #include template struct one_alloc : std::allocator { template struct rebind { using other = one_alloc;}; T* allocate(std::size_t n) { if(n > 1) throw std::bad_array_new_length(); return std::allocator::allocate(n); } std::size_t max_size() const noexcept { return 1; } }; int main() { std::list> l; l.push_back(0); l.push_back(0); assert(l.size() <= l.max_size()); } This looks very wrong. The changes in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=29134 seem too aggressive on containers like list. Logically, the container's max_size() should have nothing to do with the allocator's max_size() (which limits the number of object of value_type in a single allocation), and it should be solely determined by the internal node count type. This is also consistent to the cases where the container's size_type is always size_t (instead of size_type of the allocator). There are some more subtleties concerned with https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78448. Not sure if extra checks are required to make it conforming.
[Bug target/92137] [ia32] Missing documentation for ia32 builtins
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92137 frankhb1989 at gmail dot com changed: What|Removed |Added CC||frankhb1989 at gmail dot com --- Comment #8 from frankhb1989 at gmail dot com --- (In reply to Richard Biener from comment #1) > You shouldn't use those, they are for internal use only. That's the reason > they are not documented. There are cases of legitimate use, e.g. given that https://gcc.gnu.org/bugzilla/show_bug.cgi?id=29776 is still not fixed, one may want something like: int floor2(uint64_t x) { #if __has_builtin(__builtin_ia32_bsrdi) return __builtin_ia32_bsrdi(x); #elif __has_builtin(__builtin_clzll) return 63 - size_t(__builtin_clzll(x)); #else // ... #endif } The key point is that __has_builtin checks are apparently cleaner than traditional #if defined(__xxx__)+headers+intrinsics way. Moreover, __has_builtin and __builtin_xxx may be even more portable (among compilers) and preferred in new code. The intentional statement you quoted was posted in 2005; this seems outdated today.
[Bug driver/100937] configure: Add --enable-default-semantic-interposition
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100937 --- Comment #10 from frankhb1989 at gmail dot com --- (In reply to Jonathan Wakely from comment #9) > (In reply to frankhb1989 from comment #7) > The toolchain might not be ELF-specific, but > on targets that *do* use ELF, of course the ELF specification is relevant, True. > and deviating from it should not be done lightly. Deviating... well, are there any documented policies to clarify how much room to the non-conformance here? > Just because portability between ELF and PE/COFF is difficult and requires > care, doesn't mean we should also make it difficult to guarantee portability > across different linux distros that are all using ELF. That's just silly. > You don't make anything better by making everything equally bad. I don't mean that one portability is just unconditionally more important than another. But there are certainly things beyond portability if you are really caring "everything". Keeping the "portability", if any across ELF, makes sense to maintainers of the distros. But it is not obvious to most users, which are not specialists of ELF. For those not relying on the sneaky feature, they silently pay the unneeded cost *by default*. This is probably against to the intuition to most C and C++ users. Moreover, this also affects almost every *end users*, which should not care about such features at all. So here is the "bad": the default configuration makes things unexpected (and a laborious way to prevent it) for most users, albeit only in QoI sense. Such default may even have effects on the adoption of free software. Changing the default may likely reduce such bad things, at the cost of the compatibility. I am not arguing the change is absolutely necessary, but it is certainly NOT "making everything equally bad". (This would not remove interposition for the minority who need them indeed.) BTW, I'm not aware of such a cross-distro guarantee has been widely adopted and relied on. It is well-known the Linux kernel has the policy to maintain the stability of syscalls, but in the userland... is it already distro-specific? Correct me if I am wrong here. (Any source?)
[Bug driver/100937] configure: Add --enable-default-semantic-interposition
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100937 frankhb1989 at gmail dot com changed: What|Removed |Added CC||frankhb1989 at gmail dot com --- Comment #7 from frankhb1989 at gmail dot com --- While I feel it is fair to keep the status quo, the decision here deserves some additional comments. It is true that potability is generally important, but the current way here is actually not friendly to potability. GCC and the GNU toolchain are not ELF-specific. Nor are they responsible to the authority of the specification. The "ELF assumptions" have no natural position to be the default at the very first glance from the users' view. So the "portability" certainly include the ease of porting the programs to different targets with different image formats back and forth. Sticking on the ELF-centric defaults already fails (by reducing the platform-specific differences) if users want to really gain more portability, at least for PE/COFF targets (which do not support such interposition at all). Although it is somewhat reasonable to distinguish platforms supporting symbol interposition as first-class ones (same to the current "primary platforms"), but this still seems technically weak. Perhaps a more appropriate phrase for the reason is "backward compatibility".
[Bug libstdc++/100682] New: Outdated manual about the debug mode using
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100682 Bug ID: 100682 Summary: Outdated manual about the debug mode using Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- As I see has been removed in GCC 11, but the doc disagree: https://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode_using.html https://gcc.gnu.org/onlinedocs/gcc-11.1.0/libstdc++/manual/manual/debug_mode_using.html In table 17.2, is still at the first row. BTW, what is the compatibility policy here? Is it true that any headers could be removed in a future release of GCC without deprecation?
[Bug c++/70834] Incorrect warning for placement new when conditionally used
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70834 frankhb1989 at gmail dot com changed: What|Removed |Added CC||frankhb1989 at gmail dot com --- Comment #8 from frankhb1989 at gmail dot com --- (In reply to Martin Sebor from comment #7) > No change in GCC 11. This false positive too will be avoided by running > -Wplacement-new later, when the program is in SSA form, rather than in the > front end. Actually worse in GCC 11. Try this case: #include #include #include #include #include struct hdr_t { void* p_block; }; constexpr auto offset = sizeof(hdr_t) > alignof(hdr_t) ? sizeof(hdr_t) : alignof(hdr_t); void* operator new(std::size_t bytes, std::size_t alignment) { auto space(offset + bytes + alignment); auto ptr(static_cast(std::malloc(space))); void* p([offset]); if(std::align(alignment, bytes, p, space)) { (::new(static_cast(static_cast(p) - offset)) hdr_t)->p_block = ptr; // (::new(ptr + (std::size_t(static_cast(p) - ptr)) - offset) hdr_t)->p_block = ptr; return p; } throw std::bad_alloc(); } int main() {} This is warned in G++ 11.1, but not G++ 10.2.
[Bug c++/100472] New: [C++17] Wrong template non-type argument handling on function reference to noexcept functions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100472 Bug ID: 100472 Summary: [C++17] Wrong template non-type argument handling on function reference to noexcept functions Product: gcc Version: 10.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- Case: template void h() {} void f() noexcept {} int main() { h(); } g++ prog.cc -Wall -Wextra -std=c++17 prog.cc: In function 'int main()': prog.cc:10:7: error: no matching function for call to 'h()' 10 | h(); | ^ prog.cc:2:6: note: candidate: 'template)()> void h()' 2 | void h() | ^ prog.cc:2:6: note: template argument deduction/substitution failed: prog.cc:10:7: error: '(void (&)())f' is not a valid template argument for type 'void (&)()' 10 | h(); | ^ prog.cc:10:7: note: it must be the name of a function with external linkage Removing `noexcept` makes all errors disappeared. So, the real failure is from the initialization of the template non-type parameter. This should not fail as per the rules in [temp.arg.nontype], [dcl.init.ref] and [expr.const] (see also N4268). Even if the conversion should have been failed, the last diagnostic message is clearly wrong and confusing. This message comes from the conversion performed on the template non-type argument as I see in convert_nontype_argument_function in pt.c, and it should not occur since the [temp.arg.nontype] changes in C++11.
[Bug libstdc++/97362] [8/9/10 Regression] `__deref` in in debug mode clashes with internal macro in Windows system header
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97362 --- Comment #8 from frankhb1989 at gmail dot com --- The first diagnostic message of `#pragma GCC poison __deref` points to in my MSYS2 installation. The change is made here: https://sourceforge.net/p/mingw-w64/mingw-w64/ci/555bee806560144c6a59077f3c860bc83411153c/.
[Bug driver/82955] ICE when using -fdump-passes -fdisable-tree-einline
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82955 frankhb1989 at gmail dot com changed: What|Removed |Added CC||frankhb1989 at gmail dot com --- Comment #2 from frankhb1989 at gmail dot com --- Both cases are not reproducible using current Arch Linux's GCC 10.2.0 now. Context: I'm dealing with some compiler performance issues on opt_local_passes for this specific source: https://github.com/FrankHB/YSLib/blob/master/YFramework/source/NPL/NPLA1Forms.cpp, with -O -fsanitizer= I've met endless compilation (> 4 hours) for this file combined with -g and optimization flags and -fno-var-tracking-assignments would work around, but this time it seems a different case.
[Bug libstdc++/97362] `__deref` in in debug mode clashes with internal macro in Windows system header
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97362 --- Comment #1 from frankhb1989 at gmail dot com --- To clarify a bit: is installed by the VC++ toolchain or WDK, not by Windows SDK. Nevertheless, it is a system header both MS's CRT and Win32 headers rely on.
[Bug libstdc++/97362] New: __deref in in debug mode clashes with Windows SDK internal macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97362 Bug ID: 97362 Summary: __deref in in debug mode clashes with Windows SDK internal macro Product: gcc Version: 10.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- Case: #include #include int main() {} /tmp $ g++ -D_GLIBCXX_DEBUG a.cc In file included from F:/msys64/mingw64/include/c++/10.2.0/debug/debug.h:133, from F:/msys64/mingw64/include/c++/10.2.0/bits/stl_algobase.h:69, from F:/msys64/mingw64/include/c++/10.2.0/array:40, from F:/msys64/mingw64/include/c++/10.2.0/tuple:39, from F:/msys64/mingw64/include/c++/10.2.0/functional:54, from a.cc:2: F:/msys64/mingw64/include/c++/10.2.0/debug/functions.h:424:15: error: expected unqualified-id before ')' token 424 | __deref(); | ^ F:/msys64/mingw64/include/c++/10.2.0/debug/functions.h:427:34: error: expected primary-expression before '<' token 427 | typename = decltype(__deref<_It>() < __deref<_It>())> | ^ F:/msys64/mingw64/include/c++/10.2.0/debug/functions.h:427:38: error: expected primary-expression before '>' token 427 | typename = decltype(__deref<_It>() < __deref<_It>())> | ^ F:/msys64/mingw64/include/c++/10.2.0/debug/functions.h:427:40: error: expected primary-expression before ')' token 427 | typename = decltype(__deref<_It>() < __deref<_It>())> |^ F:/msys64/mingw64/include/c++/10.2.0/debug/functions.h:427:51: error: expected primary-expression before '<' token 427 | typename = decltype(__deref<_It>() < __deref<_It>())> | ^ F:/msys64/mingw64/include/c++/10.2.0/debug/functions.h:427:55: error: expected primary-expression before '>' token 427 | typename = decltype(__deref<_It>() < __deref<_It>())> | ^ F:/msys64/mingw64/include/c++/10.2.0/debug/functions.h:427:57: error: expected primary-expression before ')' token 427 | typename = decltype(__deref<_It>() < __deref<_It>())> | ^ F:/msys64/mingw64/include/c++/10.2.0/debug/functions.h:441:42: error: expected primary-expression before '<' token 441 | = decltype(std::declval<_Pred>()(__deref<_It>(), __deref<_It>()))> | ^ F:/msys64/mingw64/include/c++/10.2.0/debug/functions.h:441:46: error: expected primary-expression before '>' token 441 | = decltype(std::declval<_Pred>()(__deref<_It>(), __deref<_It>()))> | ^ F:/msys64/mingw64/include/c++/10.2.0/debug/functions.h:441:48: error: expected primary-expression before ')' token 441 | = decltype(std::declval<_Pred>()(__deref<_It>(), __deref<_It>()))> |^ F:/msys64/mingw64/include/c++/10.2.0/debug/functions.h:441:58: error: expected primary-expression before '<' token 441 | = decltype(std::declval<_Pred>()(__deref<_It>(), __deref<_It>()))> | ^ F:/msys64/mingw64/include/c++/10.2.0/debug/functions.h:441:62: error: expected primary-expression before '>' token 441 | = decltype(std::declval<_Pred>()(__deref<_It>(), __deref<_It>()))> | ^ F:/msys64/mingw64/include/c++/10.2.0/debug/functions.h:441:64: error: expected primary-expression before ')' token 441 | = decltype(std::declval<_Pred>()(__deref<_It>(), __deref<_It>()))> This is reproducible with MSYS2's {i686, x86_64}-w64-mingw32-g++. Note it compiles without -D_GLIBCXX_DEBUG. The offending `__deref` is from WinSDK header (also available in mingw-w64 for compatibility). As a system header, it is legitimate to have reserved identifiers. Although the workaround is simple (by #undef, since is not available in mingw-w64 yet), it is still annoying and confusing. It seems a quick workaround by avoiding using `__deref` here is more appropriate.
[Bug c++/94602] New: wrong semantic check to prvalue as decltype operand
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94602 Bug ID: 94602 Summary: wrong semantic check to prvalue as decltype operand Product: gcc Version: 9.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- Case: struct S { ~S() = delete; }; S f(); int main() { using X = decltype(f()); // #1 using Y = decltype(S{}); // #2 } #2 is wrongly rejected in C++17 mode. #1 is not ill-formed for the deleted destructor as per C++11 [dcl.type.simple]/5: > ... in the case where the operand of a decltype-specifier is a function call and the return type of the function is a class type, a special rule (5.2.2) ensures that the return type is not required to be complete (as it would be if the call appeared in a sub-expression or outside of a decltype-specifier) ... In particular, it is not necessary to allocate storage for a temporary object or to enforce the semantic constraints associated with invoking the type's destructor. ... This rule is expanded by P0135R1 for cases like #2, which is adopted in C++17. (See also P0929R2.)
[Bug libstdc++/93470] [9/10 Regression] [C++2a] std::reference_wrapper to function type is broken with Clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93470 --- Comment #4 from frankhb1989 at gmail dot com --- (In reply to Jonathan Wakely from comment #3) > (In reply to frankhb1989 from comment #2) > > Sorry, I missed to mention it only failed with `clang++ -std=c++2a` > > If you're going to claim something is broken please don't forget the most > critical piece of information. > True, I should have been mention this in the title of the bug. My mistake to leave "C++2a" but not "Clang++" and forget to rephrase it in the comment with a proper case. > GCC accepts it as an extension, which is also correct. > > You get a diagnostic with -Wsystem-headers, but not by default. Fair point. Glad to see this not depending on the compiler.
[Bug libstdc++/93470] [C++2a] std::reference_wrapper to function type is broken
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93470 --- Comment #2 from frankhb1989 at gmail dot com --- Case: #include void foo() {} int main() { std::ref(foo)(); } Sorry, I missed to mention it only failed with `clang++ -std=c++2a` (using Clang++ 9.0.1). G++ with `-std=c++2a` still accepts the code. However, it seems that Clang++ is correct here.
[Bug libstdc++/93470] New: [C++2a] std::reference_wrapper to function type is broken
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93470 Bug ID: 93470 Summary: [C++2a] std::reference_wrapper to function type is broken Product: gcc Version: 9.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- In `std::reference_wrapper::operator()` in : #if __cplusplus > 201703L static_assert(sizeof(type), "type must be complete"); #endif The static assertion is ill-formed when `type` is a function type, required by instantiation of function template specialization `std::reference_wrapper::operator()` when `T` is a function type.
[Bug c++/89640] [9 Regression] g++ chokes on lambda with __attribute__
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89640 --- Comment #9 from frankhb1989 at gmail dot com --- This seems still problematic. void test1() { []() __attribute__((noreturn)) noexcept [[]] -> int{ return 0; // Warning expected. }(); } void test2() { []() noexcept [[]] __attribute__((noreturn)) -> int{ return 0; // Warning expected. }(); } Clang++ 9 accepts test1 but not test2. (However, it issues an error instead of a warning.) Both fail in trunk G++. Are they expected work?
[Bug libstdc++/91620] std::[forward_]list::remove_if/unique should respect to DR 526
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91620 --- Comment #2 from frankhb1989 at gmail dot com --- I missed `unique` should be also affected. The fixes have been applied in libc++ in the same commit to fix `remove_if`. MSVC's current implementations are also correct, with a different implementation strategy. It uses a singly liked list for nodes pending to delete.
[Bug libstdc++/91620] [forward_]list::remove_if should respect to DR 526
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91620 --- Comment #1 from frankhb1989 at gmail dot com --- (The issue number in the case seems a typo. It is introduced in https://reviews.llvm.org/rL358534.)
[Bug c++/91620] New: [forward_]list::remove_if should respect to DR 529
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91620 Bug ID: 91620 Summary: [forward_]list::remove_if should respect to DR 529 Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- A case for std::list taken from libc++'s testsuite: #include #include #include #include using namespace std; struct PredLWG529 { PredLWG529(int i) : i_(i) {}; ~PredLWG529() { i_ = -32767; } bool operator() (const PredLWG529& p) const { return p.i_ == i_; } bool operator==(int i) const { return i == i_; } int i_; }; int main() { int a1[] = {1, 2, 1, 3, 5, 8, 11}; int a2[] = {2, 3, 5, 8, 11}; std::list c(a1, a1 + 7); c.remove_if(std::ref(c.front())); assert(c.size() == 5); for(size_t i = 0; i < c.size(); ++i) { assert(c.front() == a2[i]); c.pop_front(); } }
[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541 --- Comment #8 from frankhb1989 at gmail dot com --- (In reply to frankhb1989 from comment #5) > (In reply to Jonathan Wakely from comment #4) > > This might strictly conform to the requirements, but it's stupid. Why would > > you do that? > > > > Allocator equality doesn't care about the value type, as evidenced by the > > requirement that a==b is equivalent to a==Y::rebind::other(b). So if the > > result of == doesn't care about the value type, then why would > > is_always_equal depend on it? > > ..., and it actually throws on > comparison, then ... . > ... My bad. I should have meant that it might throw when the result of the result of == for node_allocator is `false`. This is even more stupid: `a == Y::rebind::other(b)` does not effectively imply that two values of type `Y::rebind::other` will always be equal, even that there are requirements of "reflexive, symmetric, and transitive" on "a1 == a2", consistent false negative results are not prevented because such requirements are not also forced on "a == b", so such definitions are allowed: bool operator==(const X&, const X&) noexcept { return true; } bool operator==(const Y& a1, const Y& a2) noexcept { return == } bool operator==(const X& a, const Y& b) noexcept { return a == Y::rebind::other(b); } bool operator==(const Y& b, const X& a) noexcept { return b == Y::rebind::other(a); } where `T` is the container `value_type` equivalent to `value_type` of allocator type `X` and `U` is the container node type equivalent `value_type` of allocator type `Y`.
[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541 --- Comment #6 from frankhb1989 at gmail dot com --- (In reply to frankhb1989 from comment #5) > > And the noexcept exceptions provided in the current implementations are > really inconsistent, for instance, between move operator= of std::list and > std::map. Whether the fix above is adopted, at least one container > implementation in libstdc++ is not conforming. > Correction: if the additional requirement is adopted, there will be no need to modify libstdc++ code for conformance. The inconsistency will remain literally (`_Node_alloc_traits::_S_nothrow_move()` in the std::list vs. implicit `_Alloc_traits::_S_nothrow_move() ...` implied by _Rb_tree), though.
[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541 --- Comment #5 from frankhb1989 at gmail dot com --- (In reply to Jonathan Wakely from comment #4) > This might strictly conform to the requirements, but it's stupid. Why would > you do that? > > Allocator equality doesn't care about the value type, as evidenced by the > requirement that a==b is equivalent to a==Y::rebind::other(b). So if the > result of == doesn't care about the value type, then why would > is_always_equal depend on it? Because I find no standard rules to prevent such stupid things. With such cases, the container implementations are potentially broken: if the node allocator is not is_always_true nor POCCA, and it actually throws on comparison, then the noexcept specification will cause the program terminate. This is quite counterintuitive, and I don't see this is intended anyway. Probably the easiest resolution is to add one more requirement of invariant on is_always_equal in the standard to ensure that each rebind result will keep is_always_equal unchanged. This is likely to be a DR as is_always_equal has been explicitly used as the part of noexcept specifications of containers' operator= in the standard, and I don't see the way to fix it merely for individual node-based container implementations. (Not sure traits like POCCA need the additional requirement, though.) And the noexcept exceptions provided in the current implementations are really inconsistent, for instance, between move operator= of std::list and std::map. Whether the fix above is adopted, at least one container implementation in libstdc++ is not conforming. Allocator-extended move constructors are similarly broken despite the explicit noexcept specifications required in the standard. However, if it is resolved by the fix in the standard, the implementation can remain unchanged.
[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541 --- Comment #3 from frankhb1989 at gmail dot com --- (In reply to Jonathan Wakely from comment #2) > (In reply to frankhb1989 from comment #0) > > This type does not meet the allocator requirements. For a valid allocator, > A::rebind::other must be the same type as A, and > A::rebind::other::rebind::other must also be the same type > as A. Oops, I missed those requirements. How about this? #include #include #include using P = std::pair; template struct AT { using value_type = T; template struct rebind { using other = AT; }; using is_always_equal = std::is_same; template AT(const AT&); T* allocate(std::size_t); void deallocatoe(T*, std::size_t); }; using A = AT; int main() { static_assert(std::is_same_v::other, A>); // For any U: using U = int; static_assert(std::is_same_v::other::template rebind::other, A>); using always_equal = std::allocator_traits::is_always_equal; using C = std::less<>; constexpr bool std_nothrow = always_equal::value && std::is_nothrow_move_assignable_v; static_assert(std_nothrow); static_assert(!(std_nothrow && !std::is_nothrow_move_assignable>::value)); }
[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541 --- Comment #1 from frankhb1989 at gmail dot com --- Allocator-extended constructors with explicit exception specifications may also have the value_type/node mismatch problems.
[Bug libstdc++/91541] New: [C++17] Exception specification of operator= of node-based containers may be broken
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541 Bug ID: 91541 Summary: [C++17] Exception specification of operator= of node-based containers may be broken Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- Case: #include #include #include #include struct A : std::allocator> { template struct rebind { using other = std::pmr::polymorphic_allocator; }; }; int main() { using always_equal = std::allocator_traits::is_always_equal; using C = std::less<>; constexpr bool std_nothrow = always_equal::value && std::is_nothrow_move_assignable_v; static_assert(std_nothrow); static_assert(!(std_nothrow && !std::is_nothrow_move_assignable>::value)); } The defaulted exception specification is from _Rb_tree which uses node allocator traits instead of the allocator_traits, so is_always_equal::value can differ than expected. There is a similar problem in list/forward_list::operator='s implementations: they use the node allocator_traits explicitly, not the required exception specification by the standard.
[Bug libstdc++/91531] New: _Rb_tree's copy assignment should respect to POCCA regardless of is_always_equal
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91531 Bug ID: 91531 Summary: _Rb_tree's copy assignment should respect to POCCA regardless of is_always_equal Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- In : template _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: operator=(const _Rb_tree& __x) { if (this != &__x) { // Note that _Key may be a constant type. #if __cplusplus >= 201103L if (_Alloc_traits::_S_propagate_on_copy_assign()) { auto& __this_alloc = this->_M_get_Node_allocator(); auto& __that_alloc = __x._M_get_Node_allocator(); if (!_Alloc_traits::_S_always_equal() && __this_alloc != __that_alloc) { // Replacement allocator cannot free existing storage, we need // to erase nodes first. clear(); std::__alloc_on_copy(__this_alloc, __that_alloc); } } #endif _Reuse_or_alloc_node __roan(*this); _M_impl._M_reset(); _M_impl._M_key_compare = __x._M_impl._M_key_compare; if (__x._M_root() != 0) _M_root() = _M_copy(__x, __roan); } return *this; } As `std::__alloc_on_copy` is called only when `!_Alloc_traits::_S_always_equal() && __this_alloc != __that_alloc`, so a POCCA allocator will not be propagated once it is always equal. This is also not consistent with all sequence/unordered associative standard allocator-aware containers implemented in libstdc++.
[Bug libstdc++/91480] Nonconforming definitions of standard library feature-test macros
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91480 --- Comment #4 from frankhb1989 at gmail dot com --- (In reply to Jonathan Wakely from comment #3) > (In reply to frankhb1989 from comment #0) > > Also, in , `__cpp_lib_allocator_traits_is_always_equal` is > > wrongly spelled as `__cpp_lib_allocator_is_always_equal`. > > This is incorrect. We *also* define > __cpp_lib_allocator_traits_is_always_equal, in the appropriate places. So we > have an extra, non-standard macro. We don't spell the standard one wrong. > OK, I see N4258 proposes changes both to [allocator.traits] and [default.allocator]. The macro `__cpp_lib_allocator_is_always_equal` is likely only for the latter and it's in the right header. Not a bug. The issue is remained for 'L'.
[Bug libstdc++/91480] Nonconforming definitions of standard library feature-test macros
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91480 --- Comment #2 from frankhb1989 at gmail dot com --- I agree the problem of 'L' is not likely found as a real issue in practice. Perhaps this could be forwarded as an issue of the standard which requires overspecified definitions. I don't find any intentional use cases about relying on the exactly specified type. (Despite the range limitation of int, the macro expansion results can be specified as "integer literal equal to the corresponding numerical values specified in the table" and a note about intentionally unspecified types.)
[Bug libstdc++/91480] New: Nonconforming definitions of standard library feature-test macros
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91480 Bug ID: 91480 Summary: Nonconforming definitions of standard library feature-test macros Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- These macros are lacking of the `L` suffix compared to the content of the table in [support.limits.general]. This can lead to some unexpected effects on observable behavior, e.g.: #include #include #define macro_as_string(x) #x #define stringized_length(x) std::string(macro_as_string(x)).size() int main() { std::cout << stringized_length(__cpp_lib_nonmember_container_access); } Also, in , `__cpp_lib_allocator_traits_is_always_equal` is wrongly spelled as `__cpp_lib_allocator_is_always_equal`.
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 frankhb1989 at gmail dot com changed: What|Removed |Added CC||frankhb1989 at gmail dot com --- Comment #20 from frankhb1989 at gmail dot com --- (In reply to Jonathan Wakely from comment #11) > I hate that behaviour. Having to use !__is_identifier(__builtin_launder) is > confusing (and not just to me, but to developers of LLVM's own libc++, who > I've had to explain the problem to). > > But consistency with Clang is probably more important than making > __has_builtin behave sanely. What if breaking that insane compatibility? How does it make things worse? `__has_builtin` is expected to be OK even with false negative results (but surely not false positive ones). Is there any real examples showing that relying on something like `!__has_builtin(__builtin_offsetof)` necessary for the needs in practice? Note that there is already no warranty by the standard with the use of `__`, and I don't ever find reasons that things like `int __builtin_abort = 0;` should work besides the leaked implementation details. Such abuse seems not documented at all. Even such use is eventually guaranteed to work, the extent should be justified by `__is_identifier`, with nothing to do with the `__builtin_` prefix.
[Bug c++/91127] New: Incorrect checking of nonnull attribute with argument to a constructor of class with a virtual base
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91127 Bug ID: 91127 Summary: Incorrect checking of nonnull attribute with argument to a constructor of class with a virtual base Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- Case: struct B {}; struct C : virtual B { __attribute__((nonnull(2))) C(const char*); }; a.cc:6:43: warning: 'nonnull' attribute argument value '2' refers to parameter type 'int' [-Wattributes] 6 | __attribute__((nonnull(2))) C(const char*); | ^ Removal of `virtual` makes it works. Use of `__attribute__((nonnull))` (with no argument `2`) also works. Clang++ 8 seems OK with or without `virtual`. Note it is worse in old versions of the compiler, e.g. with G++ 7.1: a.cc:6:43: error: nonnull argument references non-pointer operand (argument 1, operand 2) __attribute__((nonnull(2))) C(const char*); ^ The change in PR 87541 has made the diagnostics more explicit. Not sure whether the change from error to warning is intended, though.
[Bug c++/89640] [9 Regression] g++ chokes on lambda with __attribute__
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89640 frankhb1989 at gmail dot com changed: What|Removed |Added CC||frankhb1989 at gmail dot com --- Comment #7 from frankhb1989 at gmail dot com --- GCC 9.1 still does not work when there is a trailing-return-type: void test() { []() __attribute__((noreturn)) -> int{ return 0; // Warning expected. }(); } This looks like the same regression.
[Bug c++/90966] New: ICE in tsubst_copy, at cp/pt.c:16155
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90966 Bug ID: 90966 Summary: ICE in tsubst_copy, at cp/pt.c:16155 Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- template void f() { using S = signed char; constexpr const S v[]{0}; } int main() { f(); } a.cc: In instantiation of 'void f() [with I = int]': a.cc:10:9: required from here a.cc:5:20: internal compiler error: in tsubst_copy, at cp/pt.c:16155 5 | constexpr const S v[]{0}; |^
[Bug c++/87742] [7/8/9 Regression] false warning: array subscript 3 is above array bounds of 'const std::type_info* const [3]'
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87742 frankhb1989 at gmail dot com changed: What|Removed |Added CC||frankhb1989 at gmail dot com --- Comment #6 from frankhb1989 at gmail dot com --- struct G { template operator X() const { return *this; } } g; void w(unsigned o) { extern int b[3]; void k(int); switch (static_cast(o)) case 2: { o != 2 ? nullptr : g; k(b[o]); } } The indeterminately recursive case is still certainly false positive, as there is no rule rendering the behavior undefined, and the assertion in the message can be logically inconsistent with the fact (when the condition value is unsigned 2); it is definitely confusing. At least the wording can be improved (e.g. replace "is" to "may be"). In this case, it should ideally warn on the infinite recursion itself, rather than the subsequent caller site. Besides, the discarded-value expression here can be totally optimized away before to reason whether the call is infinitely recursive (though it may be difficult for specific optimizing implementations).
[Bug c++/41958] [c++0x] bogus variadic partial ordering code
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41958 frankhb1989 at gmail dot com changed: What|Removed |Added CC||frankhb1989 at gmail dot com --- Comment #10 from frankhb1989 at gmail dot com --- The example from IS [temp.func.order]/5 (introduced by http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3281.pdf) still fails. As per https://godbolt.org/z/6wq5Hx (from https://www.zhihu.com/question/55055208/answer/142424499), 4.6.4 is OK, but 4.7.1 is nonconforming. Not sure which change cause the behavior divergence; please confirm. (BTW, the original issue asked in the post is about PR 33807. It seems innocent. MSVC 15.8.2 does not have the operator== for allocator; not sure it is correct, but MSVC does reject the example in this issue correctly. Nevertheless, I wonder the status of LWG 2472 and whether the resolution of LWG 280 have some related effects.)
[Bug libstdc++/86954] redundant nothrow in call of ::operator delete
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86954 --- Comment #4 from frankhb1989 at gmail dot com --- Well, actually I'm not sure if the original implementation has done the right thing, as I don't find that the standard has requirement to specify that the replaced definitions must acknowledge the fact nothrow_t overloads should only be called on the specified condition (... and if so, whether it worth an LWG issue). But that still seems suspicious to me, because symmetry of call between nothrow_t placement ::operator new and ::operator delete does not exist in the language indeed, so that seems like an unintentional use unless it is documented elsewhere. On the other hand, the change here towards to a simpler and undoubtedly conformant way. BTW, I do know the feature is deprecated in C++17 and removed in C++2a. I read the paper of deprecation. It is plausible to be removed from the standard, but not a must - not with a very strong reason. However, I am sure I do need that feature so I have to reinvent my wheels... as done internally by various standard library implementations. (More specifically, I need std::_Temporary_buffer in libstdc++ and MSVC's current implementation, or at least something equivalent to std::__return_temporary_buffer in libc++, but surely I can't rely on them directly.) At least a raw call of allocation function does not always express the intended call site requirements clearly like std::get_temporary_buffer, so users who want to make it clear have to afford the extra layer of an abstraction. Arguably, the removal will bloat work for anyone wants that and discourage clearer expression of intentions.
[Bug libstdc++/86954] New: redundant nothrow in call of ::operator delete
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86954 Bug ID: 86954 Summary: redundant nothrow in call of ::operator delete Product: gcc Version: 8.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- In the current implementation std::return_temporary_buffer, ::operator delete is called with std::nothrow as 2nd argument. (It seems here is the only occurrence of such ::operator delete call in libstdc++). This seems unintentional. Normally the std::nothrow argument should not exist here. This should make no difference to intentional behavior when the allocation and deallocation functions are not replaced due to the default behavior. However, since the nothrow_t overloads are called by implementation on exceptions during the call of operator new, and the overloads can be replaceable as per [new.delete.single], this may lead to surprise result with reasonable use, e.g. when user expect to have different log messages in different replaced overloads of ::operator delete.
[Bug libstdc++/86734] New: [DR 2188] reverse_iterator::operator-> does not support overloaded operator
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86734 Bug ID: 86734 Summary: [DR 2188] reverse_iterator::operator-> does not support overloaded operator& Product: gcc Version: 8.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- Since this had been adopted by N3936, it should at least be in C++14 & C++17 modes. Note this is also in libc++ in all modes. Resolution from LWG 2775 seems to be adopted MSVC++ 15.7 but I don't find it in the current draft. BTW, the comment on reverse_iterator's default constructor is outdated. It took me half an hour to find LWG 1012 :(
[Bug libstdc++/80284] Support of associative containers with incomplete element type
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80284 frankhb1989 at gmail dot com changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID --- Comment #2 from frankhb1989 at gmail dot com --- Glad to see the clarification and the decision (though the author of N4510 told me that libstdc++ did have some considerations on the feature). And I realized it would also not even work for `vector`. I'm OK to also rule such cases out of support in the standard library; however, I did not find the rule in the standard. Now the question should better go to std-discussion, not remains here. So closed.
[Bug c++/80284] New: Support of associative containers with incomplete element type
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80284 Bug ID: 80284 Summary: Support of associative containers with incomplete element type Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.201z shows that "the feature" of N4510 (except the feature-test macro) has been supported long ago from 3.0. It is not very clear whether "the feature" is applicable on other containers not currently required by the proposed (and accepted by the working draft) rules of N4510 yet. I don't find the answer in the documentation, but I still tend to guess other containers can work in libstdc++, for several reasons: 1. N4510 mentions associative/unordered containers as well. It just not ready to require it for all implementations. 2. N4510 mentions boost.containers in parallel, which clearly states the support of incomplete element types for other containers in its documentation. 3. They (from libstdc++) can actually work as expected (at least for naive cases). The real problem raises when I meet some not-so-naive cases. Test case: #include #include using namespace std; struct node { using container_t = map<string, node>; string name; container_t container; node(const string& n) : container(), name(n) {} node(container_t&& con, const string& s) : container(move(con)), name(s) {} void swap(node& nd) noexcept { name.swap(nd.name); container.swap(nd.container); } }; int main() { node n(node::container_t{{"a", node("a")}}, "A"); n.swap(n.container.begin()->second); } Despite the undefined behavior caused by incomplete template argument as per the standard, it seems well-formed. However, it leaks. I've reproduced it on GCC 5.3 + DrMemory on Windows/GCC 6.3.1 + valgrind on Linux. It can also reproduced with clang++ instead of g++. Is it intended by design?
[Bug middle-end/17308] nonnull attribute not as useful as it could
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=17308 frankhb1989 at gmail dot com changed: What|Removed |Added CC||frankhb1989 at gmail dot com --- Comment #13 from frankhb1989 at gmail dot com --- It should be noted that current implementation is conflict with assertions in some cases, as in https://lists.fedoraproject.org/archives/list/de...@lists.fedoraproject.org/thread/VA2QCXJGXVLH43327TRR5UM2BP52DWIC/. The purpose of such an attribute is not emphasized in the documentation, which leads to the confusion. I'm actually not against the semantics it implies, but I find the warning actually reduce its availability for other reasons. Note `assert` is required to be supported by the standard, so it will work across different implementations, including those do not support `__attribute__` at all. To get the code portable, the attributes will always be wrapped in macros whose names are not reserved identifiers. It should be natural that by conditionally defining such macros as nothing, each configuration of every implementation would be happy eventually, because modifying assertions everywhere in current code (instead modifying the macros) is obviously infeasible in general. A question is, when to disable the attribute? For debug build configurations (with `NDEBUG` undefined), it has almost no side effect by conditional definition based on some conditions (like `NDEBUG`), except one: the conditions may have to be duplicated in #ifdef/#if in different places of the code. It is still not a big trouble for `assert` normally, but it can be a disaster for custom assertion macros when the conditions are complicated enough. And though rarely, it can be a nightmare after the condition macros are defined (after necessary #undef) more than once, by different authors of the code. For release configurations (such as builds with properly defined `NDEBUG`), the problem is more serious. Since the attribute is designed as a hint of optimization, it should not be defined as nothing besides debugging. But to modify all occurrence of assertions is still even more absurd, whether they will generate code or not. So there is a dilemma: which one to keep, the assertions or the attribute? Removing the assertions is infeasible; unconditionally disabling the attribute is illogical (and totally nonsense for old versions of GCC which I need to adapt to). And clearly, I don't want to maintain multiple copies of the code just for different build configurations; I definitely need both of them in such cases. Thus either choice is essentially bad. The final workaround (*not the fix*) is to disable the warning itself, which is configuration-neutral and it should does work at least as old versions of GCC. However, old compiler drivers do not recognize such options. To maintain the divergence in build scripts is dirty. So it should better be... pragmas? The last problem: #pragma or _Pragma to disable such diagnostics does not work. Is it a bug, or unsupported at all?
[Bug libstdc++/66339] g++ 5.1.0 Generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66339 --- Comment #12 from frankhb1989 at gmail dot com --- (In reply to Jonathan Wakely from comment #10) > This behaviour is by design and is not a bug. Valgrind no longer shows the > allocation as reachable. Other tools might still show the memory as unfreed, > but it's still not a bug. Clarification of "by design" is good. Better put some note elsewhere, maybe. (In reply to Jonathan Wakely from comment #11) > (In reply to frankhb1989 from comment #9) > > Following your narrow definition of "leak", it implies that any system using > > GC could never leak. That's absurd. > > Wikipedia: "a memory leak is a type of resource leak that occurs when a > computer program incorrectly manages memory allocations in such a way that > memory which is no longer needed is not released." > > This memory is still needed up until exit. > > Google: "a failure in a program to release discarded memory, causing > impaired performance or failure." > > This is not discarded memory, and does not impair performance or cause > failure. > > MSDN: "When an application dynamically allocates memory, and does not free > that memory when it is finished using it, that program has a memory leak." > > The memory is in use right until exit, so the application hasn't finished > using it. > > > > A leak of resource may occur when the client (either the code of the > > application or the underlying runtime responsible to deal with the allocated > > resource) has lost the control of the lifetime of that resource. > > The runtime hasn't lost control of it. > > > If that > > resource is not needed and there is no other way to transfer the ownership, > > it is leaked. > > It's still needed. > > > Still reachable memory can be leaked, depends on the > > intention. Sometimes the leak detector has no clue to figure out whether the > > memory should be still here or not, but we humans have, though it may be > > arguable. > > > > The situation necessitating "exit()" to cleanup almost always meets the > > condition of leak above. This is feasible only when the users can rely on > > the fact that the hosting environment will cleanup the (already leaked) > > resources of that program (likely in some magical ways unrelated to the > > program itself). This is not portable in general. > > We're not talking about arbitrary resources in the general case, we're > talking about heap memory in the GNU C++ runtime. That memory is freed on > exit. If you want to waffle about it further please take it somewhere else. > > > > (And abuse of exit() will > > easily cause other problems.) I don't see "most" programs do that seriously > > because it is not easy to guarantee the behavior predictable. I'm not sure if you are talking about the general cases here. In general, attributing leaks to unreachable resources despite the need, is nonsense; as my previous reply. For this issue, you are correct that GNU C++ runtime does not "cause impaired performance or failure". I just know the memory "is still needed" (by the runtime) by design. Fine. It can still be a QoI issue for user programs because when don't need it (as the original case), though.
[Bug libstdc++/66339] g++ 5.1.0 Generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66339 --- Comment #9 from frankhb1989 at gmail dot com --- (In reply to Andrew Pinski from comment #8) > (In reply to frankhb1989 from comment #7) > > This is definitely a leak from the view of libc. Why is the status INVALID > > instead of WONTFIX? > > It is still reachable. Since it is reachable, a pointer at deconstructor > time could use it. This pool is used to low memory situations. And can be > used even near exit. There is no leak; a leak means it is no longer > reachable. > Most programs will not free some of their memory at the end of their program > anyways; they would just call exit. Following your narrow definition of "leak", it implies that any system using GC could never leak. That's absurd. A leak of resource may occur when the client (either the code of the application or the underlying runtime responsible to deal with the allocated resource) has lost the control of the lifetime of that resource. If that resource is not needed and there is no other way to transfer the ownership, it is leaked. Still reachable memory can be leaked, depends on the intention. Sometimes the leak detector has no clue to figure out whether the memory should be still here or not, but we humans have, though it may be arguable. The situation necessitating "exit()" to cleanup almost always meets the condition of leak above. This is feasible only when the users can rely on the fact that the hosting environment will cleanup the (already leaked) resources of that program (likely in some magical ways unrelated to the program itself). This is not portable in general. (And abuse of exit() will easily cause other problems.) I don't see "most" programs do that seriously because it is not easy to guarantee the behavior predictable.
[Bug libstdc++/71444] New: Error code on MinGW-w64
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71444 Bug ID: 71444 Summary: Error code on MinGW-w64 Product: gcc Version: 5.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- Several enumerators are commented out in for MinGW-w64. However, I find several macros are actually usable in in the distribution (MSYS2) I am using, as: /* Defined as WSAETIMEDOUT. */ #ifndef ETIMEDOUT #define ETIMEDOUT 138 #endif #ifndef ELOOP #define ELOOP 114 #endif #ifndef EPROTOTYPE #define EPROTOTYPE 136 #endif #ifndef EOVERFLOW #define EOVERFLOW 132 #endif Can they be configured automatically?
[Bug c++/70480] New: Reduce RTTI code bloat for specified types
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70480 Bug ID: 70480 Summary: Reduce RTTI code bloat for specified types Product: gcc Version: unknown Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- There are cases that certain type info symbols are not needed, e.g. a class as operand of 'typeid' which has multiple Boost.Operators bases. These base classes are essentially insignificant in the class hierarchy when the program is running, and no sane users would play them with 'dynamic_cast'/'typeid' or handling them in 'catch' clauses. So it is unnecessary to emit type info for these types. However, I find no way to suppress the bloated symbol generation for them separately, even if these bases themselves are not operands of 'typeid'. (Note I do want RTTI elsewhere in the same translation units, so '-fno-rtti' does not work.) LTO also fails to optimize them away. Can there be some attributes on the class-definitions or base-specifiers tweaking the behavior here? With such attributes the compiler can also warn about unintended use.
[Bug c++/66339] g++ 5.1.0 Generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66339 frankhb1989 at gmail dot com changed: What|Removed |Added CC||frankhb1989 at gmail dot com --- Comment #7 from frankhb1989 at gmail dot com --- This is definitely a leak from the view of libc. Why is the status INVALID instead of WONTFIX?
[Bug c++/67795] Wrong code generated for conditional expression with cast
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67795 --- Comment #3 from frankhb1989 at gmail dot com --- (In reply to Markus Trippelsdorf from comment #1) > gcc even warns: > > t.cpp: In function ‘std::experimental::fundamentals_v1::string_view& > erase_left(size_t, std::experimental::fundamentals_v1::string_view&)’: > t.cpp:9:73: warning: function returns address of local variable > [-Wreturn-local-addr] >return static_cast(n != 0 ? (s.remove_prefix(n), s) : s); > ^ And if the diagnostics exist, they are definitely wrong. First, here 's' is a local variable (in sense of C++ terms) indeed, but this is perfectly valid. Note it is a _parameter_ referencing to an object whose lifetime is unknown in the function/block scopes. This should not trigger such warnings. Otherwise the identity functions for pointers/references are always invalid. That's absurd. Second, the "local variable" wording is somewhat misleading. Returning reference to a local variable is generally wrong because the variable is an _automatic object_ and it would be no sense to use the return value to reference an end-of-life object which would cause undefined behavior. Anyway, this is just not the case here.
[Bug c++/67795] Wrong code generated for conditional expression with cast
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67795 frankhb1989 at gmail dot com changed: What|Removed |Added Version|unknown |5.2.0 --- Comment #6 from frankhb1989 at gmail dot com --- I forgot mentioning the versions I used ... g++ -v gcc version 5.2.0 (Rev3, Built by MSYS2 project) clang++ -v clang version 3.7.0 (tags/RELEASE_370/final)
[Bug c++/67795] Wrong code generated for conditional expression with cast
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67795 --- Comment #8 from frankhb1989 at gmail dot com --- (In reply to Markus Trippelsdorf from comment #4) > Return by value if you want to avoid undefined behavior. No. This is not the point. For something like 'std::move' or 'std::forward', can you suggest such change? The code of the case is reduced from a function template which return 'S&&', where 'S' is a template type parameter (and 'S&&' is also in function parameter list for perfect forwarding). Simply returning object type is not acceptable in the original case because: 1. Even move construction for 'S' is not guaranteed to be zero overhead. 2.It needs one more static_cast/std::move in many places of the the client code which makes it bloat A LOT.
[Bug c++/67795] Wrong code generated for conditional expression with cast
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67795 --- Comment #9 from frankhb1989 at gmail dot com --- (In reply to Richard Biener from comment #5) > I would guess the issue is that ?: returns an rvalue (but that may not be > 100% correct if omitting the cast works and does not warn) In C++ ?: can return lvalues. I have tried inserting 'static_assert(std::is_same<string_view&, decltype(..)>);' in the function and it does not complain.
[Bug c++/67795] New: Wrong code generated for conditional expression with cast
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67795 Bug ID: 67795 Summary: Wrong code generated for conditional expression with cast Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- Case: // g++ -std=c++1y #include #include #include using namespace std; using namespace experimental; string_view& erase_left(size_t n, string_view& s) { return static_cast<string_view&>(n != 0 ? (s.remove_prefix(n), s) : s); // return n != 0 ? (s.remove_prefix(n), s) : s; } int main() { string_view sv("abcde"); cout << erase_left(3, sv).to_string() << endl; // expected "de" } The output is garbage, using i686-w64-mingw32-g++ from MSYS2. However, x86_64-w64-mingw32-clang++ is OK. So I suspect it is a frontend bug.
[Bug c++/67795] Wrong code generated for conditional expression with cast
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67795 frankhb1989 at gmail dot com changed: What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|INVALID |--- --- Comment #2 from frankhb1989 at gmail dot com --- (In reply to Markus Trippelsdorf from comment #1) > gcc even warns: > > t.cpp: In function ‘std::experimental::fundamentals_v1::string_view& > erase_left(size_t, std::experimental::fundamentals_v1::string_view&)’: > t.cpp:9:73: warning: function returns address of local variable > [-Wreturn-local-addr] >return static_cast(n != 0 ? (s.remove_prefix(n), s) : s); > ^ So why it is OK without 'static_cast'? And actually G++ gives me no warnings with -Wall -Wextra -pedantic-errors.
[Bug c++/67795] Wrong code generated for conditional expression with cast
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67795 --- Comment #10 from frankhb1989 at gmail dot com --- (In reply to Marc Glisse from comment #7) > Hmm, with the static_cast, the front-end produces: > > < = (struct string_view &) (struct string_view > *) NON_LVALUE_EXPR <(struct string_view &) &(n != 0 ? > std::experimental::fundamentals_v1::basic_string_view::remove_prefix > ((struct string_view *) s, n);, *s; : *s)>>>; > > while without it, I get: > > < = (struct string_view &) (n != 0 ? > std::experimental::fundamentals_v1::basic_string_view::remove_prefix > ((struct string_view *) s, n);, (struct string_view *) s; : (struct > string_view *) s)>>; > > I also find it fishy. > > (note that you need -O2 or more for the warning) Thank you for the suggestion. I find these diagnostics exist with -O2 or -O3. Then the output is empty ... clang++ -Weverything with -O2/-O3 still behaves as I expect. (Only [-Wmissing-prototypes].)
[Bug c/67661] Wrong warning when declare VLAs: operation on 'x' may be undefined [-Wsequence-point]
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67661 frankhb1989 at gmail dot com changed: What|Removed |Added CC||frankhb1989 at gmail dot com --- Comment #5 from frankhb1989 at gmail dot com --- "%d" in the case should be replaced by "%zu". Confirmed that clang 3.7 does not complain about it.
[Bug c/39121] strange behavior in chained operations
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39121 frankhb1989 at gmail dot com changed: What|Removed |Added CC||frankhb1989 at gmail dot com --- Comment #9 from frankhb1989 at gmail dot com --- This should work since C++11 because the rules of builtin assignment were modified (CWG 222; see also CWG 637). However, it is still undefined in C11, even if the new sequenced before wording has been copied from C++11 (WG21/N1944). Not sure if any diagnostics should be changed.
[Bug c++/65890] [C++03]sizeof(qualified-id) accepted when the operand denotes a non-static member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65890 --- Comment #7 from frankhb1989 at gmail dot com --- (In reply to Jonathan Wakely from comment #6) (In reply to frankhb1989 from comment #5) Mainly for testing of the conformance. I don't understand what this means. Testing what? G++? G++ does not exist for you to test its conformance to a standard. Most users don't care about slavish conformance to a defective specification, they want a useful compiler. Ok, since there is no strictly conforming program concept in ISO C++ as it in ISO C, I'd better to clarify, the direct point is portability of the legacy user code. Checking and ensuring the code (carefully kept undefined behavior or no diagnostics required away) to be standard-compliant is one aspect of usefulness of the compiler which provides standard modes. How can I do if 'g++ -std=c++03 -pedantic-errors' behaves different than other C++03-conforming compilers compiling the ill-formed C++03 code, besides to drop the code away? Although it is treated a defect of the design and has been changed later, the old rules are still well-defined and the published standard itself is consistent. So if I did not get wrong about the purpose of '-std=', this should be a bug. Whether it is worth being fixed is another problem. You are wrong about how -std options work. We incorporate dozens of DRs into all modes, instead of making them only apply to later standard modes. The manual says nothing about this. It tells me to obtain all the diagnostics required by the standard, you should also specify -pedantic (or -pedantic-errors if you want them to be errors rather than warnings). I thought the standard here is one of the published ones. And there seems to be no separate options to control the features in individual DRs. If the compiler frontend does right (by design) as you said, this is a documentation issue, since I am really confused about what g++ are allowed to do. Now it seems I'd better simply not rely on these -std options of g++ for these works. On the other hand, I'd debate the resolution of this CWG issue is not pure improvement. There could be a trick to distinguish static and non-static data members through SFINAE on expressions like 'sizeof((C::x))'. It is broken now. SFINAE in C++03 was not nearly as useful, and doesn't work for private members. The language is more useful now, there is no reason to hobble it with a foolish consistency to a defective design. Yes, it is obviously not so useful as C++11/14/1z. But can we just get rid of C++98/03 totally for this reason? For this issue, the (current) result is, 'g++ -std=c++03 -pedantic-errors' actually implements a dialect of C++03 with some subtle patches in the standard, which is difficult in many aspects even to experienced users. And even this is a resolved defect, the design of these related features in the language is still arguably more or less defective. The latter is nothing to do with g++ directly, though.
[Bug c++/65890] [C++03]sizeof(qualified-id) accepted when the operand denotes a non-static member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65890 --- Comment #5 from frankhb1989 at gmail dot com --- (In reply to Jonathan Wakely from comment #3) This was changed by http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#613 It was a defect in the original standard. What possible advantage is there in rejecting it in C++03 mode but accepting it in C++11 mode? i.e. why do you consider this a bug? Mainly for testing of the conformance. Although it is treated a defect of the design and has been changed later, the old rules are still well-defined and the published standard itself is consistent. So if I did not get wrong about the purpose of '-std=', this should be a bug. Whether it is worth being fixed is another problem. On the other hand, I'd debate the resolution of this CWG issue is not pure improvement. There could be a trick to distinguish static and non-static data members through SFINAE on expressions like 'sizeof((C::x))'. It is broken now.
[Bug c++/65890] New: [C++03]sizeof(qualified-id) accepted when the operand denotes a non-static member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65890 Bug ID: 65890 Summary: [C++03]sizeof(qualified-id) accepted when the operand denotes a non-static member Product: gcc Version: 4.9.1 Status: UNCONFIRMED Severity: minor Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Target Milestone: --- Case: struct Tag { int m; }; int main() { sizeof((Tag::m)); } According to ISO C++03 5.1/10, this is not well-formed. (But C++11 should work.) However, G++ 4.9.1 wrongly accepted it even with -std=c++03 -pedantic-errors. (I have no GCC 5 distro so have not tested it.)
[Bug c++/65890] [C++03]sizeof(qualified-id) accepted when the operand denotes a non-static member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65890 --- Comment #2 from frankhb1989 at gmail dot com --- Tested here: http://melpon.org/wandbox/, both G++ 5.1 and 6.0 accepted the invalid code.
[Bug c++/65890] [C++03]sizeof(qualified-id) accepted when the operand denotes a non-static member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65890 --- Comment #1 from frankhb1989 at gmail dot com --- Oops, wrong version of case pasted ... I once wanted to use this minimal one: sizeof(Tag::m); Nevertheless, the conclusion is the same for this issue. (There are other mess, e.g. Clang++ 3.6 wrongly interpret 'decltype((Tag::m))' as pointer to member but I think G++ is right here).
[Bug c++/65748] [C++11][C++14]Invalid copy elision on operand of throw-exception
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65748 --- Comment #1 from frankhb1989 at gmail dot com --- G++ 5 also seems to fail. Recent Clang++ is OK.
[Bug c++/65748] New: [C++11][C++14]Invalid copy elision on operand of throw-exception
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65748 Bug ID: 65748 Summary: [C++11][C++14]Invalid copy elision on operand of throw-exception Product: gcc Version: 4.9.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Case: struct E { E() = default; E(const E) = delete; E(E) = default; }; int main() { E e; try { // E e; // Not here. throw e; } catch(...) {} } No diagnostics with g++ -std=c++14 -pedantic -Wall -Wextra. Same to -std=c++11. It seems the move constructor is selected according to 12.8/32, which depends on copy elision. However, both ISO C++11 and C++14 forbid copy elision in this case, i.e. for operand of throw-expression, it may be elided only when: whose scope does not extend beyond the end of the innermost enclosing try-block (if there is one) as per 12.8/31.2.
[Bug libstdc++/65343] unexpected exception thrown during destruction of static object in debug mode
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65343 --- Comment #2 from frankhb1989 at gmail dot com --- (In reply to Jonathan Wakely from comment #1) Maybe we want to placement-new the mutexes into a buffer so they are never destroyed, although on mingw that will show up as leaked resources at program shutdown (and this is only really a problem on mingw as we don't need to run any destructor on the mutexes for most targets). This could be an acceptable workaround for MinGW, but I am not sure if there would be some unexpected side effects. For other targets in future, this can still be a problem.
[Bug libstdc++/65343] New: unexpected exception thrown during destruction of static object in debug mode
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65343 Bug ID: 65343 Summary: unexpected exception thrown during destruction of static object in debug mode Product: gcc Version: 4.9.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Recently I found one of my program unexpected aborted by unhandled exception. The program is compliled with '-std=c++11 -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC'. The corresponding release build (i.e. no -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC) does not behave like this. GDB tells me there is something wrong happened during destruction of some global container objects: #2 0x00454b09 in __cxxabiv1::__terminate(void (*)()) () #3 0x00635d99 in __cxa_call_terminate () #4 0x006366df in __gxx_personality_v0 () #5 0x6e952cd2 in ?? () from F:\msys\mingw\bin\libgcc_s_dw2-1.dll #6 0x6e95332b in ?? () from F:\msys\mingw\bin\libgcc_s_dw2-1.dll #7 0x00636435 in __cxa_throw () #8 0x005021ea in __gnu_cxx::__throw_concurrence_lock_error () at F:/msys/mingw/include/c++/4.9.1/ext/concurrence.h:102 #9 0x00470a15 in __gnu_debug::_Safe_sequence_base::_M_detach_all() () I searched the source of libstdc++, then I found, in C++11/debug.cc, there were mutexes used by the debug mode containers, which was some static __gnu_cxx::__mutex objects. This was probably the direct reason: the order destruction of static objects among translation units are unspecified, so the mutexes could be destroyed before the sequences contained by some other static objects (certainly in different translation units). Then, during the desturction of the sequence, _M_detach_all was called. In that function, __gnu_cxx::__scoped_lock sentry(_M_get_mutex()); tried using the (already destroyed) mutex to lock the resources, which failed and threw. Since the documentation says, all functional and exception-handling guarantees made by the normal library also hold for the debug mode library, with one exception: performance guarantees made by the normal library may not hold in the debug mode library, and ISO C++ effectively forbids destructors in standard library to throw, this should be a bug.
[Bug libstdc++/58938] [4.7/4.8/4.9 Regression] std::exception_ptr is missing on architectures with incomplete atomic int support
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58938 frankhb1989 at gmail dot com changed: What|Removed |Added CC||frankhb1989 at gmail dot com --- Comment #11 from frankhb1989 at gmail dot com --- I'd like to say it should be a bug, if I did not get it wrong. Even for a freestanding implementation, ISO C++11 explicitly specified exception as one of required header in table 16, and it should meet the same requirements as for a hosted implementation. Missing exception propagation is definitely not conforming, whether it can actually be implemented or not. Moreover, the standard doesn't specify anything about atomic operations on exception propagation, though it does requires that there should be no data race during some operations. Atomic operations here seem to be purely implementation details. Can it be implemented with something like __shared_ptr's lock policy? This issue also has effect on nested exceptions. Anyway, I feel something indeed wrong when I have to miss std::nested_exception for this reason on a platform which has even no multithreading support at all (as allowed by C++11). Sigh. BTW, libstdc++ manual Table 1.2 just tell me 'Y' for 18.8.5 and 18.8.6. Found no other notes about this issue. So at least it can be a defect of documentation.
[Bug libstdc++/63400] [C++11]precision of std::chrono::high_resolution_clock
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63400 --- Comment #2 from frankhb1989 at gmail dot com --- (In reply to Jonathan Wakely from comment #1) Which of macros are defined on mingw-w64? Preprocessing this should tell you #include chrono #ifdef _GLIBCXX_USE_CLOCK_REALTIME #ifdef _GLIBCXX_USE_CLOCK_GETTIME_SYSCALL #warning system_clock using syscall(SYS_clock_gettime, CLOCK_REALTIME, tp); #else #warning system_clock using clock_gettime(CLOCK_REALTIME, tp); #endif #elif defined(_GLIBCXX_USE_GETTIMEOFDAY) #warning system_clock using gettimeofday(tv, 0); #else #warning system_clock using std::time(0); #endif #ifdef _GLIBCXX_USE_CLOCK_MONOTONIC #ifdef _GLIBCXX_USE_CLOCK_GETTIME_SYSCALL #warning steady_clock using syscall(SYS_clock_gettime, CLOCK_MONOTONIC, tp); #else #warning steady_clock using clock_gettime(CLOCK_MONOTONIC, tp); #endif #else #warning steady_clock using time_point(system_clock::now().time_since_epoch()); #endif I've looked into c++config.h and I'm sure mingw-w64 4.9.1 distro of msys2 uses clock_gettime defined in winpthreads: /* Defined if clock_gettime syscall has monotonic and realtime clock support. */ /* #undef _GLIBCXX_USE_CLOCK_GETTIME_SYSCALL */ /* Defined if clock_gettime has monotonic clock support. */ #define _GLIBCXX_USE_CLOCK_MONOTONIC 1 /* Defined if clock_gettime has realtime clock support. */ #define _GLIBCXX_USE_CLOCK_REALTIME 1 /* Defined if gettimeofday is available. */ #define _GLIBCXX_USE_GETTIMEOFDAY 1 Here is the output (g++ -std=c++11): a.cc:7:2: warning: #warning system_clock using clock_gettime(CLOCK_REALTIME, tp); [-Wcpp] #warning system_clock using clock_gettime(CLOCK_REALTIME, tp); ^ a.cc:19:2: warning: #warning steady_clock using clock_gettime(CLOCK_MONOTONIC, tp); [-Wcpp] #warning steady_clock using clock_gettime(CLOCK_MONOTONIC, tp); ^
[Bug libstdc++/63400] [C++11]precision of std::chrono::high_resolution_clock
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63400 --- Comment #4 from frankhb1989 at gmail dot com --- (In reply to Jonathan Wakely from comment #3) What libstdc++ is doing is sensible, why is the realtime clock so much coarser than the monotonic clock on mingw-w64? It is not always true that the real time clock would have a higher resolution than monotonic clock. At least I found nothing about resolution guaranteed by POSIX, in fact, clock resolutions are implementation-defined. With mingw-w64, the following program shows that the monotonic clock is far more precise: #include pthread_time.h #include iostream int main() { using namespace std; timespec ts; if(clock_getres(CLOCK_REALTIME, ts) == 0) cout CLOCK_REALTIME: ts.tv_sec ',' ts.tv_nsec endl; if(clock_getres(CLOCK_MONOTONIC, ts) == 0) cout CLOCK_MONOTONIC: ts.tv_sec ',' ts.tv_nsec endl; } The result on my machine: CLOCK_REALTIME: 0,15625000 CLOCK_MONOTONIC: 0,489 I then found the actual implementation in winpthreads (clock.c): int clock_gettime(clockid_t clock_id, struct timespec *tp) { unsigned __int64 t; LARGE_INTEGER pf, pc; union { unsigned __int64 u64; FILETIME ft; } ct, et, kt, ut; switch(clock_id) { case CLOCK_REALTIME: { GetSystemTimeAsFileTime(ct.ft); t = ct.u64 - DELTA_EPOCH_IN_100NS; tp-tv_sec = t / POW10_7; tp-tv_nsec = ((int) (t % POW10_7)) * 100; return 0; } case CLOCK_MONOTONIC: { if (QueryPerformanceFrequency(pf) == 0) return lc_set_errno(EINVAL); if (QueryPerformanceCounter(pc) == 0) return lc_set_errno(EINVAL); tp-tv_sec = pc.QuadPart / pf.QuadPart; tp-tv_nsec = (int) (((pc.QuadPart % pf.QuadPart) * POW10_9 + (pf.QuadPart 1)) / pf.QuadPart); if (tp-tv_nsec = POW10_9) { tp-tv_sec ++; tp-tv_nsec -= POW10_9; } return 0; } case CLOCK_PROCESS_CPUTIME_ID: { if(0 == GetProcessTimes(GetCurrentProcess(), ct.ft, et.ft, kt.ft, ut.ft)) return lc_set_errno(EINVAL); t = kt.u64 + ut.u64; tp-tv_sec = t / POW10_7; tp-tv_nsec = ((int) (t % POW10_7)) * 100; return 0; } case CLOCK_THREAD_CPUTIME_ID: { if(0 == GetThreadTimes(GetCurrentThread(), ct.ft, et.ft, kt.ft, ut.ft)) return lc_set_errno(EINVAL); t = kt.u64 + ut.u64; tp-tv_sec = t / POW10_7; tp-tv_nsec = ((int) (t % POW10_7)) * 100; return 0; } default: break; } return lc_set_errno(EINVAL); } For CLOCK_REALTIME, the Windows API GetSystemTimeAsFileTime is used. GetSystemTimePreciseAsFileTime is an improved version which provide the highest possible level of precision (1us). Unfortunately, the latter is only available since Windows 8/Windows 2012, which is not suited for winpthreads for compatibility reason IMO. See this MSDN page for details: http://msdn.microsoft.com/en-us/library/windows/desktop/hh706895(v=vs.85).aspx For CLOCK_MONOTONIC, QPC(Query Performance Counter) APIs are used. This method is reasonably portable (among different versions of Windows, since Windows 2000), and Microsoft strongly suggested it when high-resolution time stamps needed, see http://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx. However, QPC is not suited for a system-wide clock.
[Bug libstdc++/63400] [C++11]precision of std::chrono::high_resolution_clock
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63400 --- Comment #5 from frankhb1989 at gmail dot com --- BTW, what if the clock_gettime call failed? The current implementation does nothing about error handling... (Though for QPC on Windows it should rarely fail for machines within a decade.)
[Bug libstdc++/63400] New: [C++11]precision of std::high_resolution_clock
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63400 Bug ID: 63400 Summary: [C++11]precision of std::high_resolution_clock Product: gcc Version: 4.9.1 Status: UNCONFIRMED Severity: minor Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com ISO C++ specifies high_resolution_clock represent clocks with the shortest tick period. The comment in chrono also says it is with the shortest tick period. However, the current implementation in chrono simply treats high_resolution_clock as an alias of system_clock, which does not actually meet it well in some platforms like MinGW-W64 and leads to strange problem. For example, the following program (copied and modified a little from http://sourceforge.net/p/mingw-w64/mailman/message/31672495/) does not work well using MSYS2 G++ 4.9.1: int main() { for (unsigned long long size = 1; size 1000; size *= 10) { auto start = std::chrono::high_resolution_clock::now(); std::vectorint v(size, 42); auto end = std::chrono::high_resolution_clock::now(); auto elapsed = end - start; std::cout size : elapsed.count() '\n'; } } If 'high_resolution_clock' is changed back to 'steady_clock' as the original one, it performs significantly better. This is indeed misleading for users who have not dig deeply into the implementation details. The workaround for client code is straightforward: just use a new alias to wrap and to replace the current 'std::high_resolution_clock'. But only libstdc++ can fix it, e.g. use some templated black magic to detect which clock is preferred for high resolution, or at least make it configurable for specific targets. Note: 1. The original program *did not* have this problem when using G++ 4.7.x (before the inline namespace std::chrono::_V2 introduced in libstdc++), because 'steady_clock' was then a buggy alias of 'system_clock', so both were *equally* badly implemented on MinGW-W64. 2. The suggested fix may have impact on current implementation, e.g. PR 54562.
[Bug c++/61019] New: ICE: incomplete type of class template as pseudo-destructor-name
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61019 Bug ID: 61019 Summary: ICE: incomplete type of class template as pseudo-destructor-name Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Case: templateclass struct S { static_assert(((S*)0)-~S(), ); }; Sint b; Result: T:\D:\MinGW\bin\g++.exe a.cc -std=c++11 a.cc: In instantiation of 'struct Sint': a.cc:7:8: required from here a.cc:3:1: internal compiler error: Segmentation fault { ^ libbacktrace could not find executable to open Please submit a full bug report, with preprocessed source if appropriate. See http://sourceforge.net/projects/mingw-w64 for instructions. Envrionment: Win2012r2 x64 with i686-w64-mingw32-g++ 4.9.0. T:\D:\MinGW\bin\g++.exe -v Using built-in specs. COLLECT_GCC=D:\MinGW\bin\g++.exe COLLECT_LTO_WRAPPER=D:/MinGW/bin/../libexec/gcc/i686-w64-mingw32/4.9.0/lto-wrapper.exe Target: i686-w64-mingw32 Configured with: ../../../src/gcc-4.9.0/configure --host=i686-w64-mingw32 --build=i686-w64-mingw32 --target=i686-w64-mingw32 --prefix=/mingw32 --with-sysroot=/c/mingw490/i686-490-posix-dwarf-rt_v3-rev 1/mingw32 --with-gxx-include-dir=/mingw32/i686-w64-mingw32/include/c++ --enable-shared --enable-static --disable-multilib --enable-languages=ada,c,c++,fortran,objc,obj-c++,lto --enable-libstdcxx-time= yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --disable-s jlj-exceptions --with-dwarf2 --disable-isl-version-check --disable-cloog-version-check --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --d isable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=i686 --with-tune=generic --with-libiconv --with-system-zlib --with-gmp=/c/mingw490/prerequisites/i686-w64-mingw32- static --with-mpfr=/c/mingw490/prerequisites/i686-w64-mingw32-static --with-mpc=/c/mingw490/prerequisites/i686-w64-mingw32-static --with-isl=/c/mingw490/prerequisites/i686-w64-mingw32-static --with-cl oog=/c/mingw490/prerequisites/i686-w64-mingw32-static --enable-cloog-backend=isl --with-pkgversion='i686-posix-dwarf-rev1, Built by MinGW-W64 project' --with-bugurl=http://sourceforge.net/projects/min gw-w64 CFLAGS='-O2 -pipe -I/c/mingw490/i686-490-posix-dwarf-rt_v3-rev1/mingw32/opt/include -I/c/mingw490/prerequisites/i686-zlib-static/include -I/c/mingw490/prerequisites/i686-w64-mingw32-static/incl ude' CXXFLAGS='-O2 -pipe -I/c/mingw490/i686-490-posix-dwarf-rt_v3-rev1/mingw32/opt/include -I/c/mingw490/prerequisites/i686-zlib-static/include -I/c/mingw490/prerequisites/i686-w64-mingw32-static/incl ude' CPPFLAGS= LDFLAGS='-pipe -L/c/mingw490/i686-490-posix-dwarf-rt_v3-rev1/mingw32/opt/lib -L/c/mingw490/prerequisites/i686-zlib-static/lib -L/c/mingw490/prerequisites/i686-w64-mingw32-static/lib' Thread model: posix gcc version 4.9.0 (i686-posix-dwarf-rev1, Built by MinGW-W64 project)
[Bug c++/61019] ICE: incomplete type of class template as pseudo-destructor-name
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61019 frankhb1989 at gmail dot com changed: What|Removed |Added Known to fail||4.8.2, 4.9.0 --- Comment #1 from frankhb1989 at gmail dot com --- GCC 4.8.2 (Rev7, Built by MSYS2 project) also fails.
[Bug c++/60709] New: [C++11]ICE when using a braced-init-list as function argument to initialize a reference to array
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60709 Bug ID: 60709 Summary: [C++11]ICE when using a braced-init-list as function argument to initialize a reference to array Product: gcc Version: 4.8.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Minimal case: templateclass T struct X{}; void f(Xint()[1]) {} int main() { f({Xint()}); } g++ a.cc -std=c++11 a.cc: In function 'int main()': a.cc:8:15: internal compiler error: Segmentation fault f({Xint()}); ^ libbacktrace could not find executable to open Please submit a full bug report, with preprocessed source if appropriate. See http://sourceforge.net/projects/mingw-w64 for instructions. Clang++ 3.4 accepted it successfully.
[Bug c++/59931] New: Wrong wording of diagnostic about imaginary member function type
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59931 Bug ID: 59931 Summary: Wrong wording of diagnostic about imaginary member function type Product: gcc Version: 4.8.2 Status: UNCONFIRMED Severity: minor Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Case: class C { public: void f() { void (C::*pf)() = f; } }; int main(){} a.cc: In member function 'void C::f()': a.cc:6:21: error: cannot convert 'C::f' from type 'void (C::)()' to type 'void (C::*)()' void (C::*pf)() = f; ^ In short, there is no type like 'void (C::)()' in modern C++, at least in ISO C++. The member 'C::f' here should have type 'void ()'(if it makes sense), just as a non-member function type. The reason should be determined by the difference between pointer types and pointer to member types, and no conversion like function-to-pointer takes effects in it. P.S. Clang++ 3.0 complains about this as: error: cannot initialize a variable of type 'void (C::*)()' with an rvalue of type 'bound member function type'. And Clang++ 3.2's: error: cannot initialize a variable of type 'void (C::*)()' with an rvalue of type 'void'.
[Bug c++/59682] New: Invalid syntax accepted: new-placement without expression-list
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59682 Bug ID: 59682 Summary: Invalid syntax accepted: new-placement without expression-list Product: gcc Version: 4.8.2 Status: UNCONFIRMED Severity: minor Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Minimal case: int main() { int* p = new() int; } This should be invalid because as per the standard(ISO C++98/03/11) or the current working draft of the standard(WG21/N3797), a new-placement should not be '()': [expr.new]/1 ... new-placement: ( expression-list ) ... There is no opt like postfix-expression ( expression-list opt), etc. And the expression-list itself should be also a non-empty sequence of tokens. G++ silently accepts the invalid code with or without -pedantic-errors/-std=c++98/-std=c++03/-std=++11/-std=c++1y. However, Clang++(trunk) rejects it correctly: a.cc:4:14: error: expected expression int* p = new() int; ^ 1 error generated.
[Bug libstdc++/58395] New: Undefined behavior vs. exception
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58395 Bug ID: 58395 Summary: Undefined behavior vs. exception Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Several operations are undefined because they failed to meet required behavior(ISO C++11 [defns.required.behavior]) at runtime. Currently libstdc++ throw exceptions for them. For example, when object of type std::string being initialized using a null pointer value, an exception of type std::logic_error is thrown by basic_stringchar::_S_construct. That's nothing wrong for libstdc++ on conformance, because an implementation is free to do anything when the behavior is undefined. However, this behavior is somewhat confusing for users not so familiar with the standard. I suggest 2 options for future releases of libstdc++: 1. Make the type of exceptions specific(i.e. as a documented feature), distinguishable with other exceptions required to be thrown by the standard. It can be a type derived from std::logic_error, as an extension. 2. Make the implementation-defined result of what() specific and distinguishable, e.g. some prefix to indicate the exception is not mandated. This is not only good for manually distinguishing UB, but also beneficial for tests on conformance/portability of user programs.
[Bug c++/53402] [C++11] non-inline namespace can be wrongly re-opened as inline
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53402 frankhb1989 at gmail dot com changed: What|Removed |Added CC||frankhb1989 at gmail dot com --- Comment #2 from frankhb1989 at gmail dot com --- Confirmed in 4.8.1. PS. Clang(trunk) treats 'non-inline namespace cannot be reopened as a inline' an error (correctly), but also complains 'inline namespace cannot be reopened as a non-inline namespace'. I'm curious why the latter should trigger a warning. G++ have no diagnostic for them at all.
[Bug c++/57444] New: ICE in instantiate_type for invalid use of member with using-declaration
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57444 Bug ID: 57444 Summary: ICE in instantiate_type for invalid use of member with using-declaration Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: frankhb1989 at gmail dot com Case: struct C { bool empty(); }; struct D : C { using C::empty; }; int main() { if(D().empty); // error expected but got ICE } Output: a.cc: In function 'int main()': a.cc:14:14: internal compiler error: in instantiate_type, at cp/class.c:7459 if(D().empty); ^ The output is OK after removing 'using C::empty;': a.cc: In function 'int main()': a.cc:13:14: error: cannot convert 'C::empty' from type 'bool (C::)()' to type 'bool' if(D().empty); ^ A real example is using debug containers(std::__debug::vector/deque...) when 'empty()' is occasionally typoed as 'empty' in if-statement.
[Bug c++/57183] New: [C++11]auto and -Wunused-variable
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57183 Bug #: 57183 Summary: [C++11]auto and -Wunused-variable Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: frankhb1...@gmail.com Case: constexpr float PI_0 = 3.1415926F; constexpr auto PI_1 = 3.1415926F; const float PI_2 = 3.1415926F; const auto PI_3 = 3.1415926F; int main(){} Using gcc version 4.8.0 (rev2, Built by MinGW-builds project). g++ a.cc -std=c++11 -Wall a.cc:2:16: warning: 'PI_1' defined but not used [-Wunused-variable] constexpr auto PI_1 = 3.1415926F; ^ a.cc:4:12: warning: 'PI_3' defined but not used [-Wunused-variable] const auto PI_3 = 3.1415926F; ^ The difference between auto and non-auto declarations seems to be not intended.
[Bug c++/56699] New: Failed for sizeof (non-static member) in lambda expression
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56699 Bug #: 56699 Summary: Failed for sizeof (non-static member) in lambda expression Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: frankhb1...@gmail.com Here are the minimal testcases: Case 1: struct A { int a; }; struct T { int x; T() : x([]{ sizeof(::A::a); return 0; }()) {} }; Case 2: struct A { int a; }; void f() { []{sizeof(A::a);}; } Tested at coliru.stacked-crooked.com (g++ -v shows it's a x86-64 linux host): Case 1: $ g++-4.8 -fsyntax-only -std=c++11 main.cpp main.cpp: In lambda function: main.cpp:11:15: error: type 'A' is not a base type for type 'T' sizeof(::A::a); ^ Case 2: $ g++-4.8 -fsyntax-only -std=c++11 main.cpp main.cpp: In lambda function: main.cpp:10:15: internal compiler error: Segmentation fault []{sizeof(A::a);}; ^ I have exactly the same errors for both cases using mingw-builds 4.8.0(i686-w64-mingw32) compiled today from sf.net on my Win7 x64 host. From some others, I've heard Case 1 is accepted by g++-4.8 compiled just now on Ubuntu12.04, but the ICE still exists for Case 2. G++ 4.7 accepts both cases.
[Bug c++/56699] Failed for sizeof (non-static member) in lambda expression
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56699 --- Comment #1 from frankhb1989 at gmail dot com 2013-03-23 16:29:09 UTC --- Sorry, something was wrong, g++-4.8 on Ubuntu should also reject Case 1 in fact.
[Bug libstdc++/55053] New: std::is_explicitly_convertible should be removed
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55053 Bug #: 55053 Summary: std::is_explicitly_convertible should be removed Classification: Unclassified Product: gcc Version: 4.7.2 Status: UNCONFIRMED Severity: minor Priority: P3 Component: libstdc++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: frankhb1...@gmail.com In the current standard ISO/IEC 14882:2011 there is no std::is_explicitly_convertible, since it was removed as per N3047. See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3047.html for details. So it should be removed at least when -std=c++11 -pedantic is specified. But I found it is still in type_traits.
[Bug c++/54216] New: Missing diagnostic for ill-formed anonymous enum declarations
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54216 Bug #: 54216 Summary: Missing diagnostic for ill-formed anonymous enum declarations Classification: Unclassified Product: gcc Version: 4.7.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: frankhb1...@gmail.com G++(-pedantic-errors) wrongly accepts following non-conforming enumeration declarations(in namespace scope or block scope) and no diagnostic output at all: enum {}; //-std=c++98 or -std=c++11 enum class {}; //-std=c++11 enum class { x }; //-std=c++11 According the standard, all of them are ill-formed: (for the first declaration) ISO C++98/03/11 7/3 ... [Example: enum { }; // ill-formed typedef class { }; // ill-formed —end example] (for others) ISO C++11 7.2/2 ... The optional identifier shall not be omitted in the declaration of a scoped enumeration. ... While clang++(trunk, also using -pedantic-errors) rejects them correctly: (for the first declaration, -std=c++98 or -std=c++11) error: declaration does not declare anything [-Werror,-Wmissing-declarations] enum {}; ^~~~ (for others, -std=c++11) error: scoped enumeration requires a name enum class { }; ^ error: declaration does not declare anything [-Werror,-Wmissing-declarations] enum class { }; ^~~~ error: scoped enumeration requires a name enum class { x }; ^
[Bug c++/54216] Missing diagnostic for ill-formed anonymous enum declarations
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54216 frankhb1989 at gmail dot com changed: What|Removed |Added Severity|normal |minor
[Bug libstdc++/53872] New: [C++11] ADL bug in std::thread
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53872 Bug #: 53872 Summary: [C++11] ADL bug in std::thread Classification: Unclassified Product: gcc Version: 4.7.1 Status: UNCONFIRMED Severity: minor Priority: P3 Component: libstdc++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: frankhb1...@gmail.com Code below fails to compile using mingw-g++4.7.1 from sourceforge.net/projects/mingwbuilds: #include thread #include memory #include functional templatetypename, typename...P void make_shared(P...) {} struct C{}; // enable ADL void f(C){} int main() { std::thread t(std::bind(::f, C())); //error } Messages: d:\mingw\bin\..\lib\gcc\i686-w64-mingw32\4.7.1\include\c++\thread||In instantiation of 'std::shared_ptrstd::thread::_Impl_Callable std::thread::_M_make_routine(_Callable) [with _Callable = std::_Bind_simplestd::_Bindvoid (*(C))(C)()]':| d:\mingw\bin\..\lib\gcc\i686-w64-mingw32\4.7.1\include\c++\thread|133|required from 'std::thread::thread(_Callable, _Args ...) [with _Callable = std::_Bindvoid (*(C))(C); _Args = {}]'| F:\Programing\Temp\T9.cpp|31|required from here| d:\mingw\bin\..\lib\gcc\i686-w64-mingw32\4.7.1\include\c++\thread|191|sorry, unimplemented: use of 'type_pack_expansion' in template| d:\mingw\bin\..\lib\gcc\i686-w64-mingw32\4.7.1\include\c++\thread|191|sorry, unimplemented: use of 'type_pack_expansion' in template| d:\mingw\bin\..\lib\gcc\i686-w64-mingw32\4.7.1\include\c++\thread|191|error: call of overloaded 'make_shared(std::_Bind_simplestd::_Bindvoid (*(C))(C)())' is ambiguous| d:\mingw\bin\..\lib\gcc\i686-w64-mingw32\4.7.1\include\c++\thread|191|note: candidates are:| d:\mingw\bin\..\lib\gcc\i686-w64-mingw32\4.7.1\include\c++\bits\shared_ptr.h|611|note: std::shared_ptr_Tp1 std::make_shared(_Args ...) [with _Tp = std::thread::_Implstd::_Bind_simplestd::_Bindvoid (*(C))(C)() ; _Args = {std::_Bind_simplestd::_Bindvoid (*(C))(C)()}]| F:\Programing\Temp\T9.cpp|22|note: void make_shared(P ...) [with template-parameter-1-1 = std::thread::_Implstd::_Bind_simplestd::_Bindvoid (*(C))(C)() ; P = {std::_Bind_simplestd::_Bindvoid (*(C))(C)()}]| The line 191 of thread(in member template _M_make_routine): return make_shared_Impl_Callable(std::forward_Callable(__f)); After I adding std:: before make_shared, it works fine. Note: there is something wrong with the error message(unimplemented). I'd file another bug for it.
[Bug c++/53873] New: [C++11] strange error message for template overloading
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53873 Bug #: 53873 Summary: [C++11] strange error message for template overloading Classification: Unclassified Product: gcc Version: 4.7.1 Status: UNCONFIRMED Severity: trivial Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: frankhb1...@gmail.com Sometimes g++ complains: sorry, unimplemented: use of 'type_pack_expansion' in template But there seems to be no apparent reason for this error. Please see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53872 for details (an example including code and full diagnostic messages).