c++: Handle SCOPE_REF in contains_placeholder_p [PR117158]
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 |
success
|
Test passed
|
linaro-tcwg-bot/tcwg_gcc_check--master-arm |
success
|
Test passed
|
Commit Message
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.
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
Comments
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;
new file mode 100644
@@ -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);
+ }
+};
@@ -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;