Eric Gallager via Gcc-patches writes: > On Wed, Jun 14, 2023 at 8:29 PM David Malcolm via Gcc-patches > wrote: >> >> PR c++/110164 notes that in cases where we have a forward decl >> of a std library type such as: >> >> std::array x; >> >> we omit this diagnostic: >> >> error: aggregate ‘std::array x’ has incomplete type and cannot be defined >> >> This patch adds this hint to the diagnostic: >> >> note: ‘std::array’ is defined in header ‘’; this is probably fixable by adding ‘#include ’ >> > > ..."probably"? > Right now, our fixit says: ``` /tmp/foo.c:1:1: note: ‘time_t’ is defined in header ‘’; did you forget to ‘#include ’? ``` We should probably use the same phrasing for consistency? >> Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. >> OK for trunk? >> >> gcc/cp/ChangeLog: >> PR c++/110164 >> * cp-name-hint.h (maybe_suggest_missing_header): New decl. >> * decl.cc: Define INCLUDE_MEMORY. Add include of >> "cp/cp-name-hint.h". >> (start_decl_1): Call maybe_suggest_missing_header. >> * name-lookup.cc (maybe_suggest_missing_header): Remove "static". >> >> gcc/testsuite/ChangeLog: >> PR c++/110164 >> * g++.dg/missing-header-pr110164.C: New test. >> --- >> gcc/cp/cp-name-hint.h | 3 +++ >> gcc/cp/decl.cc | 10 ++++++++++ >> gcc/cp/name-lookup.cc | 2 +- >> gcc/testsuite/g++.dg/missing-header-pr110164.C | 10 ++++++++++ >> 4 files changed, 24 insertions(+), 1 deletion(-) >> create mode 100644 gcc/testsuite/g++.dg/missing-header-pr110164.C >> >> diff --git a/gcc/cp/cp-name-hint.h b/gcc/cp/cp-name-hint.h >> index bfa7c53c8f6..e2387e23d1f 100644 >> --- a/gcc/cp/cp-name-hint.h >> +++ b/gcc/cp/cp-name-hint.h >> @@ -32,6 +32,9 @@ along with GCC; see the file COPYING3. If not see >> >> extern name_hint suggest_alternatives_for (location_t, tree, bool); >> extern name_hint suggest_alternatives_in_other_namespaces (location_t, tree); >> +extern name_hint maybe_suggest_missing_header (location_t location, >> + tree name, >> + tree scope); >> extern name_hint suggest_alternative_in_explicit_scope (location_t, tree, tree); >> extern name_hint suggest_alternative_in_scoped_enum (tree, tree); >> >> diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc >> index a672e4844f1..504b08ec250 100644 >> --- a/gcc/cp/decl.cc >> +++ b/gcc/cp/decl.cc >> @@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see >> line numbers. For example, the CONST_DECLs for enum values. */ >> >> #include "config.h" >> +#define INCLUDE_MEMORY >> #include "system.h" >> #include "coretypes.h" >> #include "target.h" >> @@ -46,6 +47,7 @@ along with GCC; see the file COPYING3. If not see >> #include "c-family/c-objc.h" >> #include "c-family/c-pragma.h" >> #include "c-family/c-ubsan.h" >> +#include "cp/cp-name-hint.h" >> #include "debug.h" >> #include "plugin.h" >> #include "builtins.h" >> @@ -5995,7 +5997,11 @@ start_decl_1 (tree decl, bool initialized) >> ; /* An auto type is ok. */ >> else if (TREE_CODE (type) != ARRAY_TYPE) >> { >> + auto_diagnostic_group d; >> error ("variable %q#D has initializer but incomplete type", decl); >> + maybe_suggest_missing_header (input_location, >> + TYPE_IDENTIFIER (type), >> + TYPE_CONTEXT (type)); >> type = TREE_TYPE (decl) = error_mark_node; >> } >> else if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (type)))) >> @@ -6011,8 +6017,12 @@ start_decl_1 (tree decl, bool initialized) >> gcc_assert (CLASS_PLACEHOLDER_TEMPLATE (type)); >> else >> { >> + auto_diagnostic_group d; >> error ("aggregate %q#D has incomplete type and cannot be defined", >> decl); >> + maybe_suggest_missing_header (input_location, >> + TYPE_IDENTIFIER (type), >> + TYPE_CONTEXT (type)); >> /* Change the type so that assemble_variable will give >> DECL an rtl we can live with: (mem (const_int 0)). */ >> type = TREE_TYPE (decl) = error_mark_node; >> diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc >> index 6ac58a35b56..917b481c163 100644 >> --- a/gcc/cp/name-lookup.cc >> +++ b/gcc/cp/name-lookup.cc >> @@ -6796,7 +6796,7 @@ maybe_suggest_missing_std_header (location_t location, tree name) >> for NAME within SCOPE at LOCATION, or an empty name_hint if this isn't >> applicable. */ >> >> -static name_hint >> +name_hint >> maybe_suggest_missing_header (location_t location, tree name, tree scope) >> { >> if (scope == NULL_TREE) >> diff --git a/gcc/testsuite/g++.dg/missing-header-pr110164.C b/gcc/testsuite/g++.dg/missing-header-pr110164.C >> new file mode 100644 >> index 00000000000..15980071c38 >> --- /dev/null >> +++ b/gcc/testsuite/g++.dg/missing-header-pr110164.C >> @@ -0,0 +1,10 @@ >> +// { dg-require-effective-target c++11 } >> + >> +#include >> + >> +std::array a1; /* { dg-error "incomplete type" } */ >> +/* { dg-message "'std::array' is defined in header ''; this is probably fixable by adding '#include '" "hint" { target *-*-* } .-1 } */ >> + >> +std::array a2 {5}; /* { dg-error "incomplete type" } */ >> +/* { dg-message "'std::array' is defined in header ''; this is probably fixable by adding '#include '" "hint" { target *-*-* } .-1 } */ >> + >> -- >> 2.26.3 >>