]> git.ipfire.org Git - thirdparty/gcc.git/commit
c++: Fix ICE in build_base_path -> resolves_to_fixed_type_p -> fixed_type_or_null...
authorJakub Jelinek <jakub@redhat.com>
Wed, 21 Jan 2026 13:32:26 +0000 (14:32 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 21 Jan 2026 13:32:26 +0000 (14:32 +0100)
commit4073b1bae63cf4f0bf834fefff8e02085b606e8f
treee37a43318becc95f659e5772a183fe92f23ad040
parent9abe0b4f76265a062f1646a0bff1f58b70ae5695
c++: Fix ICE in build_base_path -> resolves_to_fixed_type_p -> fixed_type_or_null [PR123692]

The move of the resolves_to_fixed_type_p call earlier in build_base_path
for constexpr virtual inheritance caused the following ICE.
What changed is that in an unevaluated context expr can be a CALL_EXPR with
class type and when it is not a ctor,
resolves_to_fixed_type_p -> fixed_type_or_null
ICEs on it:
      if (CLASS_TYPE_P (TREE_TYPE (instance)))
        {
          /* We missed a build_cplus_new somewhere, likely due to tf_decltype
             mishandling.  */
          gcc_checking_assert (false);
Now, the reason why that worked fine when resolves_to_fixed_type_p was
later in the function is that there was
      /* This must happen before the call to save_expr.  */
      expr = cp_build_addr_expr (expr, complain);
in between the new and old calls to resolves_to_fixed_type_p, and for the
uneval case like that
cp_build_addr_expr -> unary_complex_lvalue -> build_cplus_new
wraps the CALL_EXPR into a TARGET_EXPR already, so the later call
was happy.

Now, none of fixed_type_p, virtual_access or nonnull values are ever
used in the build_base_path uneval path.
  if (code == PLUS_EXPR
      && !want_pointer
      && !has_empty
      && !uneval
      && !virtual_access)
    return build_simple_base_path (expr, binfo);
doesn't look at it,
  if (!want_pointer)
    {
      rvalue = !lvalue_p (expr);
      /* This must happen before the call to save_expr.  */
      expr = cp_build_addr_expr (expr, complain);
    }
  else
    expr = mark_rvalue_use (expr);
neither, nothing soon after it either and very soon we
  if (uneval)
    {
      expr = build_nop (ptr_target_type, expr);
      goto indout;
    }
and indout: doesn't use it either.

So, if only uneval expressions have problems with moving the
resolves_to_fixed_type_p call earlier, the following patch fixes
it by just not calling that function at all in the uneval case
because we will not care about the result anyway.

2026-01-21  Jakub Jelinek  <jakub@redhat.com>

PR c++/123692
* class.cc (build_base_path): Don't call resolves_to_fixed_type_p if
uneval.

* g++.dg/cpp0x/pr123692.C: New test.
gcc/cp/class.cc
gcc/testsuite/g++.dg/cpp0x/pr123692.C [new file with mode: 0644]