[Bug tree-optimization/116277] "may be used uninitialized [-Werror=maybe-uninitialized]" instead of -Werror=dangling-reference

2024-08-07 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116277

--- Comment #3 from Frank Heckenbach  ---
When 63446 was reported, gcc didn't have -Werror=dangling-reference, so a false
positive was perhaps better than no warning in this case back then. Now it has
the proper warning for this case.

[Bug c++/116277] New: "may be used uninitialized [-Werror=maybe-uninitialized]" instead of -Werror=dangling-reference

2024-08-07 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116277

Bug ID: 116277
   Summary: "may be used uninitialized
[-Werror=maybe-uninitialized]" instead of
-Werror=dangling-reference
   Product: gcc
   Version: 14.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test.cpp 
#include 
#include 

auto C ()
{
  auto Reverse = false;
  return [&] (auto a, auto b) { return Reverse ? b < a : a < b; };
}

void f ()
{
  std::vector  r { 0, 1 };
  std::sort (begin (r), end (r), C ());
}
% g++ -O3 -std=c++23 -Wshadow -Wall -Werror -Werror=dangling-reference
In lambda function,
inlined from 'constexpr bool
__gnu_cxx::__ops::_Iter_comp_iter<_Compare>::operator()(_Iterator1, _Iterator2)
[with _Iterator1 = __gnu_cxx::__normal_iterator >;
_Iterator2 = __gnu_cxx::__normal_iterator >; _Compare =
C()::]' at
/opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/bits/predefined_ops.h:158:30,
inlined from 'constexpr void std::__insertion_sort(_RandomAccessIterator,
_RandomAccessIterator, _Compare) [with _RandomAccessIterator =
__gnu_cxx::__normal_iterator >; _Compare =
__gnu_cxx::__ops::_Iter_comp_iter >]' at
/opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/bits/stl_algo.h:1777:14,
inlined from 'constexpr void
std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator,
_Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator >; _Compare =
__gnu_cxx::__ops::_Iter_comp_iter >]' at
/opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/bits/stl_algo.h:1822:23,
inlined from 'constexpr void std::__sort(_RandomAccessIterator,
_RandomAccessIterator, _Compare) [with _RandomAccessIterator =
__gnu_cxx::__normal_iterator >; _Compare =
__gnu_cxx::__ops::_Iter_comp_iter >]' at
/opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/bits/stl_algo.h:1908:31,
inlined from 'constexpr void std::sort(_RAIter, _RAIter, _Compare) [with
_RAIter = __gnu_cxx::__normal_iterator >; _Compare =
C()::]' at
/opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/bits/stl_algo.h:4804:18,
inlined from 'void f()' at :13:13:
:7:48: error: 'Reverse' is used uninitialized [-Werror=uninitialized]
7 |   return [&] (auto a, auto b) { return Reverse ? b < a : a < b; };
  |^~~
: In function 'void f()':
:6:8: note: 'Reverse' declared here
6 |   auto Reverse = false;
  |^~~
cc1plus: all warnings being treated as errors
Compiler returned: 1

There is a bug in the code: Reverse is a dangling reference. But the message
doesn't make this clear (and ironically claims it's uninitialized while quoting
its initialization).

[Bug c++/116116] New: -Wshadow false negative

2024-07-27 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116116

Bug ID: 116116
   Summary: -Wshadow false negative
   Product: gcc
   Version: 14.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test.cpp
int a[2];
struct S { int a { sizeof (a) }; };
static_assert (S().a == sizeof (int));
% g++ -Wall -Wextra -Wshadow test.cpp -c
%

I would expect a warning here. As the static_assert shows, in the
initialization of S::a, "a" refers to itself (correctly AFAIK), so it does
shadow the outer "a" already.

[Bug c++/104343] improved error message for passing overloaded function to variadic(templated)-argument function

2024-03-16 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104343

--- Comment #7 from Frank Heckenbach  ---
#3 points out "Also, GCC 7 has been unsupported for a couple of years." My new
"duplicate" report shows that the problem still exists with current versions.
You might want to update the version number to make it clear that it's still
relevant.

(Actually, I think it would be good if bugzilla would automatically set the
version to the latest one when merging, but I don't know how hard this would be
to implement.)

[Bug c++/114362] New: wrong error message "too many arguments" with overloaded function

2024-03-16 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114362

Bug ID: 114362
   Summary: wrong error message "too many arguments" with
overloaded function
   Product: gcc
   Version: 13.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test.cpp
#include 

void f ();
void f (int);

void g ()
{
  std::tie (f) = 0;
}
% g++ test.cpp
test.cpp: In function 'void g()':
test.cpp:8:12: error: too many arguments to function 'constexpr
std::tuple<_Elements& ...> std::tie(_Elements& ...) [with _Elements = {}]'
[...]

This only happens when f is overloaded. When I comment out either of the two
declarations of f, I get only "error: no match for 'operator='" as expected.

[Bug c++/114248] New: invalid "scalar object" error

2024-03-05 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114248

Bug ID: 114248
   Summary: invalid "scalar object" error
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test.cpp  
// #pragma GCC diagnostic ignored "-Wnarrowing"
// #pragma GCC diagnostic warning "-Wnarrowing"

template  struct S
{
  S (int, int) { }
};

// template <> using S <-1> = int;

int main ()
{
  S <-1> i { 1, 2 };
}
% g++ test.cpp 
test.cpp: In function 'int main()':
test.cpp:13:8: error: narrowing conversion of '-1' from 'int' to 'unsigned int'
[-Wnarrowing]
   13 |   S <-1> i { 1, 2 };
  |^
test.cpp:13:10: error: scalar object 'i' requires one element in initializer
   13 |   S <-1> i { 1, 2 };
  |  ^

The first error is correct, of course, but the second one is not because "i" is
not scalar.

Sure, the declaration of "i" is wrong, but this leaves two possible
conclusions:

- We don't know what "i" is meant to be, so any claim about it is unjustified.

- We see that the type of "i" is meant to be an instance of S which is a
struct, and not scalar. AFAIK, even potential specializations of S cannot
change this fact (cf. the commented-out line which is doubly wrong).

Interestingly, when turning the first error off or into a warning (cf. one of
the commented-out pragmas), the second error disappears as well.

I would have expected that those options/pragmas merely control if the
narrowing problem is reported, and if so, whether it causes the compilation to
fail, but apparently it does influence gcc's representation of "i" afterwards
as well.

But that's just a side note actually -- even with a clearly wrong declaration
of "i" such as

  S <""> i { 1, 2 };

gcc gives the "scalar" error which it shouldn't.

[Bug c/114113] New: bogus -Walloc-zero warning

2024-02-26 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114113

Bug ID: 114113
   Summary: bogus -Walloc-zero warning
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test.c
void *malloc (long unsigned int size);

int p[2] = { 1, 0 };
int *a;

int main ()
{
  int n = 0;
  while (p[n])
n++;
  a = (int *) malloc (n * sizeof (int));
  int i;
  for (i = 0; i < n; i++)
a[i] = 0;
}
% gcc -O -Walloc-zero test.c
test.c: In function 'main':
test.c:11:15: warning: argument 1 value is zero [-Walloc-zero]
   11 |   a = (int *) malloc (n * sizeof (int));
  |   ^
test.c:1:7: note: in a call to allocation function 'malloc' declared here
1 | void *malloc (long unsigned int size);
  |   ^~

[Bug c++/114110] New: unhelpful message about non-movable types

2024-02-26 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114110

Bug ID: 114110
   Summary: unhelpful message about non-movable types
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

Here's another gcc output that's less than helpful:

% cat test.cpp
#include 
#include 

struct S
{
  std::unique_ptr  a, b, c, d, e, f, g, h, i, j;
  ~S () = default;
};

int main ()
{
  S a, b = std::move (a);
}
% g++ test.cpp
test.cpp: In function 'int main()':
test.cpp:12:24: error: use of deleted function 'S::S(const S&)'
   12 |   S a, b = std::move (a);
  |^
test.cpp:4:8: note: 'S::S(const S&)' is implicitly deleted because the default
definition would be ill-formed:
4 | struct S
  |^
test.cpp:4:8: error: use of deleted function 'std::unique_ptr<_Tp,
_Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp =
std::default_delete]'
In file included from /usr/include/c++/12/memory:76,
 from test.cpp:2:
/usr/include/c++/12/bits/unique_ptr.h:514:7: note: declared here
  514 |   unique_ptr(const unique_ptr&) = delete;
  |   ^~
test.cpp:4:8: error: use of deleted function 'std::unique_ptr<_Tp,
_Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp =
std::default_delete]'
4 | struct S
  |^
/usr/include/c++/12/bits/unique_ptr.h:514:7: note: declared here
  514 |   unique_ptr(const unique_ptr&) = delete;
  |   ^~
test.cpp:4:8: error: use of deleted function 'std::unique_ptr<_Tp,
_Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp =
std::default_delete]'
4 | struct S
  |^
/usr/include/c++/12/bits/unique_ptr.h:514:7: note: declared here
  514 |   unique_ptr(const unique_ptr&) = delete;
  |   ^~
test.cpp:4:8: error: use of deleted function 'std::unique_ptr<_Tp,
_Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp =
std::default_delete]'
4 | struct S
  |^
/usr/include/c++/12/bits/unique_ptr.h:514:7: note: declared here
  514 |   unique_ptr(const unique_ptr&) = delete;
  |   ^~
test.cpp:4:8: error: use of deleted function 'std::unique_ptr<_Tp,
_Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp =
std::default_delete]'
4 | struct S
  |^
/usr/include/c++/12/bits/unique_ptr.h:514:7: note: declared here
  514 |   unique_ptr(const unique_ptr&) = delete;
  |   ^~
test.cpp:4:8: error: use of deleted function 'std::unique_ptr<_Tp,
_Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp =
std::default_delete]'
4 | struct S
  |^
/usr/include/c++/12/bits/unique_ptr.h:514:7: note: declared here
  514 |   unique_ptr(const unique_ptr&) = delete;
  |   ^~
test.cpp:4:8: error: use of deleted function 'std::unique_ptr<_Tp,
_Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp =
std::default_delete]'
4 | struct S
  |^
/usr/include/c++/12/bits/unique_ptr.h:514:7: note: declared here
  514 |   unique_ptr(const unique_ptr&) = delete;
  |   ^~
test.cpp:4:8: error: use of deleted function 'std::unique_ptr<_Tp,
_Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp =
std::default_delete]'
4 | struct S
  |^
