Hi,
we have this pretty old regression where we ICE on the invalid snippet:
class A
{
int f ();
enum { a = f };
};
in fact we hit the gcc_checking_assert in cxx_eval_constant_expression
case COMPONENT_REF:
if (is_overloaded_fn (t))
{
/* We can only get here in checking mode via
build_non_dependent_expr, because any expression that
calls or takes the address of the function will have
pulled a FUNCTION_DECL out of the COMPONENT_REF. */
gcc_checking_assert (ctx->quiet || errorcount);
*non_constant_p = true;
return t;
}
which goes back to my fix for c++/58647 (that's why Jakub CC-ed me).
Three years later some archeology is required, this is the original thread:
https://gcc.gnu.org/ml/gcc-patches/2013-11/msg03059.html
Obviously the comment above isn't (fully) correct (anymore), we don't
get there via build_non_dependent_expr, the backtrace is simple:
#0 cxx_eval_constant_expression (ctx=0x7fffffffd170, t=0x7ffff68559c0,
lval=false, non_constant_p=0x7fffffffd1a7, overflow_p=0x7fffffffd1a6,
jump_target=0x0) at ../../trunk/gcc/cp/constexpr.c:3918
#1 0x0000000000929dd1 in cxx_eval_outermost_constant_expr
(t=0x7ffff68559c0, allow_non_constant=false, strict=true, object=0x0) at
../../trunk/gcc/cp/constexpr.c:4211
#2 0x000000000092a46f in cxx_constant_value (t=0x7ffff68559c0,
decl=0x0) at ../../trunk/gcc/cp/constexpr.c:4309
#3 0x00000000006aebf2 in build_enumerator (name=0x7ffff69ce000,
value=0x7ffff68559c0, enumtype=0x7ffff69bd690, attributes=0x0,
loc=250592) at ../../trunk/gcc/cp/decl.c:13588
#4 0x00000000007c9b35 in cp_parser_enumerator_definition
(parser=0x7ffff7fbeab0, type=0x7ffff69bd690) at
../../trunk/gcc/cp/parser.c:17431
thus from the parser straight through build_enumerator and then
cxx_constant_value.
Now, I suspect a fix for this issue is simple, eg, does it really make
sense to keep the gcc_checking_assert in the face of this kind of broken
but quite straightforward snippet? Of course ctx-quiet is false in this
case and errorcount is still 0 but when we return from
cxx_constant_value with such a COMPONENT_REF, build_enumerator
immediately does:
if (TREE_CODE (value) != INTEGER_CST
|| ! INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (value)))
{
error ("enumerator value for %qD is not an integer constant",
name);
value = NULL_TREE;
}
and we are Ok diagnostic-wise (if we want we could say something more
specific in build_enumerator, eg, clang says "call to non-static member
function without an object argument", edg does not).
What do you think?
Thanks,
Paolo.