Skip to content

Commit e55eda2

Browse files
committed
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.
1 parent 1158fe4 commit e55eda2

File tree

4 files changed

+63
-30
lines changed

4 files changed

+63
-30
lines changed

gcc/d/d-tree.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -671,8 +671,9 @@ extern tree layout_classinfo (ClassDeclaration *);
671671
extern unsigned base_vtable_offset (ClassDeclaration *, BaseClass *);
672672
extern tree get_typeinfo_decl (TypeInfoDeclaration *);
673673
extern tree get_classinfo_decl (ClassDeclaration *);
674-
extern void check_typeinfo_type (const Loc &, Scope *);
675-
extern tree build_typeinfo (const Loc &, Type *);
674+
extern void check_typeinfo_type (const Loc &, Scope *, Expression * = NULL);
675+
extern tree build_typeinfo (const Loc &, Type *, Expression * = NULL);
676+
extern tree build_typeinfo (Expression *, Type *);
676677
extern void create_typeinfo (Type *, Module *);
677678
extern void create_tinfo_types (Module *);
678679
extern void layout_cpp_typeinfo (ClassDeclaration *);

gcc/d/expr.cc

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ class ExprVisitor : public Visitor
427427
tree result = build_libcall (LIBCALL_ADEQ2, e->type, 3,
428428
d_array_convert (e->e1),
429429
d_array_convert (e->e2),
430-
build_typeinfo (e->loc, t1array));
430+
build_typeinfo (e, t1array));
431431

432432
if (e->op == EXP::notEqual)
433433
result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
@@ -450,7 +450,7 @@ class ExprVisitor : public Visitor
450450
{
451451
/* Use _aaEqual() for associative arrays. */
452452
tree result = build_libcall (LIBCALL_AAEQUAL, e->type, 3,
453-
build_typeinfo (e->loc, tb1),
453+
build_typeinfo (e, tb1),
454454
build_expr (e->e1),
455455
build_expr (e->e2));
456456

@@ -484,7 +484,7 @@ class ExprVisitor : public Visitor
484484
/* Build a call to _aaInX(). */
485485
this->result_ = build_libcall (LIBCALL_AAINX, e->type, 3,
486486
build_expr (e->e2),
487-
build_typeinfo (e->loc, tkey),
487+
build_typeinfo (e, tkey),
488488
build_address (key));
489489
}
490490

@@ -728,13 +728,13 @@ class ExprVisitor : public Visitor
728728
size_int (ndims), build_address (var));
729729

730730
result = build_libcall (LIBCALL_ARRAYCATNTX, e->type, 2,
731-
build_typeinfo (e->loc, e->type), arrs);
731+
build_typeinfo (e, e->type), arrs);
732732
}
733733
else
734734
{
735735
/* Handle single concatenation (a ~ b). */
736736
result = build_libcall (LIBCALL_ARRAYCATT, e->type, 3,
737-
build_typeinfo (e->loc, e->type),
737+
build_typeinfo (e, e->type),
738738
d_array_convert (etype, e->e1),
739739
d_array_convert (etype, e->e2));
740740
}
@@ -903,7 +903,7 @@ class ExprVisitor : public Visitor
903903

904904
/* So we can call postblits on const/immutable objects. */
905905
Type *tm = etype->unSharedOf ()->mutableOf ();
906-
tree ti = build_typeinfo (e->loc, tm);
906+
tree ti = build_typeinfo (e, tm);
907907

908908
/* Generate: _d_arraysetassign (t1.ptr, &t2, t1.length, ti); */
909909
result = build_libcall (LIBCALL_ARRAYSETASSIGN, Type::tvoid, 4,
@@ -977,7 +977,7 @@ class ExprVisitor : public Visitor
977977
{
978978
/* Generate: _d_arrayassign(ti, from, to); */
979979
this->result_ = build_libcall (LIBCALL_ARRAYASSIGN, e->type, 3,
980-
build_typeinfo (e->loc, etype),
980+
build_typeinfo (e, etype),
981981
d_array_convert (e->e2),
982982
d_array_convert (e->e1));
983983
}
@@ -1122,7 +1122,7 @@ class ExprVisitor : public Visitor
11221122
Type *arrtype = (e->type->ty == TY::Tsarray)
11231123
? etype->arrayOf () : e->type;
11241124
tree result = build_libcall (libcall, arrtype, 4,
1125-
build_typeinfo (e->loc, etype),
1125+
build_typeinfo (e, etype),
11261126
d_array_convert (e->e2),
11271127
d_array_convert (e->e1),
11281128
build_address (elembuf));
@@ -1193,13 +1193,13 @@ class ExprVisitor : public Visitor
11931193
{
11941194
libcall = LIBCALL_AAGETY;
11951195
ptr = build_address (build_expr (e->e1));
1196-
tinfo = build_typeinfo (e->loc, tb1->unSharedOf ()->mutableOf ());
1196+
tinfo = build_typeinfo (e, tb1->unSharedOf ()->mutableOf ());
11971197
}
11981198
else
11991199
{
12001200
libcall = LIBCALL_AAGETRVALUEX;
12011201
ptr = build_expr (e->e1);
1202-
tinfo = build_typeinfo (e->loc, tkey);
1202+
tinfo = build_typeinfo (e, tkey);
12031203
}
12041204

12051205
/* Index the associative array. */
@@ -1427,7 +1427,7 @@ class ExprVisitor : public Visitor
14271427

14281428
this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,
14291429
build_expr (e->e1),
1430-
build_typeinfo (e->loc, tkey),
1430+
build_typeinfo (e, tkey),
14311431
build_address (index));
14321432
}
14331433
else
@@ -1981,7 +1981,7 @@ class ExprVisitor : public Visitor
19811981
{
19821982
if (Type *tid = isType (e->obj))
19831983
{
1984-
tree ti = build_typeinfo (e->loc, tid);
1984+
tree ti = build_typeinfo (e, tid);
19851985

19861986
/* If the typeinfo is at an offset. */
19871987
if (tid->vtinfo->offset)
@@ -2319,7 +2319,7 @@ class ExprVisitor : public Visitor
23192319
/* Generate: _d_newitemT() */
23202320
libcall_fn libcall = htype->isZeroInit ()
23212321
? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2322-
tree arg = build_typeinfo (e->loc, e->newtype);
2322+
tree arg = build_typeinfo (e, e->newtype);
23232323
new_call = build_libcall (libcall, tb, 1, arg);
23242324

23252325
if (e->member || !e->arguments)
@@ -2387,7 +2387,7 @@ class ExprVisitor : public Visitor
23872387
libcall_fn libcall = tarray->next->isZeroInit ()
23882388
? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT;
23892389
result = build_libcall (libcall, tb, 2,
2390-
build_typeinfo (e->loc, e->type),
2390+
build_typeinfo (e, e->type),
23912391
build_expr (arg));
23922392
}
23932393
else
@@ -2419,7 +2419,7 @@ class ExprVisitor : public Visitor
24192419
libcall_fn libcall = telem->isZeroInit ()
24202420
? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX;
24212421

2422-
tree tinfo = build_typeinfo (e->loc, e->type);
2422+
tree tinfo = build_typeinfo (e, e->type);
24232423
tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()),
24242424
size_int (e->arguments->length),
24252425
build_address (var));
@@ -2446,7 +2446,7 @@ class ExprVisitor : public Visitor
24462446
libcall_fn libcall = tpointer->next->isZeroInit (e->loc)
24472447
? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
24482448