/usr/include/c++/12/bits/unique_ptr.h:514:7: note: declared here
  514 |   unique_ptr(const unique_ptr&) = delete;
  |   ^~
test.cpp:4:8: error: use of deleted function 'std::unique_ptr<_Tp,
_Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp =
std::default_delete]'
4 | struct S
  |^
/usr/include/c++/12/bits/unique_ptr.h:514:7: note: declared here
  514 |   unique_ptr(const unique_ptr&) = delete;
  |   ^~
test.cpp:4:8: error: use of deleted function 'std::unique_ptr<_Tp,
_Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp =
std::default_delete]'
4 | struct S
  |^
/usr/include/c++/12/bits/unique_ptr.h:514:7: note: declared here
  514 |   unique_ptr(const unique_ptr&) = delete;
  |   ^~

gcc explains in much detail (and not very readable, cf.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113854#c4, esp. the bottom part),
repeating the same message for each member, why the type is not copyable. Well,
I know it's not copyable, that's why I'm trying to move it. Sure, a
copy-constructor can be used when there is no useable move-constructor, but if
both copy- and move-constructor are not useable, it's quite misleading to only
explain why the copy-constructor is not useable when moving was requested in
the first place.

The actual problem here is that the move

[Bug c++/113854] the expression 'is_invocable_v ... evaluated to 'false'

2024-02-11 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113854

--- Comment #4 from Frank Heckenbach  ---
(In reply to Jonathan Wakely from comment #1 and #2)

> [...] than to get errors deep inside an instantiation stack.

But they are deep in the stack; maybe not an instantiation stack, but a
requires stack or whatever you call it. Anyway, the text is much longer than
that for plain std::find_if.

> And those are not library internals, they're the public concepts defined in
> the standard.

is:invocable_v is standard, the rest seems to be full of __library _Internals.
Perhaps I wasn't clear, that's what I'm referring to. Apart from the last line
and a few others, most of the messages are not meaningful to a mere user.

> You can look them up to see what they mean, but the problem
> boils down to what's shown at the end: your predicate can't be used with
> that argument type.
> 
> I think that's actually a more accurate description of the problem than
> telling you that a deleted copy constructor can't be used. We've just been
> conditioned by years of bad errors to know what it means. But really what
> you're trying to do is call a function, not copy a unique_ptr.

Those messages may not be optimal, and perhaps we've actually been conditioned
in a way, but at least I've learned to understand what they mean. Deleted
copy-constructor, sure, it's about non-copyable types, I have something to go
on. Whereas the concepts message basically tells me I can't call it because I
can't invoke it.

In a simple case like this, it's clear why, but if i is not just a unique_ptr,
but a struct containing one among several other members (as was the case in my
actual code), it will be less obvious. And if the function takes more than one
argument, there will be no indication which one is the problem, whereas the
std::find_if message at least says "argument 1".

Also, the message "the expression 'is_invocable_v<_Fn, _Args ...> [with _Fn =
main::._anon_116&; _Args = {std::unique_ptr
>&}]'" IMHO reads more like a text puzzle. (This is a more general issue,
should I file another bug or two for it?)

a) It introduces 3 new identifiers, resolves 2 of them right after and the last
one not at all.

b) It lists default parameters the user doesn't really care about. I get that
gcc at this point probably doesn't know whether the parameters were defaulted
or specified (and happened to match the default, which seems unlikely). It
would be a big improvement if gcc could simplify that message to something like
this:

is_invocable_v<[] (auto), std::unique_ptr> is required, but false

Please note: I'm not trying to be difficult here. I'm actually having trouble
understanding these kinds of messages. Finding the actual (see above) relevant
messages and puzzling them together now often takes more time than ignoring
them altogether and analyzing the code myself. That's why I said "something's
wrong here" would be as good a message. :(

[Bug c++/113854] New: the expression 'is_invocable_v ... evaluated to 'false'

2024-02-09 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113854

Bug ID: 113854
   Summary: the expression 'is_invocable_v ... evaluated to
'false'
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

The following error output is less than helpful. It contains a long litany of
mostly library internals. The ultimate error is "the expression
'is_invocable_v<_Fn, _Args ...> [with _Fn = main::._anon_116&; _Args =
{std::unique_ptr >&}]' evaluated to 'false'"
which, while technically correct, is still not very helpful.

The actual error is trying to pass a move-only type by value rather than by
reference, but I can't infer this from the messages. So again, unfortunately, I
have to read gcc's message as "something's wrong, but I won't tell you what"
...

One of the promises of concepts was better error messages. That's obviously not
the case here, compared to the version with plain old std::find_if (below).

% cat test.cpp
#include 
#include 
#include 

int main ()
{
  std::vector > v;
  std::ranges::find_if (v, [] (auto i) { return !!i; });
}
% g++ -std=c++20 test.cpp
test.cpp: In function 'int main()':
test.cpp:8:24: error: no match for call to '(const std::ranges::__find_if_fn)
(std::vector >&, main()::)'
8 |   std::ranges::find_if (v, [] (auto i) { return !!i; });
  |   ~^~~~
In file included from /usr/include/c++/12/ranges:47,
 from test.cpp:3:
/usr/include/c++/12/bits/ranges_util.h:474:7: note: candidate: 'template  requires (input_iterator<_Iter>)
&& (sentinel_for<_Sent, _Iter>) && (indirect_unary_predicate<_Pred,
std::projected<_Iter, _Proj> >) constexpr _Iter
std::ranges::__find_if_fn::operator()(_Iter, _Sent, _Pred, _Proj) const'
  474 |   operator()(_Iter __first, _Sent __last,
  |   ^~~~
/usr/include/c++/12/bits/ranges_util.h:474:7: note:   template argument
deduction/substitution failed:
test.cpp:8:24: note:   candidate expects 4 arguments, 2 provided
8 |   std::ranges::find_if (v, [] (auto i) { return !!i; });
  |   ~^~~~
/usr/include/c++/12/bits/ranges_util.h:487:7: note: candidate: 'template  requires (input_range<_Range>) &&
(indirect_unary_predicate<_Pred,
std::projected)())),
_Proj> >) constexpr std::ranges::borrowed_iterator_t<_Range>
std::ranges::__find_if_fn::operator()(_Range&&, _Pred, _Proj) const'
  487 |   operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
  |   ^~~~
/usr/include/c++/12/bits/ranges_util.h:487:7: note:   template argument
deduction/substitution failed:
/usr/include/c++/12/bits/ranges_util.h:487:7: note: constraints not satisfied
In file included from /usr/include/c++/12/compare:39,
 from /usr/include/c++/12/bits/stl_pair.h:65,
 from /usr/include/c++/12/bits/stl_algobase.h:64,
 from /usr/include/c++/12/vector:60,
 from test.cpp:1:
/usr/include/c++/12/concepts: In substitution of 'template  requires (input_range<_Range>) &&
(indirect_unary_predicate<_Pred,
std::projected)())),
_Proj> >) constexpr std::ranges::borrowed_iterator_t<_Range>
std::ranges::__find_if_fn::operator()(_Range&&, _Pred, _Proj) const [with
_Range = std::vector >&; _Proj = std::identity; _Pred =
main()::]':
test.cpp:8:24:   required from here
/usr/include/c++/12/concepts:336:13:   required for the satisfaction of
'invocable<_Fn, _Args ...>' [with _Fn = main::._anon_116&; _Args =
{std::unique_ptr >&}]
/usr/include/c++/12/concepts:340:13:   required for the satisfaction of
'regular_invocable<_Fn, _Args ...>' [with _Fn = main::._anon_116&; _Args =
{std::unique_ptr >&}]
/usr/include/c++/12/concepts:344:13:   required for the satisfaction of
'predicate<_Fn&, typename std::__detail::__iter_traits_impl::type, std::indirectly_readable_traits::type> >::type::value_type&>' [with _Fn =
main::._anon_116; _Iter =
std::projected<__gnu_cxx::__normal_iterator >*, std::vector >, std::allocator > > > >, std::identity>]
/usr/include/c++/12/bits/iterator_concepts.h:710:13:   required for the
satisfaction of 'indirect_unary_predicate<_Pred, std::projected())), _Proj> >' [with
_Pred = main::._anon_116; _Range = std::vector >, std::allocator > > >&; _Proj = std::identity]
/usr/include/c++/12/concepts:336:25: note: the expression 'is_invocable_v<_Fn,
_Args ...> [with _Fn = main::._anon_116&; _Args = {std::unique_ptr >&}]' evaluated to 'false'
  336 | concept invocable = is_invocable_v<_Fn, _Args...>;
  | ^

% cat test2.cpp
#include 
#include 
#include 

int main ()
{
  std::vector > v;
  std::find_if (v.begin (), v.end (), [] (auto i) { return !!i; });
}
% g++ -std=c++20 test2.cpp
In file i

[Bug c++/113839] misleading syntax error message

2024-02-08 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113839

--- Comment #3 from Frank Heckenbach  ---
> Except C++ parsing does not allow for that because C++ parsing requires
> unlimited look ahead.

While that's true in general, I think in specific cases (including most
real-world cases), the look-ahead required is limited. E.g., here, I think it's
clear the program is ill-formed at the ";" at the latest, perhaps even at the
"{}" already.

Even if gcc can't determine the cause of the error, I'd prefer if it said so
rather than chosing one (IMHO unlikely) candidate for correction. (Is there
actually a primary-expression that could be inserted there to make the program
correct, or would this only lead to the next error?)

[Bug c++/113839] New: misleading syntax error message

2024-02-08 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113839

Bug ID: 113839
   Summary: misleading syntax error message
   Product: gcc
   Version: 13.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test.cpp
void f ()
{
  static int { };
}
% g++ test.cpp
test.cpp: In function 'void f()':
test.cpp:3:3: error: expected primary-expression before 'static'
3 |   static int { };
  |   ^~

This message is clearly misleading. There is nothing missing before "static",
but rather the variable name after "int" is missing.

I seem to get a lot of such confusing messages, to the point I tend to ignore
the wording of the messages and treat them as generic "syntax error" messages,
which is sad.

While I appreciate gcc trying to by helpful, it seems it goes wrong rather
often. I'd prefer if gcc (by default, or at least optional) would limit itself
to reporting actual errors if and when they occur. (In this case, the program
is correct up to and including "static int", so there shouldn't be any error
reported on that part.)

[Bug c++/111301] New: misleading messages about missing "inline"

2023-09-05 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111301

