diff options
| author | Roland Reichwein <mail@reichwein.it> | 2020-11-21 15:19:45 +0100 | 
|---|---|---|
| committer | Roland Reichwein <mail@reichwein.it> | 2020-11-21 15:19:45 +0100 | 
| commit | 7edbd99775416a32c88acf8e9379518436905f02 (patch) | |
| tree | 6356edb79f846df4aa2f6a8a5ecfeef4e651bcc0 | |
| parent | 7250bbe5ae2d2ee6b0334bc462aab73f7d8dac0e (diff) | |
Support gcc 10 and clang 11
| -rw-r--r-- | Makefile | 46 | ||||
| -rw-r--r-- | TODO | 3 | ||||
| -rw-r--r-- | asm/intel64/div.cpp | 18 | ||||
| -rw-r--r-- | asm/intel64/encode.cpp | 41 | ||||
| -rw-r--r-- | asm/intel64/mul.cpp | 18 | ||||
| -rw-r--r-- | asm/parse.cpp | 7 | ||||
| -rw-r--r-- | cpp.cpp | 17 | ||||
| -rw-r--r-- | cpp.h | 1 | ||||
| -rw-r--r-- | cppbnf.cpp | 7 | ||||
| -rw-r--r-- | debian/control | 21 | ||||
| -rw-r--r-- | flowgraph/data.h | 1 | ||||
| -rw-r--r-- | grammer.cpp | 16 | ||||
| -rw-r--r-- | grammer.h | 4 | ||||
| -rw-r--r-- | programopts.cpp | 2 | ||||
| -rw-r--r-- | systemtest/config/unix.exp | 6 | ||||
| -rw-r--r-- | systemtest/mcc-execute.tests/exitcodes.exp | 3 | ||||
| -rw-r--r-- | systemtest/mcc-execute.tests/test-division.cpp | 1 | ||||
| -rw-r--r-- | systemtest/mcc-execute.tests/test-modulo.cpp | 1 | ||||
| -rw-r--r-- | systemtest/mcc-execute.tests/test-multiplication.cpp | 1 | ||||
| -rw-r--r-- | tests/test-asm.cpp | 60 | ||||
| -rw-r--r-- | tests/test-cpp.cpp | 14 | ||||
| -rw-r--r-- | tests/test-elf.cpp | 4 | ||||
| -rw-r--r-- | tests/test-grammer.cpp | 32 | ||||
| -rw-r--r-- | tests/test-lexer.cpp | 2 | 
24 files changed, 224 insertions, 102 deletions
| @@ -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)) @@ -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", @@ -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())}; @@ -7,6 +7,7 @@  #include <any>  #include <deque> +#include <functional>  #include <memory>  #include <vector> @@ -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"); @@ -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));  } | 
