public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-8475] d: Improve TypeInfo errors when compiling in -fno-rtti mode
@ 2022-06-13 13:09 Iain Buclaw
  0 siblings, 0 replies; only message in thread
From: Iain Buclaw @ 2022-06-13 13:09 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:5f7a1a436c1a85cc18b4f4e185dcbcbc870e4956

commit r12-8475-g5f7a1a436c1a85cc18b4f4e185dcbcbc870e4956
Author: Iain Buclaw <ibuclaw@gdcproject.org>
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),
-		    "%<object.TypeInfo%> cannot be used with %<-fno-rtti%>");
+	  static int warned = 0;
+
+	  if (expr != NULL)
+	    error_at (make_location_t (loc),
+		     "expression %qs requires %<object.TypeInfo%> and cannot "
+		     "be used with %<-fno-rtti%>", expr->toChars ());
+	  else if (!warned)
+	    error_at (make_location_t (loc),
+		      "%<object.TypeInfo%> 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." }
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-13 13:09 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-13 13:09 [gcc r12-8475] d: Improve TypeInfo errors when compiling in -fno-rtti mode Iain Buclaw

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).