[Bug c++/104765] New: Expression statement with a return in a lambda-parameter-default causes segfault when called in a different function

2022-03-02 Thread erich.keane at intel dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104765

Bug ID: 104765
   Summary: Expression statement with a return in a
lambda-parameter-default causes segfault when called
in a different function
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: erich.keane at intel dot com
  Target Milestone: ---

See this example:


template
void call_lambda(T&& L) {
L();
}

int g() {  
  auto x = [](char c = ({return 5;'c';})){};

  call_lambda(x);
  return 0;
}

int main() {
  return g();
}

:https://godbolt.org/z/T1cs766cM

Output is:
during RTL pass: expand
: In function 'void call_lambda(T&&) [with T = g()::&]':
:3:6: internal compiler error: Segmentation fault
3 | void call_lambda(T&& L) {
  |  ^~~
0x217ccb9 internal_error(char const*, ...)
???:0
0x1288575 coalesce_ssa_name(_var_map*)
???:0
0x120fadb rewrite_out_of_ssa(ssaexpand*)
???:0
Please submit a full bug report, with preprocessed source (by using
-freport-bug).
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
Compiler returned: 1




This gets somewhat more interesting when the return value of 'call_lambda' is
non-int:

https://godbolt.org/z/rE619qbz3

: In function 'long int call_lambda(T&&)':
:5:1: warning: no return statement in function returning non-void
[-Wreturn-type]
5 | }
  | ^
