https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116064

--- Comment #7 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Patrick Palka <ppa...@gcc.gnu.org>:

https://gcc.gnu.org/g:596d1ed9d40b1081fcc6c6161a0135952829b88f

commit r15-2774-g596d1ed9d40b1081fcc6c6161a0135952829b88f
Author: Patrick Palka <ppa...@redhat.com>
Date:   Tue Aug 6 20:54:03 2024 -0400

    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: Jason Merrill <ja...@redhat.com>

Reply via email to