Bug ID: 111301
   Summary: misleading messages about missing "inline"
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

Another case of misleading messages:

% cat test.cpp
struct S
{
  static int i = 0;
  static float f = 0;
};
% g++ -c -std=c++23 test.cpp
test.cpp:3:14: error: ISO C++ forbids in-class initialization of non-const
static member 'S::i'
3 |   static int i = 0;
  |  ^
test.cpp:4:16: error: 'constexpr' needed for in-class initialization of static
data member 'float S::f' of non-integral type [-fpermissive]
4 |   static float f = 0;
  |^

First of all, the two different messages are irritating. As I understand it,
that's because there is an exception for "static const int", apparently mostly
for historic reasons, and actually not really relevant here. Anyway, even if it
seems worth mentioning this exception at all (I doubt it now that we have
constexpr), the messages could be merged, saying "non-const, non-integral ..."
to make it clearer it's actually the same issue both times.

Also, "forbid" and "needed" is too strongly worded now that "static inline" is
also possible (and in fact what I meant to write).

[Bug c++/111281] unhelpful warning output ('nonnull' argument 'v' compared to NULL)

2023-09-05 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111281

--- Comment #8 from Frank Heckenbach  ---
I don't suggest to get rid of the warning. As I said in #3, if it's hard to
track, a more inclusive wording seems fine to me.

But my main grief about this message is the lack of context, i.e. the really
relevant source code location (here, where f is called). Without the concept
(which I simplified according to your suggestion, thanks), it would have been
really hard to find.

[Bug c++/111281] unhelpful warning output ('nonnull' argument 'v' compared to NULL)

2023-09-05 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111281

--- Comment #4 from Frank Heckenbach  ---
FWIW, as stated, the lack of context in the message made it hard to find the
actual location of the bug in my code -- in the end even harder than I had
expected since it was well hidden.

Fortunately I was able use concepts to the rescue. Otherwise it would have been
pure guesswork. Here's what I did if anyone cares:

#include 

template  concept IsFunction = std::is_function_v  ||
(std::is_pointer_v  && std::is_function_v >);

template  concept Outputtable = !IsFunction > || std::is_same_v ;  // the latter
part is for std::left etc.

void f (const Outputtable auto &v) { std::cout << v; }

int t ();

int main ()
{
  f (t);
}

[Bug c++/111281] unhelpful warning output ('nonnull' argument 'v' compared to NULL)

2023-09-03 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111281

--- Comment #3 from Frank Heckenbach  ---
Thanks for the additional info. I still think it would be useful if the message
told me that, rather than you. ;)

- 'nonnull' is a GCC attribute, and quoting it makes it look like it refers to
that, rather than to being a reference. If you can't easily track the
provenance, a wording like "non-null argument (reference or 'nonnull'
attribute)" might be better.

- 'NULL' is a macro (and very much a deprecated one since we have nullptr), and
both that and the comparison are generated by the compiler and not part of the
code, so a wording like "compared to nullptr or converted to bool" might be
better.

[Bug c++/111281] New: unhelpful warning output ('nonnull' argument 'v' compared to NULL)

2023-09-03 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111281

Bug ID: 111281
   Summary: unhelpful warning output ('nonnull' argument 'v'
compared to NULL)
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test.cpp
#include 

void f (const auto &v) { std::cout << v; }

int t ();

int main ()
{
  f (t);
}
% g++ -c -std=c++20 -Wall test.cpp
test.cpp: In function 'void f(const auto:11&) [with auto:11 = int()]':
test.cpp:3:36: warning: 'nonnull' argument 'v' compared to NULL
[-Wnonnull-compare]
3 | void f (const auto &v) { std::cout << v; }
  |  ~~^~~~

Of course, there is an error in the code (trying to output a function pointer),
but the message given is completely useless:

- There is no "nonnull" in the code.

- There is no comparison (to NULL or anything else for that matter) in the
code.

Most importantly, the message points to an innocent function that doesn't
contain the actual error. While other times (e.g.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109561) GCC likes to give pages
upon pages of questionable context, here it's giving clearly too little for the
message to be of any use.

I guess it's hard to determine a good amount of context to give, but the
following two pieces of information seem essential to me:

- The actual location of the code that the message refers to. Here, it must be
somewhere in the library which is often hard to read, but at least may give a
clue about what's going on. But the message doesn't say where.

- The source code location that ultimately causes the code to be generated
(here, the line in main). Of course, in the case of template instantiations it
must be tracked (but in other cases GCC does this already) and there may be
several places doing the same instantiation (but giving any of them would be
better than none).

As it is, the message doesn't say anything relevant about the code and doesn't
point to any relevant location, so when I got it in my actual code, I wouldn't
even know where to start looking. (Other than, as usual, guessing one of the
most recent changes, but for that we only need "something's wrong" messages. ;)

[Bug c++/111140] New: wrong error message

2023-08-24 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=40

Bug ID: 40
   Summary: wrong error message
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test.cpp
static void S__f (auto ...) { }

struct S
{
  static void f (auto ...) { }
};

int main ()
{
  S__f (1, { });
  S::f (1, { });
}
% g++ -std=c++20 test.cpp
test.cpp: In function 'int main()':
test.cpp:10:8: error: too many arguments to function 'void S__f(auto:1 ...)
[with auto:1 = {}]'
   10 |   S__f (1, { });
  |   ~^~~~
test.cpp:1:13: note: declared here
1 | static void S__f (auto ...) { }
  | ^~~~
test.cpp:11:8: error: no matching function for call to 'S::f(int,
)'
   11 |   S::f (1, { });
  |   ~^~~~
test.cpp:5:15: note: candidate: 'static void S::f(auto:2 ...) [with auto:2 =
{}]'
5 |   static void f (auto ...) { }
  |   ^
test.cpp:5:15: note:   candidate expects 0 arguments, 2 provided

These error messages are just misleading. The functions accept any number of
arguments. The actual problem is that no type can be deduced for "{ }". (Of
course, it's easy to see here, but in more complex situations with multiple
overloads, it makes it really hard to understand what the problem is.)

Also strange: S__f and S::f are practically the same, yet the error message is
differently worded (though the meaning is very close).

[Bug c++/110312] -Wcast-align=strict warning despite alignas

2023-06-19 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110312

--- Comment #2 from Frank Heckenbach  ---
(In reply to Andrew Pinski from comment #1)
> The decl has the increased alignment but the type does not in this case.
> 
> So I think the warning is still correct.

So there's no way around it other then disabling the warning, correct?

[Bug c++/110312] New: -Wcast-align=strict warning despite alignas

2023-06-19 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110312

Bug ID: 110312
   Summary: -Wcast-align=strict warning despite alignas
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test.cpp
alignas (int) char a[sizeof (int)];
auto b = reinterpret_cast  (a);
% g++ -c -Wcast-align=strict test.cpp  
test.cpp:2:10: warning: cast from 'char (*)[4]' to 'int*' increases required
alignment of target type [-Wcast-align]

I'd kind of understand the warning if I was casting &a to int* because the
alignas information might get lost when taking the address. So I tried casting
a reference, but apparently (telling from the message), gcc implements this via
a pointer cast anyway, so it doesn't help.

FWIW, I got this when I tried to replace aligned_storage_t (which is deprecated
in C++23 for reasons I don't really understand TBH) with a std::byte array as
suggested. Does this mean that I simply can't use -Wcast-align=strict then?

[Bug c++/92707] type alias on type alias on lambda in unevaluated context does not work

2023-05-31 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92707

Frank Heckenbach  changed:

   What|Removed |Added

 CC||f.heckenb...@fh-soft.de

--- Comment #1 from Frank Heckenbach  ---
Probably the same bug in a slightly different form:

% cat test.cpp
template  struct S { };
template  using A = S ;
template  using B = A ;
B <0> a;
% g++ -std=c++20 -Wall -Wextra test.cpp
test.cpp:4:1: error: 'B' does not name a type
4 | B <0> a;
  | ^

It works when using A instead of B.
It works when using an alias for "decltype ([] { })".
Other compilers accept it as is.

Also, I find the message confusing (even if it was rightly rejected): Of
course, 'B' does not name a type. It's followed by template arguments, so 'B'
shouldn't be a type, but a template or template alias, or 'B <0>' should be a
type.

[Bug tree-optimization/109571] potential null pointer dereference

2023-04-20 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109571

--- Comment #3 from Frank Heckenbach  ---
Thanks for the explanation, that was really helpful.

If I understand it correctly, since B has a vtable and A doesn't, upcasting
means to add some offset to the pointer, but of course not if it's null. That's
why null has to be special-cased which leads to the warning in one branch.
(Since the compiler can't see that I won't actually put any null pointers
there.)

Now I know what to watch out for if I get more such warnings.

[Bug c++/109571] New: potential null pointer dereference

2023-04-20 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109571

Bug ID: 109571
   Summary: potential null pointer dereference
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test.cpp
#include 

struct A
{
  int i = 0;
};

struct B: A
{
  virtual ~B ();
};

struct C
{
  std::vector  v;
  virtual ~C () { for (A *a: v) a->i++; }
};

int main ()
{
  C c;
}
% gcc --std=c++20 -c -Wall -Wnull-dereference -O3 test.cpp 
test.cpp: In destructor ‘C::~C()’:
test.cpp:16:36: warning: potential null pointer dereference
[-Wnull-dereference]
   16 |   virtual ~C () { for (A *a: v) a->i++; }
  | ~~~^
test.cpp:16:37: warning: potential null pointer dereference
[-Wnull-dereference]
   16 |   virtual ~C () { for (A *a: v) a->i++; }
  | ^~
In destructor ‘virtual C::~C()’,
inlined from ‘virtual C::~C()’ at test.cpp:16:41:
test.cpp:16:36: warning: potential null pointer dereference
[-Wnull-dereference]
   16 |   virtual ~C () { for (A *a: v) a->i++; }
  | ~~~^
test.cpp:16:37: warning: potential null pointer dereference
[-Wnull-dereference]
   16 |   virtual ~C () { for (A *a: v) a->i++; }
  |

Of course, strictly speaking any pointer dereference is *potentially* a null
pointer dereference, but there's no particular reason to assume one here. (In
fact, when making v private, the compiler could actually know that v will
always be empty, but still warns.)

Even more stragely, this warning depends on many factors that have nothing to
do with the elements by v being null or not, such as both the calling function
and some function in B being virtual, the for-loop variable being A* (not B*)
etc.

My actual code is of course more complex, so I'd like to understand what's
actually causing this warning, so I can avoid it. (Or should I just disable
it?)

And why is the same warning given 4 times?

[Bug c++/109569] warning: ‘void* __builtin_memmove(void*, const void*, long unsigned int)’ writing 1 or more bytes into a region of size 0 overflows the destination [-Wstringop-overflow=]

2023-04-20 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109569

--- Comment #6 from Frank Heckenbach  ---
(In reply to Frank Heckenbach from comment #4)
> Thanks.
> 
> I just got another similar one, this time with string.insert. But I guess
> it's pointless to dissect this one, or do you need more examples for your
> test suite?

Actually, on a closer look, this one is a bit different. Do you need an example
for that, or should it also be fixed in trunk?

In static member function 'static constexpr std::char_traits::char_type*
std::char_traits::copy(char_type*, const char_type*, std::size_t)',
inlined from 'static constexpr void std::__cxx11::basic_string<_CharT,
_Traits, _Alloc>::_S_copy(_CharT*, const _CharT*, size_type) [with _CharT =
char; _Traits = std::char_traits; _Alloc = std::allocator]' at
/usr/include/c++/12/bits/basic_string.h:423:21,
inlined from 'constexpr std::__cxx11::basic_string<_CharT, _Traits,
_Allocator>& std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>::_M_replace(size_type, size_type, const _CharT*, size_type) [with
_CharT = char; _Traits = std::char_traits; _Alloc =
std::allocator]' at /usr/include/c++/12/bits/basic_string.tcc:532:22,
inlined from 'constexpr std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>& std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>::replace(size_type, size_type, const _CharT*, size_type) [with _CharT =
char; _Traits = std::char_traits; _Alloc = std::allocator]' at
/usr/include/c++/12/bits/basic_string.h:2171:19,
inlined from 'constexpr std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::insert(size_type,
const _CharT*) [with _CharT = char; _Traits = std::char_traits; _Alloc =
std::allocator]' at /usr/include/c++/12/bits/basic_string.h:1928:22,
inlined from 'std::string mpf_to_string(mpf_class, size_t)' at
pi.cpp:102:12:
/usr/include/c++/12/bits/char_traits.h:431:56: error: 'void*
__builtin_memcpy(void*, const void*, long unsigned int)' accessing
9223372036854775810 or more bytes at offsets -4611686018427387902 and
[-4611686018427387903, 4611686018427387904] may overlap up to
9223372036854775813 bytes at offset -3 [-Werror=restrict]
  431 | return static_cast(__builtin_memcpy(__s1, __s2,
__n));
  |   
