This is an invalid program ``` void f(void); int main() { consteval void f(void); } ``` because of function f redeclaration with consteval. It is rejected in Clang and MSVC, but not in GCC unfortunately. Online demo: https://gcc.godbolt.org/z/n8x49h8Wa Expected error: redeclaration 'consteval void f()' differs in 'consteval' from previous declaration
``` void f(void); int main() { constexpr void f(void); } ``` Also.
We have validate_constexpr_redeclaration that should have detected this.
We never call duplicate_decls -> validate_constexpr_redeclaration because decls_match doesn't look at decl-specifiers like constexpr/consteval. for (ovl_iterator iter (binding); iter; ++iter) if (decls_match (decl, *iter, /*record_versions*/false)) { alias = *iter; break; } so they're just aliases.
Eh, let's fix this simply in push_local_extern_decl_alias.
The trunk branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>: https://gcc.gnu.org/g:d44cae2d9310660e3e47f15202e86e4f73f15b37 commit r15-3489-gd44cae2d9310660e3e47f15202e86e4f73f15b37 Author: Marek Polacek <polacek@redhat.com> Date: Fri Aug 30 14:12:22 2024 -0400 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.
Fixed.