: In function 'long int call_lambda(T&&) [with T =
g()::&]':
:3:6: error: invalid conversion in return statement
3 | long call_lambda(T&& L) {
  |  ^~~
long int

int

return D.2194;
:3:6: internal compiler error: 'verify_gimple' failed
0x217ccb9 internal_error(char const*, ...)
???:0
0x1183efd verify_gimple_in_seq(gimple*)
???:0
0xdf13b1 gimplify_body(tree_node*, bool)
???:0
0xdf1677 gimplify_function_tree(tree_node*)
???:0
0xbf78f7 cgraph_node::analyze()
???:0
0xbfbe0d symbol_table::finalize_compilation_unit()
???:0
Please submit a full bug report, with preprocessed source (by using
-freport-bug).
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
Compiler returned: 1



IMO, expression-statements in default-lambda parameters are... awkward and
perhaps worth just prohibiting.

[Bug c++/94960] extern template prevents inlining of standard library objects

2022-02-17 Thread erich.keane at intel dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94960

--- Comment #9 from Erich Keane  ---
> But in C++20 every function is 'constexpr' now, so every function is inline
> anyway, right? Even the large functions that aren't good candidates for
> inlining (see also PR 93008). So The 'inline' keyword has lost all meaning
> in  now.

Do you mean 'every function in std::string'?  If so, you'd know better than I.
In a general case, every function is NOT 'constexpr', and that didn't pass EWG.

[Bug c++/94960] extern template prevents inlining of standard library objects

2020-05-06 Thread erich.keane at intel dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94960

--- Comment #6 from Erich Keane  ---
(In reply to Jonathan Wakely from comment #5)
> (In reply to Erich Keane from comment #3)
> > As you know, "extern template" is a hint to the compiler that we don't need
> > to emit the template as a way to save on compile time.
> > 
> > Both GCC and clang will NOT instantiate these templates in O0 mode. 
> > However, in O1+ modes, both will actually still instantiate the templates in
> > the frontend, BUT only for 'inline' functions.  Basically, we're using
> > 'inline' as a heuristic that there is benefit in sending these functions to
> > the optimizer (basically, sacrificing the compile time gained by 'extern
> > template' in exchange for a better inlining experience).
> 
> Hmm, I've seen different behaviours for clang and g++ in this respect, with
> clang inlining a lot more of std::string's members. So I'm surprised they
> use the same heuristic.
> 
> Do they both instantiate the function templates marked 'inline' even at -O1?
> Presumably not at -O0.

My understanding of Clang is based on a brief debugging session. My
understanding of GCC's behavior here is a brief amount of time messing around
on godbolt. I could very well be incorrect.


> 
> > In the submitter's case, the std::string constructor calls "_M_construct". 
> > The constructor is inlined, but _M_construct is not, since it never gets to
> > the optimizer.
> > 
> > libc++ uses an __init function to do the same thing as _M_construct, however
> > IT is marked inline, and thus doesn't have the problem.
> > 
> > I believe the submitter wants to have you mark more of the functions in
> > extern-templated classes 'inline' so that it matches the heuristic better.
> 
> And that's what I don't want to do. I think it's wrong for the human to say
> "inline this!" because humans are stupid (well, I am anyway). And I don't
> want to have to examine the GIMPLE/asm again for every new GCC release to
> decide whether 'inline' is still in the right places (and whether the answer
> should be different for every different version of Clang or ICC!)
> 
> And when I say "I don't want to" I mean "I am never ever going to".
> 
> > I don't think that there is a good way to change the compiler itself without
> > making 'extern template' absolutely meaningless.
> 
> I absolutely disagree.
> 
> It would still give a reduction in object file size for cases where the
> compiler decides not to inline, and still make compilation much faster for
> -O0 and -O1.

That is fair, I guess it would slightly reduce 'link' time because of that. I
doubt people would be willing to put up with the STL compiling that much slower
though (which seems to be the major user of this feature in my experience).

> One property of -O2 and -O3 is that we try to optimize aggressively even if
> that takes a long time to compile. So we could instantiate things that have
> an explicit instantiation declaration (thus doing "redundant" work) to see
> if inlining them would be beneficial. That would take longer to compile, but
> might produce faster code. If the heuristics decide the instantiation ends
> up too big to inline, it could just discard it (because we know there's a
> definition elsewhere).

That is essentially what the frontends DO, except only with the 'inline'
functions.  If the inliner chooses to not inline it, it gets thrown out (since
we've marked it 'available externally').

> If the only way to get that is to mark every function as 'inline' (and then
> "trick" the compiler into doing all that extra work even at -O1?) then we
> might as well add 'inline' to every single function template in  and
> , ,  etc. so they're all potential candiates
> for inlining.
> 
> And if we have to mark every single function as 'inline' then maybe the
> compiler shouldn't be using it as a hint.

I don't think the idea is to mark EVERY function 'inline', simply ones that are
pretty tiny and really good candidates for inlining.

[Bug libstdc++/94960] extern template prevents inlining of standard library objects

2020-05-05 Thread erich.keane at intel dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94960

Erich Keane  changed:

   What|Removed |Added

 CC||erich.keane at intel dot com

--- Comment #3 from Erich Keane  ---
(In reply to Jonathan Wakely from comment #2)
> Please provide complete testcases, not just URLs, as required by
> https://gcc.gnu.org/bugs
> 
> #include 
> 
> int main()
> {
> std::string(size_t(0), 0);
> }
> 
> 
> I still think it's wrong for GCC to treat the 'inline' specifier as an
> inlining hint. The compiler should be a better judge of inlining decisions
> than the developer.
> 
> (In reply to Andrew Pinski from comment #1)
> > g:1a289fa36294627c252492e4c18d7877a7c80dc1 changed that.
> 
> Well that commit just meant that the explicit instantiations are declared
> for C++17 as well, where previously they were only declared for < C++17. It
> didn't add the explicit instantiations.

Hi Jon!
I helped the submitter in #llvm debug this a little, so I perhaps have a better
understanding of his issue:

As you know, "extern template" is a hint to the compiler that we don't need to
emit the template as a way to save on compile time.

Both GCC and clang will NOT instantiate these templates in O0 mode.  However,
in O1+ modes, both will actually still instantiate the templates in the
frontend, BUT only for 'inline' functions.  Basically, we're using 'inline' as
a heuristic that there is benefit in sending these functions to the optimizer
(basically, sacrificing the compile time gained by 'extern template' in
exchange for a better inlining experience).

In the submitter's case, the std::string constructor calls "_M_construct".  The
constructor is inlined, but _M_construct is not, since it never gets to the
optimizer.

libc++ uses an __init function to do the same thing as _M_construct, however IT
is marked inline, and thus doesn't have the problem.

I believe the submitter wants to have you mark more of the functions in
extern-templated classes 'inline' so that it matches the heuristic better.

I don't think that there is a good way to change the compiler itself without
making 'extern template' absolutely meaningless.

[Bug libstdc++/94203] New: experimental/executor and socket header issues-

2020-03-17 Thread erich.keane at intel dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94203

Bug ID: 94203
   Summary: experimental/executor and socket header issues-
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: erich.keane at intel dot com
  Target Milestone: ---

Again detected by trying to compile these headers with clang, I get two more
issues.  They can be reproduced here: https://godbolt.org/z/L-UVGq though that
still shows the previous version's issue with service_already_exists.

First, it appears that _TgtImpl attempts to add 'const' to the return type of
the overridden function:

../include/c++/10.0.1/experimental/executor:1170:2: error:
  return type of virtual function 'target' is not covariant with the return
type of the function it overrides (class type
  'const void *' is more qualified than class type 'void *'
target(const std::type_info& __ti) const
^
../include/c++/10.0.1/experimental/executor:1138:21: note:
  overridden virtual function is here
  virtual void* target(const std::type_info&) const = 0;




The second issue is that socket_errc doesn't pass is_error_code_enum in
__basic_socket_impl:

../include/c++/10.0.1/experimental/socket:571:9: error:
  no viable overloaded '='
  __ec = socket_errc::already_open;
   ^ ~
../include/c++/10.0.1/system_error:208:7: note:
  candidate template ignored: requirement
'is_error_code_enum::value' was not
  satisfied [with _ErrorCodeEnum = std::experimental::net::v1::socket_errc]
  operator=(_ErrorCodeEnum __e) noexcept
  ^

(it then goes on to show a bunch of other options).

However, I believe this is because Clang is instantiating this check right
away, but the explicit specialization for socket_errc is after it:
https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/experimental/socket#L2605


In fact, clang diagnoses this as well:

../include/c++/10.0.1/experimental/socket:2606:12: error:
  explicit specialization of
'std::is_error_code_enum' after
instantiation
struct is_error_code_enum
   ^~
../include/c++/10.0.1/system_error:206:26: note:
  implicit instantiation first required here
  typename enable_if::value,
 ^

[Bug libstdc++/94199] std::experimental::net::v1::make_service function template not instantiatable

2020-03-16 Thread erich.keane at intel dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94199

--- Comment #4 from Erich Keane  ---
Thanks Jonathan!

[Bug libstdc++/94199] New: std::experimental::net::v1::make_service function template not instantiatable

2020-03-16 Thread erich.keane at intel dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94199

Bug ID: 94199
   Summary: std::experimental::net::v1::make_service function
template not instantiatable
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: erich.keane at intel dot com
  Target Milestone: ---

Discovered in Clang, since Clang diagnoses the issue without an instantiation,
here is a GCC repro: https://godbolt.org/z/7guiic

The function template tries to throw service_already_exists, which isn't
default constructible:


/opt/compiler-explorer/gcc-trunk-20200316/include/c++/10.0.1/experimental/executor:581:8:
error: use of deleted function
'std::experimental::net::v1::service_already_exists::service_already_exists()'

  581 |  throw service_already_exists();

Clang diagnoses just attempting to #include the file:
https://godbolt.org/z/yH9kNp

[Bug c++/81355] New: SegFault when using attribute target dispatch with empty parameter

2017-07-07 Thread erich.keane at intel dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81355

Bug ID: 81355
   Summary: SegFault when using attribute target dispatch with
empty parameter
   Product: gcc
   Version: 7.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: erich.keane at intel dot com
  Target Milestone: ---

This very simple repro causes a segfault:
__attribute__((target("default")))
int foo() {return 99;}
__attribute__((target("sse4.2","")))
int foo() {return 1;}

int main() {
return foo();
}

As you can see, this does dispatch, and should otherwise be valid.  However,
the blank string causes a segfault: https://godbolt.org/g/dmuCaZ

Additionally of interest, ONLY the 1st parameter to target participates in
dispatch.

[Bug c++/67824] constexpr char* compare operations not constexpr, but char[] operations ARE

2016-01-27 Thread erich.keane at intel dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67824

--- Comment #3 from Erich Keane  ---
Don't know if it is a result of the red-hat packaging, or the .1 release, but
the 3.7.1 release from here: http://llvm.org/releases/download.html

seems to no longer crash.(In reply to Erich Keane from comment #2)
> Don't know if it is a result of the red-hat packaging, or the .1 release,
> but the 3.7.1 release from here: http://llvm.org/releases/download.html
> 
> seems to no longer crash.

Er, sorry, this is for a different bug meant for clang.  Please disregard, I
don't see how to delete it.

[Bug c++/67824] constexpr char* compare operations not constexpr, but char[] operations ARE

2016-01-27 Thread erich.keane at intel dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67824

--- Comment #2 from Erich Keane  ---
Don't know if it is a result of the red-hat packaging, or the .1 release, but
the 3.7.1 release from here: http://llvm.org/releases/download.html

seems to no longer crash.

[Bug c++/67824] constexpr char* compare operations not constexpr, but char[] operations ARE

2016-01-06 Thread erich.keane at intel dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67824

--- Comment #1 from Erich Keane  ---
I just reconfirmed this in 5.3.1 on Fedora:
gcc (GCC) 5.3.1 20151207 (Red Hat 5.3.1-2)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Error message for the previous example is:
constexpr_gcc_bug.cpp: In function β€˜int main()’:
constexpr_gcc_bug.cpp:8:5: error: non-constant condition for static assertion
 static_assert(root2 < root2 + 1, "This fails");
 ^
constexpr_gcc_bug.cpp:8:25: error: β€˜(((const char*)"12") < (((const char*)"12")
+ 1u))’ is not a constant expression
 static_assert(root2 < root2 + 1, "This fails");

[Bug c/67824] New: constexpr char* compare operations not constexpr, but char[] operations ARE

2015-10-02 Thread erich.keane at intel dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67824

Bug ID: 67824
   Summary: constexpr char* compare operations not constexpr, but
char[] operations ARE
   Product: gcc
   Version: 5.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: erich.keane at intel dot com
  Target Milestone: ---

The below code reproduces this bug, found in 4.9.2, but also reproduced in
5.2.1

Version results for both:

g++ (GCC) 4.9.2 20150212 (Red Hat 4.9.2-6)
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

g++ (SUSE Linux) 5.2.1 20150721 [gcc-5-branch revision 226027]
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

This code compiles correctly on clang++ 3.5 and 3.6.1.  

it seems that the 'root' variable below gets treated correctly, yet the root2,
despite being a valid string as well, doesn't allow pointer operations on it. 
This is painful, since it breaks constexpr iterators on constexpr const char*
items.



static constexpr const char root[] = "1234";
static constexpr const char* root2 = "1234";

int main()
{
static_assert(root < root + 1, "This works");
static_assert(root2 < root2 + 1, "This fails");
}