aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--boot/dependency.cc4
-rw-r--r--boot/driver.cc2
-rw-r--r--boot/evaluator.cc2
-rw-r--r--boot/materialization.cc20
-rw-r--r--boot/name_analysis.cc6
-rw-r--r--boot/result.cc6
-rw-r--r--boot/type_check.cc32
-rw-r--r--boot/validation.cc2
-rw-r--r--gcc/gcc/elna-diagnostic.cc2
-rw-r--r--gcc/gcc/elna-generic.cc7
-rw-r--r--gcc/gcc/elna-tree.cc4
-rw-r--r--include/elna/boot/dependency.h6
-rw-r--r--include/elna/boot/driver.h4
-rw-r--r--include/elna/boot/evaluator.h2
-rw-r--r--include/elna/boot/materialization.h4
-rw-r--r--include/elna/boot/name_analysis.h10
-rw-r--r--include/elna/boot/result.h16
-rw-r--r--include/elna/boot/type_check.h18
-rw-r--r--include/elna/boot/validation.h4
-rw-r--r--include/elna/gcc/elna-diagnostic.h2
-rw-r--r--testsuite/fail_compilation/case_label_overflow.elna11
21 files changed, 84 insertions, 80 deletions
diff --git a/boot/dependency.cc b/boot/dependency.cc
index bd1251a..4590513 100644
--- a/boot/dependency.cc
+++ b/boot/dependency.cc
@@ -62,7 +62,7 @@ namespace elna::boot
return outcome;
}
- error_list analyze_semantics(std::unique_ptr<unit>& tree, symbol_bag& bag,
+ diagnostic_list analyze_semantics(std::unique_ptr<unit>& tree, symbol_bag& bag,
const target_info& target)
{
name_analysis_visitor name_analyser(bag, target);
@@ -86,7 +86,7 @@ namespace elna::boot
{
return std::move(validator.errors());
}
- return error_list{};
+ return diagnostic_list{};
}
std::filesystem::path build_path(const std::vector<std::string>& segments)
diff --git a/boot/driver.cc b/boot/driver.cc
index 24a11fa..3607995 100644
--- a/boot/driver.cc
+++ b/boot/driver.cc
@@ -30,7 +30,7 @@ namespace elna::boot
}
syntax_error::syntax_error(const std::string& message, const yy::location& location)
- : error(make_position(location)), message(message)
+ : diagnostic(make_position(location)), message(message)
{
}
diff --git a/boot/evaluator.cc b/boot/evaluator.cc
index 07b2953..b37d1fa 100644
--- a/boot/evaluator.cc
+++ b/boot/evaluator.cc
@@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see
namespace elna::boot
{
non_constant_expression_error::non_constant_expression_error(const source_position position, payload_type payload)
- : error(position), payload(std::move(payload))
+ : diagnostic(position), payload(std::move(payload))
{
}
diff --git a/boot/materialization.cc b/boot/materialization.cc
index e055dfd..8c436b3 100644
--- a/boot/materialization.cc
+++ b/boot/materialization.cc
@@ -20,7 +20,7 @@ along with GCC; see the file COPYING3. If not see
namespace elna::boot
{
materialization_error::materialization_error(const source_position position)
- : error(position)
+ : diagnostic(position)
{
}
@@ -43,6 +43,11 @@ namespace elna::boot
if (auto negated_literal = literal->value.negate())
{
literal->value = negated_literal.value();
+ if (!literal->has_explicit_size
+ && !literal->value.fit_into(true, target.int_properties.front().size))
+ {
+ add_error<materialization_error>(literal->position());
+ }
}
else
{
@@ -50,12 +55,23 @@ namespace elna::boot
}
break;
case unmarked:
- if (!literal->value.fit_into(true, literal->value.size()))
+ {
+ const auto target_size = literal->has_explicit_size
+ ? literal->value.size()
+ : target.int_properties.front().size;
+
+ if (!literal->value.fit_into(true, target_size))
{
add_error<materialization_error>(literal->position());
}
break;
+ }
case _unsigned:
+ if (!literal->has_explicit_size
+ && !literal->value.fit_into(false, target.word_properties.front().size))
+ {
+ add_error<materialization_error>(literal->position());
+ }
break;
}
}
diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc
index 4127466..0889ef9 100644
--- a/boot/name_analysis.cc
+++ b/boot/name_analysis.cc
@@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see
namespace elna::boot
{
declaration_error::declaration_error(const source_position position, const std::string& name, payload_type payload)
- : error(position), name(name), payload(payload)
+ : diagnostic(position), name(name), payload(payload)
{
}
@@ -70,7 +70,7 @@ namespace elna::boot
}
const_qualifier_error::const_qualifier_error(const source_position position, payload_type payload)
- : error(position), payload(std::move(payload))
+ : diagnostic(position), payload(std::move(payload))
{
}
@@ -113,7 +113,7 @@ namespace elna::boot
member_error::member_error(const source_position position, const std::string& name,
const type& composite, payload_type payload)
- : error(position), name(name), composite(composite), payload(std::move(payload))
+ : diagnostic(position), name(name), composite(composite), payload(std::move(payload))
{
}
diff --git a/boot/result.cc b/boot/result.cc
index a5f0803..3970b1f 100644
--- a/boot/result.cc
+++ b/boot/result.cc
@@ -63,17 +63,17 @@ namespace elna::boot
return this->m_start != this->m_end;
}
- error::error(const source_position position)
+ diagnostic::diagnostic(const source_position position)
: position(position)
{
}
- std::deque<std::unique_ptr<error>>& error_container::errors()
+ std::deque<std::unique_ptr<diagnostic>>& diagnostic_container::errors()
{
return m_errors;
}
- bool error_container::has_errors() const
+ bool diagnostic_container::has_errors() const
{
return !m_errors.empty();
}
diff --git a/boot/type_check.cc b/boot/type_check.cc
index 07e563f..e58a50e 100644
--- a/boot/type_check.cc
+++ b/boot/type_check.cc
@@ -90,7 +90,7 @@ namespace elna::boot
trait_error::trait_error(const source_position position, const std::string& trait_name,
payload_type payload)
- : error(position), trait_name(trait_name), payload(std::move(payload))
+ : diagnostic(position), trait_name(trait_name), payload(std::move(payload))
{
}
@@ -115,7 +115,7 @@ namespace elna::boot
type_mismatch_error::type_mismatch_error(const source_position position,
type actual, payload_type payload)
- : error(position), actual(std::move(actual)), payload(std::move(payload))
+ : diagnostic(position), actual(std::move(actual)), payload(std::move(payload))
{
}
@@ -158,11 +158,6 @@ namespace elna::boot
return "Type '" + this->actual.to_string()
+ "' cannot be converted to '" + payload.target.to_string() + "'";
}
- else if constexpr (std::is_same_v<T, integer_literal_overflow>)
- {
- return "The number " + payload.overflow.to_string()
- + " does not fit into the type '" + actual.to_string() + "'";
- }
else if constexpr (std::is_same_v<T, constant_assignment>)
{
return "Cannot assign to a value of type '" + this->actual.to_string()
@@ -173,7 +168,7 @@ namespace elna::boot
type_requirement_error::type_requirement_error(const source_position position,
type actual, kind kind)
- : error(position), actual(std::move(actual)), m_kind(kind)
+ : diagnostic(position), actual(std::move(actual)), m_kind(kind)
{
}
@@ -207,7 +202,7 @@ namespace elna::boot
cyclic_declaration_error::cyclic_declaration_error(const source_position position,
const std::vector<std::string>& cycle)
- : error(position), cycle(cycle)
+ : diagnostic(position), cycle(cycle)
{
}
@@ -226,7 +221,7 @@ namespace elna::boot
argument_count_error::argument_count_error(const source_position position, kind kind,
std::string applicand, std::size_t expected, std::size_t actual)
- : error(position), m_kind(kind), applicand(std::move(applicand)), expected(expected), actual(actual)
+ : diagnostic(position), m_kind(kind), applicand(std::move(applicand)), expected(expected), actual(actual)
{
}
@@ -1059,21 +1054,4 @@ namespace elna::boot
}
}
- void type_analysis_visitor::visit(literal<integer_literal> *expression)
- {
- bool narrowed{ false };
- if (expression->value.is_signed())
- {
- narrowed = expression->value.fit_into(target.int_properties.front().size);
- }
- else
- {
- narrowed = expression->value.fit_into(target.word_properties.front().size);
- }
- if (!narrowed)
- {
- add_error<type_mismatch_error>(expression->position(), expression->type_decoration,
- type_mismatch_error::integer_literal_overflow{ expression->value });
- }
- }
}
diff --git a/boot/validation.cc b/boot/validation.cc
index 26d4f64..a81282b 100644
--- a/boot/validation.cc
+++ b/boot/validation.cc
@@ -22,7 +22,7 @@ along with GCC; see the file COPYING3. If not see
namespace elna::boot
{
validation_error::validation_error(const source_position position, source_position first)
- : error(position), first(first)
+ : diagnostic(position), first(first)
{
}
diff --git a/gcc/gcc/elna-diagnostic.cc b/gcc/gcc/elna-diagnostic.cc
index 3bc274e..ea1f64c 100644
--- a/gcc/gcc/elna-diagnostic.cc
+++ b/gcc/gcc/elna-diagnostic.cc
@@ -63,7 +63,7 @@ namespace elna::gcc
return make_location(caret, start, end);
}
- void report_errors(const std::deque<std::unique_ptr<boot::error>>& errors)
+ void report_errors(const std::deque<std::unique_ptr<boot::diagnostic>>& errors)
{
for (const auto& error : errors)
{
diff --git a/gcc/gcc/elna-generic.cc b/gcc/gcc/elna-generic.cc
index aff5d9d..5230196 100644
--- a/gcc/gcc/elna-generic.cc
+++ b/gcc/gcc/elna-generic.cc
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "function.h"
#include "cgraph.h"
#include "gimplify.h"
+#include "dumpfile.h"
#include "stringpool.h"
#include "realmpfr.h"
#include "fold-const.h"
@@ -475,6 +476,8 @@ namespace elna::gcc
DECL_PRESERVE_P(fndecl) = 1;
+ dump_function(TDI_original, fndecl);
+
pop_cfun();
gimplify_function_tree(fndecl);
cgraph_node::finalize_function(fndecl, true);
@@ -482,7 +485,9 @@ namespace elna::gcc
void generic_visitor::visit(boot::literal<boot::integer_literal> *literal)
{
- this->current_expression = constant_to_tree(boot::constant_value{ literal->value }, this->symbols);
+ tree literal_type = get_inner_alias(literal->type_decoration, this->symbols);
+ this->current_expression = constant_to_tree(boot::constant_value{ literal->value },
+ this->symbols, literal_type);
}
void generic_visitor::visit(boot::literal<double> *literal)
diff --git a/gcc/gcc/elna-tree.cc b/gcc/gcc/elna-tree.cc
index 688fc4a..255cf60 100644
--- a/gcc/gcc/elna-tree.cc
+++ b/gcc/gcc/elna-tree.cc
@@ -259,7 +259,7 @@ namespace elna::gcc
{
if (auto converted = literal_value.try_to<std::ptrdiff_t>())
{
- return build_int_cst(elna_int_type_node, *converted);
+ return build_int_cst(type, *converted);
}
return NULL_TREE;
}
@@ -267,7 +267,7 @@ namespace elna::gcc
{
if (auto converted = literal_value.try_to<std::size_t>())
{
- return build_int_cstu(elna_word_type_node, *converted);
+ return build_int_cstu(type, *converted);
}
return NULL_TREE;
}
diff --git a/include/elna/boot/dependency.h b/include/elna/boot/dependency.h
index 854c661..75bbed3 100644
--- a/include/elna/boot/dependency.h
+++ b/include/elna/boot/dependency.h
@@ -26,9 +26,9 @@ along with GCC; see the file COPYING3. If not see
namespace elna::boot
{
- class dependency : public error_container
+ class dependency : public diagnostic_container
{
- error_list m_errors;
+ diagnostic_list m_errors;
public:
std::unique_ptr<unit> tree;
@@ -39,7 +39,7 @@ namespace elna::boot
dependency read_source(std::istream& entry_point, const target_info& target);
std::filesystem::path build_path(const std::vector<std::string>& segments);
- error_list analyze_semantics(std::unique_ptr<unit>& tree, symbol_bag& bag,
+ diagnostic_list analyze_semantics(std::unique_ptr<unit>& tree, symbol_bag& bag,
const target_info& target);
template<typename T>
diff --git a/include/elna/boot/driver.h b/include/elna/boot/driver.h
index 2503e39..9076e23 100644
--- a/include/elna/boot/driver.h
+++ b/include/elna/boot/driver.h
@@ -25,7 +25,7 @@ namespace elna::boot
{
source_position make_position(const yy::location& location);
- class syntax_error final : public error
+ class syntax_error final : public diagnostic
{
std::string message;
@@ -35,7 +35,7 @@ namespace elna::boot
std::string what() const override;
};
- class driver final : public error_container
+ class driver final : public diagnostic_container
{
public:
std::unique_ptr<unit> tree;
diff --git a/include/elna/boot/evaluator.h b/include/elna/boot/evaluator.h
index 02db6ab..dd70483 100644
--- a/include/elna/boot/evaluator.h
+++ b/include/elna/boot/evaluator.h
@@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see
namespace elna::boot
{
- class non_constant_expression_error final : public error
+ class non_constant_expression_error final : public diagnostic
{
public:
struct initializer
diff --git a/include/elna/boot/materialization.h b/include/elna/boot/materialization.h
index 21a217d..2c571c5 100644
--- a/include/elna/boot/materialization.h
+++ b/include/elna/boot/materialization.h
@@ -21,7 +21,7 @@ along with GCC; see the file COPYING3. If not see
namespace elna::boot
{
- class materialization_error final : public error
+ class materialization_error final : public diagnostic
{
public:
materialization_error(const source_position position);
@@ -29,7 +29,7 @@ namespace elna::boot
std::string what() const override;
};
- class materialization_visitor final : public walking_visitor, public error_container
+ class materialization_visitor final : public walking_visitor, public diagnostic_container
{
const target_info& target;
diff --git a/include/elna/boot/name_analysis.h b/include/elna/boot/name_analysis.h
index a9e7f24..736874a 100644
--- a/include/elna/boot/name_analysis.h
+++ b/include/elna/boot/name_analysis.h
@@ -33,7 +33,7 @@ namespace elna::boot
* Error declaring or using a symbol (undeclared, redefinition,
* local export).
*/
- class declaration_error final : public error
+ class declaration_error final : public diagnostic
{
public:
enum class kind
@@ -63,7 +63,7 @@ namespace elna::boot
* \c const qualifier used incorrectly — wrong position or
* duplicate.
*/
- class const_qualifier_error final : public error
+ class const_qualifier_error final : public diagnostic
{
public:
enum class kind
@@ -89,7 +89,7 @@ namespace elna::boot
/**
* Error accessing or defining a member of a record or enumeration.
*/
- class member_error final : public error
+ class member_error final : public diagnostic
{
public:
enum class kind { not_found, field_on_type };
@@ -123,7 +123,7 @@ namespace elna::boot
/**
* Performs name analysis.
*/
- class name_analysis_visitor final : public walking_visitor, public error_container
+ class name_analysis_visitor final : public walking_visitor, public diagnostic_container
{
type current_type;
symbol_bag bag;
@@ -183,7 +183,7 @@ namespace elna::boot
/**
* Collects global declarations without resolving any symbols.
*/
- class declaration_visitor final : public empty_visitor, public error_container
+ class declaration_visitor final : public empty_visitor, public diagnostic_container
{
public:
forward_table unresolved;
diff --git a/include/elna/boot/result.h b/include/elna/boot/result.h
index bf2149a..23505d0 100644
--- a/include/elna/boot/result.h
+++ b/include/elna/boot/result.h
@@ -81,13 +81,13 @@ namespace elna::boot
/**
* A compilation error consists of an error message and position.
*/
- class error
+ class diagnostic
{
protected:
- error(const source_position position);
+ diagnostic(const source_position position);
public:
- virtual ~error() = default;
+ virtual ~diagnostic() = default;
/// Error position.
const source_position position;
@@ -106,17 +106,17 @@ namespace elna::boot
}
};
- using error_list = std::deque<std::unique_ptr<error>>;
+ using diagnostic_list = std::deque<std::unique_ptr<diagnostic>>;
- class error_container
+ class diagnostic_container
{
protected:
- error_list m_errors;
+ diagnostic_list m_errors;
- error_container() = default;
+ diagnostic_container() = default;
public:
- error_list& errors();
+ diagnostic_list& errors();
template<typename T, typename... Args>
void add_error(Args&&... arguments)
diff --git a/include/elna/boot/type_check.h b/include/elna/boot/type_check.h
index 52eec61..7a8eece 100644
--- a/include/elna/boot/type_check.h
+++ b/include/elna/boot/type_check.h
@@ -30,7 +30,7 @@ namespace elna::boot
/**
* Expected type does not match the actual type of an expression.
*/
- class type_mismatch_error final : public error
+ class type_mismatch_error final : public diagnostic
{
public:
struct expected_type
@@ -54,10 +54,6 @@ namespace elna::boot
{
type target;
};
- struct integer_literal_overflow
- {
- integer_literal overflow;
- };
struct constant_assignment
{
};
@@ -67,7 +63,6 @@ namespace elna::boot
unary,
binary,
invalid_cast,
- integer_literal_overflow,
constant_assignment
>;
@@ -81,7 +76,7 @@ namespace elna::boot
payload_type payload;
};
- class type_requirement_error : public error
+ class type_requirement_error : public diagnostic
{
public:
enum class kind
@@ -107,7 +102,7 @@ namespace elna::boot
/**
* Cyclic type declaration.
*/
- class cyclic_declaration_error final : public error
+ class cyclic_declaration_error final : public diagnostic
{
std::vector<std::string> cycle;
@@ -121,7 +116,7 @@ namespace elna::boot
* Argument count in a procedure call or array constructor doesn't match
* the expected number of parameters or elements.
*/
- class argument_count_error final : public error
+ class argument_count_error final : public diagnostic
{
public:
enum class kind
@@ -146,7 +141,7 @@ namespace elna::boot
/**
* A trait invocation is invalid.
*/
- class trait_error final : public error
+ class trait_error final : public diagnostic
{
public:
struct offset_not_field_name
@@ -208,7 +203,7 @@ namespace elna::boot
* procedure argument counts, record field validity,
* and type declaration well-formedness.
*/
- class type_analysis_visitor final : public walking_visitor, public error_container
+ class type_analysis_visitor final : public walking_visitor, public diagnostic_container
{
symbol_bag bag;
std::shared_ptr<procedure_info> current_procedure;
@@ -249,6 +244,5 @@ namespace elna::boot
void visit(cast_expression *expression) override;
void visit(unary_expression *expression) override;
void visit(binary_expression *expression) override;
- void visit(literal<integer_literal> *expression) override;
};
}
diff --git a/include/elna/boot/validation.h b/include/elna/boot/validation.h
index 65972b7..2b1de95 100644
--- a/include/elna/boot/validation.h
+++ b/include/elna/boot/validation.h
@@ -27,7 +27,7 @@ namespace elna::boot
/**
* Validation error.
*/
- class validation_error final : public error
+ class validation_error final : public diagnostic
{
public:
validation_error(const source_position position, source_position first);
@@ -43,7 +43,7 @@ namespace elna::boot
* Validates:
* - case label uniqueness
*/
- class validation_visitor final : public empty_visitor, public error_container
+ class validation_visitor final : public empty_visitor, public diagnostic_container
{
symbol_bag& bag;
evaluator constant_evaluator;
diff --git a/include/elna/gcc/elna-diagnostic.h b/include/elna/gcc/elna-diagnostic.h
index 3e0dd51..10d5b44 100644
--- a/include/elna/gcc/elna-diagnostic.h
+++ b/include/elna/gcc/elna-diagnostic.h
@@ -43,5 +43,5 @@ namespace elna::gcc
location_t get_location(const boot::source_position *position);
location_t make_range(const boot::source_position& position);
- void report_errors(const std::deque<std::unique_ptr<boot::error>>& errors);
+ void report_errors(const std::deque<std::unique_ptr<boot::diagnostic>>& errors);
}
diff --git a/testsuite/fail_compilation/case_label_overflow.elna b/testsuite/fail_compilation/case_label_overflow.elna
new file mode 100644
index 0000000..ab6dbfd
--- /dev/null
+++ b/testsuite/fail_compilation/case_label_overflow.elna
@@ -0,0 +1,11 @@
+var
+ x: Int8 := 100i8
+
+begin
+ case x of
+ 100i8: assert(true)
+ | 100i8 + 100i8: assert(false) (* @Error Case label must be a constant expression *)
+ else
+ assert(false)
+ end
+end.