[Bug c++/105256] [9/10/11/12 Regression] ICE compiling firefox-99

2022-04-19 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105256

--- Comment #29 from CVS Commits  ---
The master branch has been updated by Jakub Jelinek :

https://gcc.gnu.org/g:eb03e424598d30fed68801af6d6ef6236d32e32e

commit r12-8196-geb03e424598d30fed68801af6d6ef6236d32e32e
Author: Jakub Jelinek 
Date:   Tue Apr 19 18:27:41 2022 +0200

c++: Fix up CONSTRUCTOR_PLACEHOLDER_BOUNDARY handling [PR105256]

The CONSTRUCTOR_PLACEHOLDER_BOUNDARY bit is supposed to separate
PLACEHOLDER_EXPRs that should be replaced by one object or subobjects of it
(variable, TARGET_EXPR slot, ...) from other PLACEHOLDER_EXPRs that should
be replaced by different objects or subobjects.
The bit is set when finding PLACEHOLDER_EXPRs inside of a CONSTRUCTOR, not
looking into nested CONSTRUCTOR_PLACEHOLDER_BOUNDARY ctors, and we prevent
elision of TARGET_EXPRs (through TARGET_EXPR_NO_ELIDE) whose initializer
is a CONSTRUCTOR_PLACEHOLDER_BOUNDARY ctor.  The following testcase ICEs
though, we don't replace the placeholders in there at all, because
CONSTRUCTOR_PLACEHOLDER_BOUNDARY isn't set on the TARGET_EXPR_INITIAL
ctor, but on a ctor nested in such a ctor.  replace_placeholders should be
run on the whole TARGET_EXPR slot.

So, the following patch fixes it by moving the
CONSTRUCTOR_PLACEHOLDER_BOUNDARY
bit from nested CONSTRUCTORs to the CONSTRUCTOR containing those (but only
if it is closely nested, if there is some other tree sandwiched in between,
it doesn't do it).

2022-04-19  Jakub Jelinek  

PR c++/105256
* typeck2.cc (process_init_constructor_array,
process_init_constructor_record, process_init_constructor_union):
Move
CONSTRUCTOR_PLACEHOLDER_BOUNDARY flag from CONSTRUCTOR elements to
the
containing CONSTRUCTOR.

* g++.dg/cpp0x/pr105256.C: New test.

[Bug c++/105256] [9/10/11/12 Regression] ICE compiling firefox-99

2022-04-19 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105256

Richard Biener  changed:

   What|Removed |Added

 Blocks||102990

--- Comment #28 from Richard Biener  ---
(In reply to Martin Liška from comment #27)
> So it started on gcc-11 branch with r11-9711-g6ba2a7e7474135.

For

struct S {
  struct Prefs {
struct P {
  int i = 42;
  int j = i;
} p;
void Load();
  };
};

void S::Prefs::Load() {
  *this = {};
};

that is, which probably means that the assumtion CTORs are already folded
is false and with the PR102990 change we no longer constant fold the
initializer.  Before:

;; Function void S::Prefs::Load() (null)
;; enabled by -tree-original


<) >;


After:

;; Function void S::Prefs::Load() (null)
;; enabled by -tree-original


<)->i}}>) >;

which explains why the PR102990 change makes a difference here (and why it
is a recent regression for compiling Firefox on the branch).


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102990
[Bug 102990] [9/10 Regression] ICE in tsubst_copy_and_build with NSDMI and
double to int conversion

[Bug c++/105256] [9/10/11/12 Regression] ICE compiling firefox-99

2022-04-19 Thread marxin at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105256

--- Comment #27 from Martin Liška  ---
So it started on gcc-11 branch with r11-9711-g6ba2a7e7474135.

[Bug c++/105256] [9/10/11/12 Regression] ICE compiling firefox-99

2022-04-19 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105256

--- Comment #26 from Richard Biener  ---
What's odd is that we could successfully build 99.0.1 with
r11-9662-g6a1150d1524aed but it now fails this reported way with the release
candidate.

[Bug c++/105256] [9/10/11/12 Regression] ICE compiling firefox-99

2022-04-14 Thread chris2553 at googlemail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105256

