mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Merge pull request #8464 from aarlt/end-to-end-verified
[test] Extraction of 292 tests from SolidityEndToEndTest.cpp
This commit is contained in:
		
						commit
						8834b1acaf
					
				
							
								
								
									
										22
									
								
								scripts/endToEndExtraction/create_traces.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										22
									
								
								scripts/endToEndExtraction/create_traces.sh
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,22 @@ | |||||||
|  | BASE_PATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 || exit ; pwd -P )" | ||||||
|  | 
 | ||||||
|  | mkdir -p build | ||||||
|  | cd build || exit | ||||||
|  | cmake ../../../ | ||||||
|  | make soltest | ||||||
|  | cd test/ || exit | ||||||
|  | echo "running soltest on 'semanticTests/extracted'..." | ||||||
|  | ./soltest --color_output=false --log_level=test_suite -t semanticTests/extracted/ -- --testpath ${BASE_PATH}/../../test --no-smt --evmonepath /Users/alex/evmone/lib/libevmone.dylib --show-messages --show-metadata > ${BASE_PATH}/extracted-tests.trace | ||||||
|  | echo "running soltest on 'semanticTests/extracted'... done" | ||||||
|  | 
 | ||||||
|  | cd $BASE_PATH || exit | ||||||
|  | git clone git@github.com:ethereum/solidity.git solidity-develop | ||||||
|  | cd solidity-develop || exit | ||||||
|  | mkdir -p build | ||||||
|  | cd build || exit | ||||||
|  | cmake .. | ||||||
|  | make soltest | ||||||
|  | cd test/ || exit | ||||||
|  | echo "running soltest on 'SolidityEndToEndTest'..." | ||||||
|  | ./soltest --color_output=false --log_level=test_suite -t SolidityEndToEndTest/ -- --testpath ${BASE_PATH}/solidity-develop/test --no-smt --evmonepath /Users/alex/evmone/lib/libevmone.dylib --show-messages --show-metadata > ${BASE_PATH}/endToEndExtraction-tests.trace | ||||||
|  | echo "running soltest on 'SolidityEndToEndTest'... done" | ||||||
							
								
								
									
										183
									
								
								scripts/endToEndExtraction/remove-testcases.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										183
									
								
								scripts/endToEndExtraction/remove-testcases.py
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,183 @@ | |||||||
|  | #!/usr/bin/env python3 | ||||||
|  | # pylint: disable=consider-using-enumerate, import-error | ||||||
|  | 
 | ||||||
|  | import re | ||||||
|  | import os | ||||||
|  | import sys | ||||||
|  | import getopt | ||||||
|  | import tempfile | ||||||
|  | from getkey import getkey | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def parse_call(call): | ||||||
|  |     function = '' | ||||||
|  |     arguments = "" | ||||||
|  |     results = "" | ||||||
|  |     search = re.search(r'// (.*):(.*)\s->\s(.*)', call, re.MULTILINE | re.DOTALL) | ||||||
|  |     if search: | ||||||
|  |         function = search.group(1) | ||||||
|  |         arguments = search.group(2) | ||||||
|  |         results = search.group(3) | ||||||
|  |         if results.find("#") != -1: | ||||||
|  |             results = results[:results.find("#")] | ||||||
|  |     else: | ||||||
|  |         search = re.search(r'// (.*)(.*)\s->\s(.*)', call, re.MULTILINE | re.DOTALL) | ||||||
|  |         if search: | ||||||
|  |             function = search.group(1) | ||||||
|  |             arguments = search.group(2) | ||||||
|  |             results = search.group(3) | ||||||
|  |             if results.find("#") != -1: | ||||||
|  |                 results = results[:results.find("#")] | ||||||
|  |     if function.find("wei") >= 0: | ||||||
|  |         function = function[:function.find(",")] | ||||||
|  |     return function.strip(), arguments.strip(), results.strip() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def colorize(left, right, id): | ||||||
|  |     red = "\x1b[31m" | ||||||
|  |     yellow = "\x1b[33m" | ||||||
|  |     reset = "\x1b[0m" | ||||||
|  |     colors = [red, yellow] | ||||||
|  |     color = colors[id % len(colors)] | ||||||
|  |     function, arguments, results = parse_call(right) | ||||||
|  |     left = left.replace("compileAndRun", color + "compileAndRun" + reset) | ||||||
|  |     right = right.replace("constructor", color + "constructor" + reset) | ||||||
|  |     if function: | ||||||
|  |         left = left.replace(function, color + function + reset) | ||||||
|  |         right = right.replace(function, color + function + reset) | ||||||
|  |     if left.find(function): | ||||||
|  |         bottom = " " * (left.find(function) - 4) + right | ||||||
|  |     else: | ||||||
|  |         bottom = " " + right | ||||||
|  |     return "    " + left + "\n" + bottom  # " {:<90} {:<90}\n{}".format(left, right, bottom) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def get_checks(content, sol_file_path): | ||||||
|  |     constructors = [] | ||||||
|  |     checks = [] | ||||||
|  |     for line in content.split("\n"): | ||||||
|  |         line = line.strip() | ||||||
|  |         if line.startswith("compileAndRun"): | ||||||
|  |             constructors.append(line) | ||||||
|  |         if line.startswith("ABI_CHECK") or line.startswith("BOOST_REQUIRE"): | ||||||
|  |             checks.append(line) | ||||||
|  |     sol_file = open(sol_file_path, "r") | ||||||
|  |     sol_constructors = [] | ||||||
|  |     sol_checks = [] | ||||||
|  |     inside_expectations = False | ||||||
|  |     for line in sol_file.readlines(): | ||||||
|  |         if line.startswith("// constructor()"): | ||||||
|  |             sol_constructors.append(line) | ||||||
|  |         elif inside_expectations and line.startswith("// "): | ||||||
|  |             sol_checks.append(line) | ||||||
|  |         if line.startswith("// ----"): | ||||||
|  |             inside_expectations = True | ||||||
|  |     sol_file.close() | ||||||
|  |     if len(constructors) == len(sol_constructors) == 1: | ||||||
|  |         checks.insert(0, constructors[0]) | ||||||
|  |         sol_checks.insert(0, sol_constructors[0]) | ||||||
|  |     return checks, sol_checks | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def show_test(name, content, sol_file_path, current_test, test_count): | ||||||
|  |     cpp_file = tempfile.NamedTemporaryFile(delete=False) | ||||||
|  |     cpp_file.write(content.encode()) | ||||||
|  |     cpp_file.close() | ||||||
|  | 
 | ||||||
|  |     os.system("clear") | ||||||
|  |     print(str(current_test) + " / " + str(test_count) + " - " + name + "\n") | ||||||
|  |     diff_env = os.getenv('DIFF', "/usr/local/bin/colordiff -a -d -w -y -W 200 ") | ||||||
|  |     os.system(diff_env + " " + cpp_file.name + " " + sol_file_path) | ||||||
|  |     os.unlink(cpp_file.name) | ||||||
|  |     print("\n") | ||||||
|  | 
 | ||||||
|  |     checks, sol_checks = get_checks(content, sol_file_path) | ||||||
|  | 
 | ||||||
|  |     if len(checks) == len(sol_checks): | ||||||
|  |         for i in range(0, len(checks)): | ||||||
|  |             print(colorize(checks[i].strip(), sol_checks[i].strip(), i)) | ||||||
|  |     else: | ||||||
|  |         print("warning: check count not matching. this should not happen!") | ||||||
|  | 
 | ||||||
|  |     what = "" | ||||||
|  |     print("\nContinue? (ENTER) Abort? (ANY OTHER KEY)") | ||||||
|  |     while what != '\n': | ||||||
|  |         what = getkey() | ||||||
|  |         if what != '\n': | ||||||
|  |             sys.exit(0) | ||||||
|  |     print() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def get_tests(e2e_path): | ||||||
|  |     tests = [] | ||||||
|  |     for f in os.listdir(e2e_path): | ||||||
|  |         if f.endswith(".sol"): | ||||||
|  |             tests.append(f.replace(".sol", "")) | ||||||
|  |     return tests | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def process_input_file(e2e_path, input_file, interactive): | ||||||
|  |     tests = get_tests(e2e_path) | ||||||
|  |     cpp_file = open(input_file, "r") | ||||||
|  |     inside_test = False | ||||||
|  |     test_name = "" | ||||||
|  |     inside_extracted_test = False | ||||||
|  |     new_lines = 0 | ||||||
|  |     count = 0 | ||||||
|  |     test_content = "" | ||||||
|  |     for line in cpp_file.readlines(): | ||||||
|  |         test = re.search(r'BOOST_AUTO_TEST_CASE\((.*)\)', line, re.M | re.I) | ||||||
|  |         if test: | ||||||
|  |             test_name = test.group(1) | ||||||
|  |             inside_test = True | ||||||
|  |             inside_extracted_test = inside_test & (test_name in tests) | ||||||
|  |             if inside_extracted_test: | ||||||
|  |                 count = count + 1 | ||||||
|  | 
 | ||||||
|  |         if interactive and inside_extracted_test: | ||||||
|  |             test_content = test_content + line | ||||||
|  | 
 | ||||||
|  |         if not inside_extracted_test: | ||||||
|  |             if line == "\n": | ||||||
|  |                 new_lines = new_lines + 1 | ||||||
|  |             else: | ||||||
|  |                 new_lines = 0 | ||||||
|  |             if not interactive and new_lines <= 1: | ||||||
|  |                 sys.stdout.write(line) | ||||||
|  | 
 | ||||||
|  |         if line == "}\n": | ||||||
|  |             if interactive and inside_extracted_test: | ||||||
|  |                 show_test(test_name, test_content.strip(), e2e_path + "/" + test_name + ".sol", count, len(tests)) | ||||||
|  |                 test_content = "" | ||||||
|  |             inside_test = False | ||||||
|  |     cpp_file.close() | ||||||
|  |     sys.stdout.flush() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def main(argv): | ||||||
|  |     interactive = False | ||||||
|  |     input_file = None | ||||||
|  |     try: | ||||||
|  |         opts, args = getopt.getopt(argv, "if:") | ||||||
|  |     except getopt.GetoptError: | ||||||
|  |         print("./remove-testcases.py [-i] [-f <full path to SolidityEndToEndTest.cpp>]") | ||||||
|  |         sys.exit(1) | ||||||
|  | 
 | ||||||
|  |     for opt, arg in opts: | ||||||
|  |         if opt == '-i': | ||||||
|  |             interactive = True | ||||||
|  |         elif opt in '-f': | ||||||
|  |             input_file = arg | ||||||
|  | 
 | ||||||
