[gcc r15-7209] c++: Reinstate check for uninitialized bases with c++ <= 17 [PR118239]

Simon Martin simartin@gcc.gnu.org
Sat Jan 25 17:13:46 GMT 2025


https://gcc.gnu.org/g:bee1910b891f897fcd1789d1dbd3937621354943

commit r15-7209-gbee1910b891f897fcd1789d1dbd3937621354943
Author: Simon Martin <simon@nasilyan.com>
Date:   Sat Jan 25 18:09:23 2025 +0100

    c++: Reinstate check for uninitialized bases with c++ <= 17 [PR118239]
    
    We currently accept this code with c++ <= 17 even though it's invalid
    since the base is not initialized (we properly reject it with c++ >= 20)
    
    === cut here ===
    struct NoMut1 { int a, b; };
    struct NoMut3 : NoMut1 {
      constexpr NoMut3(int a, int b) {}
    };
    void mutable_subobjects() {
      constexpr NoMut3 nm3(1, 2);
    }
    === cut here ===
    
    This is a fallout of r0-118700-gc2b3ec18a494e3, that ignores all fields
    with DECL_ARTIFICIAL in cx_check_missing_mem_inits, including those that
    represent base classes, and need to be checked.
    
    This patch makes sure that we only skip fields that have DECL_ARTIFICIAL
    if they don't have DECL_FIELD_IS_BASE.
    
            PR c++/118239
    
    gcc/cp/ChangeLog:
    
            * constexpr.cc (cx_check_missing_mem_inits): Don't skip fields
            with DECL_FIELD_IS_BASE.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp0x/constexpr-base8.C: New test.

Diff:
---
 gcc/cp/constexpr.cc                          |  8 ++++----
 gcc/testsuite/g++.dg/cpp0x/constexpr-base8.C | 24 ++++++++++++++++++++++++
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 41ff78bbf2b9..94a468056f90 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -839,9 +839,8 @@ cx_check_missing_mem_inits (tree ctype, tree body, bool complain)
       if (i < nelts)
 	{
 	  index = CONSTRUCTOR_ELT (body, i)->index;
-	  /* Skip base and vtable inits.  */
-	  if (TREE_CODE (index) != FIELD_DECL
-	      || DECL_ARTIFICIAL (index))
+	  /* Skip vptr adjustment represented with a COMPONENT_REF.  */
+	  if (TREE_CODE (index) != FIELD_DECL)
 	    continue;
 	}
 
@@ -852,7 +851,8 @@ cx_check_missing_mem_inits (tree ctype, tree body, bool complain)
 	    continue;
 	  if (DECL_UNNAMED_BIT_FIELD (field))
 	    continue;
-	  if (DECL_ARTIFICIAL (field))
+	  /* Artificial fields can be ignored unless they're bases.  */
+	  if (DECL_ARTIFICIAL (field) && !DECL_FIELD_IS_BASE (field))
 	    continue;
 	  if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
 	    {
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-base8.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-base8.C
new file mode 100644
index 000000000000..ecc28693315e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-base8.C
@@ -0,0 +1,24 @@
+// PR c++/118239
+// { dg-do "compile" { target c++11 } }
+
+struct NoMut1 {
+  int a, b;
+};
+
+// Reported case.
+struct NoMut2 : NoMut1 {
+  constexpr NoMut2(int a, int b) /*: NoMut1()*/
+  {} // { dg-error "must be initialized" "" { target c++17_down } }
+};
+
+// Variant with explicit initialization of some member.
+struct NoMut3 : NoMut1 {
+  constexpr NoMut3(int a, int b) : c(0) /*, NoMut1()*/
+  {} // { dg-error "must be initialized" "" { target c++17_down } }
+  int c;
+};
+
+void mutable_subobjects() {
+  constexpr NoMut2 nm2(1, 2); // { dg-error "constant expression" }
+  constexpr NoMut3 nm3(1, 2); // { dg-error "constant expression" }
+}


More information about the Gcc-cvs mailing list