[Bug c/115185] Missing "too long" warning when string-array size doesn't include NULL byte

2024-05-22 Thread Hi-Angel at yandex dot ru via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115185

--- Comment #3 from Konstantin Kharlamov  ---
(In reply to Andrew Pinski from comment #2)
> It is included in -Wc++-compat .

Cool, thanks! I'll add the warning to the list we compile the project with,
thank you!

[Bug c/115185] New: Missing "too long" warning when string-array size doesn't include NULL byte

2024-05-22 Thread Hi-Angel at yandex dot ru via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115185

Bug ID: 115185
   Summary: Missing "too long" warning when string-array size
doesn't include NULL byte
   Product: gcc
   Version: 14.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Hi-Angel at yandex dot ru
  Target Milestone: ---

It's a common pattern to have some `enum Foo { one, two, three }`, and then
some 2-dimensinal array `FooAsString`, which allows one to get name of the
`Foo` field by passing an index, like `printf("%s",
FooAsString[my_Foo_variable])`.

Problem though is that it isn't allowed to declare multi-dimensinal array and
omit all dimensions, so one have to declare as `FooAsString[][6]` for example.
That makes programmer to rely on the compiler to detect when the `6` is not
enough to hold the string.

GCC kind of tries to warn about that, however its check is off-by-one because
it does not take into account the NULL byte that the C-string has to end with.


# Steps to reproduce (in terms of terminal commands)

λ cat test.c
#include 

int main() {
enum Foo {
hello,
} obj = hello;
static const char description[][5] = {[hello] = "hello"};

printf("%s", description[obj]);
}
λ gcc test.c -o a -Wall -Wextra


## Expected

A warning:

test.c:7:53: warning: initializer-string for array of ‘char’ is too long
7 | static const char description[][5] = {[hello] = "hello"};

## Actual

No warnings.

[Bug c/97100] -Wformat checks all arms of _Generic leading to irrelevant type expectation warnings

2024-04-16 Thread Hi-Angel at yandex dot ru via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97100

--- Comment #12 from Konstantin Kharlamov  ---
(In reply to Martin Uecker from comment #11)
> A conforming C compiler has to diagnose all violations of constraints with
> the same correct type of x in all branches (not the type it would have in
> another context where a different is taken).

As mentioned in my prev. comment, a conforming C compiler don't have to
diagnose anything at all. And in fact, GCC doesn't even diagnose anything, well
not unless you explicitly pass a -Wfoo. Which doesn't make GCC any less
conforming. Thus, I see no constraints to printing warnings that are useful.

[Bug c/97100] -Wformat checks all arms of _Generic leading to irrelevant type expectation warnings

2024-04-16 Thread Hi-Angel at yandex dot ru via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97100

--- Comment #10 from Konstantin Kharlamov  ---
(In reply to uecker from comment #9)
> Some warnings are then even required to be standard compliant.

I just searched through the C standard and no warnings seem to be required by
it. The only place where word "warning" is mentioned is in the Annex Ⅰ, which
tilted as "informative" and only serves as an example of where warnings might
be useful.

> x is - according to the C standard - always whatever it is in the controlling
> expression.

With the prev. paragraph in mind, compiler is free to warn or not to about
anything. The only (arguable) limitation is being useful. So nothing holds a
compiler off from considering for the warning purposes the `x` to have
different types on the outside of _Generic() compared to the inside.

> Note that this also does not have to be an identifier, but could be a complex
> expression. So there seems no simply algorithm for a compiler to do the right 
> thing
> in general regarding warnings.

Idk why complexity matters, it's not like `x` is dynamically typed, so no
solving halting problem requried. For me it looks simple: if `x` entered either
branch of _Generic, just consider it to have a type different from what it was
and produce correct warnings 

[Bug c/97100] -Wformat checks all arms of _Generic leading to irrelevant type expectation warnings

2024-04-15 Thread Hi-Angel at yandex dot ru via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97100

--- Comment #8 from Konstantin Kharlamov  ---
(In reply to uecker from comment #7)
> Fundamentally, the program is that _Generic is not ideally designed for this
> use case. 

Why?

> One could consider an extension
> 
> _Generic(x, int i: f(i), long l: g(l));
> 
> that allows referring to the first argument with the type it would have in
> each branch.

Unless I'm missing something, a compiler already knows if `x` is an `int` or
`long`. I see no benefit in devising such extension.

[Bug c/111598] New: Wimplicit-fallthrough print for a code that is not compiled in

2023-09-26 Thread Hi-Angel at yandex dot ru via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111598

Bug ID: 111598
   Summary: Wimplicit-fallthrough print for a code that is not
compiled in
   Product: gcc
   Version: 13.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Hi-Angel at yandex dot ru
  Target Milestone: ---

When a switch-case has a "fallthrough" case that is surrounded by an `#ifdef`
and is not compiled in, GCC does not recognize the `// fallthrough` comment and
prints a `this statement may fall through` warning.

# Steps to reproduce

$ cat test2.c
#include 

int main() {
enum {Field1, Field2} e = 0;
switch (e) {
case Field1:
puts("field1");
// fallthrough
#ifdef SOME_UNDEFINED_MACRO
case Field2:
puts("field2");
// fallthrough
#endif
default:
puts("default");
}
}
$ gcc test2.c -o /dev/null -Wimplicit-fallthrough
test2.c: In function ‘main’:
test2.c:7:13: warning: this statement may fall through
[-Wimplicit-fallthrough=]
7 | puts("field1");
  | ^~
test2.c:14:9: note: here
   14 | default:
  | ^~~


## Expected

No warning, because every case ends with a fallthrough comment

## Actual

There's a warning

[Bug c/97100] -Wformat checks all arms of _Generic leading to irrelevant type expectation warnings

2023-07-17 Thread Hi-Angel at yandex dot ru via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97100

Konstantin Kharlamov  changed:

   What|Removed |Added

 CC||Hi-Angel at yandex dot ru

--- Comment #1 from Konstantin Kharlamov  ---
Still relevant. Just stumbled upon it in 13.1.1, was about to report a bug.

[Bug c++/92559] Returning std∷map breaks tail-recursion optimization

2021-07-24 Thread Hi-Angel at yandex dot ru via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92559

--- Comment #5 from Konstantin Kharlamov  ---
(In reply to Konstantin Kharlamov from comment #4)
> By the way, FTR: I don't have the code anymore, but initially the problem
> came from a real-life algorithm involving lots of state, which looked barely
> readable when implemented in iterative way (i.e. as opposed to "recursive",
> that is when you use for/while-cycles instead of recursion). The iterative
> version was 1.5 times bigger than the recursive one, and has a lot of
> additional state-tracking variables; and I think it also has two cycles (as
> compared to recursive version that has none at all).

Oh, I just remember: the recursive version was also immutable, which also made
the code much easier to understand (and I was kinda hoping, easier for the
compiler to optimize as well). The iterative version involved lots of
mutations. They always do.

[Bug c++/92559] Returning std∷map breaks tail-recursion optimization

2021-07-24 Thread Hi-Angel at yandex dot ru via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92559

--- Comment #4 from Konstantin Kharlamov  ---
By the way, FTR: I don't have the code anymore, but initially the problem came
from a real-life algorithm involving lots of state, which looked barely
readable when implemented in iterative way (i.e. as opposed to "recursive",
that is when you use for/while-cycles instead of recursion). The iterative
version was 1.5 times bigger than the recursive one, and has a lot of
additional state-tracking variables; and I think it also has two cycles (as
compared to recursive version that has none at all).

Back then we decided that we want the readable code, because at the end of the
day, readable code is the reason people don't write assembly and rely on
compilers to optimize instead. Of course, we would have to add to CI some
checks to make sure the optimization was done as expected (tho I don't think it
was ever added, simply because since the optimization currently doesn't work,
there's nothing to check).

IIRC, this bug-report was a reduced problem of tail-recursion not working for
us. The state in the algorithm has std::map in particular I think.

[Bug c++/92559] Returning std∷map breaks tail-recursion optimization

2021-07-24 Thread Hi-Angel at yandex dot ru via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92559

--- Comment #3 from Konstantin Kharlamov  ---
(In reply to Andrew Pinski from comment #2)
> I don't think this can ever be optimized.  Mainly because there are copies
> happening due to passing via value and returning by value.

Please correct me if I'm wrong, but it seems like, given the code in question:

MyMap foo(MyMap m) {
if (m[0] == 0)
return m;
else {
m[0] -= 1;
return foo(m);
}
}

When tail-recursion optimization applied, it should be analogous to this code:

MyMap foo(MyMap m) {
while(m[0] > 0) {
m[0] -= 1;
m = MyMap(m);
}
return m;
}

Doesn't look impossible to me, unless of course I am missing something.

[Bug c/101525] New: "out of the bounds" warning for an Innocuous memset call with LTO

2021-07-20 Thread Hi-Angel at yandex dot ru via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101525

Bug ID: 101525
   Summary: "out of the bounds" warning for an Innocuous memset
call with LTO
   Product: gcc
   Version: 11.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Hi-Angel at yandex dot ru
  Target Milestone: ---

Created attachment 51176
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51176=edit
preprocessed file that triggers the warnings

Given this memset call

static bool
append_space_for_newline (struct it *it, bool default_face_p) {
[…]
  memset (>position, 0, sizeof it->position);

GCC complains:

xdisp.c: In function ‘append_space_for_newline’:
xdisp.c:21906:7: warning: ‘memset’ offset [2352, 2359] from the object at
‘it_122(D)’ is out of the bounds of referenced subobject ‘charpos’ with type
‘long int’ at offset 2344 [-Warray-bounds]
21906 |   memset (>position, 0, sizeof it->position);
  |   ^~
In file included from composite.h:29,
 from xdisp.c:441:
dispextern.h:214:13: note: subobject ‘charpos’ declared here
  214 |   ptrdiff_t charpos;
  | ^~~

I can't see any overflow on this line. Either way, further experiments show
that removing the function content below the offending line makes warnings
disappear. Since it's impossible to make overflow disappear by removing a code
below the overflow, the warning disappearance suggests the warning is a GCC bug
and should not be there.



I couldn't reduce it down to a minimal testcase because removing irrelevant
code makes warning go away, so instead in steps-to-reproduce I use a
preprocessed source. I had to compress it to be able to attach. The original is
a `src/xdisp.c` file in Emacs project at commit `6ebe8b03d80`.

# Steps to reproduce

1. Download `xdisp.preprocessed.c.zst`
2. Unpack with: zstd -d xdisp.preprocessed.c.zst
3. Compile with: gcc -c -Warray-bounds=2 -flto=2 -O3 -ffat-lto-objects 
xdisp.preprocessed.c

## Expected

No warnings for `append_space_for_newline` function

## Actual

There is a warning:

xdisp.c: In function ‘append_space_for_newline’:
xdisp.c:21906:7: warning: ‘memset’ offset [2352, 2359] from the object at
‘it_140(D)’ is out of the bounds of referenced subobject ‘charpos’ with type
‘long int’ at offset 2344 [-Warray-bounds]
In file included from composite.h:29,
 from xdisp.c:441:
dispextern.h:214:13: note: subobject ‘charpos’ declared here

[Bug middle-end/92718] [9/10/11/12 Regression] Bogus Wstringop-overflow in __builtin_memset() of an element of array of size 1 of struct

2021-07-20 Thread Hi-Angel at yandex dot ru via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92718

--- Comment #9 from Konstantin Kharlamov  ---
Omg, I am sorry, please ignore my comment. For some incomprehensible reason
bugzilla circles through bug entries upon sending a comment. My comment here
was supposed for another report, but then apparently bugzilla circled through
to another report, and I after I didn't see my comment I concluded it glitched
out and wrote it anew.

[Bug middle-end/92718] [9/10/11/12 Regression] Bogus Wstringop-overflow in __builtin_memset() of an element of array of size 1 of struct

2021-07-20 Thread Hi-Angel at yandex dot ru via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92718

Konstantin Kharlamov  changed:

   What|Removed |Added

 CC||Hi-Angel at yandex dot ru

--- Comment #8 from Konstantin Kharlamov  ---
(I hope a duplicate comment won't appear, my previous one didn't appear for
some reason)

Should this be closed? Judging by comments it was fixed, and I also can't
reproduce it with the attached testcase on GCC 11.1.0.

[Bug middle-end/93437] [9 Regression] bogus -Warray-bounds on protobuf generated code

2021-07-20 Thread Hi-Angel at yandex dot ru via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93437

Konstantin Kharlamov  changed:

   What|Removed |Added

 CC||Hi-Angel at yandex dot ru

--- Comment #6 from Konstantin Kharlamov  ---
Should this be closed? Judging by comments the bug was fixed, and I also can't
reproduce it with the attached testcase on GCC 11.1.0

[Bug c++/92559] New: Returning std∷map breaks tail-recursion optimization

2019-11-18 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92559

Bug ID: 92559
   Summary: Returning std∷map breaks tail-recursion optimization
   Product: gcc
   Version: 9.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Hi-Angel at yandex dot ru
  Target Milestone: ---

The following code, exploiting tail-recursion, does not get optimized into a
loop with -O3 option, so it crashes if you try to run it.

#include 

using MyMap = std::map;

MyMap foo(MyMap m) {
if (m[0] == 0)
return m;
else {
m[0] -= 1;
return foo(m);
}
}

int main() {
MyMap m = {{0, 99}};
foo(m);
}

While debugging GCC, I found that `find_tail_calls()` function quits at this
code¹:

  /* If the statement references memory or volatile operands, fail.  */
  if (gimple_references_memory_p (stmt)
  || gimple_has_volatile_ops (stmt))
return;


1:
https://github.com/gcc-mirror/gcc/blob/38f05dc5db9241d3de8041a683972f086edce561/gcc/tree-tailcall.c#L464

I haven't found any duplicates of this so far.

[Bug middle-end/48363] Recursion not converted into a loop

2019-11-18 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48363

Konstantin Kharlamov  changed:

   What|Removed |Added

 CC||Hi-Angel at yandex dot ru

--- Comment #4 from Konstantin Kharlamov  ---
I think this is solved. For gcc 9.2.0, when I build the testcase as `gcc test.c
-o a -g -O2`, and then look at the assembly with `objdump -d a | vim -`, I see
`main` function has just a single `callq`, which is to `printf`. So the whole
code was apparently optimized and inlined into main().

[Bug tree-optimization/71761] missing tailcall optimization

2019-11-18 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71761

--- Comment #6 from Konstantin Kharlamov  ---
Thanks, okay, so, for the record: comment #3 seems no longer relevant, since
the function `find_tail_calls()`, when analyzing g(), gets executed till its
end. No early returns anywhere. Tested with: GCC 10.0.0 20191017, commit
"a6d1006b1b2 [ARM,testsuite] Fix typo in arm_arch_v8a_ok effective target."

[Bug tree-optimization/71761] missing tailcall optimization

2019-11-18 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71761

Konstantin Kharlamov  changed:

   What|Removed |Added

 CC||Hi-Angel at yandex dot ru

--- Comment #4 from Konstantin Kharlamov  ---
(In reply to Marc Glisse from comment #3)
> For clang, this seems based on size: up to size 16 they get jmp, starting
> from 17 they get a call.
>
> For gcc, we give up on anything more complicated than a "register":
>
>   /* If the LHS of our call is not just a simple register, we can't
>  transform this into a tail or sibling call.  This situation happens,
>  in (e.g.) "*p = foo()" where foo returns a struct.  In this case
>  we won't have a temporary here, but we need to carry out the side
>  effect anyway, so tailcall is impossible.
>
>  ??? In some situations (when the struct is returned in memory via
>  invisible argument) we could deal with this, e.g. by passing 'p'
>  itself as that argument to foo, but it's too early to do this here,
>  and expand_call() will not handle it anyway.  If it ever can, then
>  we need to revisit this here, to allow that situation.  */
>   if (ass_var && !is_gimple_reg (ass_var))
> return;
>
> The ??? comment is exactly your case.

So this means, if I dump GIMPLE, I should see something wrong, right? When I do
this, given a file named test.cpp and I use `-fdump-tree-all`, the whole GIMPLE
I see in file `test.cpp.231t.optimized` is this:

;; Function g (_Z1gv, funcdef_no=0, decl_uid=2305, cgraph_uid=1,
symbol_order=0)

g ()
{
   [local count: 1073741824]:
  # DEBUG BEGIN_STMT
   = f (); [return slot optimization] [tail call]
  return ;

}



;; Function main (main, funcdef_no=1, decl_uid=2341, cgraph_uid=2,
symbol_order=1) (executed once)

main ()
{
  struct token D.2343;

   [local count: 1073741824]:
  # DEBUG BEGIN_STMT
  # DEBUG INLINE_ENTRY g
  # DEBUG BEGIN_STMT
  D.2343 = f (); [return slot optimization]
  D.2343 ={v} {CLOBBER};
  return 0;

}

What should I see? Should there be a `goto f` inside `g()` function, or what?

[Bug middle-end/91515] missed optimization: no tailcall for types of class MEMORY

2019-11-15 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91515

--- Comment #2 from Konstantin Kharlamov  ---
I think this is a duplicate of
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71761

[Bug sanitizer/92474] Sanitizer breaks tail-recursion optimization

2019-11-12 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92474

--- Comment #2 from Konstantin Kharlamov  ---
(In reply to Jakub Jelinek from comment #1)
> Note, starting with r273603, the trunk doesn't tail call optimize this
> either even without -fsanitize=, unless -fno-tree-sra.

Is there a report for this?

[Bug sanitizer/92474] New: Sanitizer breaks tail-recursion optimization

2019-11-12 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92474

Bug ID: 92474
   Summary: Sanitizer breaks tail-recursion optimization
   Product: gcc
   Version: 9.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: sanitizer
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Hi-Angel at yandex dot ru
CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at 
gcc dot gnu.org
  Target Milestone: ---

When `-fsanitize=address` applied, tail-call optimization does not kick in.

I made a testcase below. Simplest way to demonstrate it would be to try to run
executable built from the testcase with and without the option: it either
crashes or not. But since it's an arguable demonstration (because how does one
know if non-crashing version didn't simply did not consume enough stack), I
demonstrate it with a different approach: I grep the assembly for `callq
foo()`, and while the case with optimization applied has just one call to it,
the case where it wasn't applied has 2 of them.

# Steps to reproduce (in terms of terminal commands):

$ cat test.cpp
struct MyStruct {
unsigned  n_recurses;
};

MyStruct foo(MyStruct m) {
return (m.n_recurses == 0)? m : foo(MyStruct{m.n_recurses - 1});
}

int main() {
foo(MyStruct{99});
}
$ g++ test.cpp -o a -O3 -g
$ objdump -d a | grep -E "callq.*foo"
1029:   e8 12 01 00 00  callq  1140 <_Z3foo8MyStruct>
$ g++ test.cpp -o a -O3 -g -fsanitize=address
$ objdump -d a | grep -E "callq.*foo"

## Expected:

One line with the call:
1089:   e8 32 01 00 00  callq  11c0 <_Z3foo8MyStruct>

## Actual:

Two lines with the call:
1089:   e8 32 01 00 00  callq  11c0 <_Z3foo8MyStruct>
1293:   e8 28 ff ff ff  callq  11c0 <_Z3foo8MyStruct>

[Bug sanitizer/91878] No sanitizer report for past-end access of std∷set

2019-09-24 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91878

--- Comment #7 from Konstantin Kharlamov  ---
@Jonathan Wakely I think you accidentally closed the report, would you mind to
reopen it (I'm not seeing why would it be "invalid", people even confirmed that
more support for std containers is being added to sanitizers).

[Bug sanitizer/91878] No sanitizer report for past-end access of std∷set

2019-09-24 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91878

--- Comment #6 from Konstantin Kharlamov  ---
(In reply to Jonathan Wakely from comment #5)

> No, that's not how undefined behaviour works. You are wrong to expect a crash

No, in context of the report I'm not. You're correct this is not how UB works,
but this is how address sanitizer does.

> and not all cases of undefined behaviour can be detected reliably.

Well, given -D_GLIBCXX_DEBUG does handle it, probably sanitizer can either.

> As Marc said (and as I suggested on your previous bug report) you should use
> -D_GLIBCXX_DEBUG to catch these kind of bugs.

Right, thanks, FTR: my prev. report was handled by sanitizer correctly, so back
then I wouldn't need to use the additional debugging option.

[Bug sanitizer/91878] No sanitizer report for past-end access of std∷set

2019-09-24 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91878

--- Comment #4 from Konstantin Kharlamov  ---
(In reply to Marc Glisse from comment #3)
> -D_GLIBCXX_DEBUG is the current way to add many checks to libstdc++, and it
> detects this.

Oh, cool, I'll make use of it, thanks for the hint!

[Bug sanitizer/91878] No sanitizer report for past-end access of std∷set

2019-09-24 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91878

--- Comment #1 from Konstantin Kharlamov  ---
Btw, worth noting that clang 8.0.1 does not handle it either.

[Bug sanitizer/91878] New: No sanitizer report for past-end access of std∷set

2019-09-24 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91878

Bug ID: 91878
   Summary: No sanitizer report for past-end access of std∷set
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: sanitizer
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Hi-Angel at yandex dot ru
CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at 
gcc dot gnu.org
  Target Milestone: ---

# Steps to reproduce (in terms of terminal commands)

$ cat test2.cpp
#include 
#include 

int main() {
std::set s{};
printf("%i\n", *s.begin());
}
$ g++ test2.cpp -o a -g3 -O0 -fsanitize=address,undefined
$ ./a

## Expected

It either crashes on past-end access, or produces a warning (depending on
whether it's handled as a past-end access or UB).

## Actual

It prints:

0

[Bug c++/91777] No warning for iterator going out of scope

2019-09-17 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91777

--- Comment #5 from Konstantin Kharlamov  ---
(In reply to Martin Liška from comment #4)
> (In reply to Konstantin Kharlamov from comment #3)
> > (In reply to Martin Liška from comment #2)
> > > I can see a ASAN error:
> > 
> > Correct. You set the report status to WAITING: do you expect some answer
> > from me, or was it accidental?
> 
> Well, you mentioned that there's no output from ASAN. But I see it properly
> reported. That's why I set the status to waiting.

You misread it :) I didn't mention asan, and "steps to reproduce" lack the step
of running the executable.

I did add the sanitizer to options in the "steps" though, just to make sure if
anyone tries to execute the binary, it gonna crash.

[Bug c++/91777] No warning for iterator going out of scope

2019-09-17 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91777

--- Comment #3 from Konstantin Kharlamov  ---
(In reply to Martin Liška from comment #2)
> I can see a ASAN error:

Correct. You set the report status to WAITING: do you expect some answer from
me, or was it accidental?

[Bug c++/91777] No warning for iterator going out of scope

2019-09-16 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91777

--- Comment #1 from Konstantin Kharlamov  ---
FTR, on IRC was referenced the following paper that may be interesting for
implementors
https://github.com/isocpp/CppCoreGuidelines/blob/master/docs/Lifetime.pdf

[Bug c++/91777] New: No warning for iterator going out of scope

2019-09-16 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91777

Bug ID: 91777
   Summary: No warning for iterator going out of scope
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Hi-Angel at yandex dot ru
  Target Milestone: ---

The testcase below would've worked if instead of `return {l,…` was used `return
{move(l),…`. But it wasn't, and due to lack of borrow-semantics in C++ language
such mistakes are easy to make. In these circumstances programmers has to rely
on compiler warnings, so it would be amazing if GCC warn about iterators still
referencing the out-of-scope container.

# Steps to reproduce (in terms of terminal commands)

$ cat test.cpp
#include 
#include 

using namespace std;

pair, list::const_iterator> foo() {
list l = {1,2,3};
return {l, l.begin()};
}

int main() {
pair p = foo();
printf("%i\n", *p.second);
}
$ g++ test.cpp -o a -O3 -Wall -Wextra -Wsign-conversion -std=c++17
-fsanitize=address,undefined

## Expected

A warning about the second element in `return {l, l.begin()}` become invalid
once `l` goes out of scope.

## Actual

No output.

[Bug debug/91751] In backtrace, calls to c++ destructors are shown way afar from the actual place

2019-09-12 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91751

--- Comment #3 from Konstantin Kharlamov  ---
(In reply to Jonathan Wakely from comment #2)
> The advantage of showing the location of the constructor is that you can see
> which object is being destroyed. If the location was shown as the end of the
> scope, all local variables would show the same location.

Fair enough. But it's confusing too. A function may have multiple places where
it "goes out of scope", and if you debug a problem involving an object
destructor, it's hard to understand which path got executed.

Besides, it's non-intuitive, it looks as if an object was just created, and
then immediately destroyed. What you describe, on the other hand, is a natural
problem, and should not be worked around by placing line number at place with
object creation.

[Bug debug/91751] New: In backtrace, calls to c++ destructors are shown way afar from the actual place

2019-09-12 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91751

Bug ID: 91751
   Summary: In backtrace, calls to c++ destructors are shown way
afar from the actual place
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: debug
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Hi-Angel at yandex dot ru
  Target Milestone: ---

As the title says. I'm not aware of a way to get backtrace with gcc builtins,
so I'm using gdb in testcase, so it's possible that it's a bug in gdb. But to
me a wrong debugging information sounded more likely, so I'm reporting here.

# Steps to reproduce

$ cat test.cpp
#include 

struct MyStruct {
void use_the_object() { puts("MyStruct is still in use"); }
~MyStruct() {
puts("MyStruct destructor called");
}
};

int main() {
MyStruct m;
printf("line %i crossed\n", __LINE__);
m.use_the_object();
}
$ g++ test.cpp -o a -g3 -O0
$ ./a
line 12 crossed
MyStruct is still in use
MyStruct destructor called
$ gdb ./a
Reading symbols from ./a...
gdb λ br MyStruct::~MyStruct()
Breakpoint 1 at 0x1214: file test.cpp, line 6.
gdb λ r
Starting program: /tmp/a
line 12 crossed
MyStruct is still in use

Breakpoint 1, MyStruct::~MyStruct (this=0x7fffde27,
__in_chrg=) at test.cpp:6
6   puts("MyStruct destructor called");
gdb λ bt
#0  MyStruct::~MyStruct (this=0x7fffde27, __in_chrg=) at
test.cpp:6
#1  0x51af in main () at test.cpp:11


## Expected

The last line in backtrace has either line test.cpp:13 or 14, because the
destructor could not possibly get called before the last use of the object.

## Actual

Backtrace says it's called at line 11, before the last use of the object.

[Bug c++/91436] Confusing suggestion to include

2019-08-15 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91436

--- Comment #6 from Konstantin Kharlamov  ---
Thank you!

[Bug c++/91436] New: Confusing suggestion to include

2019-08-13 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91436

Bug ID: 91436
   Summary: Confusing suggestion to include 
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Hi-Angel at yandex dot ru
  Target Milestone: ---

When the reason for an undefined function is too low c++ standard, g++ still
suggests to include the header where it's supposed to be. As a result, when in
a project you're not familiar with you're trying to use all usual C++ features,
and then get upon compilation such error, you start thinking that the project
managed to somehow screw defines and what-not. When it's a Qt project, you
think it's code generator's problem.

When the reality is that the suggestion is just wrong: you just can't make this
function defined with the standard the project is using.

# Steps to reproduce (in terms of terminal commands)

$ cat test.cpp
#include 

int main() {
auto foo = std::make_unique();
}
$ g++ test.cpp -std=c++11
test.cpp: In function ‘int main()’:
test.cpp:4:21: error: ‘make_unique’ is not a member of ‘std’
4 | auto foo = std::make_unique();
  | ^~~
test.cpp:2:1: note: ‘std::make_unique’ is defined in header ‘’; did
you forget to ‘#include ’?
1 | #include 
  +++ |+#include 
2 |
test.cpp:4:33: error: expected primary-expression before ‘char’
4 | auto foo = std::make_unique();

## Expected

There's no suggestion to #include  because that's just not gonna work.

## Actual

There's suggestion to #include .

[Bug sanitizer/91311] __attribute__ ((aligned (128))) results in stack-use-after-scope and stack-buffer-overflow

2019-08-05 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91311

Konstantin Kharlamov  changed:

   What|Removed |Added

 Status|WAITING |RESOLVED
 Resolution|--- |WORKSFORME

--- Comment #4 from Konstantin Kharlamov  ---
(In reply to Martin Liška from comment #3)
> Sorry, but I can't reproduce the issue with any of GCC 7,8,9 and clang8.

Okay, thanks you! I decided to update my system (including the compiler up to
9.1.0) before digging into it any further. So now the problem went away, and
there's no reason to keep this opened. If I manage to reproduce something
similar with 9.1.0, I'll make a separate report then.

That said, does anyone have any guesses about what could've been causing it?
I.e. what to look at if I stumble upon that again?

[Bug sanitizer/91311] __attribute__ ((aligned (128))) results in stack-use-after-scope and stack-buffer-overflow

2019-07-31 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91311

--- Comment #1 from Konstantin Kharlamov  ---
Created attachment 46652
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46652=edit
rr record for the testcase, results in stack-use-after-scope

I'm also attaching the `rr` record for the testcase resulting in
`stack-use-after-scope`. To run it, unpack the directory, and execute:

rr replay asan_testcase-0

gdb prompt gonna appear, just type `continue`.

[Bug sanitizer/91311] New: __attribute__ ((aligned (128))) results in stack-use-after-scope and stack-buffer-overflow

2019-07-31 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91311

Bug ID: 91311
   Summary: __attribute__ ((aligned (128))) results in
stack-use-after-scope and stack-buffer-overflow
   Product: gcc
   Version: 8.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: sanitizer
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Hi-Angel at yandex dot ru
CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at 
gcc dot gnu.org
  Target Milestone: ---

This is sporadically (as in, ≈6/10) reproducible on 8.3.0, and not reproducible
on 7.4.0 and 9.1.0. Running the testcase sometimes results in
stack-buffer-overflow sanitizer report, othertimes it's stack-use-after-scope,
and sometimes code passes with no crashes and warnings.

This code is not so small (58 lines) because removing anything from it, or
trying to merge functions, results in getting less crashes or none at all.
Removing the `__attribute__ ((aligned (128)))` results in no crashes from 100
runs; and it's the only odd line of this code, so I suspect this is the
culprit.

Doing `export ASAN_OPTIONS=detect_stack_use_after_return=1` also seems to fix
that.

Despite the testcase being specific to 8.3.0, it seems likely that some similar
problem is present in at least older GCC versions as well. In a project I'm
working on, another developer, with 7.x.x GCC version, also had its share of
odd sanitizer crashes. It's possible, there's the same root reason.

Any suggestions or ideas for how to debug it are welcome.

# Steps to reproduce (in terms of terminal commands)

$ cat asan_testcase.c
#include 
#include 
#include 

struct MyStruct1 {
uint64_t ptr1;
char a;
uint64_t ptr2;
char b;
};

typedef struct {
const uint8_t *raw;
uint64_t err_off;
} MyStruct2 __attribute__ ((aligned (128)));



void test_func() {
struct MyStruct1 test;
char* foo = (char*)
for (size_t i = 0; i < sizeof(struct MyStruct1); ++i)
foo[i] = 0;
printf("test addr: %p", );
struct MyStruct1 test2 = {0};
printf("test addr: %p", );
exit(0);
}

void my_bson_destroy(void *foo) {
}

void my_bson_iter_init_find(MyStruct2 *foo, void *bar, const void* p) {
}

void* my_bson_new_from_json(const void* p, int a, int b) {
return 0;
}

static void test_func3() {
void *bson_param = my_bson_new_from_json((const uint8_t*)"{}", -1, 0);
do {
MyStruct2 it;
my_bson_iter_init_find(, bson_param, "");
} while(0);
my_bson_destroy(bson_param);
}

static void test_func2(const char* json_params) {
test_func3();
fputs("### rpc_operation_cud_obj called!\n", stderr);
test_func();
}

static void test_func4() { test_func2(0); }
static void* test_func5(void *arg) { test_func4(); abort(); }

int main() {
test_func5(0);
}
$ gcc -fsanitize=address -g3 -O0 -o asan_testcase asan_testcase.c
$ for i in {1..100}; do ./asan_testcase; done

## Expected

Only output from the app, bunch of lines like:
### rpc_operation_cud_obj called!
test addr: 0x7ffe31c987d0test addr: 0x7ffe31c98810%

## Actual

Aborts by address sanitizer: sometimes it's a stack-buffer-overflow:

=
==819==ERROR: AddressSanitizer: stack-buffer-overflow on address
0x7fff118a9010 at pc 0x564fb240f2f6 bp 0x7fff118a8fd0 sp 0x7fff118a8fc0
WRITE of size 1 at 0x7fff118a9010 thread T0
#0 0x564fb240f2f5 in test_func ../iscsi/asan_testcase.c:23
#1 0x564fb240f55c in test_func2 ../iscsi/asan_testcase.c:50
#2 0x564fb240f56d in test_func4 ../iscsi/asan_testcase.c:53
#3 0x564fb240f586 in test_func5 ../iscsi/asan_testcase.c:54
#4 0x564fb240f59e in main ../iscsi/asan_testcase.c:57
#5 0x7f1d87092ce2 in __libc_start_main (/usr/lib/libc.so.6+0x23ce2)
#6 0x564fb240f13d in _start (/tmp/asan_testcase+0x113d)

Address 0x7fff118a9010 is located in stack of thread T0 at offset 32 in
frame
#0 0x564fb240f218 in test_func ../iscsi/asan_testcase.c:19

This frame has 2 object(s):
[32, 64) 'test' <== Memory access at offset 32 is inside this variable
[96, 128) 'test2'
HINT: this may be a false positive if your program uses some custom stack
unwind mechanism or swapcontext
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow
../iscsi/asan_testcase.c:23 in test_func
Shadow bytes around the buggy address:
0x10006230d1b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10006230d1c0: 00 00 00 0

[Bug tree-optimization/86050] Inline break tail-call optimization

2019-07-23 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86050

--- Comment #7 from Konstantin Kharlamov  ---
(In reply to Aso Renji from comment #6)
> (In reply to Konstantin Kharlamov from comment #5)
> > Just tested with 8.3.0 version on the other PC, same there, i.e. stack space
> > does not increase when built with -O2. So this was fixed at least since
> > 8.3.0.
> 
> Tested _after_ remove __attribute__((noinline)) from code?
> g++ --version g++ (Debian 8.3.0-6) 8.3.0 bug still present for me.
> Change "static __attribute__((noinline)) void" to "static void" and:
> 
> Consumed 8384063 bytes
> Consumed 8384127 bytes
> Consumed 8384191 bytes
> Consumed 8384255 bytes
> Consumed 8384319 bytes
> Consumed 8384383 bytes
> Consumed 8384447 bytes
> Ошибка сегментирования

Oh, sorry, I didn't notice the testcase requires modification to start
crashing. Yeah, it crashes with 9.1.0 too then.

[Bug tree-optimization/86071] -O0 -foptimize-sibling-calls doesn't optimize

2019-07-23 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86071

--- Comment #2 from Konstantin Kharlamov  ---
(In reply to Alexander Monakov from comment #1)
> In GCC there's no way to selectively enable a few optimizations with their
> -f flags at -O0 level: -O0 means that optimizations are completely disabled,
> regardless of -f flags. This is mentioned in the manual:
> 
>   "Most optimizations are only enabled if an -O level is set on the command
> line.  Otherwise they are disabled, even if individual optimization flags
> are specified."
> 
> 
> Tail call optimization sometimes is not applied because there's an escaping
> local variable (possibly from an inlined function), and GCC does not take
> into account its life range. This might be what you're seeing at -O3.
> There's a recent report: PR 86050.

That said, your quote from docs does not say that optimizations are completely
disabled regardless of -f. It only says that most optimizations are disabled.

And indeed: why to have options, if they doesn't work? So I think it still
qualifies as a bug, even if a low-priority one.

[Bug tree-optimization/86050] Inline break tail-call optimization

2019-07-23 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86050

--- Comment #5 from Konstantin Kharlamov  ---
(In reply to Konstantin Kharlamov from comment #4)
> Works for me on gcc 9.1.0. I compile it as:
> 
> $ g++ test.cpp -o a -O2
> 
> And then running `./a` results in a bunch of:
> 
> Consumed 80 bytes
> Consumed 80 bytes
> Consumed 80 bytes
> Consumed 80 bytes
> Consumed 80 bytes
> Consumed 80 bytes
> Consumed 80 bytes
> Consumed 80 bytes
> Consumed 80 bytes
> Consumed 80 bytes
> Consumed 80 bytes

Just tested with 8.3.0 version on the other PC, same there, i.e. stack space
does not increase when built with -O2. So this was fixed at least since 8.3.0.

[Bug tree-optimization/86050] Inline break tail-call optimization

2019-07-23 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86050

--- Comment #4 from Konstantin Kharlamov  ---
Works for me on gcc 9.1.0. I compile it as:

$ g++ test.cpp -o a -O2

And then running `./a` results in a bunch of:

Consumed 80 bytes
Consumed 80 bytes
Consumed 80 bytes
Consumed 80 bytes
Consumed 80 bytes
Consumed 80 bytes
Consumed 80 bytes
Consumed 80 bytes
Consumed 80 bytes
Consumed 80 bytes
Consumed 80 bytes

[Bug middle-end/77433] warn about usage of object that outside of the scope of the object

2019-06-11 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77433

Konstantin Kharlamov  changed:

   What|Removed |Added

 CC||Hi-Angel at yandex dot ru

--- Comment #9 from Konstantin Kharlamov  ---
In recent news: "Arch Linux Drops GCC 9 From Testing Due To BCache Corruption
Bug"¹

The "gcc bug" turned out to be a bug in bcachefs with a pointer to an
out-of-scope variable.²

I just want to note, that lack of this warning is more important than one would
think. Had GCC warned about the bcachefs problem, it wouldn't get so much blame
on news sites.

1:
https://www.phoronix.com/scan.php?page=news_item=Arch-GCC9-BCache-Corruption-Hit
2: https://bugzilla.kernel.org/show_bug.cgi?id=203573#c6

[Bug c++/89326] [RFE] Highlight `required from here` in compile-error output

2019-02-13 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89326

--- Comment #2 from Konstantin Kharlamov  ---
Btw, I just occasionally noted: godbolt site adds their own highlight to GCC
output, in particular they highlight the whole line with "required from here"
with blue. Maybe something can be borrowed from them :)

https://godbolt.org/z/dK0CzG

[Bug c++/89326] New: [RFE] Highlight `required from here` in compile-error output

2019-02-12 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89326

Bug ID: 89326
   Summary: [RFE] Highlight `required from here` in compile-error
output
   Product: gcc
   Version: 8.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Hi-Angel at yandex dot ru
  Target Milestone: ---

Compile-errors of constructors and templates can give a lot of output. Usually
the first thing in debugging is to figure out where the offending code is used.
This place in output is marked with `required from here`, but it's very hard to
find the magic words in the output, even more so given there are sentences
"required from" without "here" that go along the call stack.

Usually just below the "required from here" is a highlighted word "error", but
it often appears in other places as well.

# Steps to reproduce (in terms of terminal commands):

$ cat test.cpp
#include 

struct NoCopy {
NoCopy(const NoCopy&) = delete;
NoCopy(NoCopy&&)  = default;
};

int main() {
// Child ch{{}};
std::list l = {NoCopy{}};
}
╭─constantine@constantine-N61Ja  /tmp ‹node-›  ‹› 
╰─$ g++ test.cpp
In file included from
/usr/include/c++/8.2.1/x86_64-pc-linux-gnu/bits/c++allocator.h:33,
 from /usr/include/c++/8.2.1/bits/allocator.h:46,
 from /usr/include/c++/8.2.1/list:61,
 from test.cpp:1:
/usr/include/c++/8.2.1/ext/new_allocator.h: In instantiation of ‘void
__gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = NoCopy;
_Args = {const NoCopy&}; _Tp = std::_List_node]’:
/usr/include/c++/8.2.1/bits/alloc_traits.h:475:4:   required from ‘static
void std::allocator_traits
>::construct(std::allocator_traits >::allocator_type&,
_Up*, _Args&& ...) [with _Up = NoCopy; _Args = {const NoCopy&}; _Tp =
std::_List_node; std::allocator_traits
>::allocator_type = std::allocator >]’
/usr/include/c++/8.2.1/bits/stl_list.h:645:33:   required from
‘std::__cxx11::list<_Tp, _Alloc>::_Node* std::__cxx11::list<_Tp,
_Alloc>::_M_create_node(_Args&& ...) [with _Args = {const NoCopy&}; _Tp =
NoCopy; _Alloc = std::allocator; std::__cxx11::list<_Tp, _Alloc>::_Node
= std::_List_node]’
/usr/include/c++/8.2.1/bits/stl_list.h:1903:10:   required from ‘void
std::__cxx11::list<_Tp, _Alloc>::_M_insert(std::__cxx11::list<_Tp,
_Alloc>::iterator, _Args&& ...) [with _Args = {const NoCopy&}; _Tp = NoCopy;
_Alloc = std::allocator; std::__cxx11::list<_Tp, _Alloc>::iterator =
std::_List_iterator]’
/usr/include/c++/8.2.1/bits/stl_list.h:1235:4:   required from ‘void
std::__cxx11::list<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {const
NoCopy&}; _Tp = NoCopy; _Alloc = std::allocator]’
/usr/include/c++/8.2.1/bits/stl_list.h:1832:6:   required from ‘void
std::__cxx11::list<_Tp, _Alloc>::_M_initialize_dispatch(_InputIterator,
_InputIterator, std::__false_type) [with _InputIterator = const NoCopy*; _Tp =
NoCopy; _Alloc = std::allocator]’
/usr/include/c++/8.2.1/bits/stl_list.h:769:9:   required from
‘std::__cxx11::list<_Tp, _Alloc>::list(std::initializer_list<_Tp>, const
allocator_type&) [with _Tp = NoCopy; _Alloc = std::allocator;
std::__cxx11::list<_Tp, _Alloc>::allocator_type = std::allocator]’
test.cpp:10:36:   required from here
/usr/include/c++/8.2.1/ext/new_allocator.h:136:4: error: use of deleted
function ‘NoCopy::NoCopy(const NoCopy&)’
  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^~
test.cpp:4:5: note: declared here
 NoCopy(const NoCopy&) = delete;

# Expected

"required from here" is highlighted with some color

# Actual

"required from here" is of the same font/color as the rest of the text.

[Bug c++/89192] New: -Wuninitialized doesn't warn about a vector initialization with uninitialized field

2019-02-04 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89192

Bug ID: 89192
   Summary: -Wuninitialized doesn't warn about a vector
initialization with uninitialized field
   Product: gcc
   Version: 8.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Hi-Angel at yandex dot ru
  Target Milestone: ---

# Steps to reproduce (in terms of terminal commands):

$ cat test.cpp
#include 

struct MyStruct {
std::vector vec;
unsigned b;

MyStruct(unsigned arg1): vec(b), b(arg1){}
};

int main() {
MyStruct m{1};
}
$ g++ test.cpp -Wuninitialized -Wmaybe-uninitialized

# Expected:

A warning about `vec` being initialized in constructor with `b` field that is
not yet initialized.

# Actual

The code silently compiles

# Additional information

The bug is specific to non-trivial types. E.g. if you replace `vector` with
`unsigned`, the warning will work. However it doesn't for std∷vector or
std∷list.

It came up in a real project, where reorder of fields resulted in a bug that
GCC doesn't warn about.

[Bug lto/89147] flto removes functions implemented in asm

2019-01-31 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89147

--- Comment #2 from Konstantin Kharlamov  ---
(In reply to Andrew Pinski from comment #1)
> >Possible workarounds are welcome.
> 
> Use -ffat-lto-objects or use a .s file.

Thank you for reply!

Adding a `-ffat-lto-objects` to the command above didn't help, still "no
symbols".

Unless no other way around, I'd like to refrain from reworking the generation
code to produce a .S file as that likely would result in a lot of work and may
introduce bugs, whereas the code works well ATM. I wonder though if it's
possible to rewrite it to use "builtin"s (I didn't look at that more closely
yet).

[Bug lto/89147] New: flto removes functions implemented in asm

2019-01-31 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89147

Bug ID: 89147
   Summary: flto removes functions implemented in asm
   Product: gcc
   Version: 8.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: lto
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Hi-Angel at yandex dot ru
CC: marxin at gcc dot gnu.org
  Target Milestone: ---

This came up while researching why -flto build of Mesa fails with linking
errors. The asm snippet below is from an auto-generated code.

Possible workarounds are welcome.

# Steps to reproduce (in terms of terminal commands):

$ cat test.c 
__asm__( ".globl " "gl""NewList" "\n"
 ".type " "gl""NewList" ", @function\n"
 ".balign 16\n" "gl""NewList" ":""\n"
 "\t""call x86_current_tls\n\t"
 "movl %gs:(%eax), %eax\n\t"
 "jmp *(4 * " "0" ")(%eax)""\n"
 );
$ gcc -O3 test.c -o test.o -c -flto
$ nm test.o

# Expected

Output of `nm test.o`:
 T glNewList
 U x86_current_tls

# Actual

Output of `nm test.o`: 
nm: test.o: no symbols

[Bug c/89082] New: Feature request: provide annotation for code that's unlikely to be executed

2019-01-27 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89082

Bug ID: 89082
   Summary: Feature request: provide annotation for code that's
unlikely to be executed
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Hi-Angel at yandex dot ru
  Target Milestone: ---

In most projects a definite pattern that's unlikely to be executed is a
PRINT_ERR macro which is basically a wrapper around fprintf() call. E.g.

if (some_error) {
PRINT_ERR("ERR");
// do cleanup
return;
}

It would be great if GCC provided an attribute or something to make a hint,
that whenever PRINT_ERR appears, whatever branch was prior to that is unlikely
to be taken.

--

This follows the original question here
https://gcc.gnu.org/ml/gcc-help/2019-01/msg00016.html TL;DR of the discussion
is that currently GCC provides α) __builtin_expect(), but it requires to be
inserted inside an if-condition; and β) `__attribute__((cold))` which requires
macro to be converted to a function, and even then it does something completely
different from being just a "branch hint" — instead it produces a very slow
code.

[Bug c++/87057] in compilation error, gcc should note about deleted copy-constructor

2018-08-22 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87057

--- Comment #6 from Konstantin Kharlamov  ---
(In reply to Jonathan Wakely from comment #4)
> (In reply to Konstantin Kharlamov from comment #2)
> > As far as such trivial optimizations concerned, I'd prefer to rely on the
> > compiler figuring that out — in the end, that's why we don't write assembly,
> > right? =)
> 
> If you write "return ret;" the compiler is allowed to move from the
> variable, and is allowed to use the NVRO. It's not allowed to do that if you
> write "return {ret};".

Hmm… But, isn't any optimization allowed that doesn't change semantic of the
program? And, at the very least, if a struct have no explicit copy- and move-
constructors, then replacing copy with a move wherever possible shouldn't go
noticed by the program.

(In reply to Jonathan Wakely from comment #5)
> (In reply to Jonathan Wakely from comment #4)
> > (In reply to Konstantin Kharlamov from comment #2)
> > > (In reply to Jonathan Wakely from comment #1)
> > > > That would require a lot of special-casing just for std::variant.
> > > 
> > > Well, I think, in place of std::variant there could be any struct-wrapper;
> > 
> > If you have an example with a simple struct then please show it, maybe we
> > can improve that case. std::variant is hundreds of lines of complex
> > metaprogramming, not a struct-wrapper.
> 
> Given:
> 
> #include 
> 
> struct PacketErr {
>   std::unique_ptr failed_devices;
> };
> 
> struct V
> {
>   PacketErr p;
> };
> 
> V deserialize() {
>   PacketErr ret;
>   return {ret};
> }
> 
> GCC says:
> 
> s.cc: In function 'V deserialize()':
> s.cc:14:14: error: use of deleted function 'PacketErr::PacketErr(const
> PacketErr&)'
> 14 |   return {ret};
>|  ^
> s.cc:3:8: note: 'PacketErr::PacketErr(const PacketErr&)' is implicitly
> deleted because the default definition would be ill-formed:
> 3 | struct PacketErr {
>   |^
> s.cc:3:8: error: use of deleted function 'std::unique_ptr<_Tp,
> _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = char; _Dp =
> std::default_delete]'
> In file included from /home/jwakely/gcc/9/include/c++/9.0.0/memory:80,
>  from s.cc:1:
> /home/jwakely/gcc/9/include/c++/9.0.0/bits/unique_ptr.h:394:7: note:
> declared here
> 394 |   unique_ptr(const unique_ptr&) = delete;
> |   ^~
> 
> This seems pretty damn good.
> 
> As I said, the problem is that std::variant consists of hundreds of lines of
> complex metaprogramming. When a variant can't be constructed from Y&
> the failure happens deep inside a nested template metaprogram. It's very
> difficult for the compiler to guess what outcome you expected and to print
> an error explaining why that didn't happen.

Oh, hmm, indeed it does print that there's a copy-constructor missing. Oh well,
I think the bug can probably be closed as WONTFIX :)

[Bug c++/87057] in compilation error, gcc should note about deleted copy-constructor

2018-08-22 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87057

--- Comment #3 from Konstantin Kharlamov  ---
(In reply to Konstantin Kharlamov from comment #2)
> Thanks, I prefer the `{x}` to just `x` because in the latter I'm being

*"in the former", sorry.

[Bug c++/87057] in compilation error, gcc should note about deleted copy-constructor

2018-08-22 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87057

--- Comment #2 from Konstantin Kharlamov  ---
(In reply to Jonathan Wakely from comment #1)
> That would require a lot of special-casing just for std::variant.

Well, I think, in place of std::variant there could be any struct-wrapper; but
I get it.

> Clang does print a lot more info, including this:
> 
> /home/jwakely/gcc/latest/lib/gcc/x86_64-pc-linux-gnu/9.0.0/../../../../
> include/c++/9.0.0/variant:1093:2: note: candidate template ignored:
> substitution failure [with _Tp = PacketErr &, $1 = void, $2 = void]:
> implicit instantiation of undefined template
>   'std::variant PacketErr>::__to_type_impl<18446744073709551615, false>'
> variant(_Tp&& __t)
> ^
> 
> But that still doesn't come close to telling you that the type is not
> copyable.

Actually, GCC does give the like output if you'd replace `return {ret}` with
explicit `return std::variant{ret}`, though it
doesn't hint about the type being non-copyable either.

> N.B. If you just write "return ret;" it will compile fine. In general
> "return x;" is better than "return {x};" because it doesn't prevent NRVO.

Thanks, I prefer the `{x}` to just `x` because in the latter I'm being explicit
that the `x` is not the type I'm returning, but there's some other type that
it's being wrapped to.

As far as such trivial optimizations concerned, I'd prefer to rely on the
compiler figuring that out — in the end, that's why we don't write assembly,
right? =)

[Bug c++/87057] New: in compilation error, gcc should note about deleted copy-constructor

2018-08-22 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87057

Bug ID: 87057
   Summary: in compilation error, gcc should note about deleted
copy-constructor
   Product: gcc
   Version: 8.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Hi-Angel at yandex dot ru
  Target Milestone: ---

When, in a code, a copy-constructor deleted but used, GCC issues an absolutely
unhelpful message that it couldn't convert the argument. "Why can't it?". It's
extremely difficult to diagnose — e.g. in my case I had to go down from a
project code to the minimal example below before I could figure it out. There's
really no other way, except as of magically guessing that some of fields used
in the struct being copied has its copy-constructor deleted.

FTR: to fix the code below you need to replace `return {ret}` with `return
{move(ret)}`.

# Steps to reproduce:

$ cat test.cpp 
#include 
#include 

struct PacketErr {
std::unique_ptr failed_devices;
};

std::variant deserialize(){
PacketErr ret;
return {ret};
}

int main() {}
$ g++ test.cpp -std=c++17
test.cpp: In function ‘std::variant
deserialize()’:
test.cpp:10:16: error: could not convert ‘{ret}’ from ‘’ to ‘std::variant’
 return {ret};

# Expected

GCC should mention that a copy is not possible since there's a copy-constructor
deleted.

# Actual

GCC basically says there's some error at the line — go figure what problem is
it.

[Bug tree-optimization/86071] New: -O0 -foptimize-sibling-calls doesn't optimize

2018-06-06 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86071

Bug ID: 86071
   Summary: -O0 -foptimize-sibling-calls doesn't optimize
   Product: gcc
   Version: 8.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Hi-Angel at yandex dot ru
  Target Milestone: ---

# Steps to reproduce:

$ cat test.cpp   
struct Node {
Node* children;
};

const Node& descend(const Node& node) {
if (!node.children) {
return node;
} else // not a leaf
return descend(*node.children);
}

int main() {
Node end;
Node ring = Node{new Node{}};
end.children = 
descend(ring);
}
$ g++ test.cpp -o a -O0 -g3 -foptimize-sibling-calls
$ ./a
[1]21291 segmentation fault (core dumped)  ./a

Running under gdb shows that crash is because of exhausted stack, i.e.
tail-recursion optimization didn't work.


# Additional information

This one testcase actually does work upon replacing -O0 with -O3.

However, I also have a bit bigger testcase, where tail-recursion optimization
doesn't work even with -O3. I wonder, if it's worth a separate bug.

[Bug c++/83425] New: No warning about assignment int to unsigned

2017-12-14 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83425

Bug ID: 83425
   Summary: No warning about assignment int to unsigned
   Product: gcc
   Version: 7.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Hi-Angel at yandex dot ru
  Target Milestone: ---

Steps to reproduce:

$ cat test.cpp
int ret_int() { return -1; }

int main() {
unsigned foo = ret_int();
(void)foo; // suppress unused variable warning
}
$ g++ test.cpp -o a -Wall -Wextra -Wpedantic
$

It does have a real-world significance, I actually found it because the like
mistake introduced a bug for me, code like:

[snip]
uint bytes = purple_ssl_read(ssl, [0], toread);
if (bytes <= 0) {
[snip]

[Bug c++/83161] Feature request: add a builtin for printing structs and classes

2017-11-25 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83161

--- Comment #1 from Constantine Kharlamov  ---
Just another data point I forgot to mention:
https://stackoverflow.com/questions/3311182/linux-c-easy-pretty-dump-printout-of-structs-like-in-gdb-from-source-co
7k views. Author of this one went as far as implementing a hack with firing up
gdb from the code, getting the representation of a struct from there to a
buffer, then printing the buffer. It didn't help very much to the OP though,
because they wanted the like for kernel module.

[Bug other/83161] New: Feature request: add a builtin for printing structs and classes

2017-11-25 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83161

Bug ID: 83161
   Summary: Feature request: add a builtin for printing structs
and classes
   Product: gcc
   Version: 7.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: other
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Hi-Angel at yandex dot ru
  Target Milestone: ---

It's very useful for debugging to pretty-print an entire struct. Typically
people firing up gdb for this, but sometimes it's hard, like on embedded
systems; and always is time-consuming.

This issue is popular enough that e.g. the new systems language Rust have this
functionality built-in.

Some relevant questions to show demand:
1. "Printing values of all fields in a C++ structure"
https://stackoverflow.com/questions/2758937/printing-values-of-all-fields-in-a-c-structure
22k views.
2. Someone attempting the same thing for linux kernel
https://stackoverflow.com/questions/14572015/how-to-print-to-screen-a-struct-and-all-its-content
4k views.

Prior art: Haskell language have a very simple implementation: adding after
declaration of a type "derive Show" generates a code for returning a string
with human-readable description of its object. And if a programmer wants to
tweak representation of a specific type, they override "show" function.

So, I imagine a function "_gcc_show()", and 2 attributes — one to generate a
code for a struct/class, another to override a "_gcc_show()" for certain type —
would be more than enough.

[Bug c++/81234] New: [regression] flexible array member not at end of ‘struct

2017-06-27 Thread Hi-Angel at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81234

Bug ID: 81234
   Summary: [regression] flexible array member not at end of
‘struct
   Product: gcc
   Version: 7.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Hi-Angel at yandex dot ru
  Target Milestone: ---

This code used to work prior to gcc-7.1 (it worked on 4.x, and — I just tested
— 6.3 works too, with a warning though):

struct DataPacket {
/* … */
unsigned szdata;
char data[];
};

struct AckPacket {
DataPacket header;
int a,b,c;
};

int main() { return 0; }

However gcc-7.1 bails out with:

λ g++ test.cpp -o a
test.cpp:4:12: error: flexible array member ‘DataPacket::data’ not at
end of ‘struct AckPacket’
  char data[];
^
test.cpp:9:6: note: next member ‘int AckPacket::a’ declared here
  int a,b,c; /* no data below */
  ^
test.cpp:7:8: note: in the definition of ‘struct AckPacket’
 struct AckPacket {

Imo the code is fine. Though I'm open to suggestions into a better design too.