Skip to content
Snippets Groups Projects
Commit 596d1ed9 authored by Patrick Palka's avatar Patrick Palka
Browse files

c++: permit errors inside uninstantiated templates [PR116064]


In recent versions of GCC we've been diagnosing more and more kinds of
errors inside a template ahead of time.  This is a largely good thing
because it catches bugs, typos, dead code etc sooner.

But if the template never gets instantiated then such errors are harmless
and can be inconvenient to work around if say the code in question is
third party and in maintenance mode.  So it'd be handy to be able to
prevent these template errors from rendering the entire TU uncompilable.
(Note that such code is "ill-formed no diagnostic required" according
the standard.)

To that end this patch turns any errors issued within a template into
permerrors associated with a new -Wtemplate-body flag so that they can
be downgraded via e.g. -fpermissive or -Wno-error=template-body.  If
the template containing a downgraded error later needs to be instantiated,
we'll issue an error then.  But if the template never gets instantiated
then the downgraded error won't affect validity of the rest of the TU.

This is implemented via a diagnostic hook that gets called for each
diagnostic, and which adjusts an error diagnostic appropriately if we
detect it's occurring from a template context, and additionally flags
the template as erroneous.

For example the new testcase permissive-error1a.C gives:

gcc/testsuite/g++.dg/template/permissive-error1a.C: In function 'void f()':
gcc/testsuite/g++.dg/template/permissive-error1a.C:7:5: warning: increment of read-only variable 'n' [-Wtemplate-body]
    7 |   ++n;
      |     ^
...
gcc/testsuite/g++.dg/template/permissive-error1a.C: In instantiation of 'void f() [with T = int]':
gcc/testsuite/g++.dg/template/permissive-error1a.C:26:9:   required from here
   26 |   f<int>();
      |   ~~~~~~^~
gcc/testsuite/g++.dg/template/permissive-error1a.C:5:6: error: instantiating erroneous template
    5 | void f() {
      |      ^
gcc/testsuite/g++.dg/template/permissive-error1a.C:7:5: note: first error appeared here
    7 |   ++n; // {
      |     ^
...

	PR c++/116064

gcc/c-family/ChangeLog:

	* c.opt (Wtemplate-body): New warning.

gcc/cp/ChangeLog:

	* cp-tree.h (erroneous_templates_t): Declare.
	(erroneous_templates): Declare.
	(cp_seen_error): Declare.
	(seen_error): #define to cp_seen_error.
	* error.cc (get_current_template): Define.
	(relaxed_template_errors): Define.
	(cp_adjust_diagnostic_info): Define.
	(cp_seen_error): Define.
	(cxx_initialize_diagnostics): Set
	diagnostic_context::m_adjust_diagnostic_info.
	* module.cc (finish_module_processing): Don't write the
	module if it contains an erroneous template.
	* pt.cc (maybe_diagnose_erroneous_template): Define.
	(instantiate_class_template): Call it.
	(instantiate_decl): Likewise.

gcc/ChangeLog:

	* diagnostic.cc (diagnostic_context::initialize): Set
	m_adjust_diagnostic_info.
	(diagnostic_context::report_diagnostic): Call
	m_adjust_diagnostic_info.
	* diagnostic.h (diagnostic_context::m_adjust_diagnostic_info):
	New data member.
	* doc/invoke.texi (-Wno-template-body): Document.
	(-fpermissive): Mention -Wtemplate-body.

gcc/testsuite/ChangeLog:

	* g++.dg/ext/typedef-init.C: Downgrade error inside template
	to warning due to -fpermissive.
	* g++.dg/pr84492.C: Likewise.
	* g++.old-deja/g++.pt/crash51.C: Remove unneeded dg-options.
	* g++.dg/template/permissive-error1.C: New test.
	* g++.dg/template/permissive-error1a.C: New test.
	* g++.dg/template/permissive-error1b.C: New test.
	* g++.dg/template/permissive-error1c.C: New test.

Reviewed-by: default avatarJason Merrill <jason@redhat.com>
parent b120ca0c
No related branches found
No related tags found
No related merge requests found
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment