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" }
+    }
+  };
+}

Reply via email to