[PATCH] c++: Enhance -Wuninitialized to check private base class [PR80681]
The issue described in PR80681 highlights a problem that: g++'s -Wuninitialized option does not warn when a privately inherited base class contains public const data or reference members, and the derived class does not have a user-provided constructor. Similarly, the same issue occurs when the privately inherited base class contains protected const data or reference members. In both cases, the derived class is unable to initialize these members in the base class. For private const data or reference members in privately inherited base classes, these members are inherently inaccessible to the derived class and cannot be initialized. Therefore, they are not considered as a condition for issuing a warning. In my proposed patch, under the condition that the current class does not have a user-provided constructor and the -Wuninitialized option is enabled, I traverse all directly privately inherited base classes of the current class. For each base class, I check whether it contains any non-private const data or reference members. If such members are found, a warning is issued at the declaration location of the current class. Additionally, supplementary information is provided to indicate the declaration location of the non-private const data or reference members in the base class. Successfully bootstrapped and regretested on x86_64-pc-linux-gnu: adds 21 PASS results to g++.sum. PR c++/80681 gcc/cp/ChangeLog: * class.cc (check_bases_and_members): Enhanced -Wuninitialized to warn for classes without user-provided constructors that privately inherit base classes with non-private const data or reference members. gcc/testsuite/ChangeLog: * g++.dg/warn/Wuninitialized-pr80681-1.C: New test. --- gcc/cp/class.cc | 61 +++ .../g++.dg/warn/Wuninitialized-pr80681-1.C| 19 ++ 2 files changed, 80 insertions(+) create mode 100644 gcc/testsuite/g++.dg/warn/Wuninitialized-pr80681-1.C diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc index d5ae69b0fdf..49c4ef08f33 100644 --- a/gcc/cp/class.cc +++ b/gcc/cp/class.cc @@ -6500,6 +6500,67 @@ check_bases_and_members (tree t) OPT_Wuninitialized, "non-static const member %q#D " "in class without a constructor", field); } + /* If the class privately inherited from a class with public + or protected non-static const or reference data members, + these members can never be initialized. */ + + tree binfo = TYPE_BINFO (t); + vec *accesses = BINFO_BASE_ACCESSES (binfo); + tree base_binfo; + unsigned i; + + for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) + { + tree basetype = TREE_TYPE (base_binfo); + + if ((*accesses)[i] == access_private_node) + { + tree base_field; + + for (base_field = TYPE_FIELDS (basetype); base_field; + base_field = DECL_CHAIN (base_field)) + { + tree field_type; + + if (TREE_CODE (base_field) != FIELD_DECL + || DECL_INITIAL (base_field) != NULL_TREE) + continue; + + field_type = TREE_TYPE (base_field); + + if (!TREE_PRIVATE (base_field)) + { + if (TYPE_REF_P (field_type)) + { + warning (OPT_Wuninitialized, + "private inheritance of base class " + "%q#T with non-private " + "non-static reference in class " + "without a constructor", + basetype); + inform (DECL_SOURCE_LOCATION (base_field), + "non-static reference %q#D here:", + base_field); + } + else if (CP_TYPE_CONST_P (field_type) + && (!CLASS_TYPE_P (field_type) + || !TYPE_HAS_DEFAULT_CONSTRUCTOR ( +field_type))) + { + warning (OPT_Wuninitialized, + "private inheritance of base class " + "%q#T with non-private " + "non-static const member in class " + "without a constructor", + basetype); + inform (DECL_SOURCE_LOCATION (base_field), + "non-static const member %q#D here:", + base_field); + } + } + } + } + } } /* Synthesize any needed methods. */ diff --git a/gcc/testsuite/g++.dg/warn/
Re: [PATCH] c++: Check invalid use of constrained auto with trailing return type [PR100589]
* Patrick Palka [2025-02-28 10:37:37]: > Hi, > > On Fri, 28 Feb 2025, Da Xie wrote: > > > This bug comes from a missing check when a function declaration has a > > late-specified return type and a constrained auto type specifier. By > > adding such a check, we can catch such uses and diagnose them as errors. > > > > Successfully bootstrapped and regretested on x86_64-pc-linux-gnu: > > adds 6 new test results and 4 UNSUPPORTED results to g++.sum. The 4 > > UNSUPPORTED results are due to the fact that concepts are not supported > > before c++20, so tests cannot pass with c++17 and lower standards. > > > > PR c++/100589 > > > > gcc/cp/ChangeLog: > > > > * decl.cc (grokdeclarator): Issue an error for a declarator with > > constrained auto type specifier and trailing return types. > > > > gcc/testsuite/ChangeLog: > > > > * g++.dg/other/pr100589.C: New test. > > Thanks for the patch! Looks good to me overall, some minor comments > below. > Thank you for the review! I'll make changes to the patch based on your advice. > > > > Signed-off-by: Da Xie > > --- > > gcc/cp/decl.cc| 7 +++ > > gcc/testsuite/g++.dg/other/pr100589.C | 7 +++ > > 2 files changed, 14 insertions(+) > > create mode 100644 gcc/testsuite/g++.dg/other/pr100589.C > > > > diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc > > index 9ca8c6c4481..f283ed996a2 100644 > > --- a/gcc/cp/decl.cc > > +++ b/gcc/cp/decl.cc > > @@ -14037,6 +14037,13 @@ grokdeclarator (const cp_declarator *declarator, > > "invalid use of %"); > > return error_mark_node; > > } > > + else if (is_constrained_auto (type)) > > + { > > + error_at (typespec_loc, "invalid use of " > > + "constrained auto type specifier " > > + "in function with trailing return type"); > > We should quote the 'auto' in this diagnostic by writing % > for consistency with the other diagnostics. > I have added an if statement to handle cases where the declarator represents a named function. In such scenarios, an error will be issued, including the function name, the use of constrained %, and the existence of a trailing return type. For all other cases, an error message will indicate the invalid use of constrained %. Curiously, I found that if the same error message occurred multiple times(In my case, the above error message does not print function names, so every function/type declartions issues the same error message), a single dg-error will catch all of them, even if these messages are issued on different lines of code. I think this is the bug mentioned in GCC Wiki (https://gcc.gnu.org/wiki/HowToPrepareATestcase#TODO). Thankfully, in the updated testcase, the error messages are issued for a function declaration and type declaration each. I have updated the dg-error regex pattern to capture error messages separately for functions and types. This ensures more precise matching and handling of the respective error cases. > > + return error_mark_node; > > + } > > tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (auto_node); > > if (!tmpl) > > if (tree late_auto = type_uses_auto (late_return_type)) > > diff --git a/gcc/testsuite/g++.dg/other/pr100589.C > > b/gcc/testsuite/g++.dg/other/pr100589.C > > new file mode 100644 > > index 000..3fa054ed34d > > --- /dev/null > > +++ b/gcc/testsuite/g++.dg/other/pr100589.C > > Since this is a concepts-specific test let's name it > > g++.dg/cpp2a/concepts-pr100589.C > Renamed. > > @@ -0,0 +1,7 @@ > > +// PR c++/100589 > > +// { dg-do compile { target c++20 } } > > + > > +template > > +concept false_concept = false; > > + > > +false_concept auto f() -> int; // { dg-error "constrained auto type > > specifier.* trailing return type" } > > It'd be good to also test a bare function type: > > using type = false_concept auto() -> int; > Test added. > > \ No newline at end of file > > -- > > 2.34.1 > > > > Thanks again for your reply. I will send updated patch when the bootstrap and regression tests are finished.