Bug 113031 - [14 Regression] ICE in cxx_fold_indirect_ref_1 starting with r14-6508
Summary: [14 Regression] ICE in cxx_fold_indirect_ref_1 starting with r14-6508
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 14.0
: P1 normal
Target Milestone: 14.0
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2023-12-15 11:22 UTC by Jonathan Wakely
Modified: 2024-01-01 03:13 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2023-12-15 00:00:00


Attachments
Gzipped preprocessed source (263.29 KB, application/gzip)
2023-12-15 11:26 UTC, Jonathan Wakely
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Wakely 2023-12-15 11:22:48 UTC
I'm seeing new ICEs in the libstdc++ testsuite with the following non-default settings:

> 
> GLIBCXX_TESTSUITE_STDS=20 make check RUNTESTFLAGS="--target_board=unix/-D_GLIBCXX_USE_CXX11_ABI=0"
> 


/home/jwakely/src/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/variant:1626:17: internal compiler error: Segmentation fault
0x11373c4 crash_signal
       ../../gcc/toplev.cc:316
0x496192 cxx_fold_indirect_ref_1
       ../../gcc/cp/constexpr.cc:5712
0x496487 cxx_fold_indirect_ref_1
       ../../gcc/cp/constexpr.cc:5743
0x496487 cxx_fold_indirect_ref_1
       ../../gcc/cp/constexpr.cc:5743
0x496487 cxx_fold_indirect_ref_1
       ../../gcc/cp/constexpr.cc:5743
0x496487 cxx_fold_indirect_ref_1
       ../../gcc/cp/constexpr.cc:5743
0x496487 cxx_fold_indirect_ref_1
       ../../gcc/cp/constexpr.cc:5743
0x496487 cxx_fold_indirect_ref_1
       ../../gcc/cp/constexpr.cc:5743
0x496487 cxx_fold_indirect_ref_1
       ../../gcc/cp/constexpr.cc:5743
0x496487 cxx_fold_indirect_ref_1
       ../../gcc/cp/constexpr.cc:5743
0x496487 cxx_fold_indirect_ref_1
       ../../gcc/cp/constexpr.cc:5743
0x496487 cxx_fold_indirect_ref_1
       ../../gcc/cp/constexpr.cc:5743
0x496487 cxx_fold_indirect_ref_1
       ../../gcc/cp/constexpr.cc:5743
0x496487 cxx_fold_indirect_ref_1
       ../../gcc/cp/constexpr.cc:5743
0x496487 cxx_fold_indirect_ref_1
       ../../gcc/cp/constexpr.cc:5743
0x496487 cxx_fold_indirect_ref_1
       ../../gcc/cp/constexpr.cc:5743
0x496487 cxx_fold_indirect_ref_1
       ../../gcc/cp/constexpr.cc:5743
0x496487 cxx_fold_indirect_ref_1
       ../../gcc/cp/constexpr.cc:5743
0x496487 cxx_fold_indirect_ref_1
       ../../gcc/cp/constexpr.cc:5743
0x496487 cxx_fold_indirect_ref_1
       ../../gcc/cp/constexpr.cc:5743
Please submit a full bug report, with preprocessed source (by using -freport-bug).
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
Comment 1 Jonathan Wakely 2023-12-15 11:26:03 UTC
Created attachment 56884 [details]
Gzipped preprocessed source

Compile the attached .ii with '-std=gnu++20 -O' (or any non-zero optimization level) to reproduce the ICE.
Comment 2 Nathaniel Shead 2023-12-15 13:52:29 UTC
Reduced to:


template <typename> class variant;

template <typename _Types, typename _Tp>
auto __variant_cast(_Tp __rhs) { return static_cast<variant<_Types>&&>(__rhs); }

template <typename _Types>
struct _Move_assign_base : _Types {
  void operator=(_Move_assign_base __rhs) { __variant_cast<_Types>(__rhs); }
};

template <typename _Types>
struct variant : _Move_assign_base<_Types> {
  void emplace() {
    variant __tmp;
    *this = __tmp;
  }
};

struct _Undefined_class {
  struct _Nocopy_types {
    void (_Undefined_class::*_M_member_pointer)();
  };
  struct function : _Nocopy_types {
    struct optional {
      void test03() {
        variant<function> v;
        v.emplace();
      }
    };
  };
};


The following patch seems to fix the immediate problem (but not yet fully regtested):

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index e1b2d27fc36..051f73fb73f 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -5709,7 +5709,8 @@ cxx_fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type,
          }

       /* Handle conversion to "as base" type.  */
-      if (CLASSTYPE_AS_BASE (optype) == type)
+      if (CLASS_TYPE_P (optype)
+         && CLASSTYPE_AS_BASE (optype) == type)
        return op;

       /* Handle conversion to an empty base class, which is represented with a
Comment 3 Jonathan Wakely 2023-12-15 13:53:44 UTC
That was quick, thanks!
Comment 4 GCC Commits 2023-12-16 04:11:15 UTC
The master branch has been updated by Nathaniel Shead <nshead@gcc.gnu.org>:

https://gcc.gnu.org/g:39f9c426f58448d6df340cdccd84e05721a20921

commit r14-6619-g39f9c426f58448d6df340cdccd84e05721a20921
Author: Nathaniel Shead <nathanieloshead@gmail.com>
Date:   Sat Dec 16 10:59:03 2023 +1100

    c++: Fix unchecked use of CLASSTYPE_AS_BASE [PR113031]
    
    My previous commit (naively) assumed that a TREE_CODE of RECORD_TYPE or
    UNION_TYPE was sufficient for optype to be considered a "class type".
    However, this does not account for e.g. template type parameters of
    record or union type. This patch corrects to check for CLASS_TYPE_P
    before checking for as-base conversion.
    
            PR c++/113031
    
    gcc/cp/ChangeLog:
    
            * constexpr.cc (cxx_fold_indirect_ref_1): Check for CLASS_TYPE
            before using CLASSTYPE_AS_BASE.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp0x/pr113031.C: New test.
    
    Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Comment 5 Jakub Jelinek 2023-12-21 19:07:48 UTC
So fixed?
Comment 6 Nathaniel Shead 2023-12-22 00:52:13 UTC
Yes, fixed as far as I'm aware.
Comment 7 Jakub Jelinek 2023-12-22 00:55:38 UTC
.