diff --git a/src/Expr.cc b/src/Expr.cc index bad6240e7d..a7903ad6cc 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -2393,8 +2393,7 @@ IntrusivePtr AssignExpr::InitVal(const BroType* t, IntrusivePtr aggr) if ( aggr->Type()->Tag() != TYPE_TABLE ) Internal("bad aggregate in AssignExpr::InitVal"); - // TODO: implement safer IntrusivePtr casts - IntrusivePtr tv{NewRef{}, aggr->AsTableVal()}; + auto tv = cast_intrusive(std::move(aggr)); const TableType* tt = tv->Type()->AsTableType(); const BroType* yt = tv->Type()->YieldType(); diff --git a/src/IntrusivePtr.h b/src/IntrusivePtr.h index b6c273a3ff..6f09bd86cd 100644 --- a/src/IntrusivePtr.h +++ b/src/IntrusivePtr.h @@ -184,6 +184,18 @@ IntrusivePtr make_intrusive(Ts&&... args) return {AdoptRef{}, new T(std::forward(args)...)}; } +/** + * Casts an @c IntrusivePtr object to another by way of static_cast on + * the underlying pointer. + * @param p The pointer of type @c U to cast to another type, @c T. + * @return The pointer, as cast to type @c T. + */ +template +IntrusivePtr cast_intrusive(IntrusivePtr p) noexcept + { + return {AdoptRef{}, static_cast(p.release())}; + } + // -- comparison to nullptr ---------------------------------------------------- /** diff --git a/src/Type.cc b/src/Type.cc index fd05c82c3e..a0ed30aa0a 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -1892,12 +1892,12 @@ IntrusivePtr merge_types(const BroType* t1, const BroType* t2) const FuncType* ft1 = (const FuncType*) t1; const FuncType* ft2 = (const FuncType*) t1; - auto args = merge_types(ft1->Args(), ft2->Args()); + auto args = cast_intrusive(merge_types(ft1->Args(), ft2->Args())); auto yield = t1->YieldType() ? merge_types(t1->YieldType(), t2->YieldType()) : nullptr; - return make_intrusive(IntrusivePtr{AdoptRef{}, args.release()->AsRecordType()}, - std::move(yield), ft1->Flavor()); + return make_intrusive(std::move(args), std::move(yield), + ft1->Flavor()); } case TYPE_RECORD: @@ -2125,7 +2125,8 @@ IntrusivePtr init_type(Expr* init) t = std::move(tl); } - return make_intrusive(IntrusivePtr{AdoptRef{}, t.release()->AsTypeList()}, nullptr); + return make_intrusive(cast_intrusive(std::move(t)), + nullptr); } bool is_atomic_type(const BroType* t)