Detect type aliasing cycles
This commit is contained in:
@ -22,6 +22,8 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "elna/gcc/elna-diagnostic.h"
|
||||
#include "elna/gcc/elna1.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "ggc.h"
|
||||
#include "function.h"
|
||||
#include "cgraph.h"
|
||||
@ -37,7 +39,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
namespace elna::gcc
|
||||
{
|
||||
tree get_inner_alias(const boot::type& type, std::shared_ptr<symbol_table> symbols,
|
||||
std::unordered_map<std::string, tree>& unresolved)
|
||||
std::unordered_map<std::string, tree>& unresolved, std::vector<std::string>& path)
|
||||
{
|
||||
if (auto reference = type.get<boot::primitive_type>())
|
||||
{
|
||||
@ -57,7 +59,7 @@ namespace elna::gcc
|
||||
}
|
||||
else if (auto reference = type.get<boot::pointer_type>())
|
||||
{
|
||||
return build_global_pointer_type(get_inner_alias(reference->base, symbols, unresolved));
|
||||
return build_global_pointer_type(get_inner_alias(reference->base, symbols, unresolved, path));
|
||||
}
|
||||
else if (auto reference = type.get<boot::array_type>())
|
||||
{
|
||||
@ -65,19 +67,27 @@ namespace elna::gcc
|
||||
tree upper_bound = build_int_cst_type(integer_type_node, reference->size);
|
||||
tree range_type = build_range_type(integer_type_node, lower_bound, upper_bound);
|
||||
|
||||
return build_array_type(get_inner_alias(reference->base, symbols, unresolved), range_type);
|
||||
return build_array_type(get_inner_alias(reference->base, symbols, unresolved, path), range_type);
|
||||
}
|
||||
else if (auto reference = type.get<boot::alias_type>())
|
||||
{
|
||||
return handle_symbol(reference->name, reference, symbols, unresolved);
|
||||
return handle_symbol(reference->name, reference, symbols, unresolved, path);
|
||||
}
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
tree handle_symbol(const std::string& symbol_name, std::shared_ptr<boot::alias_type> reference,
|
||||
std::shared_ptr<symbol_table> symbols, std::unordered_map<std::string, tree>& unresolved)
|
||||
std::shared_ptr<symbol_table> symbols, std::unordered_map<std::string, tree>& unresolved,
|
||||
std::vector<std::string>& path)
|
||||
{
|
||||
auto looked_up = get_inner_alias(reference->reference, symbols, unresolved);
|
||||
path.push_back(symbol_name);
|
||||
std::vector<std::string>::const_iterator head_peace = std::cbegin(path);
|
||||
|
||||
if (std::find(std::next(head_peace), std::cend(path), *head_peace) != std::cend(path))
|
||||
{
|
||||
return error_mark_node;
|
||||
}
|
||||
auto looked_up = get_inner_alias(reference->reference, symbols, unresolved, path);
|
||||
|
||||
unresolved.insert({ symbol_name, looked_up });
|
||||
|
||||
@ -97,7 +107,8 @@ namespace elna::gcc
|
||||
{
|
||||
for (auto& [symbol_name, symbol_info] : declaration_visitor.unresolved)
|
||||
{
|
||||
handle_symbol(symbol_name, symbol_info, symbols, unresolved);
|
||||
std::vector<std::string> type_path;
|
||||
handle_symbol(symbol_name, symbol_info, symbols, unresolved, type_path);
|
||||
}
|
||||
}
|
||||
return std::move(declaration_visitor.errors());
|
||||
@ -803,9 +814,9 @@ namespace elna::gcc
|
||||
}
|
||||
tree return_type = void_type_node;
|
||||
|
||||
if (type.return_type.type != nullptr)
|
||||
if (type.return_type.proper_type != nullptr)
|
||||
{
|
||||
type.return_type.type->accept(this);
|
||||
type.return_type.proper_type->accept(this);
|
||||
return_type = this->current_expression;
|
||||
}
|
||||
this->current_expression = NULL_TREE;
|
||||
|
Reference in New Issue
Block a user