Pārlūkot izejas kodu

fix compilation failure with -g flag in substrate integration (#1222)

* remove conflicting contract names

Signed-off-by: salaheldinsoliman <salaheldin_sameh@aucegypt.edu>
Co-authored-by: Sean Young <sean@mess.org>
salaheldinsoliman 2 gadi atpakaļ
vecāks
revīzija
b8da1555a8

+ 5 - 6
integration/substrate/create_contract.sol

@@ -1,9 +1,8 @@
-
 contract creator {
-    child public c;
+    child_create_contract public c;
 
     function create_child() public {
-        c = new child{value: 1e15}();
+        c = new child_create_contract{value: 1e15}();
     }
 
     function call_child() public view returns (string memory) {
@@ -11,10 +10,10 @@ contract creator {
     }
 }
 
-contract child {
+contract child_create_contract {
     constructor() payable {}
 
-    function say_my_name() pure public returns (string memory) {
+    function say_my_name() public pure returns (string memory) {
         return "child";
     }
-}
+}

+ 1 - 1
integration/substrate/create_contract.spec.ts

@@ -23,7 +23,7 @@ describe('Deploy create_contract contract and test', () => {
         let deploy_contract = await deploy(conn, alice, 'creator.contract', BigInt(1e16));
 
         // we need to have upload the child code
-        let _ = await deploy(conn, alice, 'child.contract', BigInt(0));
+        let _ = await deploy(conn, alice, 'child_create_contract.contract', BigInt(0));
 
         let contract = new ContractPromise(conn, deploy_contract.abi, deploy_contract.address);
 

+ 1 - 1
integration/substrate/package.json

@@ -5,7 +5,7 @@
   "main": "index.js",
   "scripts": {
     "test": "tsc; ts-mocha -t 20000 *.spec.ts",
-    "build": "parallel solang compile -v --target substrate --log-runtime-errors --math-overflow ::: *.sol test/*.sol;  solang compile debug_buffer_format.sol --target substrate -v --log-runtime-errors --log-api-return-codes",
+    "build": "parallel solang compile -v -g --target substrate --log-runtime-errors --math-overflow ::: *.sol test/*.sol;  solang compile debug_buffer_format.sol --target substrate -v --log-runtime-errors --log-api-return-codes",
     "build-ink": "docker run --rm -v $(pwd)/ink/caller:/opt/contract paritytech/contracts-ci-linux@sha256:2eaa0869c562adabcfc011a2f3ad6b2289cdd0b3a8923e24d29efd4452b397de cargo contract build --manifest-path /opt/contract/Cargo.toml"
   },
   "contributors": [

+ 4 - 4
integration/substrate/runtime_errors.sol

@@ -1,7 +1,7 @@
 contract RuntimeErrors {
     bytes b = hex"0000_00fa";
     uint256[] arr;
-    child public c;
+    child_runtime_errors public c;
 
     constructor() {}
 
@@ -65,7 +65,7 @@ contract RuntimeErrors {
 
     // contract creation failed (contract was deplyed with no value)
     function create_child() public {
-        c = new child();
+        c = new child_runtime_errors();
     }
 
     // non payable function dont_pay_me received value
@@ -125,10 +125,10 @@ contract callee_error {
     }
 }
 
-contract child {
+contract child_runtime_errors {
     constructor() payable {}
 
     function say_my_name() public pure returns (string memory) {
-        return "child";
+        return "child_runtime_errors";
     }
 }

+ 2 - 2
integration/substrate/runtime_errors.spec.ts

@@ -22,7 +22,7 @@ describe('Deploy runtime_errors.sol and test the debug buffer', () => {
             deployed_contract.address
         );
 
-        let child_contract = await deploy(conn, alice, 'child.contract', BigInt(0));
+        let child_contract = await deploy(conn, alice, 'child_runtime_errors.contract', BigInt(0));
 
         let res = await debug_buffer(conn, contract, `get_storage_bytes`, [])
         expect(res).toEqual(`runtime_error: storage array index out of bounds in runtime_errors.sol:46:19-23,
@@ -44,7 +44,7 @@ describe('Deploy runtime_errors.sol and test the debug buffer', () => {
 
 
         let res4 = await debug_buffer(conn, contract, `create_child`);
-        expect(res4).toEqual(`runtime_error: contract creation failed in runtime_errors.sol:68:13-24,
+        expect(res4).toEqual(`runtime_error: contract creation failed in runtime_errors.sol:68:13-39,
 `)
 
 

+ 7 - 16
src/bin/solang.rs

@@ -452,14 +452,14 @@ fn compile(matches: &ArgMatches) {
         // TODO: this could be parallelized using e.g. rayon
         let ns = process_file(filename, &mut resolver, target, matches, &opt);
 
-        namespaces.push((ns, filename));
+        namespaces.push(ns);
     }
 
     let mut json_contracts = HashMap::new();
 
     let std_json = *matches.get_one("STD-JSON").unwrap();
 
-    for (ns, _) in &namespaces {
+    for ns in &namespaces {
         if std_json {
             let mut out = ns.diagnostics_as_json(&resolver);
             json.errors.append(&mut out);
@@ -477,7 +477,7 @@ fn compile(matches: &ArgMatches) {
     }
 
     // Ensure we have at least one contract
-    if !errors && namespaces.iter().all(|(ns, _)| ns.contracts.is_empty()) {
+    if !errors && namespaces.iter().all(|ns| ns.contracts.is_empty()) {
         eprintln!("error: no contacts found");
         errors = true;
     }
@@ -488,7 +488,7 @@ fn compile(matches: &ArgMatches) {
         .filter(|name| {
             !namespaces
                 .iter()
-                .flat_map(|(ns, _)| ns.contracts.iter())
+                .flat_map(|ns| ns.contracts.iter())
                 .any(|contract| **name == contract.name)
         })
         .collect();
@@ -499,16 +499,9 @@ fn compile(matches: &ArgMatches) {
     }
 
     if !errors {
-        for (ns, filename) in &namespaces {
+        for ns in &namespaces {
             for contract_no in 0..ns.contracts.len() {
-                contract_results(
-                    contract_no,
-                    filename,
-                    matches,
-                    ns,
-                    &mut json_contracts,
-                    &opt,
-                );
+                contract_results(contract_no, matches, ns, &mut json_contracts, &opt);
             }
         }
     }
@@ -582,7 +575,6 @@ fn process_file(
 
 fn contract_results(
     contract_no: usize,
-    filename: &OsStr,
     matches: &ArgMatches,
     ns: &Namespace,
     json_contracts: &mut HashMap<String, JsonContract>,
@@ -617,9 +609,8 @@ fn contract_results(
     }
 
     let context = inkwell::context::Context::create();
-    let filename_string = filename.to_string_lossy();
 
-    let binary = resolved_contract.binary(ns, &context, &filename_string, opt);
+    let binary = resolved_contract.binary(ns, &context, opt);
 
     if save_intermediates(&binary, matches) {
         return;

+ 2 - 5
src/emit/binary.rs

@@ -61,17 +61,14 @@ impl<'a> Binary<'a> {
         context: &'a Context,
         contract: &'a Contract,
         ns: &'a Namespace,
-        filename: &'a str,
         opt: &'a Options,
     ) -> Self {
         let std_lib = load_stdlib(context, &ns.target);
         match ns.target {
             Target::Substrate { .. } => {
-                substrate::SubstrateTarget::build(context, &std_lib, contract, ns, filename, opt)
-            }
-            Target::Solana => {
-                solana::SolanaTarget::build(context, &std_lib, contract, ns, filename, opt)
+                substrate::SubstrateTarget::build(context, &std_lib, contract, ns, opt)
             }
+            Target::Solana => solana::SolanaTarget::build(context, &std_lib, contract, ns, opt),
             Target::EVM => unimplemented!(),
         }
     }

+ 12 - 0
src/emit/cfg.rs

@@ -193,6 +193,18 @@ pub(super) fn emit_cfg<'a, T: TargetRuntime<'a> + ?Sized>(
                         None,
                     );
                     bin.builder.set_current_debug_location(debug_loc);
+                } else {
+                    // For instructions that do not have a location, insert a debug location pointing to line 0.
+                    // If -g flag is enabled, every instruction should have a debug location. This is necessary
+                    // because llvm's inliner pass requires function call instructions to have a debug location.
+                    let debug_loc = dibuilder.create_debug_location(
+                        bin.context,
+                        0_u32,
+                        0_u32,
+                        di_func_scope.unwrap().as_debug_info_scope(),
+                        None,
+                    );
+                    bin.builder.set_current_debug_location(debug_loc);
                 }
             }
 

+ 2 - 4
src/emit/mod.rs

@@ -409,10 +409,9 @@ impl ast::Contract {
         &'a self,
         ns: &'a ast::Namespace,
         context: &'a inkwell::context::Context,
-        filename: &'a str,
         opt: &'a Options,
     ) -> binary::Binary {
-        binary::Binary::build(context, self, ns, filename, opt)
+        binary::Binary::build(context, self, ns, opt)
     }
 
     /// Generate the final program code for the contract
@@ -424,8 +423,7 @@ impl ast::Contract {
         self.code
             .get_or_init(move || {
                 let context = inkwell::context::Context::create();
-                let filename = ns.files[self.loc.file_no()].path.to_string_lossy();
-                let binary = self.binary(ns, &context, &filename, opt);
+                let binary = self.binary(ns, &context, opt);
                 binary.code(Generate::Linked).expect("llvm build")
             })
             .to_vec()

+ 2 - 4
src/emit/solana/mod.rs

@@ -4,7 +4,6 @@ pub(super) mod target;
 
 use crate::sema::ast;
 use crate::Target;
-use std::str;
 
 use crate::codegen::{cfg::ReturnCode, Options};
 use crate::sema::ast::Type;
@@ -28,16 +27,15 @@ impl SolanaTarget {
         std_lib: &Module<'a>,
         contract: &'a ast::Contract,
         ns: &'a ast::Namespace,
-        filename: &'a str,
         opt: &'a Options,
     ) -> Binary<'a> {
         let mut target = SolanaTarget();
-
+        let filename = ns.files[contract.loc.file_no()].file_name();
         let mut binary = Binary::new(
             context,
             Target::Solana,
             &contract.name,
-            filename,
+            filename.as_str(),
             opt,
             std_lib,
             None,

+ 2 - 2
src/emit/substrate/mod.rs

@@ -108,14 +108,14 @@ impl SubstrateTarget {
         std_lib: &Module<'a>,
         contract: &'a ast::Contract,
         ns: &'a ast::Namespace,
-        filename: &'a str,
         opt: &'a Options,
     ) -> Binary<'a> {
+        let filename = ns.files[contract.loc.file_no()].file_name();
         let mut binary = Binary::new(
             context,
             ns.target,
             &contract.name,
-            filename,
+            filename.as_str(),
             opt,
             std_lib,
             None,