[Bug libstdc++/111357] New: __integer_pack fails to work with values of dependent type convertible to integers

2023-09-09 Thread frankhb1989 at gmail dot com via Gcc-bugs
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

2023-07-28 Thread frankhb1989 at gmail dot com via Gcc-bugs
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

2023-05-05 Thread frankhb1989 at gmail dot com via Gcc-bugs
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

2023-05-04 Thread frankhb1989 at gmail dot com via Gcc-bugs
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_MERGED_TYPEINFO_NAMES (either 0 or 1).

The sequence (v[0], v[1], ...) here is exactly the inserted one in the actual
case, where the underlying sequence (of type vector) using
less as key_compare. Insertions of v[0] and v[1] are OK, and then
insertion of v[2] breaks the assumption of ordering in the vector. At this
point it is already corrupted. Assuming it is correct when

[Bug libstdc++/103240] std::type_info::before gives wrong answer for ARM EABI

2023-04-29 Thread frankhb1989 at gmail dot com via Gcc-bugs
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

2023-04-29 Thread frankhb1989 at gmail dot com via Gcc-bugs
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

2023-02-13 Thread frankhb1989 at gmail dot com via Gcc-bugs
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

2022-10-08 Thread frankhb1989 at gmail dot com via Gcc-bugs
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

2022-06-28 Thread frankhb1989 at gmail dot com via Gcc-bugs
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

2022-01-25 Thread frankhb1989 at gmail dot com via Gcc-bugs
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

2022-01-25 Thread frankhb1989 at gmail dot com via Gcc-bugs
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

2022-01-22 Thread frankhb1989 at gmail dot com via Gcc-bugs
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

2021-12-21 Thread frankhb1989 at gmail dot com via Gcc-bugs
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

2021-11-22 Thread frankhb1989 at gmail dot com via Gcc-bugs
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

2021-11-02 Thread frankhb1989 at gmail dot com via Gcc-bugs
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

2021-05-19 Thread frankhb1989 at gmail dot com via Gcc-bugs
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

2021-05-18 Thread frankhb1989 at gmail dot com via Gcc-bugs
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

2021-05-07 Thread frankhb1989 at gmail dot com via Gcc-bugs
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

2021-02-17 Thread frankhb1989 at gmail dot com via Gcc-bugs
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

2020-12-27 Thread frankhb1989 at gmail dot com via Gcc-bugs
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

2020-10-10 Thread frankhb1989 at gmail dot com via Gcc-bugs
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

2020-10-10 Thread frankhb1989 at gmail dot com via Gcc-bugs
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.