summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-11-21 15:19:45 +0100
committerRoland Reichwein <mail@reichwein.it>2020-11-21 15:19:45 +0100
commit7edbd99775416a32c88acf8e9379518436905f02 (patch)
tree6356edb79f846df4aa2f6a8a5ecfeef4e651bcc0
parent7250bbe5ae2d2ee6b0334bc462aab73f7d8dac0e (diff)
Support gcc 10 and clang 11
-rw-r--r--Makefile46
-rw-r--r--TODO3
-rw-r--r--asm/intel64/div.cpp18
-rw-r--r--asm/intel64/encode.cpp41
-rw-r--r--asm/intel64/mul.cpp18
-rw-r--r--asm/parse.cpp7
-rw-r--r--cpp.cpp17
-rw-r--r--cpp.h1
-rw-r--r--cppbnf.cpp7
-rw-r--r--debian/control21
-rw-r--r--flowgraph/data.h1
-rw-r--r--grammer.cpp16
-rw-r--r--grammer.h4
-rw-r--r--programopts.cpp2
-rw-r--r--systemtest/config/unix.exp6
-rw-r--r--systemtest/mcc-execute.tests/exitcodes.exp3
-rw-r--r--systemtest/mcc-execute.tests/test-division.cpp1
-rw-r--r--systemtest/mcc-execute.tests/test-modulo.cpp1
-rw-r--r--systemtest/mcc-execute.tests/test-multiplication.cpp1
-rw-r--r--tests/test-asm.cpp60
-rw-r--r--tests/test-cpp.cpp14
-rw-r--r--tests/test-elf.cpp4
-rw-r--r--tests/test-grammer.cpp32
-rw-r--r--tests/test-lexer.cpp2
24 files changed, 224 insertions, 102 deletions
diff --git a/Makefile b/Makefile
index 75df413..5247017 100644
--- a/Makefile
+++ b/Makefile
@@ -1,24 +1,20 @@
PROJECTNAME=minicc
-CXX=clang++-10
-#CXX=g++-9
+CXX=clang++-11
+#CXX=g++-10
-#CXXFLAGS=-O2 -DNDEBUG
-CXXFLAGS=-O0 -g -D_DEBUG
+CXXFLAGS=-O2 -DNDEBUG
+#CXXFLAGS=-O0 -g -D_DEBUG
# -fprofile-instr-generate -fcoverage-mapping
# gcc:--coverage
-CXXFLAGS+= -Wall -I.
+CXXFLAGS+= -Wall -I. -std=c++20
-ifeq ($(CXX),clang++-10)
-# broken with lld-8:
-# ld.lld-8: error: undefined symbol: boost::re_detail_106700::cpp_regex_traits_implementation<char>::transform(char const*, char const*) const
-CXXFLAGS+=-std=c++20 -stdlib=libc++
-else
-CXXFLAGS+=-std=c++2a
+ifeq ($(CXX),clang++-11)
+CXXFLAGS+=-stdlib=libc++
endif
-CXXTESTFLAGS=-Igoogletest/include -Igooglemock/include/ -Igoogletest -Igooglemock
+CXXTESTFLAGS+=-Igoogletest/include -Igooglemock/include/ -Igoogletest -Igooglemock
LIBS=\
-lboost_context \
@@ -30,9 +26,9 @@ LIBS=\
-lboost_regex \
-lpthread
-ifeq ($(CXX),clang++-10)
+ifeq ($(CXX),clang++-11)
LIBS+= \
--fuse-ld=lld-10 \
+-fuse-ld=lld-11 \
-lc++ \
-lc++abi
#-lc++fs
@@ -98,6 +94,7 @@ PROGSRC=\
programopts.cpp
TESTSRC=\
+ tests/test-asm.cpp \
tests/test-cpp.cpp \
tests/test-cppbnf.cpp \
tests/test-elf.cpp \
@@ -105,7 +102,6 @@ TESTSRC=\
tests/test-grammer.cpp \
tests/test-lexer.cpp \
tests/test-minicc.cpp \
- tests/test-asm.cpp \
googlemock/src/gmock-all.cpp \
googletest/src/gtest-all.cpp \
$(PROGSRC)
@@ -116,26 +112,24 @@ all: mcc
test: unittest systemtest
+check: test
+
# Tests on C++ level
unittest: test-$(PROJECTNAME)
./test-$(PROJECTNAME) #--gtest_filter='CppTest.compile_parentheses_right'
# Testing mcc executable and compiled elf programs
systemtest: mcc
- ./mcc systemtest/mcc-execute.tests/test-return-1.cpp
- ./mcc systemtest/mcc-execute.tests/test-addition.cpp
runtest --srcdir systemtest --tool mcc # --all
# testsuite ----------------------------------------------
-test-$(PROJECTNAME): $(TESTSRC:.cpp=.o)
- $(CXX) $(CXXFLAGS) $^ $(LIBS) -o $@
+test-$(PROJECTNAME): dep $(TESTSRC:.cpp=.o)
+ $(CXX) $(CXXFLAGS) $(TESTSRC:.cpp=.o) $(LIBS) -o $@
-mcc: $(SRC:.cpp=.o)
- $(CXX) $(CXXFLAGS) $^ $(LIBS) -o $@
+mcc: dep $(SRC:.cpp=.o)
+ $(CXX) $(CXXFLAGS) $(SRC:.cpp=.o) $(LIBS) -o $@
-dep:
- -rm -f $(TESTSRC:.cpp=.d) mcc.d
- $(MAKE) $(TESTSRC:.cpp=.d) mcc.d
+dep: $(TESTSRC:.cpp=.d) mcc.d
%.d: %.cpp
$(CXX) $(CXXFLAGS) $(CXXTESTFLAGS) -MM -MP -MF $@ -MT $(*D)/$(*F).o -c $<
@@ -154,8 +148,6 @@ ADD_DEP=Makefile
clean:
-rm -f test-$(PROJECTNAME) mcc tempfile.txt
-find . -name '*.o' -o -name '*.d' -o -name '*.gcno' -o -name '*.gcda' | xargs rm -f
- -rm -f systemtest/mcc-execute.tests/test-return-1
- -rm -f systemtest/mcc-execute.tests/test-addition
-rm -f *.log *.sum
zip: clean
@@ -163,6 +155,6 @@ zip: clean
zip -r ../$(PROJECTNAME).zip *
ls -l ../$(PROJECTNAME).zip
-.PHONY: clean all zip dep systemtest unittest
+.PHONY: clean all zip dep test check systemtest unittest
-include $(wildcard $(SRC:.cpp=.d))
diff --git a/TODO b/TODO
index 3c8bc93..6f10842 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,3 @@
-encode.cpp: UnaryOperation
-asm parser
-
Fix stack
grammer.cpp: match() : return point of match error ("Compile error")
diff --git a/asm/intel64/div.cpp b/asm/intel64/div.cpp
index 9ca24e9..1e98b7b 100644
--- a/asm/intel64/div.cpp
+++ b/asm/intel64/div.cpp
@@ -20,6 +20,15 @@ Op_div::Op_div(const Asm::Args& args)
} else if (args[0].type() == typeid(Asm::Args::Register64)) { // div reg64 (accu is rax (remainder=rdx) <- rdx:rax / reg64)
machine_code = REX("W") + std::vector<uint8_t>{ 0xF7 } +
ModRM("/6", std::any_cast<Asm::Args::Register64>(args[0]).name());
+ } else if (args[0].type() == typeid(Asm::Args::Mem8Ptr64)) { // div byte ptr [reg64] (accu is al (remainder=ah) <- ah / x)
+ machine_code = std::vector<uint8_t>{ 0xF6 } +
+ ModRM("/6", std::any_cast<Asm::Args::Mem8Ptr64>(args[0]).reg());
+ } else if (args[0].type() == typeid(Asm::Args::Mem32Ptr64)) { // div dword ptr [reg64] (accu is eax (remainder=edx) <- edx:eax / x)
+ machine_code = std::vector<uint8_t>{ 0xF7 } +
+ ModRM("/6", std::any_cast<Asm::Args::Mem32Ptr64>(args[0]).reg());
+ } else if (args[0].type() == typeid(Asm::Args::Mem64Ptr64)) { // div qword ptr [reg64] (accu is rax (remainder=rdx) <- rdx:rax / x)
+ machine_code = REX("W") + std::vector<uint8_t>{ 0xF7 } +
+ ModRM("/6", std::any_cast<Asm::Args::Mem64Ptr64>(args[0]).reg());
} else {
throw std::runtime_error("Unimplemented: div "s + args[0].type().name());
}
@@ -36,6 +45,15 @@ bool registered {
}) &&
registerOp(mangleName<Asm::Args::Register64>("div"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_div>(args);
+ }) &&
+ registerOp(mangleName<Asm::Args::Mem8Ptr64>("div"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
+ return std::make_shared<Op_div>(args);
+ }) &&
+ registerOp(mangleName<Asm::Args::Mem32Ptr64>("div"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
+ return std::make_shared<Op_div>(args);
+ }) &&
+ registerOp(mangleName<Asm::Args::Mem64Ptr64>("div"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
+ return std::make_shared<Op_div>(args);
})
};
diff --git a/asm/intel64/encode.cpp b/asm/intel64/encode.cpp
index 1b35d89..a2434fd 100644
--- a/asm/intel64/encode.cpp
+++ b/asm/intel64/encode.cpp
@@ -114,6 +114,36 @@ std::vector<std::shared_ptr<Chunk>> makeMulValue(const FlowGraph::Data& data, co
throw std::runtime_error("ICE: Unsupported type for operand data at mul: "s + demangle(typeid(data_storage)));
}
+std::vector<std::shared_ptr<Chunk>> makeDivValue(const FlowGraph::Data& data, const FlowGraph::Graph& graph)
+{
+ if (data.type() != FlowGraph::DataType::Int) {
+ throw std::runtime_error("Bad type for operand: "s + std::to_string(int(data.type())));
+ }
+
+ if (!data.storage())
+ throw std::runtime_error("ICE: Operand storage is 0");
+
+ auto& data_storage{*data.storage()};
+ if (typeid(data_storage) == typeid(FlowGraph::Constant)) {
+ FlowGraph::Constant& value {dynamic_cast<FlowGraph::Constant&>(data_storage)};
+ if (value.value().size() < sizeof(uint32_t))
+ throw std::runtime_error("ICE: Int data from operand needs at least 4 bytes, got "s + std::to_string(value.value().size()));
+
+ uint32_t immediate = from_little_endian(value.value());
+
+ return {{
+ makeOp("mov", Asm::Args{{Asm::Args::Register32("ebx"), Asm::Args::Immediate32(immediate)}}),
+ makeOp("div", Asm::Args{{Asm::Args::Register32("ebx")}})
+ }};
+ } else if (typeid(data_storage) == typeid(FlowGraph::TemporaryStorage)) {
+ //FlowGraph::TemporaryStorage& storage {dynamic_cast<FlowGraph::TemporaryStorage&>(data_storage)};
+
+ index_t index { graph.scope()->indexOfData(data)};
+ return {{makeOp("div", Asm::Args{{Asm::Args::Mem32Ptr64("rbp", int32_t(index) * -4)}})}};
+ } else
+ throw std::runtime_error("ICE: Unsupported type for operand data at div: "s + demangle(typeid(data_storage)));
+}
+
} // namespace
void Asm::toMachineCode(const FlowGraph::Graph& graph, Segment& segment)
@@ -165,6 +195,17 @@ void Asm::toMachineCode(const FlowGraph::Graph& graph, Segment& segment)
segment.push_back(makeLoadValue(operands[1], graph));
segment.append(makeMulValue(operands[2], graph));
segment.push_back(makeStoreValue(operands[0], graph));
+ } else if (op.type() == FlowGraph::BinaryOperationType::Divide) {
+ segment.push_back(makeLoadValue(operands[1], graph));
+ segment.append(parseAsm("xor edx, edx"));
+ segment.append(makeDivValue(operands[2], graph));
+ segment.push_back(makeStoreValue(operands[0], graph));
+ } else if (op.type() == FlowGraph::BinaryOperationType::Modulo) {
+ segment.push_back(makeLoadValue(operands[1], graph));
+ segment.append(parseAsm("xor edx, edx"));
+ segment.append(makeDivValue(operands[2], graph));
+ segment.append(parseAsm("mov eax, edx")); // remainder is in edx
+ segment.push_back(makeStoreValue(operands[0], graph));
} else
throw std::runtime_error("ICE: Asm: Unsupported binary operation type: "s + std::to_string(static_cast<int>(op.type())));
diff --git a/asm/intel64/mul.cpp b/asm/intel64/mul.cpp
index 502b1d9..5825e2a 100644
--- a/asm/intel64/mul.cpp
+++ b/asm/intel64/mul.cpp
@@ -20,6 +20,15 @@ Op_mul::Op_mul(const Asm::Args& args)
} else if (args[0].type() == typeid(Asm::Args::Register64)) { // mul reg64 (accu is rdx:rax <- rax)
machine_code = REX("W") + std::vector<uint8_t>{ 0xF7 } +
ModRM("/4", std::any_cast<Asm::Args::Register64>(args[0]).name());
+ } else if (args[0].type() == typeid(Asm::Args::Mem8Ptr64)) { // mul byte ptr [reg64] (accu is ax <- al)
+ machine_code = std::vector<uint8_t>{ 0xF6 } +
+ ModRM("/4", std::any_cast<Asm::Args::Mem8Ptr64>(args[0]).reg());
+ } else if (args[0].type() == typeid(Asm::Args::Mem32Ptr64)) { // mul dword ptr [reg64] (accu is edx:eax <- eax)
+ machine_code = std::vector<uint8_t>{ 0xF7 } +
+ ModRM("/4", std::any_cast<Asm::Args::Mem32Ptr64>(args[0]).reg());
+ } else if (args[0].type() == typeid(Asm::Args::Mem64Ptr64)) { // mul qword ptr [reg64] (accu is rdx:rax <- rax)
+ machine_code = REX("W") + std::vector<uint8_t>{ 0xF7 } +
+ ModRM("/4", std::any_cast<Asm::Args::Mem64Ptr64>(args[0]).reg());
} else {
throw std::runtime_error("Unimplemented: mul "s + args[0].type().name());
}
@@ -36,6 +45,15 @@ bool registered {
}) &&
registerOp(mangleName<Asm::Args::Register64>("mul"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_mul>(args);
+ }) &&
+ registerOp(mangleName<Asm::Args::Mem8Ptr64>("mul"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
+ return std::make_shared<Op_mul>(args);
+ }) &&
+ registerOp(mangleName<Asm::Args::Mem32Ptr64>("mul"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
+ return std::make_shared<Op_mul>(args);
+ }) &&
+ registerOp(mangleName<Asm::Args::Mem64Ptr64>("mul"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
+ return std::make_shared<Op_mul>(args);
})
};
diff --git a/asm/parse.cpp b/asm/parse.cpp
index 8f6f831..28e79f3 100644
--- a/asm/parse.cpp
+++ b/asm/parse.cpp
@@ -20,6 +20,13 @@ namespace {
"dl", "dh",
};
+ std::unordered_set<std::string> reg16 {
+ "ax", "sp",
+ "bx", "bp",
+ "cx", "si",
+ "dx", "di",
+ };
+
std::unordered_set<std::string> reg32 {
"eax", "esp",
"ebx", "ebp",
diff --git a/cpp.cpp b/cpp.cpp
index 837eae9..61fdc0e 100644
--- a/cpp.cpp
+++ b/cpp.cpp
@@ -10,9 +10,6 @@
#include "grammer.h"
#include "minicc.h"
-#include <gtest/gtest.h>
-#include <gmock/gmock.h>
-
#include <boost/core/demangle.hpp>
#include <functional>
@@ -399,7 +396,7 @@ std::unordered_map<std::string, std::function<std::any(index_t)>> CPP::getNodeEv
},
{ "multiplicative-expression", [&](index_t index) -> std::any
{
- if (childTypesOfNodeMatch(index, {"multiplicative-expression", "*", "pm-expression"})) {
+ if (childTypesOfNodeMatch(index, {"multiplicative-expression", "", "pm-expression"})) {
if (getValue(index, 0).type() != typeid(FlowGraph::Graph))
throw std::runtime_error("ICE: multiplicative-expression: Bad data type for argument 1: "s + demangle(getValue(index, 0).type()));
if (getValue(index, 2).type() != typeid(FlowGraph::Graph))
@@ -416,7 +413,17 @@ std::unordered_map<std::string, std::function<std::any(index_t)>> CPP::getNodeEv
FlowGraph::Data destination{FlowGraph::MakeTemporaryInt(result.scope())};
- std::shared_ptr<FlowGraph::Node> node {std::make_shared<FlowGraph::BinaryOperation>(FlowGraph::BinaryOperationType::Multiply,
+ FlowGraph::BinaryOperationType type{};
+ if (getType(index, 1) == "*")
+ type = FlowGraph::BinaryOperationType::Multiply;
+ else if (getType(index, 1) == "/")
+ type = FlowGraph::BinaryOperationType::Divide;
+ else if (getType(index, 1) == "%")
+ type = FlowGraph::BinaryOperationType::Modulo;
+ else
+ throw std::runtime_error("ICE: multiplicative-expression: Unknown operand: "s + getType(index, 1));
+
+ std::shared_ptr<FlowGraph::Node> node {std::make_shared<FlowGraph::BinaryOperation>(type,
destination,
lastOp0->destination(), lastOp1->destination())};
diff --git a/cpp.h b/cpp.h
index 11588b8..3207ef9 100644
--- a/cpp.h
+++ b/cpp.h
@@ -7,6 +7,7 @@
#include <any>
#include <deque>
+#include <functional>
#include <memory>
#include <vector>
diff --git a/cppbnf.cpp b/cppbnf.cpp
index 7e8ec15..3fddb66 100644
--- a/cppbnf.cpp
+++ b/cppbnf.cpp
@@ -7,9 +7,6 @@
#include <boost/algorithm/string/predicate.hpp>
-#include <gtest/gtest.h>
-#include <gmock/gmock.h>
-
using namespace std::string_literals;
namespace {
@@ -123,7 +120,7 @@ namespace {
void resolveOptional(std::vector<std::vector<std::string>>& lists)
{
- for (int i = 0; i < lists.size(); i++) {
+ for (size_t i = 0; i < lists.size(); i++) {
if (containsOptional(lists[i])) {
auto insertList = resolveOptional(lists[i]);
// replace element i with new list
@@ -150,7 +147,7 @@ namespace {
// vectorize terminal symbols
for (auto& [symbol, lists] : bnf) {
for (auto& list : lists) {
- for (int i = 0; i < list.size(); i++) {
+ for (size_t i = 0; i < list.size(); i++) {
if (list[i].size() > 1 && isTerminal(bnf, list[i])) {
auto newList = vectorize(list[i]);
list.erase(list.begin() + i);
diff --git a/debian/control b/debian/control
index 181df4a..3a18e3d 100644
--- a/debian/control
+++ b/debian/control
@@ -1 +1,20 @@
-Depends: dejagnu, expect
+Source: minicc
+Section: devel
+Priority: optional
+Maintainer: Roland Reichwein <mail@reichwein.it>
+Build-Depends: debhelper (>= 12), libboost-all-dev, clang | g++-10, dejagnu, expect
+Standards-Version: 4.5.0
+Homepage: http://www.reichwein.it/minicc/
+
+Package: minicc
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends},
+Homepage: http://www.reichwein.it/minicc/
+Description: Simple Compiler
+ Minicc is a simple C++20 compiler.
+ .
+ Features:
+ - C++ Front End
+ - Incomplete feature set of C++20
+ - Assembler
+ - Intel 64 backend
diff --git a/flowgraph/data.h b/flowgraph/data.h
index e2def93..a52627d 100644
--- a/flowgraph/data.h
+++ b/flowgraph/data.h
@@ -3,6 +3,7 @@
#pragma once
#include <cstdint>
+#include <memory>
#include <vector>
namespace FlowGraph {
diff --git a/grammer.cpp b/grammer.cpp
index 4af1fd4..f949e2a 100644
--- a/grammer.cpp
+++ b/grammer.cpp
@@ -46,6 +46,16 @@ int32_t Gram::ChildIdFromTokenId(index_t token_id)
return -1 - int32_t(token_id);
}
+index_t Gram::NodeIdFromChildId(int32_t child_id)
+{
+ return static_cast<index_t>(child_id);
+}
+
+int32_t Gram::ChildIdFromNodeId(index_t node_id)
+{
+ return static_cast<int32_t>(node_id);
+}
+
void Compiler::DumpTree()
{
Debug("= Dump =======================================");
@@ -73,7 +83,7 @@ void Compiler::DumpTree()
todo.pop_front();
std::string line;
- for (int i = 0; i < indent; i++)
+ for (size_t i = 0; i < indent; i++)
line += "| ";
if (ChildIdIsToken(current_index)) {
index_t token_id {TokenIdFromChildId(current_index)};
@@ -85,7 +95,7 @@ void Compiler::DumpTree()
line += "Node("s + std::to_string(current_index) + "): "s + node.type + "/" + std::to_string(node.variant);
auto child_ids{node.child_ids};
- for (int i = 0; i < child_ids.size(); i++) {
+ for (size_t i = 0; i < child_ids.size(); i++) {
todo.insert(todo.begin() + i, std::pair<int32_t, size_t>{child_ids[i], indent + 1});
}
}
@@ -405,7 +415,7 @@ namespace {
if (ChildIdIsToken(child_id)) // token can't be ext node
return false;
- if (child_id >= nodes.size())
+ if (NodeIdFromChildId(child_id) >= nodes.size())
throw std::runtime_error("Child node out of range at ext node detection: "s + std::to_string(child_id) + " vs. "s + std::to_string(nodes.size()));
return nodes[child_id].type.ends_with("-EXT");
diff --git a/grammer.h b/grammer.h
index 90f9e87..5c80d57 100644
--- a/grammer.h
+++ b/grammer.h
@@ -102,5 +102,9 @@ bool ChildIdIsNode(int32_t child_id); // identity
index_t TokenIdFromChildId(int32_t child_id);
int32_t ChildIdFromTokenId(index_t token_id);
+// only convenience functions
+index_t NodeIdFromChildId(int32_t child_id);
+int32_t ChildIdFromNodeId(index_t node_id);
+
} // namespace Gram
diff --git a/programopts.cpp b/programopts.cpp
index aee8b05..611bbea 100644
--- a/programopts.cpp
+++ b/programopts.cpp
@@ -40,7 +40,7 @@ ProgramOpts::~ProgramOpts()
void ProgramOpts::process()
{
- for (size_t i = 1; i < m_pimpl->m_argc; i++) {
+ for (int i = 1; i < m_pimpl->m_argc; i++) {
std::string arg{ m_pimpl->m_argv[i] };
if (arg.size() == 0)
throw std::runtime_error("Empty option #"s + std::to_string(i));
diff --git a/systemtest/config/unix.exp b/systemtest/config/unix.exp
index 2de93b0..1bd9310 100644
--- a/systemtest/config/unix.exp
+++ b/systemtest/config/unix.exp
@@ -1,9 +1,13 @@
proc runtest_exit_code { test_name command_line exit_code } {
+ exec ./mcc $command_line.cpp
+
spawn $command_line
expect eof
-
+
+ exec rm $command_line
+
lassign [wait] pid spawnid os_error_flag value
if {$os_error_flag == 0} {
diff --git a/systemtest/mcc-execute.tests/exitcodes.exp b/systemtest/mcc-execute.tests/exitcodes.exp
index 48d19a1..0480be8 100644
--- a/systemtest/mcc-execute.tests/exitcodes.exp
+++ b/systemtest/mcc-execute.tests/exitcodes.exp
@@ -2,4 +2,7 @@
runtest_exit_code "Return 1" "systemtest/mcc-execute.tests/test-return-1" 1
runtest_exit_code "Addition" "systemtest/mcc-execute.tests/test-addition" 3
+runtest_exit_code "Multiplication" "systemtest/mcc-execute.tests/test-multiplication" 6
+runtest_exit_code "Division" "systemtest/mcc-execute.tests/test-division" 2
+runtest_exit_code "Modulo" "systemtest/mcc-execute.tests/test-modulo" 1
diff --git a/systemtest/mcc-execute.tests/test-division.cpp b/systemtest/mcc-execute.tests/test-division.cpp
new file mode 100644
index 0000000..21fc59f
--- /dev/null
+++ b/systemtest/mcc-execute.tests/test-division.cpp
@@ -0,0 +1 @@
+int main() { return 6 / 3; }
diff --git a/systemtest/mcc-execute.tests/test-modulo.cpp b/systemtest/mcc-execute.tests/test-modulo.cpp
new file mode 100644
index 0000000..c20fe78
--- /dev/null
+++ b/systemtest/mcc-execute.tests/test-modulo.cpp
@@ -0,0 +1 @@
+int main() { return 7 % 3; }
diff --git a/systemtest/mcc-execute.tests/test-multiplication.cpp b/systemtest/mcc-execute.tests/test-multiplication.cpp
new file mode 100644
index 0000000..d510f96
--- /dev/null
+++ b/systemtest/mcc-execute.tests/test-multiplication.cpp
@@ -0,0 +1 @@
+int main() { return 2 * 3; }
diff --git a/tests/test-asm.cpp b/tests/test-asm.cpp
index 019f89c..650a48a 100644
--- a/tests/test-asm.cpp
+++ b/tests/test-asm.cpp
@@ -57,7 +57,7 @@ TEST_F(AsmTest, Intel64_add) {
Asm::Args args{{Asm::Args::Register32("eax"), Asm::Args::Immediate32(1)}};
segment.push_back(makeOp("add", args));
- ASSERT_EQ(segment.size(), 1);
+ ASSERT_EQ(segment.size(), size_t(1));
ASSERT_EQ(segment.getCode(), std::vector<uint8_t>({0x05, 0x01, 0x00, 0x00, 0x00}));
}
@@ -66,7 +66,7 @@ TEST_F(AsmTest, Intel64_int_0) {
Asm::Args args{{Asm::Args::Immediate8(0)}};
segment.push_back(makeOp("int", args));
- ASSERT_EQ(segment.size(), 1);
+ ASSERT_EQ(segment.size(), size_t(1));
ASSERT_EQ(segment.getCode(), std::vector<uint8_t>{0xCE});
}
@@ -75,7 +75,7 @@ TEST_F(AsmTest, Intel64_int_1) {
Asm::Args args{{Asm::Args::Immediate8(1)}};
segment.push_back(makeOp("int", args));
- ASSERT_EQ(segment.size(), 1);
+ ASSERT_EQ(segment.size(), size_t(1));
ASSERT_EQ(segment.getCode(), std::vector<uint8_t>{0xF1});
}
@@ -84,7 +84,7 @@ TEST_F(AsmTest, Intel64_int_5) {
Asm::Args args{{Asm::Args::Immediate8(5)}};
segment.push_back(makeOp("int", args));
- ASSERT_EQ(segment.size(), 1);
+ ASSERT_EQ(segment.size(), size_t(1));
ASSERT_EQ(segment.getCode(), std::vector<uint8_t>({0xCD, 0x05}));
}
@@ -92,7 +92,7 @@ TEST_F(AsmTest, Intel64_nop) {
Segment segment;
segment.push_back(makeOp("nop"));
- ASSERT_EQ(segment.size(), 1);
+ ASSERT_EQ(segment.size(), size_t(1));
ASSERT_EQ(segment.getCode(), std::vector<uint8_t>{0x90});
}
@@ -100,7 +100,7 @@ TEST_F(AsmTest, Intel64_ret) {
Segment segment;
segment.push_back(makeOp("ret"));
- ASSERT_EQ(segment.size(), 1);
+ ASSERT_EQ(segment.size(), size_t(1));
ASSERT_EQ(segment.getCode(), std::vector<uint8_t>{0xC3});
}
@@ -119,7 +119,7 @@ TEST_F(AsmTest, Intel64_multiple) {
segment.insertAddresses();
- ASSERT_EQ(segment.size(), 7);
+ ASSERT_EQ(segment.size(), size_t(7));
ASSERT_EQ(segment.getCode(), std::vector<uint8_t>(
{
0x90, // nop
@@ -133,7 +133,7 @@ TEST_F(AsmTest, Intel64_multiple) {
segment.optimize();
- ASSERT_EQ(segment.size(), 7);
+ ASSERT_EQ(segment.size(), size_t(7));
ASSERT_EQ(segment.getCode(), std::vector<uint8_t>(
{
0x90, // nop
@@ -148,38 +148,38 @@ TEST_F(AsmTest, Intel64_multiple) {
TEST_F(AsmParseTest, parse_empty) {
std::vector<std::shared_ptr<Chunk>> chunks0{parseAsm("")};
- ASSERT_EQ(chunks0.size(), 0);
+ ASSERT_EQ(chunks0.size(), 0u);
std::vector<std::shared_ptr<Chunk>> chunks1{parseAsm("\n\n")};
- ASSERT_EQ(chunks1.size(), 0);
+ ASSERT_EQ(chunks1.size(), 0u);
std::vector<std::shared_ptr<Chunk>> chunks2{parseAsm("\n\n")};
- ASSERT_EQ(chunks2.size(), 0);
+ ASSERT_EQ(chunks2.size(), 0u);
}
TEST_F(AsmParseTest, parse_op_0) {
std::vector<std::shared_ptr<Chunk>> chunks0{parseAsm("nop")};
- ASSERT_EQ(chunks0.size(), 1);
+ ASSERT_EQ(chunks0.size(), 1u);
}
TEST_F(AsmParseTest, parse_op_1) {
std::vector<std::shared_ptr<Chunk>> chunks1{parseAsm("neg edi")};
- ASSERT_EQ(chunks1.size(), 1);
+ ASSERT_EQ(chunks1.size(), 1u);
}
TEST_F(AsmParseTest, parse_op_2) {
std::vector<std::shared_ptr<Chunk>> chunks2{parseAsm("add eax, edx")};
- ASSERT_EQ(chunks2.size(), 1);
+ ASSERT_EQ(chunks2.size(), 1u);
}
TEST_F(AsmParseTest, parse_op_3) {
std::vector<std::shared_ptr<Chunk>> chunks3{parseAsm("add eax, 3")};
- ASSERT_EQ(chunks3.size(), 1);
+ ASSERT_EQ(chunks3.size(), 1u);
}
TEST_F(AsmParseTest, parse_op_4) {
std::vector<std::shared_ptr<Chunk>> chunks4{parseAsm("add [rdi], 3")};
- ASSERT_EQ(chunks4.size(), 1);
+ ASSERT_EQ(chunks4.size(), 1u);
}
TEST_F(AsmParseTest, parse_op_4_error) {
@@ -188,7 +188,7 @@ TEST_F(AsmParseTest, parse_op_4_error) {
TEST_F(AsmParseTest, parse_op_5) {
std::vector<std::shared_ptr<Chunk>> chunks5{parseAsm("add byte ptr [rdi], 3")};
- ASSERT_EQ(chunks5.size(), 1);
+ ASSERT_EQ(chunks5.size(), 1u);
}
TEST_F(AsmParseTest, parse_op_5_error) {
@@ -197,7 +197,7 @@ TEST_F(AsmParseTest, parse_op_5_error) {
TEST_F(AsmParseTest, parse_op_6) {
std::vector<std::shared_ptr<Chunk>> chunks6{parseAsm("add dword ptr[rdi], 3")};
- ASSERT_EQ(chunks6.size(), 1);
+ ASSERT_EQ(chunks6.size(), 1u);
}
TEST_F(AsmParseTest, parse_op_6_error) {
@@ -206,46 +206,46 @@ TEST_F(AsmParseTest, parse_op_6_error) {
TEST_F(AsmParseTest, parse_op_7) {
std::vector<std::shared_ptr<Chunk>> chunks7{parseAsm("add qword ptr[rdi], 3")};
- ASSERT_EQ(chunks7.size(), 1);
+ ASSERT_EQ(chunks7.size(), 1u);
}
TEST_F(AsmParseTest, parse_label) {
std::vector<std::shared_ptr<Chunk>> chunks0{parseAsm("label1:")};
- ASSERT_EQ(chunks0.size(), 1);
+ ASSERT_EQ(chunks0.size(), 1u);
std::vector<std::shared_ptr<Chunk>> chunks1{parseAsm("label2: add eax, 3")};
- ASSERT_EQ(chunks1.size(), 2);
+ ASSERT_EQ(chunks1.size(), 2u);
}
TEST_F(AsmParseTest, parse_multiline) {
std::vector<std::shared_ptr<Chunk>> chunks1{parseAsm("add eax, 3\n")};
- ASSERT_EQ(chunks1.size(), 1);
+ ASSERT_EQ(chunks1.size(), 1u);
std::vector<std::shared_ptr<Chunk>> chunks2{parseAsm("label2: add eax, 3\n mul rdx")};
- ASSERT_EQ(chunks2.size(), 3);
+ ASSERT_EQ(chunks2.size(), 3u);
std::vector<std::shared_ptr<Chunk>> chunks3{parseAsm("label2: add eax, 3\n mul rdx\n")};
- ASSERT_EQ(chunks3.size(), 3);
+ ASSERT_EQ(chunks3.size(), 3u);
std::vector<std::shared_ptr<Chunk>> chunks4{parseAsm("label2: add eax, 3\n\n\n mul rdx")};
- ASSERT_EQ(chunks4.size(), 3);
+ ASSERT_EQ(chunks4.size(), 3u);
}
TEST_F(AsmParseTest, parse_comment) {
std::vector<std::shared_ptr<Chunk>> chunks0{parseAsm(" ; Comment 1")};
- ASSERT_EQ(chunks0.size(), 0);
+ ASSERT_EQ(chunks0.size(), 0u);
std::vector<std::shared_ptr<Chunk>> chunks1{parseAsm("label2: add eax, 3 ; A comment")};
- ASSERT_EQ(chunks1.size(), 2);
+ ASSERT_EQ(chunks1.size(), 2u);
std::vector<std::shared_ptr<Chunk>> chunks3{parseAsm("label2: add eax, 3 // Another comment")};
- ASSERT_EQ(chunks3.size(), 2);
+ ASSERT_EQ(chunks3.size(), 2u);
std::vector<std::shared_ptr<Chunk>> chunks4{parseAsm("label2: add eax, 3 // Another comment\nadd rax, rdi")};
- ASSERT_EQ(chunks4.size(), 3);
+ ASSERT_EQ(chunks4.size(), 3u);
std::vector<std::shared_ptr<Chunk>> chunks5{parseAsm("label2: add eax, 3 // Another comment\n \t add rax, rdi")};
- ASSERT_EQ(chunks5.size(), 3);
+ ASSERT_EQ(chunks5.size(), 3u);
}
TEST_F(AsmParseTest, parse_error) {
diff --git a/tests/test-cpp.cpp b/tests/test-cpp.cpp
index 2e1b29e..d4e8c66 100644
--- a/tests/test-cpp.cpp
+++ b/tests/test-cpp.cpp
@@ -34,30 +34,30 @@ TEST_F(CppTest, preprocessing_tokenize) {
CPP cpp;
auto pp_tokens = cpp.preprocessing_tokenize("int main() { return 1; }");
- ASSERT_EQ(pp_tokens.size(), 9);
+ ASSERT_EQ(pp_tokens.size(), size_t(9));
auto tokens = cpp.tokens_from_pptokens(pp_tokens);
- ASSERT_EQ(tokens.size(), 9);
+ ASSERT_EQ(tokens.size(), size_t(9));
auto nodes = cpp.analysis(tokens);
- ASSERT_EQ(nodes.size(), 43);
+ ASSERT_EQ(nodes.size(), size_t(43));
}
TEST_F(CppTest, preprocessing_tokenize_empty) {
CPP cpp;
auto pp_tokens = cpp.preprocessing_tokenize("");
- ASSERT_EQ(pp_tokens.size(), 0);
+ ASSERT_EQ(pp_tokens.size(), size_t(0));
auto tokens = cpp.tokens_from_pptokens(pp_tokens);
- ASSERT_EQ(tokens.size(), 0);
+ ASSERT_EQ(tokens.size(), size_t(0));
auto nodes = cpp.analysis(tokens);
- ASSERT_EQ(nodes.size(), 1);
+ ASSERT_EQ(nodes.size(), size_t(1));
ASSERT_EQ(nodes[0].type, "translation-unit");
}
@@ -68,7 +68,7 @@ TEST_F(CppTest, preprocessing_tokenize_compile_error) {
auto tokens = cpp.tokens_from_pptokens(ppTree);
- ASSERT_EQ(tokens.size(), 2);
+ ASSERT_EQ(tokens.size(), size_t(2));
try {
auto nodes = cpp.analysis(tokens);
diff --git a/tests/test-elf.cpp b/tests/test-elf.cpp
index 0bf1d42..737ba65 100644
--- a/tests/test-elf.cpp
+++ b/tests/test-elf.cpp
@@ -53,7 +53,7 @@ TEST_F(ElfTest, write_code) {
}, {});
ASSERT_TRUE(fs::exists(TempFilename()));
- ASSERT_GT(fs::file_size(TempFilename()), 0);
+ ASSERT_GT(fs::file_size(TempFilename()), size_t(0));
}
TEST_F(ElfTest, write_code_data) {
@@ -67,5 +67,5 @@ TEST_F(ElfTest, write_code_data) {
{1, 0, 0, 0, 0, 0, 0, 0});
ASSERT_TRUE(fs::exists(TempFilename()));
- ASSERT_GT(fs::file_size(TempFilename()), 0);
+ ASSERT_GT(fs::file_size(TempFilename()), size_t(0));
}
diff --git a/tests/test-grammer.cpp b/tests/test-grammer.cpp
index 6af6992..06b674c 100644
--- a/tests/test-grammer.cpp
+++ b/tests/test-grammer.cpp
@@ -45,21 +45,21 @@ TEST_F(GrammerTest, minimumSymbolsNeeded) {
Gram::Compiler compiler(bnf, "translation-unit");
- EXPECT_EQ(minimumSymbolsNeeded(compiler, std::vector<std::string>{}), 0);
- EXPECT_EQ(minimumSymbolsNeeded(compiler, "translation-unit"), 0);
- EXPECT_EQ(minimumSymbolsNeeded(compiler, "logical-or-expression"), 1);
- EXPECT_EQ(minimumSymbolsNeeded(compiler, "assignment-expression"), 1);
- EXPECT_EQ(minimumSymbolsNeeded(compiler, "declaration"), 1);
- EXPECT_EQ(minimumSymbolsNeeded(compiler, "block-declaration"), 2);
- EXPECT_EQ(minimumSymbolsNeeded(compiler, "simple-declaration"), 2);
- EXPECT_EQ(minimumSymbolsNeeded(compiler, "asm-declaration"), 5);
- EXPECT_EQ(minimumSymbolsNeeded(compiler, "namespace-alias-definition"), 5);
- EXPECT_EQ(minimumSymbolsNeeded(compiler, "using-declaration"), 4);
- EXPECT_EQ(minimumSymbolsNeeded(compiler, "using-enum-declaration"), 4);
- EXPECT_EQ(minimumSymbolsNeeded(compiler, "using-directive"), 4);
- EXPECT_EQ(minimumSymbolsNeeded(compiler, "static_assert-declaration"), 5);
- EXPECT_EQ(minimumSymbolsNeeded(compiler, "alias-declaration"), 5);
- EXPECT_EQ(minimumSymbolsNeeded(compiler, "opaque-enum-declaration"), 3);
- EXPECT_EQ(minimumSymbolsNeeded(compiler, "function-definition"), 3);
+ EXPECT_EQ(minimumSymbolsNeeded(compiler, std::vector<std::string>{}), size_t(0));
+ EXPECT_EQ(minimumSymbolsNeeded(compiler, "translation-unit"), 0u);
+ EXPECT_EQ(minimumSymbolsNeeded(compiler, "logical-or-expression"), 1u);
+ EXPECT_EQ(minimumSymbolsNeeded(compiler, "assignment-expression"), 1u);
+ EXPECT_EQ(minimumSymbolsNeeded(compiler, "declaration"), 1u);
+ EXPECT_EQ(minimumSymbolsNeeded(compiler, "block-declaration"), 2u);
+ EXPECT_EQ(minimumSymbolsNeeded(compiler, "simple-declaration"), 2u);
+ EXPECT_EQ(minimumSymbolsNeeded(compiler, "asm-declaration"), 5u);
+ EXPECT_EQ(minimumSymbolsNeeded(compiler, "namespace-alias-definition"), 5u);
+ EXPECT_EQ(minimumSymbolsNeeded(compiler, "using-declaration"), 4u);
+ EXPECT_EQ(minimumSymbolsNeeded(compiler, "using-enum-declaration"), 4u);
+ EXPECT_EQ(minimumSymbolsNeeded(compiler, "using-directive"), 4u);
+ EXPECT_EQ(minimumSymbolsNeeded(compiler, "static_assert-declaration"), 5u);
+ EXPECT_EQ(minimumSymbolsNeeded(compiler, "alias-declaration"), 5u);
+ EXPECT_EQ(minimumSymbolsNeeded(compiler, "opaque-enum-declaration"), 3u);
+ EXPECT_EQ(minimumSymbolsNeeded(compiler, "function-definition"), 3u);
}
diff --git a/tests/test-lexer.cpp b/tests/test-lexer.cpp
index 23983f1..02bce69 100644
--- a/tests/test-lexer.cpp
+++ b/tests/test-lexer.cpp
@@ -35,5 +35,5 @@ TEST_F(LexerTest, Lex) {
std::vector<Token> tokens{lexer.Lex("int main() { return 1; }")};
- ASSERT_EQ(tokens.size(), 9);
+ ASSERT_EQ(tokens.size(), size_t(9));
}