On Tue, Jul 14, 2026 at 10:59:49AM -0400, Jason Merrill wrote:
> > It works too (and doesn't emit the undesirable diagnostics in
> > cpp0x/dealloc2.C line 9 for C++29).
>
> OK.
Unfortunately full testing revealed that this version doesn't work,
regresses
FAIL: g++.dg/init/placement4.C -std=c++29 (internal compiler error: in
type_dependent_expression_p, at cp/pt.cc:30510)
FAIL: g++.dg/init/placement4.C -std=c++29 (test for errors, line 25)
FAIL: g++.dg/init/placement4.C -std=c++29 (test for warnings, line 32)
FAIL: g++.dg/init/placement4.C -std=c++29 (test for excess errors)
FAIL: g++.dg/warn/Wmismatched-new-delete-10.C -std=gnu++29 (internal compiler
error: in type_dependent_expression_p, at cp/pt.cc:30510)
FAIL: g++.dg/warn/Wmismatched-new-delete-10.C -std=gnu++29 (test for excess
errors)
FAIL: g++.dg/warn/Wmismatched-new-delete-9.C -std=c++29 (internal compiler
error: in type_dependent_expression_p, at cp/pt.cc:30510)
FAIL: g++.dg/warn/Wmismatched-new-delete-9.C -std=c++29 at line 32 (test for
warnings, line 31)
FAIL: g++.dg/warn/Wmismatched-new-delete-9.C -std=c++29 at line 33 (test for
warnings, line 31)
FAIL: g++.dg/warn/Wmismatched-new-delete-9.C -std=c++29 at line 35 (test for
warnings, line 34)
FAIL: g++.dg/warn/Wmismatched-new-delete-9.C -std=c++29 at line 36 (test for
warnings, line 34)
FAIL: g++.dg/warn/Wmismatched-new-delete-9.C -std=c++29 at line 42 (test for
warnings, line 41)
FAIL: g++.dg/warn/Wmismatched-new-delete-9.C -std=c++29 at line 43 (test for
warnings, line 41)
FAIL: g++.dg/warn/Wmismatched-new-delete-9.C -std=c++29 at line 45 (test for
warnings, line 44)
FAIL: g++.dg/warn/Wmismatched-new-delete-9.C -std=c++29 at line 46 (test for
warnings, line 44)
FAIL: g++.dg/warn/Wmismatched-new-delete-9.C -std=c++29 (test for excess
errors)
FAIL: g++.dg/warn/Wshadow-15.C -std=gnu++29 (internal compiler error: in
type_dependent_expression_p, at cp/pt.cc:30510)
FAIL: g++.dg/warn/Wshadow-15.C -std=gnu++29 (test for warnings, line 7)
FAIL: g++.dg/warn/Wshadow-15.C -std=gnu++29 (test for excess errors)
The ICEs are in all cases
/* Otherwise, if the function decl isn't from a dependent scope, it can't be
type-dependent. Checking this is important for functions with auto return
type, which looks like a dependent type. */
if (TREE_CODE (expression) == FUNCTION_DECL
&& !(DECL_CLASS_SCOPE_P (expression)
&& dependent_type_p (DECL_CONTEXT (expression)))
&& !(DECL_LANG_SPECIFIC (expression)
&& DECL_UNIQUE_FRIEND_P (expression)
&& (!DECL_FRIEND_CONTEXT (expression)
|| dependent_type_p (DECL_FRIEND_CONTEXT (expression))))
&& !DECL_LOCAL_DECL_P (expression))
{
gcc_assert (!dependent_type_p (TREE_TYPE (expression))
|| undeduced_auto_decl (expression));
return false;
}
in type_dependent_expression_p, the type e.g. in placement4.C of
template<typename T>
void operator delete(void *p,Pool<T>& pool)
{
undef<T> t; // { dg-error "incomplete" }
free(p);
}
is dependent at that point. maybe_instantiate_noexcept is guarded by
/* Don't instantiate a noexcept-specification from template context. */
if (processing_template_decl
&& (!flag_noexcept_type || type_dependent_expression_p (fn)))
return true;
So, shall that be
if (processing_template_decl
&& (!flag_noexcept_type
|| dependent_type_p (TREE_TYPE (fn))
|| type_dependent_expression_p (fn)))
return true;
or shall I use that check in maybe_diagnose_deallocation_noexcept_false?
operator delete has to return void, so maybe I don't need to be afraid
about undeduced_auto_decl.
Anyway, isn't grokfndecl too early? I mean for cases like
struct E {
static void operator delete (void *) noexcept (C) {}
static constexpr bool C = false;
};
which I should add to the testsuite. When grokfndecl is called,
TYPE_RAISES_EXCEPTION (TREE_TYPE (fn)) is
<tree_list 0x7fffe99a4f28
purpose <deferred_parse 0x7fffe99bbe70>>
and so nothing is reported.
This is only changed in fixup_deferred_exception_variants.
Or should cp_parser_class_specifier call
maybe_diagnose_deallocation_noexcept_false again if it parses it?
Note, the first version of the patch doesn't ICE on the above 4
testcases and handles thie E::operator delete case right too.
Jakub