summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2022-06-13 14:35:38 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2022-06-13 15:09:15 +0200
commit5f7a1a436c1a85cc18b4f4e185dcbcbc870e4956 (patch)
tree62d8df94da24f7a870eda42072a0e896edda8ec0
parentDaily bump. (diff)
downloadgcc-5f7a1a436c1a85cc18b4f4e185dcbcbc870e4956.tar.gz
gcc-5f7a1a436c1a85cc18b4f4e185dcbcbc870e4956.tar.bz2
gcc-5f7a1a436c1a85cc18b4f4e185dcbcbc870e4956.tar.xz
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)
-rw-r--r--gcc/d/d-tree.h5
-rw-r--r--gcc/d/expr.cc36
-rw-r--r--gcc/d/typeinfo.cc34
-rw-r--r--gcc/testsuite/gdc.dg/rtti1.d18
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 *);
671extern unsigned base_vtable_offset (ClassDeclaration *, BaseClass *); 671extern unsigned base_vtable_offset (ClassDeclaration *, BaseClass *);
672extern tree get_typeinfo_decl (TypeInfoDeclaration *); 672extern tree get_typeinfo_decl (TypeInfoDeclaration *);
673extern tree get_classinfo_decl (ClassDeclaration *); 673extern tree get_classinfo_decl (ClassDeclaration *);
674extern void check_typeinfo_type (const Loc &, Scope *); 674extern void check_typeinfo_type (const Loc &, Scope *, Expression * = NULL);
675extern tree build_typeinfo (const Loc &, Type *); 675extern tree build_typeinfo (const Loc &, Type *, Expression * = NULL);
676extern tree build_typeinfo (Expression *, Type *);
676extern void create_typeinfo (Type *, Module *); 677extern void create_typeinfo (Type *, Module *);
677extern void create_tinfo_types (Module *); 678extern void create_tinfo_types (Module *);
678extern void layout_cpp_typeinfo (ClassDeclaration *); 679extern 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:
427 tree result = build_libcall (LIBCALL_ADEQ2, e->type, 3, 427 tree result = build_libcall (LIBCALL_ADEQ2, e->type, 3,
428 d_array_convert (e->e1), 428 d_array_convert (e->e1),
429 d_array_convert (e->e2), 429 d_array_convert (e->e2),
430 build_typeinfo (e->loc, t1array)); 430 build_typeinfo (e, t1array));
431 431
432 if (e->op == EXP::notEqual) 432 if (e->op == EXP::notEqual)
433 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result); 433 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
@@ -450,7 +450,7 @@ public:
450 { 450 {
451 /* Use _aaEqual() for associative arrays. */ 451 /* Use _aaEqual() for associative arrays. */
452 tree result = build_libcall (LIBCALL_AAEQUAL, e->type, 3, 452 tree result = build_libcall (LIBCALL_AAEQUAL, e->type, 3,
453 build_typeinfo (e->loc, tb1), 453 build_typeinfo (e, tb1),
454 build_expr (e->e1), 454 build_expr (e->e1),
455 build_expr (e->e2)); 455 build_expr (e->e2));
456 456
@@ -484,7 +484,7 @@ public:
484 /* Build a call to _aaInX(). */ 484 /* Build a call to _aaInX(). */
485 this->result_ = build_libcall (LIBCALL_AAINX, e->type, 3, 485 this->result_ = build_libcall (LIBCALL_AAINX, e->type, 3,
486 build_expr (e->e2), 486 build_expr (e->e2),
487 build_typeinfo (e->loc, tkey), 487 build_typeinfo (e, tkey),
488 build_address (key)); 488 build_address (key));
489 } 489 }
490 490
@@ -728,13 +728,13 @@ public:
728 size_int (ndims), build_address (var)); 728 size_int (ndims), build_address (var));
729 729
730 result = build_libcall (LIBCALL_ARRAYCATNTX, e->type, 2, 730 result = build_libcall (LIBCALL_ARRAYCATNTX, e->type, 2,
731 build_typeinfo (e->loc, e->type), arrs); 731 build_typeinfo (e, e->type), arrs);
732 } 732 }
733 else 733 else
734 { 734 {
735 /* Handle single concatenation (a ~ b). */ 735 /* Handle single concatenation (a ~ b). */
736 result = build_libcall (LIBCALL_ARRAYCATT, e->type, 3, 736 result = build_libcall (LIBCALL_ARRAYCATT, e->type, 3,
737 build_typeinfo (e->loc, e->type), 737 build_typeinfo (e, e->type),
738 d_array_convert (etype, e->e1), 738 d_array_convert (etype, e->e1),
739 d_array_convert (etype, e->e2)); 739 d_array_convert (etype, e->e2));
740 } 740 }
@@ -946,7 +946,7 @@ public:
946 946
947 /* So we can call postblits on const/immutable objects. */ 947 /* So we can call postblits on const/immutable objects. */
948 Type *tm = etype->unSharedOf ()->mutableOf (); 948 Type *tm = etype->unSharedOf ()->mutableOf ();
949 tree ti = build_typeinfo (e->loc, tm); 949 tree ti = build_typeinfo (e, tm);
950 950
951 /* Generate: _d_arraysetassign (t1.ptr, &t2, t1.length, ti); */ 951 /* Generate: _d_arraysetassign (t1.ptr, &t2, t1.length, ti); */
952 result = build_libcall (LIBCALL_ARRAYSETASSIGN, Type::tvoid, 4, 952 result = build_libcall (LIBCALL_ARRAYSETASSIGN, Type::tvoid, 4,
@@ -1020,7 +1020,7 @@ public:
1020 { 1020 {
1021 /* Generate: _d_arrayassign(ti, from, to); */ 1021 /* Generate: _d_arrayassign(ti, from, to); */
1022 this->result_ = build_libcall (LIBCALL_ARRAYASSIGN, e->type, 3, 1022 this->result_ = build_libcall (LIBCALL_ARRAYASSIGN, e->type, 3,
1023 build_typeinfo (e->loc, etype), 1023 build_typeinfo (e, etype),
1024 d_array_convert (e->e2), 1024 d_array_convert (e->e2),
1025 d_array_convert (e->e1)); 1025 d_array_convert (e->e1));
1026 } 1026 }
@@ -1165,7 +1165,7 @@ public:
1165 Type *arrtype = (e->type->ty == TY::Tsarray) 1165 Type *arrtype = (e->type->ty == TY::Tsarray)
1166 ? etype->arrayOf () : e->type; 1166 ? etype->arrayOf () : e->type;
1167 tree result = build_libcall (libcall, arrtype, 4, 1167 tree result = build_libcall (libcall, arrtype, 4,
1168 build_typeinfo (e->loc, etype), 1168 build_typeinfo (e, etype),
1169 d_array_convert (e->e2), 1169 d_array_convert (e->e2),
1170 d_array_convert (e->e1), 1170 d_array_convert (e->e1),
1171 build_address (elembuf)); 1171 build_address (elembuf));
@@ -1236,13 +1236,13 @@ public:
1236 { 1236 {
1237 libcall = LIBCALL_AAGETY; 1237 libcall = LIBCALL_AAGETY;
1238 ptr = build_address (build_expr (e->e1)); 1238 ptr = build_address (build_expr (e->e1));
1239 tinfo = build_typeinfo (e->loc, tb1->unSharedOf ()->mutableOf ()); 1239 tinfo = build_typeinfo (e, tb1->unSharedOf ()->mutableOf ());
1240 } 1240 }
1241 else 1241 else
1242 { 1242 {
1243 libcall = LIBCALL_AAGETRVALUEX; 1243 libcall = LIBCALL_AAGETRVALUEX;
1244 ptr = build_expr (e->e1); 1244 ptr = build_expr (e->e1);
1245 tinfo = build_typeinfo (e->loc, tkey); 1245 tinfo = build_typeinfo (e, tkey);
1246 } 1246 }
1247 1247
1248 /* Index the associative array. */ 1248 /* Index the associative array. */
@@ -1470,7 +1470,7 @@ public:
1470 1470
1471 this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3, 1471 this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,
1472 build_expr (e->e1), 1472 build_expr (e->e1),
1473 build_typeinfo (e->loc, tkey), 1473 build_typeinfo (e, tkey),
1474 build_address (index)); 1474 build_address (index));
1475 } 1475 }
1476 else 1476 else
@@ -2024,7 +2024,7 @@ public:
2024 { 2024 {
2025 if (Type *tid = isType (e->obj)) 2025 if (Type *tid = isType (e->obj))
2026 { 2026 {
2027 tree ti = build_typeinfo (e->loc, tid); 2027 tree ti = build_typeinfo (e, tid);
2028 2028
2029 /* If the typeinfo is at an offset. */ 2029 /* If the typeinfo is at an offset. */
2030 if (tid->vtinfo->offset) 2030 if (tid->vtinfo->offset)
@@ -2358,7 +2358,7 @@ public:
2358 /* Generate: _d_newitemT() */ 2358 /* Generate: _d_newitemT() */
2359 libcall_fn libcall = htype->isZeroInit () 2359 libcall_fn libcall = htype->isZeroInit ()
2360 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT; 2360 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2361 tree arg = build_typeinfo (e->loc, e->newtype); 2361 tree arg = build_typeinfo (e, e->newtype);
2362 new_call = build_libcall (libcall, tb, 1, arg); 2362 new_call = build_libcall (libcall, tb, 1, arg);
2363 2363
2364 if (e->member || !e->arguments) 2364 if (e->member || !e->arguments)
@@ -2426,7 +2426,7 @@ public:
2426 libcall_fn libcall = tarray->next->isZeroInit () 2426 libcall_fn libcall = tarray->next->isZeroInit ()
2427 ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT; 2427 ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT;
2428 result = build_libcall (libcall, tb, 2, 2428 result = build_libcall (libcall, tb, 2,
2429 build_typeinfo (e->loc, e->type), 2429 build_typeinfo (e, e->type),
2430 build_expr (arg)); 2430 build_expr (arg));
2431 } 2431 }
2432 else 2432 else
@@ -2458,7 +2458,7 @@ public:
2458 libcall_fn libcall = telem->isZeroInit () 2458 libcall_fn libcall = telem->isZeroInit ()
2459 ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX; 2459 ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX;
2460 2460
2461 tree tinfo = build_typeinfo (e->loc, e->type); 2461 tree tinfo = build_typeinfo (e, e->type);
2462 tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()), 2462 tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()),
2463 size_int (e->arguments->length), 2463 size_int (e->arguments->length),
2464 build_address (var)); 2464 build_address (var));
@@ -2485,7 +2485,7 @@ public:
2485 libcall_fn libcall = tpointer->next->isZeroInit (e->loc) 2485 libcall_fn libcall = tpointer->next->isZeroInit (e->loc)
2486 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT; 2486 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2487 2487
2488 tree arg = build_typeinfo (e->loc, e->newtype); 2488 tree arg = build_typeinfo (e, e->newtype);
2489 result = build_libcall (libcall, tb, 1, arg); 2489 result = build_libcall (libcall, tb, 1, arg);
2490 2490
2491 if (e->arguments && e->arguments->length == 1) 2491 if (e->arguments && e->arguments->length == 1)
@@ -2730,7 +2730,7 @@ public:
2730 /* Allocate space on the memory managed heap. */ 2730 /* Allocate space on the memory managed heap. */
2731 tree mem = build_libcall (LIBCALL_ARRAYLITERALTX, 2731 tree mem = build_libcall (LIBCALL_ARRAYLITERALTX,
2732 etype->pointerTo (), 2, 2732 etype->pointerTo (), 2,
2733 build_typeinfo (e->loc, etype->arrayOf ()), 2733 build_typeinfo (e, etype->arrayOf ()),
2734 size_int (e->elements->length)); 2734 size_int (e->elements->length));
2735 mem = d_save_expr (mem); 2735 mem = d_save_expr (mem);
2736 2736
@@ -2787,7 +2787,7 @@ public:
2787 build_address (avals)); 2787 build_address (avals));
2788 2788
2789 tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3, 2789 tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3,
2790 build_typeinfo (e->loc, ta), keys, vals); 2790 build_typeinfo (e, ta), keys, vals);
2791 2791
2792 /* Return an associative array pointed to by MEM. */ 2792 /* Return an associative array pointed to by MEM. */
2793 tree aatype = build_ctype (ta); 2793 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)
1394} 1394}
1395 1395
1396/* Performs sanity checks on the `object.TypeInfo' type, raising an error if 1396/* Performs sanity checks on the `object.TypeInfo' type, raising an error if
1397 RTTI is disabled, or the type is missing. */ 1397 RTTI is disabled, or the type is missing. LOC is the location used for error
1398 messages. SC is the context, and EXPR is expression where TypeInfo is
1399 required from, if either are set. */
1398 1400
1399void 1401void
1400check_typeinfo_type (const Loc &loc, Scope *sc) 1402check_typeinfo_type (const Loc &loc, Scope *sc, Expression *expr)
1401{ 1403{
1402 if (!global.params.useTypeInfo) 1404 if (!global.params.useTypeInfo)
1403 { 1405 {
1404 static int warned = 0;
1405
1406 /* Even when compiling without RTTI we should still be able to evaluate 1406 /* Even when compiling without RTTI we should still be able to evaluate
1407 TypeInfo at compile-time, just not at run-time. */ 1407 TypeInfo at compile-time, just not at run-time. */
1408 if (!warned && (!sc || !(sc->flags & SCOPEctfe))) 1408 if (!sc || !(sc->flags & SCOPEctfe))
1409 { 1409 {
1410 error_at (make_location_t (loc), 1410 static int warned = 0;
1411 "%<object.TypeInfo%> cannot be used with %<-fno-rtti%>"); 1411
1412 if (expr != NULL)
1413 error_at (make_location_t (loc),
1414 "expression %qs requires %<object.TypeInfo%> and cannot "
1415 "be used with %<-fno-rtti%>", expr->toChars ());
1416 else if (!warned)
1417 error_at (make_location_t (loc),
1418 "%<object.TypeInfo%> cannot be used with %<-fno-rtti%>");
1419
1412 warned = 1; 1420 warned = 1;
1413 } 1421 }
1414 } 1422 }
@@ -1429,17 +1437,23 @@ check_typeinfo_type (const Loc &loc, Scope *sc)
1429 } 1437 }
1430} 1438}
1431 1439
1432/* Returns typeinfo reference for TYPE. */ 1440/* Returns typeinfo reference for TYPE. LOC is the location used for error
1441 messages. EXPR is the expression where TypeInfo is required, if set. */
1433 1442
1434tree 1443tree
1435build_typeinfo (const Loc &loc, Type *type) 1444build_typeinfo (const Loc &loc, Type *type, Expression *expr)
1436{ 1445{
1437 gcc_assert (type->ty != TY::Terror); 1446 gcc_assert (type->ty != TY::Terror);
1438 check_typeinfo_type (loc, NULL); 1447 check_typeinfo_type (loc, NULL, expr);
1439 create_typeinfo (type, NULL); 1448 create_typeinfo (type, NULL);
1440 return build_address (get_typeinfo_decl (type->vtinfo)); 1449 return build_address (get_typeinfo_decl (type->vtinfo));
1441} 1450}
1442 1451
1452tree build_typeinfo (Expression *expr, Type *type)
1453{
1454 return build_typeinfo (expr->loc, type, expr);
1455}
1456
1443/* Like layout_classinfo, but generates an Object that wraps around a 1457/* Like layout_classinfo, but generates an Object that wraps around a
1444 pointer to C++ type_info so it can be distinguished from D TypeInfo. */ 1458 pointer to C++ type_info so it can be distinguished from D TypeInfo. */
1445 1459
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 @@
1// { dg-do compile }
2// { dg-options "-fno-rtti" }
3// { dg-shouldfail "expressions depend on TypeInfo" }
4
5int* testInExp(int key, int[int] aa)
6{
7 return key in aa; // { dg-error "requires .object.TypeInfo. and cannot be used with .-fno-rtti." }
8}
9
10bool testAAEqual(int[string] aa1, int[string] aa2)
11{
12 return aa1 == aa2; // { dg-error "requires .object.TypeInfo. and cannot be used with .-fno-rtti." }
13}
14
15string testConcat(string a, string b)
16{
17 return a ~ b; // { dg-error "requires .object.TypeInfo. and cannot be used with .-fno-rtti." }
18}