--- Comment #25 from Chris Clayton  ---
 I went ahead and patched gcc-11-0220409 and with the resultant compiler have
had two successful builds of firefox-99. I then reverted to the unpatched gcc
and a build of firefox-99 failed with the same ICE that I reported in comment
1.

[Bug c++/105256] [9/10/11/12 Regression] ICE compiling firefox-99

2022-04-14 Thread chris2553 at googlemail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105256

--- Comment #24 from Chris Clayton  ---
I see the patch is for gcc-12. As I said in comment, I don't get the ICE with
the latest gcc-12 snapshot, but is it worth me applying the patch to gcc-11
(with which I do get the ICE) and testing a build with that?

[Bug c++/105256] [9/10/11/12 Regression] ICE compiling firefox-99

2022-04-14 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105256

--- Comment #23 from Jakub Jelinek  ---
Created attachment 52811
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52811&action=edit
gcc12-pr105256.patch

Untested patch to do that.

[Bug c++/105256] [9/10/11/12 Regression] ICE compiling firefox-99

2022-04-14 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105256

--- Comment #22 from Jakub Jelinek  ---
So, wonder if for a CONSTRUCTOR containing elements which are CONSTRUCTORs with
CONSTRUCTOR_PLACEHOLDER_BOUNDARY set we shouldn't move the
CONSTRUCTOR_PLACEHOLDER_BOUNDARY flag to the outer CONSTRUCTOR (if not set
there already).
The reason why the flag was introduced was to catch e.g. those
X x { 1, bar (X{2}).n }; etc. cases where the X{2} contains an unrelated
PLACEHOLDER_EXPR to the outer one.
But when we have directly nested CONSTRUCTORs, we can replace_placeholders all
of those PLACEHOLDER_EXPRs from in there, the object will be simply some member
of the var or TARGET_EXPR slot etc.

[Bug c++/105256] [9/10/11/12 Regression] ICE compiling firefox-99

2022-04-14 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105256

--- Comment #21 from Jakub Jelinek  ---
Ah, we have:
case TARGET_EXPR:
  if (TARGET_EXPR_INITIAL (stmt)
  && TREE_CODE (TARGET_EXPR_INITIAL (stmt)) == CONSTRUCTOR
  && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (TARGET_EXPR_INITIAL (stmt)))
TARGET_EXPR_NO_ELIDE (stmt) = 1;
  break;
but that doesn't trigger in this case because the TARGET_EXPR's CONSTRUCTOR
is not CONSTRUCTOR_PLACEHOLDER_BOUNDARY, instead it is a CONSTRUCTOR that
contains a CONSTRUCTOR_PLACEHOLDER_BOUNDARY CONSTRUCTOR as one of its elements.

[Bug c++/105256] [9/10/11/12 Regression] ICE compiling firefox-99

2022-04-14 Thread mpolacek at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105256

--- Comment #20 from Marek Polacek  ---
(In reply to Jakub Jelinek from comment #16)
> Don't both of those tests have UB (sure, we shouldn't ICE), using
> uninitialized non-static data member?

NSDMIs are parsed at the end of the class, but I think I should have switched
the order of the initialization:

struct S {
  struct Prefs {
struct P {
  int i = 42;
  int j = i;
} p;
void Load();
  };
};

void S::Prefs::Load() {
  *this = {};
};

but your test is good too.

[Bug c++/105256] [9/10/11/12 Regression] ICE compiling firefox-99

2022-04-14 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105256

--- Comment #19 from Jakub Jelinek  ---
The TARGET_EXPR is elided in gimplify_modify_expr_rhs:
case TARGET_EXPR:
  {
/* If we are initializing something from a TARGET_EXPR, strip the
   TARGET_EXPR and initialize it directly, if possible.  This can't
   be done if the initializer is void, since that implies that the
   temporary is set in some non-trivial way.

   ??? What about code that pulls out the temp and uses it
   elsewhere? I think that such code never uses the TARGET_EXPR as
   an initializer.  If I'm wrong, we'll die because the temp won't
   have any RTL.  In that case, I guess we'll need to replace
   references somehow.  */
tree init = TARGET_EXPR_INITIAL (*from_p);

if (init
&& (TREE_CODE (*expr_p) != MODIFY_EXPR
|| !TARGET_EXPR_NO_ELIDE (*from_p))
&& !VOID_TYPE_P (TREE_TYPE (init)))
  {
*from_p = init;
ret = GS_OK;
changed = true;
  }
  }
  break;

