Message ID | 01020192e6fb44f4-ef53170f-2e9d-427a-ad18-e4fc2dd31c25-000000@eu-west-1.amazonses.com |
---|---|
State | New |
Headers | show |
Series | c++: Handle SCOPE_REF in contains_placeholder_p [PR117158] | expand |
On 11/1/24 5:07 AM, Simon Martin wrote: > Since r10-3793-g1a37b6d9a7e57c, we ICE upon the following valid code > with -std=c++17 and above > > === cut here === > struct Base { > unsigned int *intarray; > }; > template <typename T> struct Sub : public Base { > bool Get(int i) { > return (Base::intarray[++i] == 0); > } > }; > === cut here === > > The problem is that from c++17 on, we use -fstrong-eval-order and need > to wrap the array access expression into a SAVE_EXPR, and end up calling > contains_placeholder_p with a SCOPE_REF, that it does not handle well. > > This patch fixes this by skipping the first operand of SCOPE_REFs in > contains_placeholder_p. Code in gcc/ shouldn't refer to tree codes from cp-tree.def. We probably shouldn't do the strong-eval-order transformation when processing_template_decl anyway. > Successfully tested on x86_64-pc-linux-gnu. > > PR c++/117158 > > gcc/ChangeLog: > > * tree.cc (contains_placeholder_p): Skip the first operand of > SCOPE_REFs. > > gcc/testsuite/ChangeLog: > > * g++.dg/parse/crash77.C: New test. > > --- > gcc/testsuite/g++.dg/parse/crash77.C | 13 +++++++++++++ > gcc/tree.cc | 3 +++ > 2 files changed, 16 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/parse/crash77.C > > diff --git a/gcc/testsuite/g++.dg/parse/crash77.C b/gcc/testsuite/g++.dg/parse/crash77.C > new file mode 100644 > index 00000000000..25a426fa6d6 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/parse/crash77.C > @@ -0,0 +1,13 @@ > +// PR c++/117158 > +// { dg-do "compile" } > + > +struct Base { > + unsigned int *intarray; > +}; > + > +template <typename T> > +struct Sub : public Base { > + bool Get(int i) { > + return (Base::intarray[++i] == 0); > + } > +}; > diff --git a/gcc/tree.cc b/gcc/tree.cc > index b4c059d3b0d..7f8911002d0 100644 > --- a/gcc/tree.cc > +++ b/gcc/tree.cc > @@ -4122,6 +4122,9 @@ contains_placeholder_p (const_tree exp) > if (!exp) > return false; > > + if (TREE_CODE (exp) == SCOPE_REF) > + exp = TREE_OPERAND (exp, 1); > + > code = TREE_CODE (exp); > if (code == PLACEHOLDER_EXPR) > return true;
diff --git a/gcc/testsuite/g++.dg/parse/crash77.C b/gcc/testsuite/g++.dg/parse/crash77.C new file mode 100644 index 00000000000..25a426fa6d6 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/crash77.C @@ -0,0 +1,13 @@ +// PR c++/117158 +// { dg-do "compile" } + +struct Base { + unsigned int *intarray; +}; + +template <typename T> +struct Sub : public Base { + bool Get(int i) { + return (Base::intarray[++i] == 0); + } +}; diff --git a/gcc/tree.cc b/gcc/tree.cc index b4c059d3b0d..7f8911002d0 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -4122,6 +4122,9 @@ contains_placeholder_p (const_tree exp) if (!exp) return false; + if (TREE_CODE (exp) == SCOPE_REF) + exp = TREE_OPERAND (exp, 1); + code = TREE_CODE (exp); if (code == PLACEHOLDER_EXPR) return true;