From patchwork Mon Jun 13 13:10:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 1642813 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=u0HDKFeq; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4LMBl74DR8z9s0r for ; Mon, 13 Jun 2022 23:10:42 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E5ED83851A9F for ; Mon, 13 Jun 2022 13:10:34 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E5ED83851A9F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1655125834; bh=Z7xwEOIIyY+AI4Qe0QCSkEHliBuGcWCvRJF6LHNXNqo=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=u0HDKFeqY0lFDUBdPz9mRUrTrteCc8rzG4OmqNcXXdOKu7EBThnA3xpWzZW3JI3RI sQ6/I7dnGO18joNJfQV4bWeKNSnG+qODxy35u/siSn+uD7FYHCBlK+r1mYBcIioHD7 3p7XUUY+XeOMOLsxrXdm+PyUIMjOELaK8g13zHqo= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mout-p-202.mailbox.org (mout-p-202.mailbox.org [80.241.56.172]) by sourceware.org (Postfix) with ESMTPS id 5FE713852744 for ; Mon, 13 Jun 2022 13:10:13 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5FE713852744 Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::102]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-202.mailbox.org (Postfix) with ESMTPS id 4LMBkT71rmz9spZ; Mon, 13 Jun 2022 15:10:09 +0200 (CEST) To: gcc-patches@gcc.gnu.org Subject: [committed] d: Improve TypeInfo errors when compiling in -fno-rtti mode Date: Mon, 13 Jun 2022 15:10:08 +0200 Message-Id: <20220613131008.1445396-1-ibuclaw@gdcproject.org> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4LMBkT71rmz9spZ X-Spam-Status: No, score=-13.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Iain Buclaw via Gcc-patches From: Iain Buclaw Reply-To: Iain Buclaw Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" Hi, The existing TypeInfo errors can be cryptic. This patch alters the diagnostic to include which expression is requiring `object.TypeInfo'. Bootstrapped and regression tested on x86_64-linux-gnu, and backported to releases/gcc-12 branch. Regards, Iain. --- gcc/d/ChangeLog: * d-tree.h (check_typeinfo_type): Add Expression* parameter. (build_typeinfo): Likewise. Declare new override. * expr.cc (ExprVisitor): Call build_typeinfo with Expression*. * typeinfo.cc (check_typeinfo_type): Include expression in the diagnostic message. (build_typeinfo): New override. gcc/testsuite/ChangeLog: * gdc.dg/rtti1.d: New test. --- gcc/d/d-tree.h | 5 +++-- gcc/d/expr.cc | 36 ++++++++++++++++++------------------ gcc/d/typeinfo.cc | 34 ++++++++++++++++++++++++---------- gcc/testsuite/gdc.dg/rtti1.d | 18 ++++++++++++++++++ 4 files changed, 63 insertions(+), 30 deletions(-) create mode 100644 gcc/testsuite/gdc.dg/rtti1.d diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h index d93d02c2954..5f6b9d61001 100644 --- a/gcc/d/d-tree.h +++ b/gcc/d/d-tree.h @@ -671,8 +671,9 @@ extern tree layout_classinfo (ClassDeclaration *); extern unsigned base_vtable_offset (ClassDeclaration *, BaseClass *); extern tree get_typeinfo_decl (TypeInfoDeclaration *); extern tree get_classinfo_decl (ClassDeclaration *); -extern void check_typeinfo_type (const Loc &, Scope *); -extern tree build_typeinfo (const Loc &, Type *); +extern void check_typeinfo_type (const Loc &, Scope *, Expression * = NULL); +extern tree build_typeinfo (const Loc &, Type *, Expression * = NULL); +extern tree build_typeinfo (Expression *, Type *); extern void create_typeinfo (Type *, Module *); extern void create_tinfo_types (Module *); extern void layout_cpp_typeinfo (ClassDeclaration *); diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 179f9a5f4fd..fba397bed35 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -427,7 +427,7 @@ public: tree result = build_libcall (LIBCALL_ADEQ2, e->type, 3, d_array_convert (e->e1), d_array_convert (e->e2), - build_typeinfo (e->loc, t1array)); + build_typeinfo (e, t1array)); if (e->op == EXP::notEqual) result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result); @@ -450,7 +450,7 @@ public: { /* Use _aaEqual() for associative arrays. */ tree result = build_libcall (LIBCALL_AAEQUAL, e->type, 3, - build_typeinfo (e->loc, tb1), + build_typeinfo (e, tb1), build_expr (e->e1), build_expr (e->e2)); @@ -484,7 +484,7 @@ public: /* Build a call to _aaInX(). */ this->result_ = build_libcall (LIBCALL_AAINX, e->type, 3, build_expr (e->e2), - build_typeinfo (e->loc, tkey), + build_typeinfo (e, tkey), build_address (key)); } @@ -728,13 +728,13 @@ public: size_int (ndims), build_address (var)); result = build_libcall (LIBCALL_ARRAYCATNTX, e->type, 2, - build_typeinfo (e->loc, e->type), arrs); + build_typeinfo (e, e->type), arrs); } else { /* Handle single concatenation (a ~ b). */ result = build_libcall (LIBCALL_ARRAYCATT, e->type, 3, - build_typeinfo (e->loc, e->type), + build_typeinfo (e, e->type), d_array_convert (etype, e->e1), d_array_convert (etype, e->e2)); } @@ -903,7 +903,7 @@ public: /* So we can call postblits on const/immutable objects. */ Type *tm = etype->unSharedOf ()->mutableOf (); - tree ti = build_typeinfo (e->loc, tm); + tree ti = build_typeinfo (e, tm); /* Generate: _d_arraysetassign (t1.ptr, &t2, t1.length, ti); */ result = build_libcall (LIBCALL_ARRAYSETASSIGN, Type::tvoid, 4, @@ -977,7 +977,7 @@ public: { /* Generate: _d_arrayassign(ti, from, to); */ this->result_ = build_libcall (LIBCALL_ARRAYASSIGN, e->type, 3, - build_typeinfo (e->loc, etype), + build_typeinfo (e, etype), d_array_convert (e->e2), d_array_convert (e->e1)); } @@ -1122,7 +1122,7 @@ public: Type *arrtype = (e->type->ty == TY::Tsarray) ? etype->arrayOf () : e->type; tree result = build_libcall (libcall, arrtype, 4, - build_typeinfo (e->loc, etype), + build_typeinfo (e, etype), d_array_convert (e->e2), d_array_convert (e->e1), build_address (elembuf)); @@ -1193,13 +1193,13 @@ public: { libcall = LIBCALL_AAGETY; ptr = build_address (build_expr (e->e1)); - tinfo = build_typeinfo (e->loc, tb1->unSharedOf ()->mutableOf ()); + tinfo = build_typeinfo (e, tb1->unSharedOf ()->mutableOf ()); } else { libcall = LIBCALL_AAGETRVALUEX; ptr = build_expr (e->e1); - tinfo = build_typeinfo (e->loc, tkey); + tinfo = build_typeinfo (e, tkey); } /* Index the associative array. */ @@ -1427,7 +1427,7 @@ public: this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3, build_expr (e->e1), - build_typeinfo (e->loc, tkey), + build_typeinfo (e, tkey), build_address (index)); } else @@ -1981,7 +1981,7 @@ public: { if (Type *tid = isType (e->obj)) { - tree ti = build_typeinfo (e->loc, tid); + tree ti = build_typeinfo (e, tid); /* If the typeinfo is at an offset. */ if (tid->vtinfo->offset) @@ -2319,7 +2319,7 @@ public: /* Generate: _d_newitemT() */ libcall_fn libcall = htype->isZeroInit () ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT; - tree arg = build_typeinfo (e->loc, e->newtype); + tree arg = build_typeinfo (e, e->newtype); new_call = build_libcall (libcall, tb, 1, arg); if (e->member || !e->arguments) @@ -2387,7 +2387,7 @@ public: libcall_fn libcall = tarray->next->isZeroInit () ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT; result = build_libcall (libcall, tb, 2, - build_typeinfo (e->loc, e->type), + build_typeinfo (e, e->type), build_expr (arg)); } else @@ -2419,7 +2419,7 @@ public: libcall_fn libcall = telem->isZeroInit () ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX; - tree tinfo = build_typeinfo (e->loc, e->type); + tree tinfo = build_typeinfo (e, e->type); tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()), size_int (e->arguments->length), build_address (var)); @@ -2446,7 +2446,7 @@ public: libcall_fn libcall = tpointer->next->isZeroInit (e->loc) ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT; - tree arg = build_typeinfo (e->loc, e->newtype); + tree arg = build_typeinfo (e, e->newtype); result = build_libcall (libcall, tb, 1, arg); if (e->arguments && e->arguments->length == 1) @@ -2691,7 +2691,7 @@ public: /* Allocate space on the memory managed heap. */ tree mem = build_libcall (LIBCALL_ARRAYLITERALTX, etype->pointerTo (), 2, - build_typeinfo (e->loc, etype->arrayOf ()), + build_typeinfo (e, etype->arrayOf ()), size_int (e->elements->length)); mem = d_save_expr (mem); @@ -2748,7 +2748,7 @@ public: build_address (avals)); tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3, - build_typeinfo (e->loc, ta), keys, vals); + build_typeinfo (e, ta), keys, vals); /* Return an associative array pointed to by MEM. */ tree aatype = build_ctype (ta); diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc index a6507e80a62..1647521555d 100644 --- a/gcc/d/typeinfo.cc +++ b/gcc/d/typeinfo.cc @@ -1394,21 +1394,29 @@ get_classinfo_decl (ClassDeclaration *decl) } /* Performs sanity checks on the `object.TypeInfo' type, raising an error if - RTTI is disabled, or the type is missing. */ + RTTI is disabled, or the type is missing. LOC is the location used for error + messages. SC is the context, and EXPR is expression where TypeInfo is + required from, if either are set. */ void -check_typeinfo_type (const Loc &loc, Scope *sc) +check_typeinfo_type (const Loc &loc, Scope *sc, Expression *expr) { if (!global.params.useTypeInfo) { - static int warned = 0; - /* Even when compiling without RTTI we should still be able to evaluate TypeInfo at compile-time, just not at run-time. */ - if (!warned && (!sc || !(sc->flags & SCOPEctfe))) + if (!sc || !(sc->flags & SCOPEctfe)) { - error_at (make_location_t (loc), - "% cannot be used with %<-fno-rtti%>"); + static int warned = 0; + + if (expr != NULL) + error_at (make_location_t (loc), + "expression %qs requires % and cannot " + "be used with %<-fno-rtti%>", expr->toChars ()); + else if (!warned) + error_at (make_location_t (loc), + "% cannot be used with %<-fno-rtti%>"); + warned = 1; } } @@ -1429,17 +1437,23 @@ check_typeinfo_type (const Loc &loc, Scope *sc) } } -/* Returns typeinfo reference for TYPE. */ +/* Returns typeinfo reference for TYPE. LOC is the location used for error + messages. EXPR is the expression where TypeInfo is required, if set. */ tree -build_typeinfo (const Loc &loc, Type *type) +build_typeinfo (const Loc &loc, Type *type, Expression *expr) { gcc_assert (type->ty != TY::Terror); - check_typeinfo_type (loc, NULL); + check_typeinfo_type (loc, NULL, expr); create_typeinfo (type, NULL); return build_address (get_typeinfo_decl (type->vtinfo)); } +tree build_typeinfo (Expression *expr, Type *type) +{ + return build_typeinfo (expr->loc, type, expr); +} + /* Like layout_classinfo, but generates an Object that wraps around a pointer to C++ type_info so it can be distinguished from D TypeInfo. */ diff --git a/gcc/testsuite/gdc.dg/rtti1.d b/gcc/testsuite/gdc.dg/rtti1.d new file mode 100644 index 00000000000..ed5f3440689 --- /dev/null +++ b/gcc/testsuite/gdc.dg/rtti1.d @@ -0,0 +1,18 @@ +// { dg-do compile } +// { dg-options "-fno-rtti" } +// { dg-shouldfail "expressions depend on TypeInfo" } + +int* testInExp(int key, int[int] aa) +{ + return key in aa; // { dg-error "requires .object.TypeInfo. and cannot be used with .-fno-rtti." } +} + +bool testAAEqual(int[string] aa1, int[string] aa2) +{ + return aa1 == aa2; // { dg-error "requires .object.TypeInfo. and cannot be used with .-fno-rtti." } +} + +string testConcat(string a, string b) +{ + return a ~ b; // { dg-error "requires .object.TypeInfo. and cannot be used with .-fno-rtti." } +}