|  |     base_path = os.path.dirname(__file__) | ||||||
|  | 
 | ||||||
|  |     if not input_file: | ||||||
|  |         input_file = base_path + "/../../test/libsolidity/SolidityEndToEndTest.cpp" | ||||||
|  | 
 | ||||||
|  |     e2e_path = base_path + "/../../test/libsolidity/semanticTests/extracted" | ||||||
|  | 
 | ||||||
|  |     process_input_file(e2e_path, input_file, interactive) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     main(sys.argv[1:]) | ||||||
							
								
								
									
										215
									
								
								scripts/endToEndExtraction/verify-testcases.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										215
									
								
								scripts/endToEndExtraction/verify-testcases.py
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,215 @@ | |||||||
|  | #!/usr/bin/env python3 | ||||||
|  | # | ||||||
|  | # - SolidityEndToEndTest.trace was created with soltest with the following command on | ||||||
|  | #     ./soltest --color_output=false --log_level=test_suite -t SolidityEndToEndTest/ -- --no-smt | ||||||
|  | #         --evmonepath /Users/alex/evmone/lib/libevmone.dylib --show-messages > SolidityEndToEndTest.trace | ||||||
|  | # - a trace of the semantic tests can be created by using | ||||||
|  | #     ./soltest --color_output=false --log_level=test_suite -t semanticTests/extracted/ -- --no-smt | ||||||
|  | #         --evmonepath /Users/alex/evmone/lib/libevmone.dylib --show-messages > semanticTests.trace | ||||||
|  | # | ||||||
|  | # verify-testcases.py will compare both traces. If these traces are identical, the extracted tests where | ||||||
|  | # identical with the tests specified in SolidityEndToEndTest.cpp. | ||||||
|  | # | ||||||
|  | # pylint: disable=too-many-instance-attributes | ||||||
|  | 
 | ||||||
|  | import re | ||||||
|  | import os | ||||||
|  | import sys | ||||||
|  | import getopt | ||||||
|  | import json | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Trace: | ||||||
|  |     def __init__(self, kind, parameter): | ||||||
|  |         self.kind = kind | ||||||
|  |         self.parameter = parameter | ||||||
|  |         self._input = "" | ||||||
|  |         self._output = "" | ||||||
|  |         self.value = "" | ||||||
|  |         self.result = "" | ||||||
|  |         self.gas = "" | ||||||
|  | 
 | ||||||
|  |     def get_input(self): | ||||||
|  |         return self._input | ||||||
|  | 
 | ||||||
|  |     def set_input(self, input): | ||||||
|  |         if self.kind == "create": | ||||||
|  |             # remove cbor encoded metadata from bytecode | ||||||
|  |             length = int(input[-4:], 16) * 2 | ||||||
|  |             self._input = input[:len(input) - length - 4] | ||||||
|  | 
 | ||||||
|  |     def get_output(self): | ||||||
|  |         return self._output | ||||||
|  | 
 | ||||||
|  |     def set_output(self, output): | ||||||
|  |         if self.kind == "create": | ||||||
|  |             # remove cbor encoded metadata from bytecode | ||||||
|  |             length = int(output[-4:], 16) * 2 | ||||||
|  |             self._output = output[:len(output) - length - 4] | ||||||
|  | 
 | ||||||
|  |     def __str__(self): | ||||||
|  |         # we ignore the used gas | ||||||
|  |         result = str( | ||||||
|  |             "kind='" + self.kind + "' parameter='" + self.parameter + "' input='" + self._input + | ||||||
|  |             "' output='" + self._output + "' value='" + self.value + "' result='" + self.result + "'" | ||||||
|  |         ) | ||||||
|  |         return result | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class TestCase: | ||||||
|  |     def __init__(self, name): | ||||||
|  |         self.name = name | ||||||
|  |         self.metadata = None | ||||||
|  |         self.traces = [] | ||||||
|  | 
 | ||||||
|  |     def add_trace(self, kind, parameter): | ||||||
|  |         trace = Trace(kind, parameter) | ||||||
|  |         self.traces.append(trace) | ||||||
|  |         return trace | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class TraceAnalyser: | ||||||
|  |     def __init__(self, file): | ||||||
|  |         self.file = file | ||||||
|  |         self.tests = {} | ||||||
|  |         self.ready = False | ||||||
|  | 
 | ||||||
|  |     def analyse(self): | ||||||
|  |         trace_file = open(self.file, "r") | ||||||
|  |         trace = None | ||||||
|  |         test_case = None | ||||||
|  |         for line in trace_file.readlines(): | ||||||
|  |             test = re.search(r'Entering test case "(.*)"', line, re.M | re.I) | ||||||
|  |             if test: | ||||||
|  |                 test_name = test.group(1) | ||||||
|  |                 test_case = TestCase(test_name) | ||||||
|  |                 self.tests[test_name] = test_case | ||||||
|  | 
 | ||||||
|  |             metadata = re.search(r'\s*metadata:\s*(.*)$', line, re.M | re.I) | ||||||
|  |             if metadata: | ||||||
|  |                 test_case.metadata = json.loads(metadata.group(1)) | ||||||
|  |                 del test_case.metadata["sources"] | ||||||
|  |                 del test_case.metadata["compiler"]["version"] | ||||||
|  | 
 | ||||||
|  |             create = re.search(r'CREATE\s*([a-fA-F0-9]*):', line, re.M | re.I) | ||||||
|  |             if create: | ||||||
|  |                 trace = test_case.add_trace("create", create.group(1)) | ||||||
|  | 
 | ||||||
|  |             call = re.search(r'CALL\s*([a-fA-F0-9]*)\s*->\s*([a-fA-F0-9]*):', line, re.M | re.I) | ||||||
|  |             if call: | ||||||
|  |                 trace = test_case.add_trace("call", call.group(1))  # + "->" + call.group(2)) | ||||||
|  | 
 | ||||||
|  |             if not create and not call: | ||||||
|  |                 self.parse_parameters(line, trace) | ||||||
|  | 
 | ||||||
|  |         trace_file.close() | ||||||
|  | 
 | ||||||
|  |         print(self.file + ":", len(self.tests), "test-cases.") | ||||||
|  | 
 | ||||||
|  |         self.ready = True | ||||||
|  | 
 | ||||||
|  |     @staticmethod | ||||||
|  |     def parse_parameters(line, trace): | ||||||
|  |         input = re.search(r'\s*in:\s*([a-fA-F0-9]*)', line, re.M | re.I) | ||||||
|  |         if input: | ||||||
|  |             trace.input = input.group(1) | ||||||
|  |         output = re.search(r'\s*out:\s*([a-fA-F0-9]*)', line, re.M | re.I) | ||||||
|  |         if output: | ||||||
|  |             trace.output = output.group(1) | ||||||
|  |         result = re.search(r'\s*result:\s*([a-fA-F0-9]*)', line, re.M | re.I) | ||||||
|  |         if result: | ||||||
|  |             trace.result = result.group(1) | ||||||
|  |         gas_used = re.search(r'\s*gas\sused:\s*([a-fA-F0-9]*)', line, re.M | re.I) | ||||||
|  |         if gas_used: | ||||||
|  |             trace.gas = gas_used.group(1) | ||||||
|  |         value = re.search(r'\s*value:\s*([a-fA-F0-9]*)', line, re.M | re.I) | ||||||
|  |         if value: | ||||||
|  |             trace.value = value.group(1) | ||||||
|  | 
 | ||||||
|  |     def diff(self, analyser): | ||||||
|  |         if not self.ready: | ||||||
|  |             self.analyse() | ||||||
|  |         if not analyser.ready: | ||||||
|  |             analyser.analyse() | ||||||
|  | 
 | ||||||
|  |         intersection = set(self.tests.keys()) & set(analyser.tests.keys()) | ||||||
|  |         mismatches = set() | ||||||
|  | 
 | ||||||
|  |         for test_name in intersection: | ||||||
|  |             left = self.tests[test_name] | ||||||
|  |             right = analyser.tests[test_name] | ||||||
|  |             if json.dumps(left.metadata) != json.dumps(right.metadata): | ||||||
|  |                 mismatches.add( | ||||||
|  |                     (test_name, "metadata where different: " + json.dumps(left.metadata) + " != " + json.dumps( | ||||||
|  |                         right.metadata))) | ||||||
|  |             if len(left.traces) != len(right.traces): | ||||||
|  |                 mismatches.add((test_name, "trace count are different: " + str(len(left.traces)) + | ||||||
|  |                                 " != " + str(len(right.traces)))) | ||||||
|  |             else: | ||||||
|  |                 self.check_traces(test_name, left, right, mismatches) | ||||||
|  | 
 | ||||||
|  |         for mismatch in mismatches: | ||||||
|  |             print(mismatch[0]) | ||||||
|  |             print(mismatch[1]) | ||||||
|  | 
 | ||||||
|  |         print(len(intersection), "test-cases - ", len(mismatches), " mismatche(s)") | ||||||
|  | 
 | ||||||