^

[Bug c++/109569] warning: ‘void* __builtin_memmove(void*, const void*, long unsigned int)’ writing 1 or more bytes into a region of size 0 overflows the destination [-Wstringop-overflow=]

2023-04-20 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109569

--- Comment #4 from Frank Heckenbach  ---
Thanks.

I just got another similar one, this time with string.insert. But I guess it's
pointless to dissect this one, or do you need more examples for your test
suite?

[Bug tree-optimization/109565] -Wstrict-overflow false positive

2023-04-20 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109565

--- Comment #5 from Frank Heckenbach  ---
> Agreed, but you asked for it with that option.

Nope, I asked for warnings about signed integer overflow.

> So you shouldn't have to care about begin(c) < end(c) either, it has to be
> true. But you asked the compiler to give a warning if it relies on that
> assumption.

This was a simplified example. My real code was more like "auto i = begin (c);
((i >= end (c) || f (*i++)), ...);".

> > Note that https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html doesn't
> > even mention pointers (let alone objects such as span) for 
> > -Wstrict-overflow.
> 
> You're comparing std::span iterators, and those iterators are pointers.

Yes, pointers, and this warning isn't (documented to be) about pointers, but
about signed overflow. I don't know if GCC considers pointers signed
internally; I don't; and even GCC's output of pointers treats them as unsigned;
if anything, that's an implementation detail.

If you're not going to change it, please at least mention pointers in the
manual so the user has a small chance to understand what's going on.

[Bug c++/109569] warning: ‘void* __builtin_memmove(void*, const void*, long unsigned int)’ writing 1 or more bytes into a region of size 0 overflows the destination [-Wstringop-overflow=]

2023-04-20 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109569

--- Comment #1 from Frank Heckenbach  ---
At least I found a work-around (for now): Moving, rather than copying the
(emtpy) shared_ptr parameter to the (unused) shared_ptr member avoids the
warning.

Still, I'd like to know if this is an actual bug, or another false positive.

[Bug c++/109569] New: warning: ‘void* __builtin_memmove(void*, const void*, long unsigned int)’ writing 1 or more bytes into a region of size 0 overflows the destination [-Wstringop-overflow=]

2023-04-20 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109569

Bug ID: 109569
   Summary: warning: ‘void* __builtin_memmove(void*, const void*,
long unsigned int)’ writing 1 or more bytes into a
region of size 0 overflows the destination
[-Wstringop-overflow=]
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

Unlike most of the other issues I reported today, this one doesn't seem so
harmless, or is it?

How can I avoid it; should I just disable this warning?

Removing the shared_ptr makes it go away, even though the shared_ptr is
completely unused (in this code -- I need it in my actual code).

% cat test.cpp  
#include 
#include 

struct D
{
  const char *s = "a";
  std::shared_ptr  p;
  D (std::shared_ptr  p_ = { }): p (p_) { }
};

struct T
{
  std::vector  v;
  T ()
  {
D d;
v.insert (v.end (), d.s, d.s + 1);
  }
};

int main ()
{
  T t;
}
% g++ -c -std=c++20 -Wall -Wextra -O2  test.cpp
In file included from /usr/include/c++/12/vector:60,
 from test.cpp:1:
In static member function ‘static constexpr _Tp* std::__copy_move<_IsMove,
true, std::random_access_iterator_tag>::__copy_m(const _Tp*, const _Tp*, _Tp*)
[with _Tp = char; bool _IsMove = true]’,
inlined from ‘constexpr _OI std::__copy_move_a2(_II, _II, _OI) [with bool
_IsMove = true; _II = char*; _OI = char*]’ at
/usr/include/c++/12/bits/stl_algobase.h:495:30,
inlined from ‘constexpr _OI std::__copy_move_a1(_II, _II, _OI) [with bool
_IsMove = true; _II = char*; _OI = char*]’ at
/usr/include/c++/12/bits/stl_algobase.h:522:42,
inlined from ‘constexpr _OI std::__copy_move_a(_II, _II, _OI) [with bool
_IsMove = true; _II = char*; _OI = char*]’ at
/usr/include/c++/12/bits/stl_algobase.h:529:31,
inlined from ‘constexpr _OI std::copy(_II, _II, _OI) [with _II =
move_iterator; _OI = char*]’ at
/usr/include/c++/12/bits/stl_algobase.h:620:7,
inlined from ‘static _ForwardIterator
std::__uninitialized_copy::__uninit_copy(_InputIterator, _InputIterator,
_ForwardIterator) [with _InputIterator = std::move_iterator;
_ForwardIterator = char*]’ at
/usr/include/c++/12/bits/stl_uninitialized.h:147:27,
inlined from ‘_ForwardIterator std::uninitialized_copy(_InputIterator,
_InputIterator, _ForwardIterator) [with _InputIterator = move_iterator;
_ForwardIterator = char*]’ at
/usr/include/c++/12/bits/stl_uninitialized.h:185:15,
inlined from ‘constexpr _ForwardIterator
std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator,
allocator<_Tp>&) [with _InputIterator = move_iterator; _ForwardIterator
= char*; _Tp = char]’ at /usr/include/c++/12/bits/stl_uninitialized.h:372:37,
inlined from ‘constexpr _ForwardIterator
std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator,
_ForwardIterator, _Allocator&) [with _InputIterator = char*; _ForwardIterator =
char*; _Allocator = allocator]’ at
/usr/include/c++/12/bits/stl_uninitialized.h:397:2,
inlined from ‘constexpr void std::vector<_Tp,
_Alloc>::_M_range_insert(iterator, _ForwardIterator, _ForwardIterator,
std::forward_iterator_tag) [with _ForwardIterator = const char*; _Tp = char;
_Alloc = std::allocator]’ at /usr/include/c++/12/bits/vector.tcc:801:9,
inlined from ‘constexpr void std::vector<_Tp,
_Alloc>::_M_insert_dispatch(iterator, _InputIterator, _InputIterator,
std::__false_type) [with _InputIterator = const char*; _Tp = char; _Alloc =
std::allocator]’ at /usr/include/c++/12/bits/stl_vector.h:1779:19,
inlined from ‘constexpr std::vector<_Tp, _Alloc>::iterator std::vector<_Tp,
_Alloc>::insert(const_iterator, _InputIterator, _InputIterator) [with
_InputIterator = const char*;  = void; _Tp = char;
_Alloc = std::allocator]’ at
/usr/include/c++/12/bits/stl_vector.h:1481:22,
inlined from ‘T::T()’ at test.cpp:17:14:
/usr/include/c++/12/bits/stl_algobase.h:431:30: warning: ‘void*
__builtin_memmove(void*, const void*, long unsigned int)’ writing 1 or more
bytes into a region of size 0 overflows the destination [-Wstringop-overflow=]
  431 | __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
  | ~^~~
In file included from
/usr/include/x86_64-linux-gnu/c++/12/bits/c++allocator.h:33,
 from /usr/include/c++/12/bits/allocator.h:46,
 from /usr/include/c++/12/vector:61:
