public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jakub Jelinek <jakub@redhat.com>
To: Jason Merrill <jason@redhat.com>
Cc: gcc-patches@gcc.gnu.org
Subject: [C++ PATCH] Improve C++ error recovery (PR c++/59655)
Date: Tue, 10 Dec 2019 21:02:00 -0000	[thread overview]
Message-ID: <20191210210247.GH10088@tucnak> (raw)

Hi!

On the following testcase, we emit 2 errors and 1 warning, when the user
really should see one error.  The desirable error is static_assert failure,
the bogus error is during error recovery, complaining that a no_linkage
template isn't defined when it really is defined, but we haven't bothered
instantiating it, because limit_bad_template_recursion sad so.
And finally a warning from the middle-end about function being used even
when it is not defined.

The last one already checks TREE_NO_WARNING on the function decl to avoid
the warning, so this patch just uses TREE_NO_WARNING to signal this case,
both to that warning and to no_linkage_error.

Now, I admit I'm not 100% sure if using TREE_NO_WARNING is the best thing
for no_linkage_error, another possibility might be adding some bit in
lang_decl_base or so and setting that bit in addition to TREE_NO_WARNING,
where that new bit would mean this decl might be defined if we didn't decide
not to instantiate it.  With the patch as is, there is a risk if
TREE_NO_WARNING is set for some other reason on a fndecl (or variable
template instantiation?) and some errors have been reported already that we
won't report another error for it when we should.  But perhaps that is
acceptable, once users fix the original errors even if TREE_NO_WARNING will
be set, errorcount + sorrycount will be zero and thus no_linkage_error will
still report it.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Or do you want to use an additional bit for that?

2019-12-10  Jakub Jelinek  <jakub@redhat.com>

	PR c++/59655
	* pt.c (push_tinst_level_loc): If limit_bad_template_recursion,
	set TREE_NO_WARNING on tldcl.
	* decl2.c (no_linkage_error): Treat templates with TREE_NO_WARNING
	as defined during error recovery.

	* g++.dg/cpp0x/diag3.C: New test.

--- gcc/cp/pt.c.jj	2019-12-10 00:52:39.017449262 +0100
+++ gcc/cp/pt.c	2019-12-10 19:20:11.046062705 +0100
@@ -10640,7 +10640,12 @@ push_tinst_level_loc (tree tldcl, tree t
      anything else.  Do allow deduction substitution and decls usable in
      constant expressions.  */
   if (!targs && limit_bad_template_recursion (tldcl))
-    return false;
+    {
+      /* Avoid no_linkage_errors and unused function warnings for this
+	 decl.  */
+      TREE_NO_WARNING (tldcl) = 1;
+      return false;
+    }
 
   /* When not -quiet, dump template instantiations other than functions, since
      announce_function will take care of those.  */
--- gcc/cp/decl2.c.jj	2019-11-28 09:05:13.376262983 +0100
+++ gcc/cp/decl2.c	2019-12-10 19:33:05.555237052 +0100
@@ -4414,7 +4414,14 @@ decl_maybe_constant_var_p (tree decl)
 void
 no_linkage_error (tree decl)
 {
-  if (cxx_dialect >= cxx11 && decl_defined_p (decl))
+  if (cxx_dialect >= cxx11
+      && (decl_defined_p (decl)
+	  /* Treat templates which limit_bad_template_recursion decided
+	     not to instantiate as if they were defined.  */
+	  || (errorcount + sorrycount > 0
+	      && DECL_LANG_SPECIFIC (decl)
+	      && DECL_TEMPLATE_INFO (decl)
+	      && TREE_NO_WARNING (decl))))
     /* In C++11 it's ok if the decl is defined.  */
     return;
   tree t = no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false);
--- gcc/testsuite/g++.dg/cpp0x/diag3.C.jj	2019-12-10 19:39:06.659722663 +0100
+++ gcc/testsuite/g++.dg/cpp0x/diag3.C	2019-12-10 19:37:30.617189316 +0100
@@ -0,0 +1,20 @@
+// PR c++/59655
+// { dg-do compile { target c++11 } }
+
+template<typename T> struct A { static constexpr bool value = false; };
+
+struct B {
+  template<typename T>
+  B (T t)
+  {
+    static_assert (A<T>::value, "baz");		// { dg-error "static assertion failed" }
+    foo (t);
+  }
+  template<typename T> void foo (T) {}		// { dg-bogus "used but never defined" }
+};
+
+int
+main ()
+{
+  B t([](int) { });
+}

	Jakub

             reply	other threads:[~2019-12-10 21:02 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-10 21:02 Jakub Jelinek [this message]
2019-12-17 14:33 ` C++ Patch Ping (was Re: [C++ PATCH] Improve C++ error recovery (PR c++/59655)) Jakub Jelinek
2019-12-17 19:28 ` [C++ PATCH] Improve C++ error recovery (PR c++/59655) Jason Merrill

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191210210247.GH10088@tucnak \
    --to=jakub@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jason@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).