@@ -6,6 +6,8 @@ use crate::asm_lang::allocated_ops::{AllocatedOp, AllocatedOpcode};
6
6
use crate :: asm_lang:: * ;
7
7
use crate :: error:: * ;
8
8
9
+ use sway_ir:: * ;
10
+
9
11
/// Checks for disallowed opcodes in non-contract code.
10
12
/// i.e., if this is a script or predicate, we can't use certain contract opcodes.
11
13
/// See https://github.com/FuelLabs/sway/issues/350 for details.
@@ -72,3 +74,43 @@ fn check_for_contract_opcodes(ops: &[AllocatedOp]) -> CompileResult<()> {
72
74
err ( vec ! [ ] , errors)
73
75
}
74
76
}
77
+
78
+ pub fn check_invalid_return ( ir : & Context , module : & Module ) -> CompileResult < ( ) > {
79
+ let default_span =
80
+ sway_types:: span:: Span :: new ( "no span found for opcode" . into ( ) , 0 , 1 , None ) . unwrap ( ) ;
81
+ match module. get_kind ( ir) {
82
+ Kind :: Contract | Kind :: Library => ok ( ( ) , vec ! [ ] , vec ! [ ] ) ,
83
+ Kind :: Predicate | Kind :: Script => {
84
+ let entry_point_function = module
85
+ . function_iter ( & ir)
86
+ . find ( |func| func. get_name ( & ir) == crate :: constants:: DEFAULT_ENTRY_POINT_FN_NAME )
87
+ . unwrap ( ) ;
88
+
89
+ let ret_ty = entry_point_function. get_return_type ( ir) ;
90
+
91
+ if type_has_ptr ( & ir, & ret_ty) {
92
+ err (
93
+ vec ! [ ] ,
94
+ vec ! [ CompileError :: PointerReturnNotAllowedInMain {
95
+ span: default_span. clone( ) ,
96
+ } ] ,
97
+ )
98
+ } else {
99
+ ok ( ( ) , vec ! [ ] , vec ! [ ] )
100
+ }
101
+ }
102
+ }
103
+ }
104
+
105
+ fn type_has_ptr ( ir : & Context , ty : & Type ) -> bool {
106
+ match ty {
107
+ Type :: Pointer ( _) => true ,
108
+ Type :: Array ( aggregate) | Type :: Union ( aggregate) | Type :: Struct ( aggregate) => {
109
+ match aggregate. get_content ( ir) {
110
+ AggregateContent :: ArrayType ( ty, _) => type_has_ptr ( ir, ty) ,
111
+ AggregateContent :: FieldTypes ( tys) => tys. iter ( ) . any ( |ty| type_has_ptr ( ir, ty) ) ,
112
+ }
113
+ }
114
+ _ => false ,
115
+ }
116
+ }
0 commit comments