Detect circular type definitions
With forward type declarations it is possible to create a circular type definition where a type resolves to itself. E.g. ``` typedef T1; typedef T1 T2; typedef T2 T1; ``` Flag a type as elaborating when elaboration of the type is started and clear it when elaboration finishes. If the elaboration function is entered again while the flag is still set a circular type has been detected and an error is reported. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
parent
2e0d6d5af1
commit
8ee9d6b5ea
15
elab_type.cc
15
elab_type.cc
|
|
@ -49,7 +49,20 @@ ivl_type_t data_type_t::elaborate_type(Design*des, NetScope*scope)
|
|||
if (pos != cache_type_elaborate_.end() && pos->first == use_definitions)
|
||||
return pos->second;
|
||||
|
||||
ivl_type_t tmp = elaborate_type_raw(des, scope);
|
||||
ivl_type_t tmp;
|
||||
if (elaborating) {
|
||||
des->errors++;
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Circular type definition found involving `" << *this << "`."
|
||||
<< endl;
|
||||
// Try to recover
|
||||
tmp = netvector_t::integer_type();
|
||||
} else {
|
||||
elaborating = true;
|
||||
tmp = elaborate_type_raw(des, scope);
|
||||
elaborating = false;
|
||||
}
|
||||
|
||||
cache_type_elaborate_.insert(pos, pair<NetScope*,ivl_type_t>(scope, tmp));
|
||||
return tmp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,6 +167,8 @@ class data_type_t : public PNamedItem {
|
|||
virtual ivl_type_t elaborate_type_raw(Design*des, NetScope*scope) const;
|
||||
virtual NetScope *find_scope(Design* des, NetScope *scope) const;
|
||||
|
||||
bool elaborating = false;
|
||||
|
||||
// Keep per-scope elaboration results cached.
|
||||
std::map<Definitions*,ivl_type_t> cache_type_elaborate_;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue