From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1873) id 192AB3852760; Mon, 13 Jun 2022 13:09:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 192AB3852760 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-8475] d: Improve TypeInfo errors when compiling in -fno-rtti mode X-Act-Checkin: gcc X-Git-Author: Iain Buclaw X-Git-Refname: refs/heads/releases/gcc-12 X-Git-Oldrev: 54ec210b72eb5a2eef70a2d005d8dcd8d459852e X-Git-Newrev: 5f7a1a436c1a85cc18b4f4e185dcbcbc870e4956 Message-Id: <20220613130953.192AB3852760@sourceware.org> Date: Mon, 13 Jun 2022 13:09:53 +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, 13 Jun 2022 13:09:53 -0000 https://gcc.gnu.org/g:5f7a1a436c1a85cc18b4f4e185dcbcbc870e4956 commit r12-8475-g5f7a1a436c1a85cc18b4f4e185dcbcbc870e4956 Author: Iain Buclaw Date: Mon Jun 13 14:35:38 2022 +0200 d: Improve TypeInfo errors when compiling in -fno-rtti mode The existing TypeInfo errors can be cryptic. This alters the diagnostic to include which expression is requiring `object.TypeInfo'. 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. (cherry picked from commit e55eda238545e93708c020fd21249459be64c463) Diff: --- 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(-) 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 c683d9da333..325cbed892f 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)); } @@ -946,7 +946,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, @@ -1020,7 +1020,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)); } @@ -1165,7 +1165,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)); @@ -1236,13 +1236,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. */ @@ -1470,7 +1470,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 @@ -2024,7 +2024,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) @@ -2358,7 +2358,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) @@ -2426,7 +2426,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 @@ -2458,7 +2458,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)); @@ -2485,7 +2485,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) @@ -2730,7 +2730,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); @@ -2787,7 +2787,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 668b7b3c8e1..439380b7da9 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." } +}