https://gcc.gnu.org/g:4e4c378ac1f923a310fa31be85ed8c0c50e9f5ef
commit r15-7096-g4e4c378ac1f923a310fa31be85ed8c0c50e9f5ef Author: Simon Martin <si...@nasilyan.com> Date: Tue Jan 21 13:31:41 2025 +0100 c++: Don't ICE in build_class_member_access_expr during error recovery [PR118225] The invalid case in this PR trips on an assertion in build_class_member_access_expr that build_base_path would never return an error_mark_node, which is actually incorrect if the object involves a tree with an error_mark_node DECL_INITIAL, like here. This patch changes the assert to not fire if an error has been reported. PR c++/118225 gcc/cp/ChangeLog: * typeck.cc (build_class_member_access_expr): Let errors that that have been reported go through. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-ice21.C: New test. Diff: --- gcc/cp/typeck.cc | 2 +- gcc/testsuite/g++.dg/cpp0x/constexpr-ice21.C | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index 3e0d71102abd..6b549809243a 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -2980,7 +2980,7 @@ build_class_member_access_expr (cp_expr object, tree member, /*nonnull=*/1, complain); /* If we found the base successfully then we should be able to convert to it successfully. */ - gcc_assert (object != error_mark_node); + gcc_assert (object != error_mark_node || seen_error ()); } /* If MEMBER is from an anonymous aggregate, we have converted diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ice21.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice21.C new file mode 100644 index 000000000000..46273654f240 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice21.C @@ -0,0 +1,17 @@ +// PR c++/118225 +// { dg-do "compile" { target c++11} } + +struct NoMut1 { int a, b; }; +struct NoMut3 : virtual NoMut1 { + constexpr NoMut3(int a, int b) // { dg-error "virtual base" "" { target c++23 } } + : NoMut1{a, b} + {} // { dg-error "virtual base" } +}; +void mutable_subobjects() { + constexpr NoMut3 nm3 = {1, 2}; // { dg-error "call to non" } + struct A { + void f() { + static_assert(nm3.a == 1, ""); // { dg-error "local variable" } + } + }; +}