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;