Explorar o código

We do not support push()/pop() on bytes on Solana

The Solana BPF heap does not have realloc().

Signed-off-by: Sean Young <sean@mess.org>
Sean Young %!s(int64=4) %!d(string=hai) anos
pai
achega
b69b77c207

+ 16 - 0
src/sema/expression.rs

@@ -6558,6 +6558,14 @@ fn method_call_pos_args(
 
     if matches!(var_ty, Type::Array(..) | Type::DynamicBytes) {
         if func.name == "push" {
+            if ns.target == Target::Solana {
+                diagnostics.push(Diagnostic::error(
+                    func.loc,
+                    format!("‘push()’ not supported on ‘bytes’ on target {}", ns.target),
+                ));
+                return Err(());
+            }
+
             let elem_ty = match &var_ty {
                 Type::Array(ty, _) => ty,
                 Type::DynamicBytes => &Type::Uint(8),
@@ -6598,6 +6606,14 @@ fn method_call_pos_args(
             ));
         }
         if func.name == "pop" {
+            if ns.target == Target::Solana {
+                diagnostics.push(Diagnostic::error(
+                    func.loc,
+                    format!("‘pop()’ not supported on ‘bytes’ on target {}", ns.target),
+                ));
+                return Err(());
+            }
+
             if !args.is_empty() {
                 diagnostics.push(Diagnostic::error(
                     func.loc,

+ 37 - 0
tests/solana_tests/expressions.rs

@@ -221,3 +221,40 @@ fn tx() {
         "builtin ‘tx.gasprice’ does not exist"
     );
 }
+
+#[test]
+fn pushpop() {
+    let ns = parse_and_resolve(
+        r#"
+        contract foo {
+            function test() public {
+                bytes x;
+
+                x.push();
+            }
+        }"#,
+        Target::Solana,
+    );
+
+    assert_eq!(
+        first_error(ns.diagnostics),
+        "‘push()’ not supported on ‘bytes’ on target solana"
+    );
+
+    let ns = parse_and_resolve(
+        r#"
+        contract foo {
+            function test() public {
+                bytes x;
+
+                x.pop();
+            }
+        }"#,
+        Target::Solana,
+    );
+
+    assert_eq!(
+        first_error(ns.diagnostics),
+        "‘pop()’ not supported on ‘bytes’ on target solana"
+    );
+}

+ 1 - 1
tests/undefined_variable_detection.rs

@@ -7,7 +7,7 @@ use solang::{parse_and_resolve, Target};
 fn parse_and_codegen(src: &'static str) -> Namespace {
     let mut cache = FileResolver::new();
     cache.set_file_contents("test.sol", src.to_string());
-    let mut ns = parse_and_resolve("test.sol", &mut cache, Target::Solana);
+    let mut ns = parse_and_resolve("test.sol", &mut cache, Target::Ewasm);
 
     let opt = Options {
         dead_storage: false,

+ 2 - 2
tests/unused_variable_detection.rs

@@ -8,7 +8,7 @@ fn parse(src: &'static str) -> ast::Namespace {
     let mut cache = FileResolver::new();
     cache.set_file_contents("test.sol", src.to_string());
 
-    parse_and_resolve("test.sol", &mut cache, Target::Solana)
+    parse_and_resolve("test.sol", &mut cache, Target::Ewasm)
 }
 
 fn parse_two_files(src1: &'static str, src2: &'static str) -> ast::Namespace {
@@ -16,7 +16,7 @@ fn parse_two_files(src1: &'static str, src2: &'static str) -> ast::Namespace {
     cache.set_file_contents("test.sol", src1.to_string());
     cache.set_file_contents("test2.sol", src2.to_string());
 
-    parse_and_resolve("test.sol", &mut cache, Target::Solana)
+    parse_and_resolve("test.sol", &mut cache, Target::Ewasm)
 }
 
 fn count_warnings(diagnostics: &[Diagnostic]) -> usize {