On 12/21/24 11:35 AM, Simon Martin wrote:
When erroring out due to an incomplete type, we add a contextual note
about the type. However, when the error is suppressed by
-Wno-template-body, the note remains, making the compiler output quite
puzzling.
This patch makes sure the note is suppressed if we're processing a
template declaration body with -Wno-template-body.
Successfully tested on x86_64-pc-linux-gnu.
PR c++/118163
gcc/cp/ChangeLog:
* cp-tree.h (get_current_template): Declare.
* error.cc (get_current_template): Make non static.
* typeck2.cc (cxx_incomplete_type_inform): Suppress note when
parsing a template declaration with -Wno-template-body.
I think rather than adding this sort of thing in lots of places where an
error is followed by an inform, we should change error to return bool
like other diagnostic functions, and check its return value before
calling cxx_incomplete_type_inform or plain inform. This likely
involves the same number of changes, but they should be smaller.
Patrick, what do you think?
gcc/testsuite/ChangeLog:
* g++.dg/diagnostic/incomplete-type-2.C: New test.
* g++.dg/diagnostic/incomplete-type-2a.C: New test.
---
gcc/cp/cp-tree.h | 1 +
gcc/cp/error.cc | 2 +-
gcc/cp/typeck2.cc | 6 ++++++
gcc/testsuite/g++.dg/diagnostic/incomplete-type-2.C | 7 +++++++
.../g++.dg/diagnostic/incomplete-type-2a.C | 13 +++++++++++++
5 files changed, 28 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/g++.dg/diagnostic/incomplete-type-2.C
create mode 100644 gcc/testsuite/g++.dg/diagnostic/incomplete-type-2a.C
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 6de8f64b5ee..52f954b63d9 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7297,6 +7297,7 @@ struct decl_location_traits
typedef hash_map<tree, location_t, decl_location_traits>
erroneous_templates_t;
extern GTY((cache)) erroneous_templates_t *erroneous_templates;
+extern tree get_current_template ();
extern bool cp_seen_error ();
#define seen_error() cp_seen_error ()
diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
index 8c0644fba7e..7fd03dd6d12 100644
--- a/gcc/cp/error.cc
+++ b/gcc/cp/error.cc
@@ -197,7 +197,7 @@ class cxx_format_postprocessor : public format_postprocessor
/* Return the in-scope template that's currently being parsed, or
NULL_TREE otherwise. */
-static tree
+tree
get_current_template ()
{
if (scope_chain && in_template_context && !current_instantiation ())
diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc
index fce687e83b3..505c143dae7 100644
--- a/gcc/cp/typeck2.cc
+++ b/gcc/cp/typeck2.cc
@@ -273,6 +273,12 @@ cxx_incomplete_type_inform (const_tree type)
if (!TYPE_MAIN_DECL (type))
return;
+ /* When processing a template declaration body, the error generated by the
+ caller (if any) might have been suppressed by -Wno-template-body. If that
+ is the case, suppress the inform as well. */
+ if (!warn_template_body && get_current_template ())
+ return;
+
location_t loc = DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type));
tree ptype = strip_top_quals (CONST_CAST_TREE (type));
diff --git a/gcc/testsuite/g++.dg/diagnostic/incomplete-type-2.C b/gcc/testsuite/g++.dg/diagnostic/incomplete-type-2.C
new file mode 100644
index 00000000000..e2fb20a4ae8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/incomplete-type-2.C
@@ -0,0 +1,7 @@
+// PR c++/118163
+// { dg-do "compile" }
+
+template<class T>
+struct S { // { dg-note "until the closing brace" }
+ S s; // { dg-error "has incomplete type" }
+};
diff --git a/gcc/testsuite/g++.dg/diagnostic/incomplete-type-2a.C
b/gcc/testsuite/g++.dg/diagnostic/incomplete-type-2a.C
new file mode 100644
index 00000000000..d13021d0b68
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/incomplete-type-2a.C
@@ -0,0 +1,13 @@
+// PR c++/118163
+// { dg-do "compile" }
+// { dg-additional-options "-Wno-template-body" }
+
+template<class T>
+struct S { // { dg-bogus "until the closing brace" }
+ S s; // { dg-bogus "has incomplete type" }
+};
+
+// Check that we don't suppress errors outside of the body.
+struct forward_decl; // { dg-note "forward declaration" }
+template<class T>
+void foo (forward_decl) {} // { dg-error "has incomplete type" }