From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1873) id 36CC73858C2F; Mon, 15 Aug 2022 20:34:13 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 36CC73858C2F MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Iain Buclaw To: gcc-cvs@gcc.gnu.org Subject: [gcc r12-8688] d: Fix internal compiler error: Segmentation fault at gimple-expr.cc:88 X-Act-Checkin: gcc X-Git-Author: Iain Buclaw X-Git-Refname: refs/heads/releases/gcc-12 X-Git-Oldrev: 0dd50365ba1556cc3b9e8b24551e978f9de14eec X-Git-Newrev: dc230a0c690794cd45cc4065fa13303fd6cdfc40 Message-Id: <20220815203413.36CC73858C2F@sourceware.org> Date: Mon, 15 Aug 2022 20:34:13 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 15 Aug 2022 20:34:13 -0000 https://gcc.gnu.org/g:dc230a0c690794cd45cc4065fa13303fd6cdfc40 commit r12-8688-gdc230a0c690794cd45cc4065fa13303fd6cdfc40 Author: Iain Buclaw Date: Mon Aug 15 17:51:03 2022 +0200 d: Fix internal compiler error: Segmentation fault at gimple-expr.cc:88 Because complex types are deprecated in the language, the new way to expose native complex types is by defining an enum with a basetype of a library-defined struct that is implicitly treated as-if it is native. As casts are not implicitly added by the front-end when downcasting from enum to its underlying type, we must insert an explicit cast during the code generation pass. PR d/106623 gcc/d/ChangeLog: * d-codegen.cc (underlying_complex_expr): New function. (d_build_call): Handle passing native complex objects as the library-defined equivalent. * d-tree.h (underlying_complex_expr): Declare. * expr.cc (ExprVisitor::visit (DotVarExp *)): Call underlying_complex_expr instead of build_vconvert. gcc/testsuite/ChangeLog: * gdc.dg/torture/pr106623.d: New test. (cherry picked from commit e206fecaac29f559f4990312b875604eb1ce3ef3) Diff: --- gcc/d/d-codegen.cc | 34 +++++++++++++++++++++++++++++++++ gcc/d/d-tree.h | 1 + gcc/d/expr.cc | 2 +- gcc/testsuite/gdc.dg/torture/pr106623.d | 28 +++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc index 22090a8c755..0f2110ec7c1 100644 --- a/gcc/d/d-codegen.cc +++ b/gcc/d/d-codegen.cc @@ -1578,6 +1578,32 @@ complex_expr (tree type, tree re, tree im) type, re, im); } +/* Build a two-field record TYPE representing the complex expression EXPR. */ + +tree +underlying_complex_expr (tree type, tree expr) +{ + gcc_assert (list_length (TYPE_FIELDS (type)) == 2); + + expr = d_save_expr (expr); + + /* Build a constructor from the real and imaginary parts. */ + if (COMPLEX_FLOAT_TYPE_P (TREE_TYPE (expr)) && + (!INDIRECT_REF_P (expr) + || !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (expr, 0))))) + { + vec *ve = NULL; + CONSTRUCTOR_APPEND_ELT (ve, TYPE_FIELDS (type), + real_part (expr)); + CONSTRUCTOR_APPEND_ELT (ve, TREE_CHAIN (TYPE_FIELDS (type)), + imaginary_part (expr)); + return build_constructor (type, ve); + } + + /* Replace type in the reinterpret cast with a cast to the record type. */ + return build_vconvert (type, expr); +} + /* Cast EXP (which should be a pointer) to TYPE* and then indirect. The back-end requires this cast in many cases. */ @@ -2204,6 +2230,14 @@ d_build_call (TypeFunction *tf, tree callable, tree object, build_address (targ)); } + /* Complex types are exposed as special types with an underlying + struct representation, if we are passing the native type to a + function that accepts the library-defined version, then ensure + it is properly reinterpreted as the underlying struct type. */ + if (COMPLEX_FLOAT_TYPE_P (TREE_TYPE (targ)) + && arg->type->isTypeStruct ()) + targ = underlying_complex_expr (build_ctype (arg->type), targ); + /* Type `noreturn` is a terminator, as no other arguments can possibly be evaluated after it. */ if (TREE_TYPE (targ) == noreturn_type_node) diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h index 5f6b9d61001..ec2b1b65729 100644 --- a/gcc/d/d-tree.h +++ b/gcc/d/d-tree.h @@ -564,6 +564,7 @@ extern tree size_mult_expr (tree, tree); extern tree real_part (tree); extern tree imaginary_part (tree); extern tree complex_expr (tree, tree, tree); +extern tree underlying_complex_expr (tree, tree); extern tree indirect_ref (tree, tree); extern tree build_deref (tree); extern tree build_array_index (tree, tree); diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 6fba382f0ed..6654244292e 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -1911,7 +1911,7 @@ public: underlying is really a complex type. */ if (e->e1->type->ty == TY::Tenum && e->e1->type->isTypeEnum ()->sym->isSpecial ()) - object = build_vconvert (build_ctype (tb), object); + object = underlying_complex_expr (build_ctype (tb), object); this->result_ = component_ref (object, get_symbol_decl (vd)); } diff --git a/gcc/testsuite/gdc.dg/torture/pr106623.d b/gcc/testsuite/gdc.dg/torture/pr106623.d new file mode 100644 index 00000000000..d782b236861 --- /dev/null +++ b/gcc/testsuite/gdc.dg/torture/pr106623.d @@ -0,0 +1,28 @@ +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106623 +// { dg-do compile } +private struct _Complex(T) { T re; T im; } +enum __c_complex_double : _Complex!double; + +pragma(inline, true) +ulong hashOf()(scope const double val) +{ + return *cast(ulong*)&val; +} + +pragma(inline, true) +ulong hashOf()(scope const _Complex!double val, ulong seed = 0) +{ + return hashOf(val.re) + hashOf(val.im); +} + +pragma(inline, true) +ulong hashOf()(__c_complex_double val, ulong seed = 0) +{ + return hashOf(cast(_Complex!double) val, seed); +} + +ulong test106623() +{ + __c_complex_double val; + return hashOf(val); +}