22// SPDX-License-Identifier: Apache-2.0 OR MIT
33use super :: typ:: { is_pointer, pointee_type, TypeExt } ;
44use crate :: utils:: { dynamic_fat_ptr, slice_fat_ptr} ;
5- use crate :: GotocCtx ;
5+ use crate :: { GotocCtx , VtableCtx } ;
66use cbmc:: goto_program:: { BuiltinFn , Expr , Location , Stmt , Symbol , Type } ;
77use cbmc:: utils:: { aggr_tag, BUG_REPORT_URL } ;
88use cbmc:: MachineModel ;
@@ -722,7 +722,17 @@ impl<'tcx> GotocCtx<'tcx> {
722722
723723 // Lookup in the symbol table using the full symbol table name/key
724724 let fn_name = self . symbol_name ( instance) ;
725+
725726 if let Some ( fn_symbol) = self . symbol_table . lookup ( & fn_name) {
727+ if self . vtable_ctx . emit_vtable_restrictions {
728+ // Add to the possible method names for this trait type
729+ self . vtable_ctx . add_possible_method (
730+ self . normalized_trait_name ( t) . into ( ) ,
731+ idx,
732+ fn_name. into ( ) ,
733+ ) ;
734+ }
735+
726736 // Create a pointer to the method
727737 // Note that the method takes a self* as the first argument, but the vtable field type has a void* as the first arg.
728738 // So we need to cast it at the end.
@@ -746,13 +756,22 @@ impl<'tcx> GotocCtx<'tcx> {
746756 trait_ty : & ' tcx ty:: TyS < ' tcx > ,
747757 ) -> Expr {
748758 let drop_instance = Instance :: resolve_drop_in_place ( self . tcx , ty) . polymorphize ( self . tcx ) ;
749- let drop_sym_name = self . symbol_name ( drop_instance) ;
759+ let drop_sym_name: InternedString = self . symbol_name ( drop_instance) . into ( ) ;
750760
751761 // The drop instance has the concrete object type, for consistency with
752762 // type codegen we need the trait type for the function parameter.
753763 let trait_fn_ty = self . trait_vtable_drop_type ( trait_ty) ;
754764
755- if let Some ( drop_sym) = self . symbol_table . lookup ( & drop_sym_name) {
765+ if let Some ( drop_sym) = self . symbol_table . lookup ( drop_sym_name) {
766+ if self . vtable_ctx . emit_vtable_restrictions {
767+ // Add to the possible method names for this trait type
768+ self . vtable_ctx . add_possible_method (
769+ self . normalized_trait_name ( trait_ty) . into ( ) ,
770+ VtableCtx :: drop_index ( ) ,
771+ drop_sym_name,
772+ ) ;
773+ }
774+
756775 Expr :: symbol_expression ( drop_sym_name, drop_sym. clone ( ) . typ )
757776 . address_of ( )
758777 . cast_to ( trait_fn_ty)
@@ -761,37 +780,37 @@ impl<'tcx> GotocCtx<'tcx> {
761780 // for it. Build and insert a function that just calls an unimplemented block
762781 // to maintain soundness.
763782 let drop_sym_name = format ! ( "{}_unimplemented" , self . symbol_name( drop_instance) ) ;
764-
765- // Function body
766- let unimplemented = self
767- . codegen_unimplemented (
768- format ! ( "drop_in_place for {}" , drop_sym_name) . as_str ( ) ,
769- Type :: empty ( ) ,
783+ let drop_sym = self . ensure ( & drop_sym_name, |ctx, name| {
784+ // Function body
785+ let unimplemented = ctx
786+ . codegen_unimplemented (
787+ format ! ( "drop_in_place for {}" , drop_sym_name) . as_str ( ) ,
788+ Type :: empty ( ) ,
789+ Location :: none ( ) ,
790+ "https://github.com/model-checking/rmc/issues/281" ,
791+ )
792+ . as_stmt ( Location :: none ( ) ) ;
793+
794+ // Declare symbol for the single, self parameter
795+ let param_name = format ! ( "{}::1::var{:?}" , drop_sym_name, 0 ) ;
796+ let param_sym = Symbol :: variable (
797+ param_name. clone ( ) ,
798+ param_name,
799+ ctx. codegen_ty ( trait_ty) . to_pointer ( ) ,
800+ Location :: none ( ) ,
801+ ) ;
802+ ctx. symbol_table . insert ( param_sym. clone ( ) ) ;
803+
804+ // Build and insert the function itself
805+ Symbol :: function (
806+ name,
807+ Type :: code ( vec ! [ param_sym. to_function_parameter( ) ] , Type :: empty ( ) ) ,
808+ Some ( Stmt :: block ( vec ! [ unimplemented] , Location :: none ( ) ) ) ,
809+ NO_PRETTY_NAME ,
770810 Location :: none ( ) ,
771- "https://github.com/model-checking/rmc/issues/281" ,
772811 )
773- . as_stmt ( Location :: none ( ) ) ;
774-
775- // Declare symbol for the single, self parameter
776- let param_name = format ! ( "{}::1::var{:?}" , drop_sym_name, 0 ) ;
777- let param_sym = Symbol :: variable (
778- param_name. clone ( ) ,
779- param_name,
780- self . codegen_ty ( trait_ty) . to_pointer ( ) ,
781- Location :: none ( ) ,
782- ) ;
783- self . symbol_table . insert ( param_sym. clone ( ) ) ;
784-
785- // Build and insert the function itself
786- let sym = Symbol :: function (
787- & drop_sym_name,
788- Type :: code ( vec ! [ param_sym. to_function_parameter( ) ] , Type :: empty ( ) ) ,
789- Some ( Stmt :: block ( vec ! [ unimplemented] , Location :: none ( ) ) ) ,
790- NO_PRETTY_NAME ,
791- Location :: none ( ) ,
792- ) ;
793- self . symbol_table . insert ( sym. clone ( ) ) ;
794- Expr :: symbol_expression ( drop_sym_name, sym. typ ) . address_of ( ) . cast_to ( trait_fn_ty)
812+ } ) ;
813+ drop_sym. to_expr ( ) . address_of ( ) . cast_to ( trait_fn_ty)
795814 }
796815 }
797816
0 commit comments