2449-
tree arg = build_typeinfo (e->loc, e->newtype);
2449+
tree arg = build_typeinfo (e, e->newtype);
24502450
result = build_libcall (libcall, tb, 1, arg);
24512451

24522452
if (e->arguments && e->arguments->length == 1)
@@ -2691,7 +2691,7 @@ class ExprVisitor : public Visitor
26912691
/* Allocate space on the memory managed heap. */
26922692
tree mem = build_libcall (LIBCALL_ARRAYLITERALTX,
26932693
etype->pointerTo (), 2,
2694-
build_typeinfo (e->loc, etype->arrayOf ()),
2694+
build_typeinfo (e, etype->arrayOf ()),
26952695
size_int (e->elements->length));
26962696
mem = d_save_expr (mem);
26972697

@@ -2748,7 +2748,7 @@ class ExprVisitor : public Visitor
27482748
build_address (avals));
27492749

27502750
tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3,
2751-
build_typeinfo (e->loc, ta), keys, vals);
2751+
build_typeinfo (e, ta), keys, vals);
27522752

27532753
/* Return an associative array pointed to by MEM. */
27542754
tree aatype = build_ctype (ta);

gcc/d/typeinfo.cc

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,21 +1394,29 @@ get_classinfo_decl (ClassDeclaration *decl)
13941394
}
13951395

13961396
/* 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. */
13981400

13991401
void
1400-
check_typeinfo_type (const Loc &loc, Scope *sc)
1402+
check_typeinfo_type (const Loc &loc, Scope *sc, Expression *expr)
14011403
{
14021404
if (!global.params.useTypeInfo)
14031405
{
1404-
static int warned = 0;
1405-
14061406
/* Even when compiling without RTTI we should still be able to evaluate
14071407
TypeInfo at compile-time, just not at run-time. */
1408-
if (!warned && (!sc || !(sc->flags & SCOPEctfe)))
1408+
if (!sc || !(sc->flags & SCOPEctfe))
14091409
{
1410-
error_at (make_location_t (loc),
1411-
"%<object.TypeInfo%> cannot be used with %<-fno-rtti%>");
1410+
static int warned = 0;
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+
14121420
warned = 1;
14131421
}
14141422
}
@@ -1429,17 +1437,23 @@ check_typeinfo_type (const Loc &loc, Scope *sc)
14291437
}
14301438
}
14311439

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. */
14331442

14341443
tree
1435-
build_typeinfo (const Loc &loc, Type *type)
1444+
build_typeinfo (const Loc &loc, Type *type, Expression *expr)
14361445
{
14371446
gcc_assert (type->ty != TY::Terror);
1438-
check_typeinfo_type (loc, NULL);
1447+
check_typeinfo_type (loc, NULL, expr);
14391448
create_typeinfo (type, NULL);
14401449
return build_address (get_typeinfo_decl (type->vtinfo));
14411450
}
14421451

1452+
tree build_typeinfo (Expression *expr, Type *type)
1453+
{
1454+
return build_typeinfo (expr->loc, type, expr);
1455+
}
1456+
14431457
/* Like layout_classinfo, but generates an Object that wraps around a
14441458
pointer to C++ type_info so it can be distinguished from D TypeInfo. */
14451459

gcc/testsuite/gdc.dg/rtti1.d

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// { dg-do compile }
2+
// { dg-options "-fno-rtti" }
3+
// { dg-shouldfail "expressions depend on TypeInfo" }
4+
5+
int* 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+
10+
bool 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+
15+
string testConcat(string a, string b)
16+
{
17+
return a ~ b; // { dg-error "requires .object.TypeInfo. and cannot be used with .-fno-rtti." }
18+
}

0 commit comments

Comments
 (0)