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.

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" }
-- 
2.44.0

Reply via email to