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.

Reply via email to