@@ -7,6 +7,7 @@ use crate::asm_lang::*;
7
7
use crate :: error:: * ;
8
8
9
9
use sway_error:: error:: CompileError ;
10
+ use sway_ir:: * ;
10
11
11
12
/// Checks for disallowed opcodes in non-contract code.
12
13
/// i.e., if this is a script or predicate, we can't use certain contract opcodes.
@@ -74,3 +75,42 @@ fn check_for_contract_opcodes(ops: &[AllocatedOp]) -> CompileResult<()> {
74
75
err ( vec ! [ ] , errors)
75
76
}
76
77
}
78
+
79
+ pub fn check_invalid_return ( ir : & Context , module : & Module ) -> CompileResult < ( ) > {
80
+ let default_span = sway_types:: span:: Span :: new ( "no span found" . 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| {
87
+ func. get_name ( ir) == sway_types:: constants:: DEFAULT_ENTRY_POINT_FN_NAME
88
+ } )
89
+ . unwrap ( ) ;
90
+
91
+ let ret_ty = entry_point_function. get_return_type ( ir) ;
92
+
93
+ if type_has_ptr ( ir, & ret_ty) {
94
+ err (
95
+ vec ! [ ] ,
96
+ vec ! [ CompileError :: PointerReturnNotAllowedInMain { span: default_span } ] ,
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