|  |     def check_traces(self, test_name, left, right, mismatches): | ||||||
|  |         for trace_id in range(0, len(left.traces)): | ||||||
|  |             left_trace = left.traces[trace_id] | ||||||
|  |             right_trace = right.traces[trace_id] | ||||||
|  |             assert (left_trace.kind == right_trace.kind) | ||||||
|  |             if str(left_trace) != str(right_trace): | ||||||
|  |                 mismatch_info = "    " + str(left_trace) + "\n" | ||||||
|  |                 mismatch_info += "    " + str(right_trace) + "\n" | ||||||
|  |                 mismatch_info += "    " | ||||||
|  |                 for ch in range(0, len(str(left_trace))): | ||||||
|  |                     if ch < len(str(left_trace)) and ch < len(str(right_trace)): | ||||||
|  |                         if str(left_trace)[ch] != str(right_trace)[ch]: | ||||||
|  |                             mismatch_info += "|" | ||||||
|  |                         else: | ||||||
|  |                             mismatch_info += " " | ||||||
|  |                     else: | ||||||
|  |                         mismatch_info += "|" | ||||||
|  |                 mismatch_info += "\n" | ||||||
|  |                 mismatches.add((test_name, mismatch_info)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def main(argv): | ||||||
|  |     extracted_tests_trace_file = None | ||||||
|  |     end_to_end_trace_file = None | ||||||
|  |     try: | ||||||
|  |         opts, args = getopt.getopt(argv, "s:e:") | ||||||
|  |     except getopt.GetoptError: | ||||||
|  |         print("verify-testcases.py [-s <path to semantic-trace>] [-e <path to endToEndExtraction-trace>]") | ||||||
|  |         sys.exit(2) | ||||||
|  | 
 | ||||||
|  |     for opt, arg in opts: | ||||||
|  |         if opt in '-s': | ||||||
|  |             extracted_tests_trace_file = arg | ||||||
|  |         elif opt in '-e': | ||||||
|  |             end_to_end_trace_file = arg | ||||||
|  | 
 | ||||||
|  |     base_path = os.path.dirname(__file__) | ||||||
|  |     if not extracted_tests_trace_file: | ||||||
|  |         extracted_tests_trace_file = base_path + "/extracted-tests.trace" | ||||||
|  |     if not end_to_end_trace_file: | ||||||
|  |         end_to_end_trace_file = base_path + "/endToEndExtraction-tests.trace" | ||||||
|  | 
 | ||||||
|  |     for f in [extracted_tests_trace_file, end_to_end_trace_file]: | ||||||
|  |         if not os.path.isfile(f): | ||||||
|  |             print("trace file '" + f + "' not found. aborting.") | ||||||
|  |             sys.exit(1) | ||||||
|  | 
 | ||||||
|  |     if not os.path.isfile(extracted_tests_trace_file): | ||||||
|  |         print("semantic trace file '" + extracted_tests_trace_file + "' not found. aborting.") | ||||||
|  |         sys.exit(1) | ||||||
|  | 
 | ||||||
|  |     semantic_trace = TraceAnalyser(extracted_tests_trace_file) | ||||||
|  |     end_to_end_trace = TraceAnalyser(end_to_end_trace_file) | ||||||
|  | 
 | ||||||
|  |     semantic_trace.diff(end_to_end_trace) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     main(sys.argv[1:]) | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | contract C { | ||||||
|  |     function f(bytes calldata data) external pure returns (uint256[] memory) { | ||||||
|  |         return abi.decode(data, (uint256[])); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 | ||||||
| @ -0,0 +1,12 @@ | |||||||
|  | contract C { | ||||||
|  |     function f(bytes calldata data) | ||||||
|  |         external | ||||||
|  |         pure | ||||||
|  |         returns (uint256[2][3] memory) | ||||||
|  |     { | ||||||
|  |         return abi.decode(data, (uint256[2][3])); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6 | ||||||
| @ -0,0 +1,15 @@ | |||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     function f(bytes calldata data) | ||||||
|  |         external | ||||||
|  |         pure | ||||||
|  |         returns (uint256[2][3] memory) | ||||||
|  |     { | ||||||
|  |         return abi.decode(data, (uint256[2][3])); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6 | ||||||
| @ -0,0 +1,8 @@ | |||||||
|  | contract C { | ||||||
|  |     function f(bytes memory data) public pure returns (uint256) { | ||||||
|  |         return abi.decode(data, (uint256)); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f(bytes): 0x20, 0x20, 0x21 -> 33 | ||||||
							
								
								
									
										22
									
								
								test/libsolidity/semanticTests/extracted/abi_decode_v2.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								test/libsolidity/semanticTests/extracted/abi_decode_v2.sol
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | |||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     struct S { | ||||||
|  |         uint256 a; | ||||||
|  |         uint256[] b; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f() public pure returns (S memory) { | ||||||
|  |         S memory s; | ||||||
|  |         s.a = 8; | ||||||
|  |         s.b = new uint256[](3); | ||||||
|  |         s.b[0] = 9; | ||||||
|  |         s.b[1] = 10; | ||||||
|  |         s.b[2] = 11; | ||||||
|  |         return abi.decode(abi.encode(s), (S)); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb | ||||||
| @ -0,0 +1,16 @@ | |||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     struct S { | ||||||
|  |         uint256 a; | ||||||
|  |         uint256[] b; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f(bytes calldata data) external pure returns (S memory) { | ||||||
|  |         return abi.decode(data, (S)); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f(bytes): 0x20, 0xe0, 0x20, 0x21, 0x40, 0x3, 0xa, 0xb, 0xc -> 0x20, 0x21, 0x40, 0x3, 0xa, 0xb, 0xc | ||||||
| @ -0,0 +1,24 @@ | |||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     bytes data; | ||||||
|  |     struct S { | ||||||
|  |         uint256 a; | ||||||
|  |         uint256[] b; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f() public returns (S memory) { | ||||||
|  |         S memory s; | ||||||
|  |         s.a = 8; | ||||||
|  |         s.b = new uint256[](3); | ||||||
|  |         s.b[0] = 9; | ||||||
|  |         s.b[1] = 10; | ||||||
|  |         s.b[2] = 11; | ||||||
|  |         data = abi.encode(s); | ||||||
|  |         return abi.decode(data, (S)); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb | ||||||
							
								
								
									
										36
									
								
								test/libsolidity/semanticTests/extracted/abi_encode.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								test/libsolidity/semanticTests/extracted/abi_encode.sol
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | |||||||
|  | contract C { | ||||||
|  |     function f0() public returns (bytes memory) { | ||||||
|  |         return abi.encode(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f1() public returns (bytes memory) { | ||||||
|  |         return abi.encode(1, 2); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f2() public returns (bytes memory) { | ||||||
|  |         string memory x = "abc"; | ||||||
|  |         return abi.encode(1, x, 2); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f3() public returns (bytes memory r) { | ||||||
|  |         // test that memory is properly allocated | ||||||
|  |         string memory x = "abc"; | ||||||
|  |         r = abi.encode(1, x, 2); | ||||||
|  |         bytes memory y = "def"; | ||||||
|  |         require(y[0] == "d"); | ||||||
|  |         y[0] = "e"; | ||||||
|  |         require(y[0] == "e"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f4() public returns (bytes memory) { | ||||||
|  |         bytes4 x = "abcd"; | ||||||
|  |         return abi.encode(bytes2(x)); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f0() -> 0x20, 0x0 | ||||||
|  | // f1() -> 0x20, 0x40, 0x1, 0x2 | ||||||
|  | // f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc" | ||||||
|  | // f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc" | ||||||
|  | // f4() -> 0x20, 0x20, "ab" | ||||||
							
								
								
									
										26
									
								
								test/libsolidity/semanticTests/extracted/abi_encode_call.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								test/libsolidity/semanticTests/extracted/abi_encode_call.sol
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | |||||||
|  | contract C { | ||||||
|  |     bool x; | ||||||
|  | 
 | ||||||
|  |     function c(uint256 a, uint256[] memory b) public { | ||||||
|  |         require(a == 5); | ||||||
|  |         require(b.length == 2); | ||||||
|  |         require(b[0] == 6); | ||||||
|  |         require(b[1] == 7); | ||||||
|  |         x = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f() public returns (bool) { | ||||||
|  |         uint256 a = 5; | ||||||
|  |         uint256[] memory b = new uint256[](2); | ||||||
|  |         b[0] = 6; | ||||||
|  |         b[1] = 7; | ||||||
|  |         (bool success, ) = address(this).call( | ||||||
|  |             abi.encodeWithSignature("c(uint256,uint256[])", a, b) | ||||||
|  |         ); | ||||||
|  |         require(success); | ||||||
|  |         return x; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f() -> true | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | contract C { | ||||||
|  |     function f() public pure returns (uint256, bytes memory) { | ||||||
|  |         bytes memory arg = "abcdefg"; | ||||||
|  |         return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes)); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f() -> 0x21, 0x40, 0x7, "abcdefg" | ||||||
| @ -0,0 +1,13 @@ | |||||||
|  | // Tests that this will not end up using a "bytes0" type | ||||||
|  | // (which would assert) | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     function f() public pure returns (bytes memory, bytes memory) { | ||||||
|  |         return (abi.encode(""), abi.encodePacked("")); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f() -> 0x40, 0xa0, 0x40, 0x20, 0x0, 0x0 | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | // Tests that rational numbers (even negative ones) are encoded properly. | ||||||
|  | contract C { | ||||||
|  |     function f() public pure returns (bytes memory) { | ||||||
|  |         return abi.encode(1, -2); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f() -> 0x20, 0x40, 0x1, -2 | ||||||
| @ -0,0 +1,12 @@ | |||||||
|  | // Tests that rational numbers (even negative ones) are encoded properly. | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     function f() public pure returns (bytes memory) { | ||||||
|  |         return abi.encode(1, -2); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f() -> 0x20, 0x40, 0x1, -2 | ||||||
							
								
								
									
										53
									
								
								test/libsolidity/semanticTests/extracted/abi_encode_v2.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								test/libsolidity/semanticTests/extracted/abi_encode_v2.sol
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | |||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     struct S { | ||||||
|  |         uint256 a; | ||||||
|  |         uint256[] b; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f0() public pure returns (bytes memory) { | ||||||
|  |         return abi.encode(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f1() public pure returns (bytes memory) { | ||||||
|  |         return abi.encode(1, 2); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f2() public pure returns (bytes memory) { | ||||||
|  |         string memory x = "abc"; | ||||||
|  |         return abi.encode(1, x, 2); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f3() public pure returns (bytes memory r) { | ||||||
|  |         // test that memory is properly allocated | ||||||
|  |         string memory x = "abc"; | ||||||
|  |         r = abi.encode(1, x, 2); | ||||||
|  |         bytes memory y = "def"; | ||||||
|  |         require(y[0] == "d"); | ||||||
|  |         y[0] = "e"; | ||||||
|  |         require(y[0] == "e"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     S s; | ||||||
|  | 
 | ||||||
|  |     function f4() public returns (bytes memory r) { | ||||||
|  |         string memory x = "abc"; | ||||||
|  |         s.a = 7; | ||||||
|  |         s.b.push(2); | ||||||
|  |         s.b.push(3); | ||||||
|  |         r = abi.encode(1, x, s, 2); | ||||||
|  |         bytes memory y = "def"; | ||||||
|  |         require(y[0] == "d"); | ||||||
|  |         y[0] = "e"; | ||||||
|  |         require(y[0] == "e"); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f0() -> 0x20, 0x0 | ||||||
|  | // f1() -> 0x20, 0x40, 0x1, 0x2 | ||||||
|  | // f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc" | ||||||
|  | // f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc" | ||||||
|  | // f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, "abc", 0x7, 0x40, 0x2, 0x2, 0x3 | ||||||
| @ -0,0 +1,30 @@ | |||||||
|  | contract Base { | ||||||
|  |     uint256 dataBase; | ||||||
|  | 
 | ||||||
|  |     function getViaBase() public returns (uint256 i) { | ||||||
|  |         return dataBase; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract Derived is Base { | ||||||
|  |     uint256 dataDerived; | ||||||
|  | 
 | ||||||
|  |     function setData(uint256 base, uint256 derived) public returns (bool r) { | ||||||
|  |         dataBase = base; | ||||||
|  |         dataDerived = derived; | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function getViaDerived() public returns (uint256 base, uint256 derived) { | ||||||
|  |         base = dataBase; | ||||||
|  |         derived = dataDerived; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ==== | ||||||
|  | // compileViaYul: also | ||||||
|  | // ---- | ||||||
|  | // setData(uint256,uint256): 1, 2 -> true | ||||||
|  | // getViaBase() -> 1 | ||||||
|  | // getViaDerived() -> 1, 2 | ||||||
| @ -0,0 +1,6 @@ | |||||||
|  | contract Lotto { | ||||||
|  |     uint256 public constant ticketPrice = 555; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // ticketPrice() -> 555 | ||||||
| @ -0,0 +1,8 @@ | |||||||
|  | contract Lotto { | ||||||
|  |     uint256 public ticketPrice = 500; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ==== | ||||||
|  | // compileViaYul: also | ||||||
|  | // ---- | ||||||
|  | // ticketPrice() -> 500 | ||||||
							
								
								
									
										12
									
								
								test/libsolidity/semanticTests/extracted/addmod_mulmod.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								test/libsolidity/semanticTests/extracted/addmod_mulmod.sol
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | contract C { | ||||||
|  |     function test() public returns (uint256) { | ||||||
|  |         // Note that this only works because computation on literals is done using | ||||||
|  |         // unbounded integers. | ||||||
|  |         if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 1; | ||||||
|  |         if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 2; | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> 0 | ||||||
| @ -0,0 +1,24 @@ | |||||||
|  | contract C { | ||||||
|  |     function f(uint256 d) public pure returns (uint256) { | ||||||
|  |         addmod(1, 2, d); | ||||||
|  |         return 2; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function g(uint256 d) public pure returns (uint256) { | ||||||
|  |         mulmod(1, 2, d); | ||||||
|  |         return 2; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function h() public pure returns (uint256) { | ||||||
|  |         mulmod(0, 1, 2); | ||||||
|  |         mulmod(1, 0, 2); | ||||||
|  |         addmod(0, 1, 2); | ||||||
|  |         addmod(1, 0, 2); | ||||||
|  |         return 2; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f(uint256): 0 -> FAILURE | ||||||
|  | // g(uint256): 0 -> FAILURE | ||||||
|  | // h() -> 2 | ||||||
| @ -0,0 +1,24 @@ | |||||||
|  | contract C { | ||||||
|  |     function balance() public returns (uint256) { | ||||||
|  |         return 1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function transfer(uint256 amount) public returns (uint256) { | ||||||
|  |         return amount; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract D { | ||||||
|  |     function f() public returns (uint256) { | ||||||
|  |         return (new C()).balance(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function g() public returns (uint256) { | ||||||
|  |         return (new C()).transfer(5); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f() -> 1 | ||||||
|  | // g() -> 5 | ||||||
| @ -0,0 +1,21 @@ | |||||||
|  | contract c { | ||||||
|  |     bytes8[] data1; // 4 per slot | ||||||
|  |     bytes10[] data2; // 3 per slot | ||||||
|  | 
 | ||||||
|  |     function test() | ||||||
|  |         public | ||||||
|  |         returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e) | ||||||
|  |     { | ||||||
|  |         data1 = new bytes8[](9); | ||||||
|  |         for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i)); | ||||||
|  |         data2 = data1; | ||||||
|  |         a = data2[1]; | ||||||
|  |         b = data2[2]; | ||||||
|  |         c = data2[3]; | ||||||
|  |         d = data2[4]; | ||||||
|  |         e = data2[5]; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000 | ||||||
| @ -0,0 +1,15 @@ | |||||||
|  | contract c { | ||||||
|  |     uint256[4][] a; | ||||||
|  |     uint256[10][] b; | ||||||
|  |     uint256[][] c; | ||||||
|  | 
 | ||||||
|  |     function test(uint256[2][] calldata d) external returns (uint256) { | ||||||
|  |         a = d; | ||||||
|  |         b = a; | ||||||
|  |         c = b; | ||||||
|  |         return c[1][1] | c[1][2] | c[1][3] | c[1][4]; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10 | ||||||
| @ -0,0 +1,20 @@ | |||||||
|  | // NOTE: This does not really test copying from storage to ABI directly, | ||||||
|  | // because it will always copy to memory first. | ||||||
|  | contract c { | ||||||
|  |     int16[] x; | ||||||
|  | 
 | ||||||
|  |     function test() public returns (int16[] memory) { | ||||||
|  |         x.push(int16(-1)); | ||||||
|  |         x.push(int16(-1)); | ||||||
|  |         x.push(int16(8)); | ||||||
|  |         x.push(int16(-16)); | ||||||
|  |         x.push(int16(-2)); | ||||||
|  |         x.push(int16(6)); | ||||||
|  |         x.push(int16(8)); | ||||||
|  |         x.push(int16(-1)); | ||||||
|  |         return x; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1 | ||||||
| @ -0,0 +1,14 @@ | |||||||
|  | contract c { | ||||||
|  |     uint256[9] data1; | ||||||
|  |     uint256[] data2; | ||||||
|  | 
 | ||||||
|  |     function test() public returns (uint256 x, uint256 y) { | ||||||
|  |         data1[8] = 4; | ||||||
|  |         data2 = data1; | ||||||
|  |         x = data2.length; | ||||||
|  |         y = data2[8]; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> 9, 4 | ||||||
| @ -0,0 +1,17 @@ | |||||||
|  | contract c { | ||||||
|  |     uint256[40] data1; | ||||||
|  |     uint256[20] data2; | ||||||
|  | 
 | ||||||
|  |     function test() public returns (uint256 x, uint256 y) { | ||||||
|  |         data1[30] = 4; | ||||||
|  |         data1[2] = 7; | ||||||
|  |         data1[3] = 9; | ||||||
|  |         data2[3] = 8; | ||||||
|  |         data1 = data2; | ||||||
|  |         x = data1[3]; | ||||||
|  |         y = data1[30]; // should be cleared | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> 8, 0 | ||||||
| @ -0,0 +1,22 @@ | |||||||
|  | // since the copy always copies whole slots, we have to make sure that the source size maxes | ||||||
|  | // out a whole slot and at the same time there are still elements left in the target at that point | ||||||
|  | contract c { | ||||||
|  |     bytes8[4] data1; // fits into one slot | ||||||
|  |     bytes10[6] data2; // 4 elements need two slots | ||||||
|  | 
 | ||||||
|  |     function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) { | ||||||
|  |         data1[0] = bytes8(uint64(1)); | ||||||
|  |         data1[1] = bytes8(uint64(2)); | ||||||
|  |         data1[2] = bytes8(uint64(3)); | ||||||
|  |         data1[3] = bytes8(uint64(4)); | ||||||
|  |         for (uint256 i = 0; i < data2.length; ++i) | ||||||
|  |             data2[i] = bytes10(uint80(0xffff00 | (1 + i))); | ||||||
|  |         data2 = data1; | ||||||
|  |         r1 = data2[3]; | ||||||
|  |         r2 = data2[4]; | ||||||
|  |         r3 = data2[5]; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0 | ||||||
| @ -0,0 +1,21 @@ | |||||||
|  | contract c { | ||||||
|  |     bytes8[9] data1; // 4 per slot | ||||||
|  |     bytes17[10] data2; // 1 per slot, no offset counter | ||||||
|  | 
 | ||||||
|  |     function test() | ||||||
|  |         public | ||||||
|  |         returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e) | ||||||
|  |     { | ||||||
|  |         for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i)); | ||||||
|  |         data2[8] = data2[9] = bytes8(uint64(2)); | ||||||
|  |         data2 = data1; | ||||||
|  |         a = data2[1]; | ||||||
|  |         b = data2[2]; | ||||||
|  |         c = data2[3]; | ||||||
|  |         d = data2[4]; | ||||||
|  |         e = data2[9]; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0 | ||||||
							
								
								
									
										16
									
								
								test/libsolidity/semanticTests/extracted/array_pop.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								test/libsolidity/semanticTests/extracted/array_pop.sol
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | contract c { | ||||||
|  |     uint256[] data; | ||||||
|  | 
 | ||||||
|  |     function test() public returns (uint256 x, uint256 l) { | ||||||
|  |         data.push(7); | ||||||
|  |         data.push(3); | ||||||
|  |         x = data.length; | ||||||
|  |         data.pop(); | ||||||
|  |         x = data.length; | ||||||
|  |         data.pop(); | ||||||
|  |         l = data.length; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> 1, 0 | ||||||
| @ -0,0 +1,11 @@ | |||||||
|  | contract c { | ||||||
|  |     uint256[] data; | ||||||
|  | 
 | ||||||
|  |     function test() public returns (bool) { | ||||||
|  |         data.pop(); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> FAILURE | ||||||
| @ -0,0 +1,13 @@ | |||||||
|  | // This tests that the compiler knows the correct size of the function on the stack. | ||||||
|  | contract c { | ||||||
|  |     uint256[] data; | ||||||
|  | 
 | ||||||
|  |     function test() public returns (uint256 x) { | ||||||
|  |         x = 2; | ||||||
|  |         data.pop; | ||||||
|  |         x = 3; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> 3 | ||||||
							
								
								
									
										19
									
								
								test/libsolidity/semanticTests/extracted/array_push.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								test/libsolidity/semanticTests/extracted/array_push.sol
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | contract c { | ||||||
|  |     uint256[] data; | ||||||
|  | 
 | ||||||
|  |     function test() | ||||||
|  |         public | ||||||
|  |         returns (uint256 x, uint256 y, uint256 z, uint256 l) | ||||||
|  |     { | ||||||
|  |         data.push(5); | ||||||
|  |         x = data[0]; | ||||||
|  |         data.push(4); | ||||||
|  |         y = data[1]; | ||||||
|  |         data.push(3); | ||||||
|  |         l = data.length; | ||||||
|  |         z = data[2]; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> 5, 4, 3, 3 | ||||||
| @ -0,0 +1,16 @@ | |||||||
|  | contract c { | ||||||
|  |     uint80[] x; | ||||||
|  | 
 | ||||||
|  |     function test() public returns (uint80, uint80, uint80, uint80) { | ||||||
|  |         x.push(1); | ||||||
|  |         x.push(2); | ||||||
|  |         x.push(3); | ||||||
|  |         x.push(4); | ||||||
|  |         x.push(5); | ||||||
|  |         x.pop(); | ||||||
|  |         return (x[0], x[1], x[2], x[3]); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> 1, 2, 3, 4 | ||||||
| @ -0,0 +1,23 @@ | |||||||
|  | contract c { | ||||||
|  |     struct S { | ||||||
|  |         uint16 a; | ||||||
|  |         uint16 b; | ||||||
|  |         uint16[3] c; | ||||||
|  |         uint16[] d; | ||||||
|  |     } | ||||||
|  |     S[] data; | ||||||
|  | 
 | ||||||
|  |     function test() public returns (uint16, uint16, uint16, uint16) { | ||||||
|  |         S memory s; | ||||||
|  |         s.a = 2; | ||||||
|  |         s.b = 3; | ||||||
|  |         s.c[2] = 4; | ||||||
|  |         s.d = new uint16[](4); | ||||||
|  |         s.d[2] = 5; | ||||||
|  |         data.push(s); | ||||||
|  |         return (data[0].a, data[0].b, data[0].c[2], data[0].d[2]); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> 2, 3, 4, 5 | ||||||
							
								
								
									
										24
									
								
								test/libsolidity/semanticTests/extracted/assert_require.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								test/libsolidity/semanticTests/extracted/assert_require.sol
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | |||||||
|  | contract C { | ||||||
|  |     function f() public { | ||||||
|  |         assert(false); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function g(bool val) public returns (bool) { | ||||||
|  |         assert(val == true); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function h(bool val) public returns (bool) { | ||||||
|  |         require(val); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ==== | ||||||
|  | // compileViaYul: also | ||||||
|  | // ---- | ||||||
|  | // f() -> FAILURE | ||||||
|  | // g(bool): false -> FAILURE | ||||||
|  | // g(bool): true -> true | ||||||
|  | // h(bool): false -> FAILURE | ||||||
|  | // h(bool): true -> true | ||||||
| @ -0,0 +1,10 @@ | |||||||
|  | contract C { | ||||||
|  |     uint256 constant x = 0x123 + 0x456; | ||||||
|  | 
 | ||||||
|  |     function f() public returns (uint256) { | ||||||
|  |         return x + 1; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f() -> 0x57a | ||||||
							
								
								
									
										13
									
								
								test/libsolidity/semanticTests/extracted/balance.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								test/libsolidity/semanticTests/extracted/balance.sol
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | |||||||
|  | contract test { | ||||||
|  |     constructor() public payable {} | ||||||
|  | 
 | ||||||
|  |     function getBalance() public returns (uint256 balance) { | ||||||
|  |         return address(this).balance; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ==== | ||||||
|  | // compileViaYul: also | ||||||
|  | // ---- | ||||||
|  | // constructor(), 23 wei -> | ||||||
|  | // getBalance() -> 23 | ||||||
| @ -0,0 +1,21 @@ | |||||||
|  | contract C { | ||||||
|  |     function() returns (uint256) internal x; | ||||||
|  | 
 | ||||||
|  |     function set() public { | ||||||
|  |         C.x = g; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function g() public pure returns (uint256) { | ||||||
|  |         return 2; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function h() public returns (uint256) { | ||||||
|  |         return C.x(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // g() -> 2 | ||||||
|  | // h() -> FAILURE | ||||||
|  | // set() -> | ||||||
|  | // h() -> 2 | ||||||
| @ -0,0 +1,24 @@ | |||||||
|  | contract BaseBase { | ||||||
|  |     uint256 m_a; | ||||||
|  | 
 | ||||||
|  |     constructor(uint256 a) public { | ||||||
|  |         m_a = a; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract Base is BaseBase(7) { | ||||||
|  |     constructor() public { | ||||||
|  |         m_a *= m_a; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract Derived is Base { | ||||||
|  |     function getA() public returns (uint256 r) { | ||||||
|  |         return m_a; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // getA() -> 49 | ||||||
| @ -0,0 +1,20 @@ | |||||||
|  | contract C { | ||||||
|  |     uint256 public x; | ||||||
|  |     modifier run() { | ||||||
|  |         for (uint256 i = 0; i < 10; i++) { | ||||||
|  |             _; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f() public run { | ||||||
|  |         uint256 k = x; | ||||||
|  |         uint256 t = k + 1; | ||||||
|  |         x = t; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // x() -> 0 | ||||||
|  | // f() -> | ||||||
|  | // x() -> 1 | ||||||
							
								
								
									
										17
									
								
								test/libsolidity/semanticTests/extracted/byte_array_pop.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								test/libsolidity/semanticTests/extracted/byte_array_pop.sol
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | contract c { | ||||||
|  |     bytes data; | ||||||
|  | 
 | ||||||
|  |     function test() public returns (uint256 x, uint256 y, uint256 l) { | ||||||
|  |         data.push(0x07); | ||||||
|  |         data.push(0x03); | ||||||
|  |         x = data.length; | ||||||
|  |         data.pop(); | ||||||
|  |         data.pop(); | ||||||
|  |         data.push(0x02); | ||||||
|  |         y = data.length; | ||||||
|  |         l = data.length; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> 2, 1, 1 | ||||||
| @ -0,0 +1,12 @@ | |||||||
|  | contract c { | ||||||
|  |     bytes data; | ||||||
|  | 
 | ||||||
|  |     function test() public returns (bytes memory) { | ||||||
|  |         for (uint256 i = 0; i < 33; i++) data.push(0x03); | ||||||
|  |         for (uint256 j = 0; j < 4; j++) data.pop(); | ||||||
|  |         return data; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> 0x20, 29, 0x0303030303030303030303030303030303030303030303030303030303000000 | ||||||
| @ -0,0 +1,14 @@ | |||||||
|  | contract c { | ||||||
|  |     uint256 a; | ||||||
|  |     uint256 b; | ||||||
|  |     uint256 c; | ||||||
|  |     bytes data; | ||||||
|  | 
 | ||||||
|  |     function test() public returns (bool) { | ||||||
|  |         data.pop(); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> FAILURE | ||||||
| @ -0,0 +1,13 @@ | |||||||
|  | // This tests that the compiler knows the correct size of the function on the stack. | ||||||
|  | contract c { | ||||||
|  |     bytes data; | ||||||
|  | 
 | ||||||
|  |     function test() public returns (uint256 x) { | ||||||
|  |         x = 2; | ||||||
|  |         data.pop; | ||||||
|  |         x = 3; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> 3 | ||||||
| @ -0,0 +1,12 @@ | |||||||
|  | contract c { | ||||||
|  |     bytes data; | ||||||
|  | 
 | ||||||
|  |     function test() public returns (bytes memory) { | ||||||
|  |         for (uint256 i = 0; i < 34; i++) data.push(0x03); | ||||||
|  |         data.pop(); | ||||||
|  |         return data; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> 0x20, 33, 0x303030303030303030303030303030303030303030303030303030303030303, 0x0300000000000000000000000000000000000000000000000000000000000000 | ||||||
							
								
								
									
										18
									
								
								test/libsolidity/semanticTests/extracted/byte_array_push.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								test/libsolidity/semanticTests/extracted/byte_array_push.sol
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | |||||||
|  | contract c { | ||||||
|  |     bytes data; | ||||||
|  | 
 | ||||||
|  |     function test() public returns (bool x) { | ||||||
|  |         data.push(0x05); | ||||||
|  |         if (data.length != 1) return true; | ||||||
|  |         if (data[0] != 0x05) return true; | ||||||
|  |         data.push(0x04); | ||||||
|  |         if (data[1] != 0x04) return true; | ||||||
|  |         data.push(0x03); | ||||||
|  |         uint256 l = data.length; | ||||||
|  |         if (data[2] != 0x03) return true; | ||||||
|  |         if (l != 0x03) return true; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> false | ||||||
| @ -0,0 +1,18 @@ | |||||||
|  | // Tests transition between short and long encoding | ||||||
|  | contract c { | ||||||
|  |     bytes data; | ||||||
|  | 
 | ||||||
|  |     function test() public returns (uint256) { | ||||||
|  |         for (uint8 i = 1; i < 40; i++) { | ||||||
|  |             data.push(bytes1(i)); | ||||||
|  |             if (data.length != i) return 0x1000 + i; | ||||||
|  |             if (data[data.length - 1] != bytes1(i)) return i; | ||||||
|  |         } | ||||||
|  |         for (uint8 i = 1; i < 40; i++) | ||||||
|  |             if (data[i - 1] != bytes1(i)) return 0x1000000 + i; | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> 0 | ||||||
| @ -0,0 +1,19 @@ | |||||||
|  | contract C { | ||||||
|  |     function f(uint256 x) public returns (uint256 a) { | ||||||
|  |         assembly { | ||||||
|  |             a := byte(x, 31) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function g(uint256 x) public returns (uint256 a) { | ||||||
|  |         assembly { | ||||||
|  |             a := byte(31, x) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ==== | ||||||
|  | // compileViaYul: also | ||||||
|  | // ---- | ||||||
|  | // f(uint256): 2 -> 0 | ||||||
|  | // g(uint256): 2 -> 2 | ||||||
| @ -0,0 +1,19 @@ | |||||||
|  | contract c { | ||||||
|  |     bytes data; | ||||||
|  | 
 | ||||||
|  |     function test1() external returns (bool) { | ||||||
|  |         data = new bytes(100); | ||||||
|  |         for (uint256 i = 0; i < data.length; i++) data[i] = bytes1(uint8(i)); | ||||||
|  |         delete data[94]; | ||||||
|  |         delete data[96]; | ||||||
|  |         delete data[98]; | ||||||
|  |         return | ||||||
|  |             data[94] == 0 && | ||||||
|  |             uint8(data[95]) == 95 && | ||||||
|  |             data[96] == 0 && | ||||||
|  |             uint8(data[97]) == 97; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test1() -> true | ||||||
| @ -0,0 +1,17 @@ | |||||||
|  | contract c { | ||||||
|  |     function set() public returns (bool) { | ||||||
|  |         data = msg.data; | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function getLength() public returns (uint256) { | ||||||
|  |         return data.length; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bytes data; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // getLength() -> 0 | ||||||
|  | // set(): 1, 2 -> true | ||||||
|  | // getLength() -> 68 | ||||||
| @ -0,0 +1,28 @@ | |||||||
|  | contract test { | ||||||
|  |     function f0() public returns (uint) { | ||||||
|  |         return 2; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f1() internal returns (function() internal returns (uint)) { | ||||||
|  |         return f0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f2() internal returns (function() internal returns (function () internal returns (uint))) { | ||||||
|  |         return f1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) { | ||||||
|  |         return f2; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f() public returns (uint) { | ||||||
|  |         function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x; | ||||||
|  |         x = f3; | ||||||
|  |         return x()()()(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ==== | ||||||
|  | // compileViaYul: also | ||||||
|  | // ---- | ||||||
|  | // f() -> 2 | ||||||
							
								
								
									
										16
									
								
								test/libsolidity/semanticTests/extracted/calldata_array.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								test/libsolidity/semanticTests/extracted/calldata_array.sol
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     function f(uint256[2] calldata s) | ||||||
|  |         external | ||||||
|  |         pure | ||||||
|  |         returns (uint256 a, uint256 b) | ||||||
|  |     { | ||||||
|  |         a = s[0]; | ||||||
|  |         b = s[1]; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f(uint256[2]): 42, 23 -> 42, 23 | ||||||
| @ -0,0 +1,21 @@ | |||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     function f(uint256[][] calldata a) external returns (uint256) { | ||||||
|  |         return 42; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function g(uint256[][] calldata a) external returns (uint256) { | ||||||
|  |         a[0]; | ||||||
|  |         return 42; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub # | ||||||
|  | // f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding # | ||||||
|  | // f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access # | ||||||
|  | // g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE | ||||||
|  | // f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access # | ||||||
|  | // g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE | ||||||
| @ -0,0 +1,30 @@ | |||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     function f(uint256[][1][] calldata a) external returns (uint256) { | ||||||
|  |         return 42; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function g(uint256[][1][] calldata a) external returns (uint256) { | ||||||
|  |         a[0]; | ||||||
|  |         return 42; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function h(uint256[][1][] calldata a) external returns (uint256) { | ||||||
|  |         a[0][0]; | ||||||
|  |         return 42; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub # | ||||||
|  | // f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding # | ||||||
|  | // f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access # | ||||||
|  | // g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE | ||||||
|  | // f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access # | ||||||
|  | // g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 | ||||||
|  | // h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE | ||||||
|  | // f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42 | ||||||
|  | // g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42 | ||||||
|  | // h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE | ||||||
| @ -0,0 +1,24 @@ | |||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     struct S { | ||||||
|  |         uint256 a; | ||||||
|  |         uint256 b; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f(S[] calldata s) | ||||||
|  |         external | ||||||
|  |         pure | ||||||
|  |         returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d) | ||||||
|  |     { | ||||||
|  |         l = s.length; | ||||||
|  |         a = s[0].a; | ||||||
|  |         b = s[0].b; | ||||||
|  |         c = s[1].a; | ||||||
|  |         d = s[1].b; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4 | ||||||
| @ -0,0 +1,25 @@ | |||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     struct S { | ||||||
|  |         uint256 a; | ||||||
|  |         uint256 b; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f(S[] calldata s) | ||||||
|  |         external | ||||||
|  |         pure | ||||||
|  |         returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d) | ||||||
|  |     { | ||||||
|  |         S[] memory m = s; | ||||||
|  |         l = m.length; | ||||||
|  |         a = m[0].a; | ||||||
|  |         b = m[0].b; | ||||||
|  |         c = m[1].a; | ||||||
|  |         d = m[1].b; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4 | ||||||
| @ -0,0 +1,15 @@ | |||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     function f(uint256[][] calldata a) | ||||||
|  |         external | ||||||
|  |         returns (uint256, uint256[] memory) | ||||||
|  |     { | ||||||
|  |         uint256[] memory m = a[0]; | ||||||
|  |         return (a.length, m); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a | ||||||
							
								
								
									
										17
									
								
								test/libsolidity/semanticTests/extracted/calldata_struct.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								test/libsolidity/semanticTests/extracted/calldata_struct.sol
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     struct S { | ||||||
|  |         uint256 a; | ||||||
|  |         uint256 b; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f(S calldata s) external pure returns (uint256 a, uint256 b) { | ||||||
|  |         a = s.a; | ||||||
|  |         b = s.b; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f((uint256,uint256)): 42, 23 -> 42, 23 | ||||||
| @ -0,0 +1,20 @@ | |||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     struct S { | ||||||
|  |         uint256 a; | ||||||
|  |         uint256 b; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f(uint256 a, S calldata s, uint256 b) | ||||||
|  |         external | ||||||
|  |         pure | ||||||
|  |         returns (uint256, uint256, uint256, uint256) | ||||||
|  |     { | ||||||
|  |         return (a, s.a, s.b, b); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f(uint256,(uint256,uint256),uint256): 1, 2, 3, 4 -> 1, 2, 3, 4 | ||||||
| @ -0,0 +1,24 @@ | |||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     struct S { | ||||||
|  |         uint256 a; | ||||||
|  |         uint256[2] b; | ||||||
|  |         uint256 c; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f(S calldata s) | ||||||
|  |         external | ||||||
|  |         pure | ||||||
|  |         returns (uint256 a, uint256 b0, uint256 b1, uint256 c) | ||||||
|  |     { | ||||||
|  |         a = s.a; | ||||||
|  |         b0 = s.b[0]; | ||||||
|  |         b1 = s.b[1]; | ||||||
|  |         c = s.c; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23 | ||||||
| @ -0,0 +1,17 @@ | |||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     struct S { | ||||||
|  |         uint256 a; | ||||||
|  |         uint256 b; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f(S calldata s) external pure returns (uint256, uint256) { | ||||||
|  |         S memory m = s; | ||||||
|  |         return (m.a, m.b); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f((uint256,uint256)): 42, 23 -> 42, 23 | ||||||
| @ -0,0 +1,27 @@ | |||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     struct S1 { | ||||||
|  |         uint256 a; | ||||||
|  |         uint256 b; | ||||||
|  |     } | ||||||
|  |     struct S2 { | ||||||
|  |         uint256 a; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f(S1 calldata s1, S2 calldata s2, S1 calldata s3) | ||||||
|  |         external | ||||||
|  |         pure | ||||||
|  |         returns (uint256 a, uint256 b, uint256 c, uint256 d, uint256 e) | ||||||
|  |     { | ||||||
|  |         a = s1.a; | ||||||
|  |         b = s1.b; | ||||||
|  |         c = s2.a; | ||||||
|  |         d = s3.a; | ||||||
|  |         e = s3.b; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f((uint256,uint256),(uint256),(uint256,uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5 | ||||||
| @ -0,0 +1,28 @@ | |||||||
|  | abstract contract D { | ||||||
|  |     function g() public virtual; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     D d = D(0x1212); | ||||||
|  | 
 | ||||||
|  |     function f() public returns (uint256) { | ||||||
|  |         d.g(); | ||||||
|  |         return 7; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function g() public returns (uint256) { | ||||||
|  |         d.g.gas(200)(); | ||||||
|  |         return 7; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function h() public returns (uint256) { | ||||||
|  |         address(d).call(""); // this does not throw (low-level) | ||||||
|  |         return 7; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f() -> FAILURE | ||||||
|  | // g() -> FAILURE | ||||||
|  | // h() -> 7 | ||||||
| @ -0,0 +1,17 @@ | |||||||
|  | contract C { | ||||||
|  |     function intern() public returns (uint256) { | ||||||
|  |         function (uint) internal returns (uint) x; | ||||||
|  |         x(2); | ||||||
|  |         return 7; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function extern() public returns (uint256) { | ||||||
|  |         function (uint) external returns (uint) x; | ||||||
|  |         x(2); | ||||||
|  |         return 7; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // intern() -> FAILURE # This should throw exceptions # | ||||||
|  | // extern() -> FAILURE | ||||||
| @ -0,0 +1,20 @@ | |||||||
|  | contract C { | ||||||
|  |     function() returns (uint256) internal x; | ||||||
|  |     int256 mutex; | ||||||
|  | 
 | ||||||
|  |     function t() public returns (uint256) { | ||||||
|  |         if (mutex > 0) { | ||||||
|  |             assembly { | ||||||
|  |                 mstore(0, 7) | ||||||
|  |                 return(0, 0x20) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         mutex = 1; | ||||||
|  |         // Avoid re-executing this function if we jump somewhere. | ||||||
|  |         x(); | ||||||
|  |         return 2; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // t() -> FAILURE | ||||||
| @ -0,0 +1,20 @@ | |||||||
|  | contract C { | ||||||
|  |     int256 mutex; | ||||||
|  | 
 | ||||||
|  |     function t() public returns (uint256) { | ||||||
|  |         if (mutex > 0) { | ||||||
|  |             assembly { | ||||||
|  |                 mstore(0, 7) | ||||||
|  |                 return(0, 0x20) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         mutex = 1; | ||||||
|  |         // Avoid re-executing this function if we jump somewhere. | ||||||
|  |         function() internal returns (uint)[200] memory x; | ||||||
|  |         x[0](); | ||||||
|  |         return 2; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // t() -> FAILURE | ||||||
| @ -0,0 +1,33 @@ | |||||||
|  | contract C { | ||||||
|  |     function f() public pure returns (address r) { | ||||||
|  |         bytes21 x = 0x1122334455667788990011223344556677889900ff; | ||||||
|  |         bytes20 y; | ||||||
|  |         assembly { | ||||||
|  |             y := x | ||||||
|  |         } | ||||||
|  |         address z = address(y); | ||||||
|  |         assembly { | ||||||
|  |             r := z | ||||||
|  |         } | ||||||
|  |         require(z == 0x1122334455667788990011223344556677889900); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function g() public pure returns (address payable r) { | ||||||
|  |         bytes21 x = 0x1122334455667788990011223344556677889900ff; | ||||||
|  |         bytes20 y; | ||||||
|  |         assembly { | ||||||
|  |             y := x | ||||||
|  |         } | ||||||
|  |         address payable z = address(y); | ||||||
|  |         assembly { | ||||||
|  |             r := z | ||||||
|  |         } | ||||||
|  |         require(z == 0x1122334455667788990011223344556677889900); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ==== | ||||||
|  | // compileViaYul: also | ||||||
|  | // ---- | ||||||
|  | // f() -> 0x1122334455667788990011223344556677889900 | ||||||
|  | // g() -> 0x1122334455667788990011223344556677889900 | ||||||
| @ -0,0 +1,15 @@ | |||||||
|  | contract C { | ||||||
|  |     function f() public pure returns (bytes32 r) { | ||||||
|  |         bytes4 x = 0xffffffff; | ||||||
|  |         bytes2 y = bytes2(x); | ||||||
|  |         assembly { | ||||||
|  |             r := y | ||||||
|  |         } | ||||||
|  |         // At this point, r and y both store four bytes, but | ||||||
|  |         // y is properly cleaned before the equality check | ||||||
|  |         require(y == bytes2(0xffff)); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f() -> "\xff\xff\xff\xff" | ||||||
| @ -0,0 +1,13 @@ | |||||||
|  | contract C { | ||||||
|  |     function test() public returns (uint256, uint256) { | ||||||
|  |         uint32 a = 0xffffffff; | ||||||
|  |         uint16 x = uint16(a); | ||||||
|  |         uint16 y = x; | ||||||
|  |         x /= 0x100; | ||||||
|  |         y = y / 0x100; | ||||||
|  |         return (x, y); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> 0xff, 0xff | ||||||
| @ -0,0 +1,42 @@ | |||||||
|  | contract D { | ||||||
|  |     bytes32 public x; | ||||||
|  | 
 | ||||||
|  |     constructor() public { | ||||||
|  |         bytes32 codeHash; | ||||||
|  |         assembly { | ||||||
|  |             let size := codesize() | ||||||
|  |             codecopy(mload(0x40), 0, size) | ||||||
|  |             codeHash := keccak256(mload(0x40), size) | ||||||
|  |         } | ||||||
|  |         x = codeHash; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     function testRuntime() public returns (bool) { | ||||||
|  |         D d = new D(); | ||||||
|  |         bytes32 runtimeHash = keccak256(type(D).runtimeCode); | ||||||
|  |         bytes32 otherHash; | ||||||
|  |         uint256 size; | ||||||
|  |         assembly { | ||||||
|  |             size := extcodesize(d) | ||||||
|  |             extcodecopy(d, mload(0x40), 0, size) | ||||||
|  |             otherHash := keccak256(mload(0x40), size) | ||||||
|  |         } | ||||||
|  |         require(size == type(D).runtimeCode.length); | ||||||
|  |         require(runtimeHash == otherHash); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function testCreation() public returns (bool) { | ||||||
|  |         D d = new D(); | ||||||
|  |         bytes32 creationHash = keccak256(type(D).creationCode); | ||||||
|  |         require(creationHash == d.x()); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // testRuntime() -> true | ||||||
|  | // testCreation() -> true | ||||||
| @ -0,0 +1,26 @@ | |||||||
|  | contract D { | ||||||
|  |     uint256 x; | ||||||
|  | 
 | ||||||
|  |     constructor() public { | ||||||
|  |         x = 7; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f() public view returns (uint256) { | ||||||
|  |         return x; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     function test() public returns (uint256) { | ||||||
|  |         bytes memory c = type(D).creationCode; | ||||||
|  |         D d; | ||||||
|  |         assembly { | ||||||
|  |             d := create(0, add(c, 0x20), mload(c)) | ||||||
|  |         } | ||||||
|  |         return d.f(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> 7 | ||||||
| @ -0,0 +1,19 @@ | |||||||
|  | contract D { | ||||||
|  |     function f() public pure returns (uint256) { | ||||||
|  |         return 7; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     function diff() public pure returns (uint256 remainder) { | ||||||
|  |         bytes memory a = type(D).creationCode; | ||||||
|  |         bytes memory b = type(D).runtimeCode; | ||||||
|  |         assembly { | ||||||
|  |             remainder := mod(sub(b, a), 0x20) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes # | ||||||
							
								
								
									
										22
									
								
								test/libsolidity/semanticTests/extracted/constant_string.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								test/libsolidity/semanticTests/extracted/constant_string.sol
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | |||||||
|  | contract C { | ||||||
|  |     bytes constant a = "\x03\x01\x02"; | ||||||
|  |     bytes constant b = hex"030102"; | ||||||
|  |     string constant c = "hello"; | ||||||
|  | 
 | ||||||
|  |     function f() public returns (bytes memory) { | ||||||
|  |         return a; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function g() public returns (bytes memory) { | ||||||
|  |         return b; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function h() public returns (bytes memory) { | ||||||
|  |         return bytes(c); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f() -> 0x20, 3, "\x03\x01\x02" | ||||||
|  | // g() -> 0x20, 3, "\x03\x01\x02" | ||||||
|  | // h() -> 0x20, 5, "hello" | ||||||
| @ -0,0 +1,14 @@ | |||||||
|  | contract C { | ||||||
|  |     uint256 constant LEN = 3; | ||||||
|  |     uint256[LEN] public a; | ||||||
|  | 
 | ||||||
|  |     constructor(uint256[LEN] memory _a) public { | ||||||
|  |         a = _a; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // constructor(): 1, 2, 3 -> | ||||||
|  | // a(uint256): 0 -> 1 | ||||||
|  | // a(uint256): 1 -> 2 | ||||||
|  | // a(uint256): 2 -> 3 | ||||||
| @ -0,0 +1,11 @@ | |||||||
|  | contract Foo { | ||||||
|  |     uint256 constant x = 56; | ||||||
|  |     enum ActionChoices {GoLeft, GoRight, GoStraight, Sit} | ||||||
|  |     ActionChoices constant choices = ActionChoices.GoLeft; | ||||||
|  |     bytes32 constant st = "abc\x00\xff__"; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ==== | ||||||
|  | // compileViaYul: also | ||||||
|  | // ---- | ||||||
|  | // constructor() -> | ||||||
| @ -0,0 +1,12 @@ | |||||||
|  | contract c { | ||||||
|  |     enum Truth {False, True} | ||||||
|  | 
 | ||||||
|  |     function test() public returns (uint256) { | ||||||
|  |         return uint256(Truth(uint8(0x701))); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ==== | ||||||
|  | // compileViaYul: also | ||||||
|  | // ---- | ||||||
|  | // test() -> 1 | ||||||
| @ -0,0 +1,22 @@ | |||||||
|  | contract Main { | ||||||
|  |     bytes3 name; | ||||||
|  |     bool flag; | ||||||
|  | 
 | ||||||
|  |     constructor(bytes3 x, bool f) public { | ||||||
|  |         name = x; | ||||||
|  |         flag = f; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function getName() public returns (bytes3 ret) { | ||||||
|  |         return name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function getFlag() public returns (bool ret) { | ||||||
|  |         return flag; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // constructor(): "abc", true | ||||||
|  | // getFlag() -> true | ||||||
|  | // getName() -> "abc" | ||||||
| @ -0,0 +1,38 @@ | |||||||
|  | contract Helper { | ||||||
|  |     bytes3 name; | ||||||
|  |     bool flag; | ||||||
|  | 
 | ||||||
|  |     constructor(bytes3 x, bool f) public { | ||||||
|  |         name = x; | ||||||
|  |         flag = f; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function getName() public returns (bytes3 ret) { | ||||||
|  |         return name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function getFlag() public returns (bool ret) { | ||||||
|  |         return flag; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract Main { | ||||||
|  |     Helper h; | ||||||
|  | 
 | ||||||
|  |     constructor() public { | ||||||
|  |         h = new Helper("abc", true); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function getFlag() public returns (bool ret) { | ||||||
|  |         return h.getFlag(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function getName() public returns (bytes3 ret) { | ||||||
|  |         return h.getName(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // getFlag() -> true | ||||||
|  | // getName() -> "abc" | ||||||
| @ -0,0 +1,16 @@ | |||||||
|  | contract C { | ||||||
|  |     uint256 public a; | ||||||
|  |     uint256[3] public b; | ||||||
|  | 
 | ||||||
|  |     constructor(uint256 _a, uint256[3] memory _b) public { | ||||||
|  |         a = _a; | ||||||
|  |         b = _b; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // constructor(): 1, 2, 3, 4 -> | ||||||
|  | // a() -> 1 | ||||||
|  | // b(uint256): 0 -> 2 | ||||||
|  | // b(uint256): 1 -> 3 | ||||||
|  | // b(uint256): 2 -> 4 | ||||||
| @ -0,0 +1,20 @@ | |||||||
|  | contract C { | ||||||
|  |     uint256 public x; | ||||||
|  |     modifier run() { | ||||||
|  |         for (uint256 i = 0; i < 10; i++) { | ||||||
|  |             if (i % 2 == 1) continue; | ||||||
|  |             _; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f() public run { | ||||||
|  |         uint256 k = x; | ||||||
|  |         uint256 t = k + 1; | ||||||
|  |         x = t; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // x() -> 0 | ||||||
|  | // f() -> | ||||||
|  | // x() -> 5 | ||||||
| @ -0,0 +1,20 @@ | |||||||
|  | contract A { | ||||||
|  |     function f() public { | ||||||
|  |         new B(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract B { | ||||||
|  |     function f() public {} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C { | ||||||
|  |     function f() public { | ||||||
|  |         new B(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // constructor() -> | ||||||
| @ -0,0 +1,18 @@ | |||||||
|  | contract C { | ||||||
|  |     function() internal returns (uint)[] x; | ||||||
|  |     function() internal returns (uint)[] y; | ||||||
|  | 
 | ||||||
|  |     function test() public returns (uint256) { | ||||||
|  |         x = new function() internal returns (uint)[](10); | ||||||
|  |         x[9] = a; | ||||||
|  |         y = x; | ||||||
|  |         return y[9](); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function a() public returns (uint256) { | ||||||
|  |         return 7; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // test() -> 7 | ||||||
| @ -0,0 +1,22 @@ | |||||||
|  | contract C { | ||||||
|  |     function() internal returns (uint)[20] x; | ||||||
|  |     int256 mutex; | ||||||
|  | 
 | ||||||
|  |     function one() public returns (uint256) { | ||||||
|  |         function() internal returns (uint)[20] memory xmem; | ||||||
|  |         x = xmem; | ||||||
|  |         return 3; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function two() public returns (uint256) { | ||||||
|  |         if (mutex > 0) return 7; | ||||||
|  |         mutex = 1; | ||||||
|  |         // If this test fails, it might re-execute this function. | ||||||
|  |         x[0](); | ||||||
|  |         return 2; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // one() -> 3 | ||||||
|  | // two() -> FAILURE | ||||||
| @ -0,0 +1,15 @@ | |||||||
|  | contract C { | ||||||
|  |     function f() public returns (uint256 r) { | ||||||
|  |         uint256; | ||||||
|  |         uint256; | ||||||
|  |         uint256; | ||||||
|  |         uint256; | ||||||
|  |         int256 x = -7; | ||||||
|  |         return uint256(x); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ==== | ||||||
|  | // compileViaYul: also | ||||||
|  | // ---- | ||||||
|  | // f() -> -7 | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | contract C { | ||||||
|  |     function f() public returns (uint256) { | ||||||
|  |         uint256[][] memory a = new uint256[][](0); | ||||||
|  |         return 7; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f() -> 7 | ||||||
| @ -0,0 +1,21 @@ | |||||||
|  | contract C { | ||||||
|  |     struct S { | ||||||
|  |         uint256[2] a; | ||||||
|  |         bytes b; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f() public returns (bytes1, uint256, uint256, bytes1) { | ||||||
|  |         bytes memory x = new bytes(200); | ||||||
|  |         x[199] = "A"; | ||||||
|  |         uint256[2][] memory y = new uint256[2][](300); | ||||||
|  |         y[203][1] = 8; | ||||||
|  |         S[] memory z = new S[](180); | ||||||
|  |         z[170].a[1] = 4; | ||||||
|  |         z[170].b = new bytes(102); | ||||||
|  |         z[170].b[99] = "B"; | ||||||
|  |         return (x[199], y[203][1], z[170].a[1], z[170].b[99]); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f() -> "A", 8, 4, "B" | ||||||
| @ -0,0 +1,34 @@ | |||||||
|  | contract C { | ||||||
|  |     function f() public returns (uint256) { | ||||||
|  |         uint256[][] memory x = new uint256[][](42); | ||||||
|  |         assert(x[0].length == 0); | ||||||
|  |         x[0] = new uint256[](1); | ||||||
|  |         x[0][0] = 1; | ||||||
|  |         assert(x[4].length == 0); | ||||||
|  |         x[4] = new uint256[](1); | ||||||
|  |         x[4][0] = 2; | ||||||
|  |         assert(x[10].length == 0); | ||||||
|  |         x[10] = new uint256[](1); | ||||||
|  |         x[10][0] = 44; | ||||||
|  |         uint256[][] memory y = new uint256[][](24); | ||||||
|  |         assert(y[0].length == 0); | ||||||
|  |         y[0] = new uint256[](1); | ||||||
|  |         y[0][0] = 1; | ||||||
|  |         assert(y[4].length == 0); | ||||||
|  |         y[4] = new uint256[](1); | ||||||
|  |         y[4][0] = 2; | ||||||
|  |         assert(y[10].length == 0); | ||||||
|  |         y[10] = new uint256[](1); | ||||||
|  |         y[10][0] = 88; | ||||||
|  |         if ( | ||||||
|  |             (x[0][0] == y[0][0]) && | ||||||
|  |             (x[4][0] == y[4][0]) && | ||||||
|  |             (x[10][0] == 44) && | ||||||
|  |             (y[10][0] == 88) | ||||||
|  |         ) return 7; | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f() -> 7 | ||||||
| @ -0,0 +1,17 @@ | |||||||
|  | contract Lib { | ||||||
|  |     struct S { | ||||||
|  |         uint256 a; | ||||||
|  |         uint256 b; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract Test { | ||||||
|  |     function f() public returns (uint256 r) { | ||||||
|  |         Lib.S memory x = Lib.S({a: 2, b: 3}); | ||||||
|  |         r = x.b; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f() -> 3 | ||||||
							
								
								
									
										10
									
								
								test/libsolidity/semanticTests/extracted/decayed_tuple.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								test/libsolidity/semanticTests/extracted/decayed_tuple.sol
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | contract C { | ||||||
|  |     function f() public returns (uint256) { | ||||||
|  |         uint256 x = 1; | ||||||
|  |         (x) = 2; | ||||||
|  |         return x; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f() -> 2 | ||||||
| @ -0,0 +1,20 @@ | |||||||
|  | // Test for a bug where we did not increment the counter properly while deleting a dynamic array. | ||||||
|  | contract C { | ||||||
|  |     struct S { | ||||||
|  |         uint256 x; | ||||||
|  |         uint256[] y; | ||||||
|  |     } | ||||||
|  |     S[] data; | ||||||
|  | 
 | ||||||
|  |     function f() public returns (bool) { | ||||||
|  |         S storage s1 = data.push(); | ||||||
|  |         s1.x = 2**200; | ||||||
|  |         S storage s2 = data.push(); | ||||||
|  |         s2.x = 2**200; | ||||||
|  |         delete data; | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f() -> true # This code interprets x as an array length and thus will go out of gas. neither of the two should throw due to out-of-bounds access # | ||||||
| @ -0,0 +1,21 @@ | |||||||
|  | contract B { | ||||||
|  |     function f() public returns (uint256) { | ||||||
|  |         return 10; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C is B { | ||||||
|  |     function f(uint256 i) public returns (uint256) { | ||||||
|  |         return 2 * i; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function g() public returns (uint256) { | ||||||
|  |         return f(1); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ==== | ||||||
|  | // compileViaYul: also | ||||||
|  | // ---- | ||||||
|  | // g() -> 2 | ||||||
| @ -0,0 +1,29 @@ | |||||||
|  | contract A { | ||||||
|  |     function f(uint256 a) public returns (uint256) { | ||||||
|  |         return 2 * a; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract B { | ||||||
|  |     function f() public returns (uint256) { | ||||||
|  |         return 10; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | contract C is A, B { | ||||||
|  |     function g() public returns (uint256) { | ||||||
|  |         return f(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function h() public returns (uint256) { | ||||||
|  |         return f(1); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ==== | ||||||
|  | // compileViaYul: also | ||||||
|  | // ---- | ||||||
|  | // g() -> 10 | ||||||
|  | // h() -> 2 | ||||||
| @ -0,0 +1,36 @@ | |||||||
|  | contract C { | ||||||
|  |     uint256 x = 7; | ||||||
|  |     bytes data; | ||||||
|  |     uint256[] y; | ||||||
|  |     uint256[] arrayData; | ||||||
|  | 
 | ||||||
|  |     function returnsArray() public returns (uint256[] memory) { | ||||||
|  |         arrayData = new uint256[](9); | ||||||
|  |         arrayData[2] = 5; | ||||||
|  |         arrayData[7] = 4; | ||||||
|  |         return arrayData; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function f(bytes memory s) public returns (uint256) { | ||||||
|  |         uint256 loc; | ||||||
|  |         uint256[] memory memArray; | ||||||
|  |         (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2); | ||||||
|  |         if (loc != 8) return 1; | ||||||
|  |         if (x != 4) return 2; | ||||||
|  |         if (y.length != 9) return 3; | ||||||
|  |         if (y[2] != 5) return 4; | ||||||
|  |         if (y[7] != 4) return 5; | ||||||
|  |         if (data.length != s.length) return 6; | ||||||
|  |         if (data[3] != s[3]) return 7; | ||||||
|  |         if (arrayData[3] != 2) return 8; | ||||||
|  |         (memArray, loc) = (arrayData, 3); | ||||||
|  |         if (loc != 3) return 9; | ||||||
|  |         if (memArray.length != arrayData.length) return 10; | ||||||
|  |         bytes memory memBytes; | ||||||
|  |         (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415); | ||||||
|  |         if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // f(bytes): 0x20, 0x5, "abcde" -> 0 | ||||||
| @ -0,0 +1,15 @@ | |||||||
|  | contract C { | ||||||
|  |     function div(uint256 a, uint256 b) public returns (uint256) { | ||||||
|  |         return a / b; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function mod(uint256 a, uint256 b) public returns (uint256) { | ||||||
|  |         return a % b; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // div(uint256,uint256): 7, 2 -> 3 | ||||||
|  | // div(uint256,uint256): 7, 0 -> FAILURE # throws # | ||||||
|  | // mod(uint256,uint256): 7, 2 -> 1 | ||||||
|  | // mod(uint256,uint256): 7, 0 -> FAILURE # throws # | ||||||
| @ -0,0 +1,53 @@ | |||||||
|  | contract c { | ||||||
|  |     struct Data { | ||||||
|  |         uint256 x; | ||||||
|  |         uint256 y; | ||||||
|  |     } | ||||||
|  |     Data[] data; | ||||||
|  |     uint256[] ids; | ||||||
|  | 
 | ||||||
|  |     function setIDStatic(uint256 id) public { | ||||||
|  |         ids[2] = id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function setID(uint256 index, uint256 id) public { | ||||||
|  |         ids[index] = id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function setData(uint256 index, uint256 x, uint256 y) public { | ||||||
|  |         data[index].x = x; | ||||||
|  |         data[index].y = y; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function getID(uint256 index) public returns (uint256) { | ||||||
|  |         return ids[index]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function getData(uint256 index) public returns (uint256 x, uint256 y) { | ||||||
|  |         x = data[index].x; | ||||||
|  |         y = data[index].y; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function getLengths() public returns (uint256 l1, uint256 l2) { | ||||||
|  |         l1 = data.length; | ||||||
|  |         l2 = ids.length; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function setLengths(uint256 l1, uint256 l2) public { | ||||||
|  |         while (data.length < l1) data.push(); | ||||||
|  |         while (ids.length < l2) ids.push(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- | ||||||
|  | // getLengths() -> 0, 0 | ||||||
|  | // setLengths(uint256,uint256): 48, 49 -> | ||||||
|  | // getLengths() -> 48, 49 | ||||||
|  | // setIDStatic(uint256): 11 -> | ||||||
|  | // getID(uint256): 2 -> 11 | ||||||
|  | // setID(uint256,uint256): 7, 8 -> | ||||||
|  | // getID(uint256): 7 -> 8 | ||||||
|  | // setData(uint256,uint256,uint256): 7, 8, 9 -> | ||||||
|  | // setData(uint256,uint256,uint256): 8, 10, 11 -> | ||||||
|  | // getData(uint256): 7 -> 8, 9 | ||||||
|  | // getData(uint256): 8 -> 10, 11 | ||||||
| @ -0,0 +1,34 @@ | |||||||
|  | contract c { | ||||||
|  |     uint256[] data; | ||||||
|  | 
 | ||||||
|  |     function enlarge(uint256 amount) public returns (uint256) { | ||||||
|  |         while (data.length < amount) data.push(); | ||||||
|  |         return data.length; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function set(uint256 index, uint256 value) public returns (bool) { | ||||||
|  |         data[index] = value; | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function get(uint256 index) public returns (uint256) { | ||||||
|  |         return data[index]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function length() public returns (uint256) { | ||||||
|  |         return data.length; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ==== | ||||||
|  | // compileViaYul: also | ||||||
|  | // ---- | ||||||
|  | // length() -> 0 | ||||||
|  | // get(uint256): 3 -> FAILURE | ||||||
|  | // enlarge(uint256): 4 -> 4 | ||||||
|  | // length() -> 4 | ||||||
|  | // set(uint256,uint256): 3, 4 -> true | ||||||
|  | // get(uint256): 3 -> 4 | ||||||
|  | // length() -> 4 | ||||||
|  | // set(uint256,uint256): 4, 8 -> FAILURE | ||||||
|  | // length() -> 4 | ||||||
| @ -0,0 +1,10 @@ | |||||||
|  | contract test { | ||||||
|  |     function f(uint256 k) public returns (uint256) { | ||||||
|  |         return k; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ==== | ||||||
|  | // compileViaYul: also | ||||||
|  | // ---- | ||||||
|  | // f(uint256): 9 -> 9 | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user