Though, can the TARGET_EXPR be elided if there are PLACEHOLDER_EXPRs in it?
If not, something should probably set TARGET_EXPR_NO_ELIDE somewhere.
If yes, perhaps we need to replace_placeholders perhaps through a language hook
at the
above point.  But it is unclear to what it should be replaced...

[Bug c++/105256] [9/10/11/12 Regression] ICE compiling firefox-99

2022-04-14 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105256

--- Comment #18 from Jakub Jelinek  ---
The rationale for introduction of CONSTRUCTOR_PLACEHOLDER_BOUNDARY was given in
the
https://gcc.gnu.org/legacy-ml/gcc-patches/2018-03/threads.html#00681
thread, not all PLACEHOLDER_EXPRs nested in an expression should be replaced by
the same object, if there are e.g. nested TARGET_EXPRs with PLACEHOLDER_EXPRs
in their initializers, those nested PLACEHOLDER_EXPRs should be replaced by the
TARGET_EXPR's slot rather than the outermost expression.
Before the r8-7334-g570f86f94eca76fbf, the PLACEHOLDER_EXPR was replaced from
build_over_call, but that has removed.  The expectation was that we'd always
have some object (var being constructed, TARGET_EXPR slot, etc. and we'd
replace_placeholders when gimplifying INIT_EXPR for it).
But on:

int bar (int &);

struct S {
  struct T {
struct U {
  int i = bar (i);
} u;
  };
};

void
foo (S::T *p)
{
  *p = {};
};

cp_gimplify_init_expr is never called, gimplify_target_expr neither, because we
ICE earlier than that.
While we have there a TARGET_EXPR when we start gimplification:
*NON_LVALUE_EXPR  = *(struct T &) &TARGET_EXPR )->i)}}>, seems something has elided it.

[Bug c++/105256] [9/10/11/12 Regression] ICE compiling firefox-99

2022-04-14 Thread chris2553 at googlemail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105256

--- Comment #17 from Chris Clayton  ---
Created attachment 52810
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52810&action=edit
Compiler commands

Finally got them by running running "ps ax" in a while true loop, grepping the
output for the file name and writing any matches to a file. There must be an
easier way!

[Bug c++/105256] [9/10/11/12 Regression] ICE compiling firefox-99

2022-04-14 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105256

--- Comment #16 from Jakub Jelinek  ---
Don't both of those tests have UB (sure, we shouldn't ICE), using uninitialized
non-static data member?
Perhaps:

int
bar (int &)
{
  return 1;
}

struct S {
  struct T {
struct U {
  int i = bar (i);
} p;
void foo ();
  };
};

void
S::T::foo ()
{
  *this = {};
};

is better?

[Bug c++/105256] [9/10/11/12 Regression] ICE compiling firefox-99

2022-04-13 Thread mpolacek at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105256

Marek Polacek  changed:

   What|Removed |Added

   Keywords||ice-on-valid-code

--- Comment #15 from Marek Polacek  ---
Better test:

struct S {
  struct Prefs {
struct {
  int i = j;
  int j = 42;
} p;
void Load();
  };
};

void S::Prefs::Load() {
  *this = {};
};

[Bug c++/105256] [9/10/11/12 Regression] ICE compiling firefox-99

2022-04-13 Thread mpolacek at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105256

Marek Polacek  changed:

   What|Removed |Added

   Target Milestone|--- |9.5
Summary|ICE compiling firefox-99|[9/10/11/12 Regression] ICE
   ||compiling firefox-99
 Status|WAITING |NEW
   Priority|P3  |P2

--- Comment #14 from Marek Polacek  ---
The testcase in the previous comment started to ICE with r258593:

commit 570f86f94eca76fbfab919dcbfe639a5ba69f20e
Author: Jakub Jelinek 
Date:   Fri Mar 16 13:46:12 2018 +0100

re PR c++/79937 (ICE in replace_placeholders_r)

So confirmed.  I'm not sure this is the same ICE Chris saw though...