In member function ‘_Tp* std::__new_allocator<_Tp>::allocate(size_type, const
void*) [with _Tp = char]’,
inlined from ‘constexpr _Tp* std::allocator< 
>::allocate(std::size_t) [with _Tp = char]’ at
/usr/include/c++/12/bits/allocator.h:188:40,
inlined from ‘static constexpr _Tp*
std::allocator_traits >::allocate(allocator_type&,
size_type) [with _Tp = 

[Bug tree-optimization/109565] -Wstrict-overflow false positive

2023-04-20 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109565

--- Comment #2 from Frank Heckenbach  ---
Maybe technically correct, but not useful to the user.

The user's code doesn't involve pointers at all. It makes two queries about a
span object. As the user, I don't even (and shouldn't have to) care whether
pointer wraparound can occur in valid code on the given platform. (I don't
think so on Linux, but I'm not even sure.)

So if it can't validly occur, GCC can assume it doesn't, but won't need to
warn. And if it can occur, it shouldn't do this optimization.

Note that https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html doesn't even
mention pointers (let alone objects such as span) for -Wstrict-overflow.

[Bug c++/109565] New: -Wstrict-overflow false positive

2023-04-20 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109565

Bug ID: 109565
   Summary: -Wstrict-overflow false positive
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test.cpp
#include 

bool f (std::span  c)
{
  return size (c) == 2 && begin (c) < end (c);
}
% g++ -c -std=c++20 -O2 -Wstrict-overflow test.cpp
test.cpp: In function ‘bool f(std::span)’:
test.cpp:5:24: warning: assuming pointer wraparound does not occur when
comparing P +- C1 with P +- C2 [-Wstrict-overflow]
5 |   return size (c) == 2 && begin (c) < end (c);
  |  ~~^~

[Bug tree-optimization/109563] accessing 9223372036854775810 or more bytes at offsets [2, 9223372036854775807] and 1 may overlap up to 9223372036854775813 bytes at offset -3 [-Wrestrict]

2023-04-19 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109563

--- Comment #2 from Frank Heckenbach  ---
Since I can't easily upgrade to trunk, I need to know if the warning is bogus
in 12.2 and I can safely disable it, or do I need to worry about the generated
code?

[Bug c++/109563] New: accessing 9223372036854775810 or more bytes at offsets [2, 9223372036854775807] and 1 may overlap up to 9223372036854775813 bytes at offset -3 [-Wrestrict]

2023-04-19 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109563

Bug ID: 109563
   Summary: accessing 9223372036854775810 or more bytes at offsets
[2, 9223372036854775807] and 1 may overlap up to
9223372036854775813 bytes at offset -3 [-Wrestrict]
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

I'd like to know if the warning is bogus or the library actually accesses
invalid memory.

% cat test.cpp
#include 

void f (const std::string &s)
{
  "x" + std::string (s);
}
% g++ --std=c++20 -O3 -Wall -c test.cpp
In file included from /usr/include/c++/12/string:40,
 from test.cpp:1:
In static member function ‘static constexpr std::char_traits::char_type*
std::char_traits::copy(char_type*, const char_type*, std::size_t)’,
inlined from ‘static constexpr void std::__cxx11::basic_string<_CharT,
_Traits, _Alloc>::_S_copy(_CharT*, const _CharT*, size_type) [with _CharT =
char; _Traits = std::char_traits; _Alloc = std::allocator]’ at
/usr/include/c++/12/bits/basic_string.h:423:21,
inlined from ‘constexpr std::__cxx11::basic_string<_CharT, _Traits,
_Allocator>& std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>::_M_replace(size_type, size_type, const _CharT*, size_type) [with
_CharT = char; _Traits = std::char_traits; _Alloc =
std::allocator]’ at /usr/include/c++/12/bits/basic_string.tcc:532:22,
inlined from ‘constexpr std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>& std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>::replace(size_type, size_type, const _CharT*, size_type) [with _CharT =
char; _Traits = std::char_traits; _Alloc = std::allocator]’ at
/usr/include/c++/12/bits/basic_string.h:2171:19,
inlined from ‘constexpr std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::insert(size_type,
const _CharT*) [with _CharT = char; _Traits = std::char_traits; _Alloc =
std::allocator]’ at /usr/include/c++/12/bits/basic_string.h:1928:22,
inlined from ‘constexpr std::__cxx11::basic_string<_CharT, _Traits,
_Allocator> std::operator+(const _CharT*, __cxx11::basic_string<_CharT,
_Traits, _Allocator>&&) [with _CharT = char; _Traits = char_traits;
_Alloc = allocator]’ at /usr/include/c++/12/bits/basic_string.h:3541:36,
inlined from ‘void f(const std::string&)’ at test.cpp:5:7:
/usr/include/c++/12/bits/char_traits.h:431:56: warning: ‘void*
__builtin_memcpy(void*, const void*, long unsigned int)’ accessing
9223372036854775810 or more bytes at offsets [2, 9223372036854775807] and 1 may
overlap up to 9223372036854775813 bytes at offset -3 [-Wrestrict]
  431 | return static_cast(__builtin_memcpy(__s1, __s2,
__n));
  |

[Bug c++/109561] New: -Wmaybe-uninitialized false positive false positive false positive false positive false positive

2023-04-19 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109561

Bug ID: 109561
   Summary: -Wmaybe-uninitialized false positive false positive
false positive false positive false positive
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

(code and error below)

I don't know how to put this nicely, this is a terrible message:

- Most of it consists of standard library internals.

- The actual message ("may be used uninitialized") is buried well within it and
also refers to internal fields.

- It is reported no less than 5 times!?

- Most of all, AFAICS, it's bogus. The default constructor of std::optional
should construct an object that does not contain a value and such objects can
be copied just fine.

- Like many such bogus warnings apparently, it's rather volatile. Unrelated
changes, e.g. to i or removing the defaulted constructor declaration, can make
it disappear. Producing this minimal example was a lot of guesswork what can be
removed in which order without disturbing the message.

- It's a regression from 10.2.1 and 11.3.

% cat test.cpp
#include 
#include 
#include 

struct O
{
  std::optional  i;
  std::optional  s;
  O () = default;
};

std::vector  a;

void f ()
{
  for (auto &i: a)
i = { };
}
% g++ --std=c++20 -O2 -Wall -c test.cpp
In file included from /usr/include/c++/12/string:53,
 from test.cpp:3:
In member function ‘constexpr std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>::pointer std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_M_data()
const [with _CharT = char; _Traits = std::char_traits; _Alloc =
std::allocator]’,
inlined from ‘constexpr bool std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>::_M_is_local() const [with _CharT = char; _Traits =
std::char_traits; _Alloc = std::allocator]’ at
/usr/include/c++/12/bits/basic_string.h:274:23,
inlined from ‘constexpr std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>& std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>::operator=(std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&&) [with
_CharT = char; _Traits = std::char_traits; _Alloc =
std::allocator]’ at /usr/include/c++/12/bits/basic_string.h:859:23,
inlined from ‘constexpr void
std::_Optional_payload_base<_Tp>::_M_move_assign(std::_Optional_payload_base<_Tp>&&)
[with _Tp = std::__cxx11::basic_string]’ at
/usr/include/c++/12/optional:194:19,
inlined from ‘constexpr std::_Optional_payload<_Tp, true, false, false>&
std::_Optional_payload<_Tp, true, false,
false>::operator=(std::_Optional_payload<_Tp, true, false, false>&&) [with _Tp
= std::__cxx11::basic_string]’ at /usr/include/c++/12/optional:420:22,
inlined from ‘constexpr std::_Optional_payload<_Tp, false, _Copy, _Move>&
std::_Optional_payload<_Tp, false, _Copy,
_Move>::operator=(std::_Optional_payload<_Tp, false, _Copy, _Move>&&) [with _Tp
= std::__cxx11::basic_string; bool _Copy = false; bool _Move = false]’ at
/usr/include/c++/12/optional:436:26,
inlined from ‘constexpr std::_Optional_base<_Tp, , 
>& std::_Optional_base<_Tp, , 
>::operator=(std::_Optional_base<_Tp, ,  >&&) [with _Tp =
std::__cxx11::basic_string; bool  = false; bool  =
false]’ at /usr/include/c++/12/optional:550:23,
inlined from ‘constexpr std::optional >&
std::optional
>::operator=(std::optional >&&)’ at
/usr/include/c++/12/optional:705:11,
inlined from ‘constexpr O& O::operator=(O&&)’ at test.cpp:5:8,
inlined from ‘void f()’ at test.cpp:17:11:
/usr/include/c++/12/bits/basic_string.h:234:28: warning: ‘*(const
std::__cxx11::basic_string, std::allocator
>*)((char*)& + offsetof(O,
O::s.std::optional,
std::allocator >
>::.std::_Optional_base, std::allocator >, false,
false>::)).std::__cxx11::basic_string::_M_dataplus.std::__cxx11::basic_string::_Alloc_hider::_M_p’
may be used uninitialized [-Wmaybe-uninitialized]
  234 |   { return _M_dataplus._M_p; }
  |^~~~
test.cpp: In function ‘void f()’:
test.cpp:17:11: note: ‘’ declared here
   17 | i = { };
  |   ^
In member function ‘constexpr std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>::size_type std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size()
const [with _CharT = char; _Traits = std::char_traits; _Alloc =
std::allocator]’,
inlined from ‘constexpr std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>& std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>::operator=(std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&&) [with
_CharT = char; _Traits = std::char_traits; _Alloc =
std::allocator]’ at /usr/include/c++/12/bits/basic_string.h:866:17,
inlined from ‘constexpr void
std::_Optional_payload_base<_Tp>::_M_move_assign(std::_Optional_payload_base<_Tp>&&)
[with _Tp = std::__cxx11::basic_string]’ at
/usr/include/c++/12/optional:194:19,

[Bug c/109550] warning: "p" may be used uninitialized

2023-04-19 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109550

--- Comment #2 from Frank Heckenbach  ---
It might be useful then to actually say to in the warning, e.g. "p[...] may be
used uninitialized". This might have saved me some debugging effort.

But actually, that's not all. This code still gives the warning, although the
memory pointed to is now initialized:

#include 

void f (int, char const *);
void g (int);

void a (int n, char const *s)
{
  char *p = alloca (n);
  for (int i = 0; i < n; i++)
p[i] = s[i];
  f (n, p);
  for (int i = 0; i < n; i++)
g (i);
}

Though this time, the warning disappears when I remove the unrelated code below
(with the call to g). Why is that?

[Bug c/109550] New: warning: "p" may be used uninitialized

2023-04-18 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109550

Bug ID: 109550
   Summary: warning: "p" may be used uninitialized
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test.c
#include 

int f (char const *p);

void a (void)
{
  char const *p = alloca (1);
  f (p);
}
% gcc -c -Wall test.c
test.c: In function "a":
test.c:8:3: warning: "p" may be used uninitialized [-Wmaybe-uninitialized]
8 |   f (p);
  |   ^
test.c:3:5: note: by argument 1 of type "const char *" to "f" declared here
3 | int f (char const *p);
  | ^

It also happens with "malloc" instead of "alloca", but not with a normal
function.

The warning disappears when removing "const" in both places.

Ironically, when trying to work around the warning, I noticed that wrapping
alloca in another function gets rid of the warning. However, that would
actually be wrong (dangling pointer).

[Bug libstdc++/88508] std::bad_cast in std::basic_ostringstream.oss.fill()

2023-04-09 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88508

--- Comment #6 from Frank Heckenbach  ---
Yet ironically, char8_t and char16_t are meant to be used with a certain
encoding (UTF-8 and UTF-16, respectively) which is locale-independent, whereas
char is very much locale-dependent (with even EBCDIC still supported), yet it's
the latter that works out of the box without setting a locale.

[Bug libstdc++/88508] std::bad_cast in std::basic_ostringstream.oss.fill()

2023-04-07 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88508

--- Comment #4 from Frank Heckenbach  ---
(In reply to Jonathan Wakely from comment #3)

I don't think my description is "completely wrong". I'm basically saying the
same as you, in plain English.

char8_t was introduced as the preferred type for holding UTF-8 text, so this
clearly has to do with UTF-8. (And I say "text" intentionally -- single
characters are usually better represented as char32_t code points while
encodings such as UTF-8 are used for text.) Streams are the main tool for input
and output and formatting in the standard library, so a text type which does
not support input, output and formatting is indeed ridiculous.

And "imbue the stream with the relevant facets" is just techspeak for telling
the stream what the space character is (and possibly other things), like I
said.

Moreover, if streams don't support char8_t by default, they should clearly say
so (which should be easy these days with concepts, otherwise even with SFINAE)
instead of giving obscure errors about a bad cast where there is no cast.

Again, I'm not blaming gcc if the standard says so, so this discussion here is
probably a waste of time, but it might serve as a warning to other users, to
avoid falling into this trap like I did -- which is easy to fall into when u8""
literals are char8_t[] by default, and char8_t's stated purpose is to hold
UTF-8.

[Bug libstdc++/88508] std::bad_cast in std::basic_ostringstream.oss.fill()

2023-04-05 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88508

Frank Heckenbach  changed:

   What|Removed |Added

 CC||f.heckenb...@fh-soft.de

--- Comment #2 from Frank Heckenbach  ---
According to
https://stackoverflow.com/questions/57406448/canot-read-char8-t-from-basic-stringstreamchar8-t
this seems to be the same issue, so I'm not filing a new bug, just adding a
comment.

Apparently this is no GCC bug, but according to the standard. IMHO this shows
how ridiculous the current UTF-8 support is. A common I/O manipulator (setw)
fails with an inscrutable error (bad cast, what cast?) which is even suppressed
by default, unless enabled with o.exceptions, so by the default the stream just
mysteriously stops working. And all that because the library doesn't know what
the space character is in UTF-8. Just ranting, I know, but it's silly.

% cat test.cpp
#include 
#include 
#include 

int main ()
{
  std::basic_ostringstream  o;
  o.exceptions (std::ifstream::badbit);
  o << std::setw (1) << u8"";
}
% g++ -std=c++20 -Wall -Wextra -o test test.cpp  
% ./test
terminate called after throwing an instance of 'std::bad_cast'
  what():  std::bad_cast
Aborted

[Bug c++/109367] bogus -Wunused-function warning

2023-03-31 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109367

--- Comment #2 from Frank Heckenbach  ---
My full testcase consists of many includes files, libraries etc.

The type declarations (corresponding to the first two lines of the
stripped-down example) are in a header to be called from other translation
units, and the function implementation (the last line) in a cpp file, as usual.

So this means, decltype can't be used this way at all? If so, not a compiler
bug; but severely disappointed in the standard again, rendering a hopeful
feature mostly useless by too strict limitations. I hope it will be rectified
in C++38 or so ... :/

[Bug c++/109367] New: bogus -Wunused-function warning

2023-03-31 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109367

Bug ID: 109367
   Summary: bogus -Wunused-function warning
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test.cpp
using T = decltype ([]{});
struct S { static void f(T); };
void S::f(T) {}
% g++ --std=c++20 -Wall -c test.cpp
test.cpp:3:6: warning: 'static void S::f(T)' defined but not used
[-Wunused-function]
3 | void S::f(T) {}
  |  ^

This happens with decltype of a lambda or a type containing such (in my actual
use case, a multimap with a comparator defined this way) in the function's
arguments or return type.

The warning is bogus since static member functions can be accessed from
elsewhere.

[Bug c++/104577] needs copy constructor for class non-type template parameter

2022-12-27 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104577

--- Comment #3 from Frank Heckenbach  ---
(In reply to mail from comment #2)

> I looked a bit further into this and into what the standard says. GCC does
> partially the correct thing in this case, whereas several other compilers do
> the wrong thing. See https://jhellings.nl/article?articleid=1 for the full
> analysis.

I'm not a standard expert. However, I don't think your analysis applies to
quite the same situation. Your test code uses two templates with non-type
parameters, test_cases and print_nttp, and I think the critical copy occurs at
the point where the value is passed from one to the other. If I avoid the
latter template by turning it into "void print_nttp(const copy_counter &C)" and
adjusting the callers accordingly, GCC outputs "0 0 0 0 1" as I'd expect.

> The short summary:
> In Clause 8 of Section [temp.param], the standard defines the value of a
> non-type template argument:
> "An id-expression naming a non-type template-parameter of class type T
> denotes a static storage duration object of type const T known as a template
> parameter object, whose value is that of the corresponding template argument
> after it has been converted to the type of the template-parameter. ..."
> 
> Hence, whatever is provided as a non-type template parameter argument (of
> type S in this bug report) is converted to the type S and the value
> resulting from this conversion is available within the template as an lvalue
> object of type const S.
> 
> To convert an expression to type S, you either need a constexpr copy
> constructor (general case) or a constexpr move constructor (in the special
> case in which you provide a movable value). 
(which you then demonstrate using static_cast)

As I said I'm not a standard expert, but if that's so, shouldn't this program
also require a copy/move constructor? GCC accepts it without one.

struct S
{
  constexpr S () = default;
  S (S &&) = delete;
};

int main ()
{
  static_cast  (S{});
}

But let's assume it does require one. This would then indeed apply to my
original example which uses "S{}" as the template argument (which then may need
to be copied/moved), but it wouldn't apply if I change it to just "i <{}>", or
to an int such as this:

struct S
{
  constexpr S (int) { }
  S (S &&) = delete;
  operator int () const { return 0; }
};

template  int i = s;

int main ()
{
  return i <0>;
}

Now the template argument is either an empty braced-list or the integer 0 and
converting it to S does not require a copy/move constructor, but rather the
default constructor or the constructor taking an int, respectively. Still GCC
requires a copy/move constructor.

Further notes:

- If converting implies copying as you say, shouldn't GCC give 2 in the last
row? First you make an explicit copy (having count 1), then it's converted to
the argument of print_nttp which should yield in count 2, shouldn't it?

- The list of possible explanations given under "Dissecting the issue of
copy_counter" is not exhaustive:

* As you briefly mention in the text below, possible changes in the standard
between what the given compiler versions implement could be another explanation
(which may be relevant since the feature is rather new and the respective
standards have not been fully implemented by some or all of the given
compilers).

* Also possibly relevant, there's also the possibility that the program is
correct, but the standard does allow different results. I don't know and don't
claim that it is the case here, but I know there are cases where a constructor
must be available, but may or may not be actually called (copy elision). So
testing whether it is called may not not necessarily give the same answer as
finding out whether a constructor must be available.

[Bug c++/106774] warning about comparison to true/false

2022-08-31 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106774

--- Comment #6 from Frank Heckenbach  ---
> --- Comment #4 from Eric Gallager  ---
> (In reply to Richard Biener from comment #3)
> > that's more coding style though?
> 
> Yeah I personally prefer the more explicit way of writing it with both 
> operands
> myself

It's not really about operands, but the whole operation is
redundant: "mybool == true" is exactly equivalent to just "mybool".

So it's similar to a cast to the original type which GCC can also
warn about (-Wuseless-cast).

Some other existing warnings (-Wredundant-decls, -Wredundant-move)
also seem to warn about things that are no potential problems, just
redundant.

Of course, all of this can be considered a matter of style, that's
why warnings can be selected by options. (As I said, I assume it
would not be enabled by -Wall, and I don't mind whether or not it's
enabled by -Wextra.)

[Bug c++/106774] warning about comparison to true/false

2022-08-29 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106774

--- Comment #2 from Frank Heckenbach  ---
This should cover all cases mentioned:

void t (bool a, int i, float e, double f)
{
  // Boolean literal comparisons
  if (a == true)  // better: if (a)
return;
  if (a == false)  // better: if (!a)
return;
  if (a != true)  // better: if (!a)
return;
  if (a != false)  // better: if (a)
return;
  // also reversed to be sure
  if (true == a)  // better: if (a)
return;
  if (false != a)  // better: if (a)
return;

  // Integer comparisons to Boolean literals
  if (i == true)  // better: if (i == 1)
return;
  if (i == false)  // better: if (i == 0) or: if (!i)
return;  
  if (i != true)  // better: if (i != 1)
return;
  if (i != false)  // better: if (i != 0) or: if (i)
return;

  // Floating-point comparisons to Boolean literals
  if (e == true)  // very strange at all, if meant so, then better: if (e ==
1.0f)
return;
  if (f == false)  // very strange at all, if meant so, then better: if (f ==
0.0)
return;
}

[Bug c++/106774] New: warning about comparison to true/false

2022-08-29 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106774

Bug ID: 106774
   Summary: warning about comparison to true/false
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

gcc has "-Wbool-compare" to warn about boolean expression compared with an
integer value different from true/false. This warning is enabled by -Wall.

However, a warning for comparisons with true and false may also be useful. The
former is redundant, the latter can be replaced with "!".

Actually, this warning may also be given when comparing a non-Boolean integral
expression with true or false. The former is not redundant, but may often not
be what's intended (if so, one should compare with 1). The latter is equivalent
to comparing with 0, but still strange style. And comparing non-integral (e.g.
floating-point) expressions with Boolean literals is certainly warning-worthy
(though it may be caught by "-Wfloat-equal" as well).

To sum up, a new warning about comparing any expression with true/false
literals. 

Maybe something like "-Wbool-compare=2" (which would not be enabled by -Wall, I
guess; maybe by -Wextra, but even if it must be given manually, I'd find it
useful).

[Bug c/60523] Warning flag for octal literals [-Woctal-literals]

2022-08-29 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60523

Frank Heckenbach  changed:

   What|Removed |Added

 CC||f.heckenb...@fh-soft.de

--- Comment #11 from Frank Heckenbach  ---
For file modes we have S_IXUSR etc., and most programs don't even need them
very often. So I think making it part of -Wextra seems reasonable these days,
but I'd welcome such a warning either way.

https://thedailywtf.com/articles/padded-mailers recently reminded me that
0-prefixed octals can cause real problems even for experienced programmers.

[Bug c++/97165] [10/11/12/13 Regression] Infinite error stream on invalid code

2022-08-07 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97165

--- Comment #8 from Frank Heckenbach  ---
Actually not infinite, just very many, see 106549.

(Can the title be changed? It's why I didn't see this as a possible duplicate.)

[Bug c++/106549] New: excessive error messages with nested undefined template

2022-08-07 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106549

Bug ID: 106549
   Summary: excessive error messages with nested undefined
template
   Product: gcc
   Version: 10.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test.cpp
void f (X >>);
% g++ --std=c++20 test.cpp |& head -n 30
test.cpp:1:27: error: 'X' was not declared in this scope
1 | void f (X >>);
  |   ^
test.cpp:1:27: error: 'X' was not declared in this scope
test.cpp:1:27: error: 'X' was not declared in this scope
test.cpp:1:27: error: 'X' was not declared in this scope
test.cpp:1:27: error: 'X' was not declared in this scope
test.cpp:1:27: error: 'X' was not declared in this scope
test.cpp:1:27: error: 'X' was not declared in this scope
test.cpp:1:27: error: 'X' was not declared in this scope
test.cpp:1:27: error: 'X' was not declared in this scope
test.cpp:1:27: error: 'X' was not declared in this scope
test.cpp:1:27: error: 'X' was not declared in this scope
test.cpp:1:24: error: 'X' was not declared in this scope
1 | void f (X >>);
  |^
test.cpp:1:27: error: 'X' was not declared in this scope
1 | void f (X >>);
  |   ^
test.cpp:1:27: error: 'X' was not declared in this scope
test.cpp:1:27: error: 'X' was not declared in this scope
test.cpp:1:27: error: 'X' was not declared in this scope
test.cpp:1:27: error: 'X' was not declared in this scope
test.cpp:1:27: error: 'X' was not declared in this scope
test.cpp:1:27: error: 'X' was not declared in this scope
test.cpp:1:27: error: 'X' was not declared in this scope
test.cpp:1:27: error: 'X' was not declared in this scope
test.cpp:1:27: error: 'X' was not declared in this scope
test.cpp:1:27: error: 'X' was not declared in this scope
test.cpp:1:27: error: 'X' was not declared in this scope
% g++ --std=c++20 test.cpp |& wc
2921195 24780807 155318228

I don't have newer GCC versions installed locally, but according to a Godbolt
test, it seems to happen with them too (but since Godbolt truncates the
messages, I can't tell whether they produce quite the same amount).

The number of messages seems to grow exponentially with the number of template
nestings with a growth factor >11.

PS: Couldn't resist the opportunity to turn compiler output into an
animation/screensaver: ;)
g++ --std=c++20 test.cpp |& sed -un 's/   / /g;s/^  | //p' | tr -d '\n'

[Bug tree-optimization/103724] [9/10/11/12 Regression] invalid warning: iteration 7 invokes undefined behavior

2022-03-09 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103724

--- Comment #7 from Frank Heckenbach  ---
(In reply to Richard Biener from comment #6)
> (In reply to Frank Heckenbach from comment #5)
> > (In reply to Richard Biener from comment #4)
> > > One thing we could do is annotate struct loop * with the (high level)
> > > optimizations we've applied so that when we emit this warning we could say
> > > 
> > > note: this loop is the copy generated by loop unswitching where b == 0
> > > 
> > > or so.  Or maybe at least show
> > > 
> > > note: this loop was unswitched
> > 
> > If this is meant to apply to user-visible warnings, I'm not sure I'd like
> > it. I usually run with -Werror, and this would still be a warning turned
> > error then, wouldn't it?
> 
> Yes.  It might provide you with hints how to work around things though,
> like do if (c) since b must be != 0.

That was just a simplified test case. In my real code, there's nothing to
simplify from a user's point of view.

> That said, I don't think we can reasonably do something on the GCC side here.

How about an option or warning level (if not default) to just omit the warning
in the cases you'd say "note: this loop was unswitched"?

[Bug c++/104577] New: needs copy constructor to call method of class non-type template parameter

2022-02-16 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104577

Bug ID: 104577
   Summary: needs copy constructor to call method of class
non-type template parameter
   Product: gcc
   Version: 11.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test.cpp
struct S
{
  constexpr S () = default;
  S (S &&) = delete;
  operator int () const { return 0; }
};

template  int i = s;

int main ()
{
  return i ;
}
% g++ -std=c++20 test.cpp
test.cpp:8:20: error: use of deleted function 'constexpr S::S(const S&)'
test.cpp:1:8: note: 'constexpr S::S(const S&)' is implicitly declared as
deleted because 'S' declares a move constructor or move assignment operator

I don't see why a copy constructor should be needed here. (clang accepts it.)

[Bug libstdc++/104495] call_once hangs in call after exceptional call

2022-02-10 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104495

--- Comment #10 from Frank Heckenbach  ---
If it was me, it wasn't intentional, sorry.

The select box on the web form defaults to "FIXED" for me even on reload (F5).
I had to click on the link to itself to get a clean form (set to "DUPLICATE").
Don't know if that's the expected behaviour, but it did apparently confuse me.

[Bug libstdc++/104495] call_once hangs in call after exceptional call

2022-02-10 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104495

Frank Heckenbach  changed:

   What|Removed |Added

 Resolution|DUPLICATE   |FIXED

--- Comment #7 from Frank Heckenbach  ---
Not quite the same:

- 66146 reports wrong output, not hanging
- 66146 says "amd64 has the correct behavior", this once fails on amd64

[Bug libstdc++/104495] call_once hangs in call after exceptional call

2022-02-10 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104495

--- Comment #5 from Frank Heckenbach  ---
As I replacement, I'll use the following code. It's a simple double-checked
lock, probably not as efficient as the original, but seems to work.

Posted here as RFC and for anyone else who encounters the problem. Released
under CC0/public domain.

#include 
#include 
#include 

class once_flag
{
  std::atomic  a { };
  std::mutex m;
public:
  once_flag () = default;
  once_flag (once_flag &) = delete;
  friend void call_once (once_flag &o, auto &&f, auto && ... args)
  {
if (!o.a)
  if (std::lock_guard g (o.m); !o.a)
{
  std::invoke (std::forward  (f), std::forward  (args) ...);
  o.a = true;
}
  }
};

[Bug libstdc++/104495] call_once hangs in call after exceptional call

2022-02-10 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104495

--- Comment #4 from Frank Heckenbach  ---
Indeed, it has 2.31.

2.34 is only just in Debian experimental, and apparently not available as a
backport.

Since I need my code to run on various systems and I can't realistically
compile a new glibc on them, this means I have to avoid std::once_flag until
2.34 is in widespread use, is that correct?

[Bug libstdc++/104495] call_once hangs in call after exceptional call

2022-02-10 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104495

--- Comment #2 from Frank Heckenbach  ---
% g++ -print-multiarch
x86_64-linux-gnu

Debian 11.2, Linux 5.10.0-9-amd64

[Bug libstdc++/104495] New: call_once hangs in call after exceptional call

2022-02-10 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104495

Bug ID: 104495
   Summary: call_once hangs in call after exceptional call
   Product: gcc
   Version: 11.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test.cpp
#include 
#include 
#include 

std::once_flag flag2;

void may_throw_function(bool do_throw)
{
  if (do_throw) {
std::cout << "throw: call_once will retry\n";
throw std::exception();
  }
  std::cout << "Didn't throw, call_once will not attempt again\n";
}

void do_once(bool do_throw)
{
  try {
std::call_once(flag2, may_throw_function, do_throw);
  }
  catch (...) {
  }
}

int main()
{
do_once (true);
do_once (false);
}
% g++ test.cpp -pthread
% ./a.out
throw: call_once will retry
[hangs]

This is a simplified version of the example from
https://en.cppreference.com/w/cpp/thread/call_once -- the full example also
hangs.

My actual use case is a bit different, but it seems any call after an exception
call hangs; that's all that seems relevant.

[Bug c++/104494] New: -Wsuggest-attribute=noreturn catch 22

2022-02-10 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104494

Bug ID: 104494
   Summary: -Wsuggest-attribute=noreturn catch 22
   Product: gcc
   Version: 11.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test3.cpp 
void f ()
{
  [] { throw 42; } ();
}
% g++ -Wsuggest-attribute=noreturn -O3 test3.cpp -c
test3.cpp: In function 'void f()':
test3.cpp:1:6: warning: function might be candidate for attribute 'noreturn'
[-Wsuggest-attribute=noreturn]

% cat test3.cpp 
[[noreturn]] void f ()
{
  [] { throw 42; } ();
}
% g++ -Wsuggest-attribute=noreturn -O3 test3.cpp -c
test3.cpp: In function 'void f()':
test3.cpp:4:1: warning: 'noreturn' function does return

clang also gives the latter warning (it doesn't seem to have the
-Wsuggest-attribute=noreturn flag), so maybe something in the standard does
make f unsuitable for [[noreturn]]. But then -Wsuggest-attribute=noreturn
should not suggest so.

[Bug c++/104231] New: private ignored in non-type template parameter

2022-01-25 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104231

Bug ID: 104231
   Summary: private ignored in non-type template parameter
   Product: gcc
   Version: 11.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test.cpp
class A
{
  struct B
  {
constexpr B (int) { }
void error () const { throw 0; }
  };
};

template  void foo () { s.error (); }

int main ()
{
  foo <0> ();
}
% g++ -std=c++20 test.cpp
% ./a.out 
terminate called after throwing an instance of 'int'
Aborted

Being a private member of A, B should not be accessible.

The exception thrown is just to prove that a B object is indeed constructed.

[Bug c++/69818] warn for C++ functional cast expression on pointer or reference (i.e. add -Wfunctional-cast)

2022-01-23 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69818

Frank Heckenbach  changed:

   What|Removed |Added

 CC||f.heckenb...@fh-soft.de

--- Comment #8 from Frank Heckenbach  ---
Some such cases, including the original example, will run afoul of aliasing
rules and at least produce a warning about that.

However, that's not the case when the target is char &, since char is
explicitly allowed to alias. So here's an example that doesn't produce any kind
of warning with any option I tried:

#include 

int main ()
{
  float x = 1.2345f;
  using T = char &;
  std::cout << +T (x);
}

It outputs 25 on x86_64 (LE) rather than 1 as with a value cast to char.

I agree that it may occur unnoticed in generic programming where a type
parameter may easily become of reference type.

I don't see any reason why someone would intentionally want to use this
"feature" -- if one wants a reinterpret cast, one should write
reinterpret_cast.

So I agree a warning would be very useful -- I'd even say it should be included
in -Wall or -Wextra if not on by default.

See also:
https://quuxplusone.github.io/blog/2020/01/22/expression-list-in-functional-cast/

[Bug tree-optimization/103724] [9/10/11/12 Regression] invalid warning: iteration 7 invokes undefined behavior

2022-01-19 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103724

--- Comment #5 from Frank Heckenbach  ---
(In reply to Richard Biener from comment #4)
> One thing we could do is annotate struct loop * with the (high level)
> optimizations we've applied so that when we emit this warning we could say
> 
> note: this loop is the copy generated by loop unswitching where b == 0
> 
> or so.  Or maybe at least show
> 
> note: this loop was unswitched

If this is meant to apply to user-visible warnings, I'm not sure I'd like it. I
usually run with -Werror, and this would still be a warning turned error then,
wouldn't it?

[Bug c++/94061] defaulted member operator <=> defined as deleted if a base has protected member operator <=>

2022-01-08 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94061

--- Comment #3 from Frank Heckenbach  ---
(In reply to Patrick Palka from comment #2)
> How do you define it?  It works if we define it as
> 
>   auto operator <=> (const B& b) const {
> return A::operator<=>(b);
>   }
> 
> but not if it's defined as
> 
>   auto operator <=> (const B& b) const {
> return static_cast(*this) <=> static_cast(b);
>   }

I'd do the former. I don't know what the standard says exactly, but intuitively
it seems to me that "protected" should suffice, also by comparison with
constructors.

[Bug c++/94061] defaulted member operator <=> defined as deleted if a base has protected member operator <=>

2022-01-07 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94061

Frank Heckenbach  changed:

   What|Removed |Added

 CC||f.heckenb...@fh-soft.de

--- Comment #1 from Frank Heckenbach  ---
I ran into the same problem.

Interestingly, clang also seems to reject it, so maybe it is wrong by the
letter of the standard? Though it would seem strange to me -- after all, when
manually implementing B::operator<=> a protected operator in A will do fine.

I hope someone who knows the standard more intimately can confirm whether
that's so and possibly open a defect report to the standard.

Fun fact: When I independently created a minimal test program, my result was
exactly identical to yours (modulo whitespace), including the names of the
structs. :)

[Bug c++/103947] New: wishlist: warning if explicitly defaulted (spaceship) operator is deleted

2022-01-07 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103947

Bug ID: 103947
   Summary: wishlist: warning if explicitly defaulted (spaceship)
operator is deleted
   Product: gcc
   Version: 11.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test.cpp
#include 

struct A { };

struct B: A
{
  auto operator <=> (const B &) const = default;
};

int main ()
{
  B () == B ();
}
% g++ -std=c++20 -Wall -Wextra test.cpp
test.cpp:7:8: note: 'constexpr bool B::operator==(const B&) const' is
implicitly deleted because the default definition would be ill-formed:
[...]

This error is correct, of course.

When commenting out the statement in main, though, the program compiles without
a warning.

I think a warning would be useful here, since the programmer explicitly
declared the defaulted operator, so they wouldn't expect it to be deleted.

In my actual use case, I did get the error where the code tried to use the
operator, but that was (a) far removed from that declaration and (b) buried in
lots of "candidate" notes (as is common, especially with commonly used
operators), so I actually had to grep through the compiler output to find the
place where it explained why this (intended) candidate was deleted. A warning
right at the declaration would have made it much easier to find.

[Bug c/103725] New: warning: assuming signed overflow does not occur when simplifying conditional to constant

2021-12-14 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103725

Bug ID: 103725
   Summary: warning: assuming signed overflow does not occur when
simplifying conditional to constant
   Product: gcc
   Version: 11.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test.c  
int d = 0, b = 8, a[8][8];

struct S
{
  int c;
};

void foo (int *c)
{
  if (b >= 0)
{
  if (*c) d = *c;
  if (*c < 0) d = *c;
}
}

int main ()
{
  struct S i = { 0 };
  for (int e = 0; e < 11; e++, i.c++)
{
  d = a[i.c >= b ? i.c - b : i.c][i.c + 1 >= b ? i.c + 1 - b : i.c + 1];
  foo (&i.c);
}
}
% gcc -O2 -Wstrict-overflow test.c 
test.c: In function 'main':
test.c:22:66: warning: assuming signed overflow does not occur when simplifying
conditional to constant [-Wstrict-overflow]
   22 |   d = a[i.c >= b ? i.c - b : i.c][i.c + 1 >= b ? i.c + 1 - b : i.c
+ 1];
  |  
~~~^

This is not the same as https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103724 (in
fact, that was a collateral damage while bisecting this one), though they may
be internally related since this warning also depends only many circumstances,
plus a few more (like, there must be a struct, a plain integer won't cause the
warning; and e and i.c must be distinct although they count in lockstep).

To a user, the warning is worrying since none of the visible conditionals
should be able to be simplified to a constant.

What seems to be happening, as far as I can tell from looking at the generated
code, is that GCC internally splits cases and then simplifies conditions in one
of them (since i.c >= b implies i.c + 1 >= b, unless signed overflow which
seems to explain the cause of the warning).

But the user normally doesn't see this and gets the impression one of their
conditions is wrongly simplified. This, and the fact that the warning doesn't
seem very robust in the first place (i.e. depends on many circumstances), seems
to make the whole "-Wstrict-overflow" option a bit less than useful, IMHO.

I get another spurious warning like this in a more complex piece of my code,
and it also seems to depend on many circumstances, so I can't easily provide a
reproducible example, but it may be a similar situation like this one in the
end. (And these were the only ones I got, i.e. it didn't actually help me find
a real bug in my code.)

Since it also doesn't seem possible to suppress the warning locally with a
pragma (since it's generated at a late stage, I suppose), I think I'll have to
disable it again. (I had re-enabled it after I heard
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70455 was fixed. It may work
better now, but still too mysterious to actually help me.)

[Bug c/103724] invalid warning: iteration 7 invokes undefined behavior

2021-12-14 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103724

Frank Heckenbach  changed:

   What|Removed |Added

Summary|warning |invalid warning: iteration
   ||7 invokes undefined
   ||behavior

--- Comment #1 from Frank Heckenbach  ---
% cat test.c 
int d = 0, b = 8, a[8][8];

int main ()
{
  for (int c = 0; c < 11; c++)
{
  d = a[c >= b ? c - b : c][c + 1 >= b ? c + 1 - b : c + 1];
  if (b && c)
d = c;
}
}
% gcc -O3 test.c
test.c: In function 'main':
test.c:7:32: warning: iteration 7 invokes undefined behavior
[-Waggressive-loop-optimizations]
7 |   d = a[c >= b ? c - b : c][c + 1 >= b ? c + 1 - b : c + 1];
  |   ~^~~~
test.c:5:3: note: within this loop
5 |   for (int c = 0; c < 11; c++)
  |   ^~~

Many things are strange about this warning:

- First, I think it's invalid -- the "?:" ensures the array indexes are in
bounds, all variables are initialized,so I don't see what would be UB.

- It claims UB occurs on iteration 7, but the warning disappears when I change
the loop condition to "c < 10" (which would also include iteration 7)

- The "if" statement with both conditions and the assignment is necessary to
trigger the warning, although it has no actual effect.

- The warning seems to apply to the 2nd array index, but already disappears
when I turn the first index into "0" without changing the 2nd one.

- It disappears when I make all variables local or all global.

[Bug c/103724] New: warning

2021-12-14 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103724

Bug ID: 103724
   Summary: warning
   Product: gcc
   Version: 11.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

[Bug c++/103703] New: ICE with -Wmismatched-tags

2021-12-13 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103703

Bug ID: 103703
   Summary: ICE with -Wmismatched-tags
   Product: gcc
   Version: 11.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat test.cpp
template  struct A { struct B { }; };
template  struct C { friend struct A ::B; };
% g++ -Wmismatched-tags test.cpp
test.cpp:2:59: internal compiler error: Segmentation fault
2 | template  struct C { friend struct A ::B; };
  |   ^
0x1786229 internal_error(char const*, ...)
???:0
0x78c6ed class_decl_loc_t::diag_mismatched_tags(tree_node*)
???:0
0x790955 class_decl_loc_t::diag_mismatched_tags()
???:0
0x7c482e c_parse_file()
???:0
0x896762 c_common_parse_file()
???:0
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See  for instructions.
Compiler returned: 1

[Bug target/103098] bogus error: the last argument must be an 8-bit immediate

2021-11-05 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103098

--- Comment #2 from Frank Heckenbach  ---
https://gcc.gnu.org/onlinedocs/gcc/x86-Built-in-Functions.html

[Bug c/103098] New: bogus error: the last argument must be an 8-bit immediate

2021-11-05 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103098

Bug ID: 103098
   Summary: bogus error: the last argument must be an 8-bit
immediate
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

% cat t.c
long long int __attribute__ ((__vector_size__ (16))) a;

int main (void)
{
  a = __builtin_ia32_pslldqi128 (a, 1);
}
% gcc t.c
t.c: In function 'main':
t.c:5:7: error: the last argument must be an 8-bit immediate
   a = __builtin_ia32_pslldqi128 (a, 1);
   ^~~~

[Bug c++/102921] error: modification of '' is not a constant expression

2021-10-24 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102921

--- Comment #1 from Frank Heckenbach  ---
The following program, compiled with "-std=c++20" gives this error message; I
don't even understand what it's trying to tell me:

  error: modification of '' is not a constant expression

#include 
#include 

constexpr std::initializer_list  a { "" };

Other compilers seem to have no problem with it.

Digging through the headers, I could trace it (via char_traits and
__constant_string_p) to __builtin_is_constant_evaluated. The following version
gives the same error (but I'm still not sure if the problem is in the compiler
or the headers):

#include 
#include 

struct S
{
  constexpr S () noexcept { }
  int a = std::is_constant_evaluated ();
};

constexpr std::initializer_list  a { { } };

[Bug c++/102921] New: error: modification of '' is not a constant expression

2021-10-24 Thread f.heckenbach--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102921

Bug ID: 102921
   Summary: error: modification of '' is not a constant
expression
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---