]> git.ipfire.org Git - thirdparty/gcc.git/commit
c++: fn redecl in fn scope wrongly accepted [PR116239]
authorMarek Polacek <polacek@redhat.com>
Fri, 30 Aug 2024 18:12:22 +0000 (14:12 -0400)
committerMarek Polacek <polacek@redhat.com>
Thu, 5 Sep 2024 15:07:03 +0000 (11:07 -0400)
commitd44cae2d9310660e3e47f15202e86e4f73f15b37
tree8a73f52b31f6e1a839559e3b44e46e9cd9d8c014
parentae88e91938af364ef5613e5461b12b484b578bc5
c++: fn redecl in fn scope wrongly accepted [PR116239]

Redeclaration such as

  void f(void);
  consteval void f(void);

is invalid.  In a namespace scope, we detect the collision in
validate_constexpr_redeclaration, but not when one declaration is
at block scope.

When we have

  void f(void);
  void g() { consteval void f(void); }

we call pushdecl on the second f and call push_local_extern_decl_alias.
It finds the namespace-scope f:

        for (ovl_iterator iter (binding); iter; ++iter)
          if (decls_match (decl, *iter, /*record_versions*/false))
            {
              alias = *iter;
              break;
            }

but decls_match says they match so we just set DECL_LOCAL_DECL_ALIAS
(and do not call another pushdecl leading to duplicate_decls which
would detect mismatching return types, for example).  I don't think
we want to change decls_match, so a simple fix is to detect the
problem in push_local_extern_decl_alias.

PR c++/116239

gcc/cp/ChangeLog:

* cp-tree.h (validate_constexpr_redeclaration): Declare.
* decl.cc (validate_constexpr_redeclaration): No longer static.
* name-lookup.cc (push_local_extern_decl_alias): Call
validate_constexpr_redeclaration.

gcc/testsuite/ChangeLog:

* g++.dg/diagnostic/redeclaration-6.C: New test.
gcc/cp/cp-tree.h
gcc/cp/decl.cc
gcc/cp/name-lookup.cc
gcc/testsuite/g++.dg/diagnostic/redeclaration-6.C [new file with mode: 0644]