Merge pull request #815 from larsclausen/class-virtual-new

Do not allow to create objects of virtual classes
This commit is contained in:
Stephen Williams 2022-12-17 11:11:30 -08:00 committed by GitHub
commit dd7bea1d5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 38 additions and 3 deletions

View File

@ -6652,6 +6652,14 @@ NetExpr* PENewClass::elaborate_expr(Design*des, NetScope*scope,
return 0; return 0;
} }
if (ctype->is_virtual()) {
cerr << get_fileline() << ": error: "
<< "Can not create object of virtual class `"
<< ctype->get_name() << "`." << endl;
des->errors++;
return 0;
}
NetExpr*obj = new NetENew(ntype); NetExpr*obj = new NetENew(ntype);
obj->set_line(*this); obj->set_line(*this);

View File

@ -493,6 +493,7 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
class_scope->set_class_def(use_class); class_scope->set_class_def(use_class);
use_class->set_class_scope(class_scope); use_class->set_class_scope(class_scope);
use_class->set_definition_scope(scope); use_class->set_definition_scope(scope);
use_class->set_virtual(use_type->virtual_class);
set_scope_timescale(des, class_scope, pclass); set_scope_timescale(des, class_scope, pclass);
class_scope->add_typedefs(&pclass->typedefs); class_scope->add_typedefs(&pclass->typedefs);

View File

@ -0,0 +1,15 @@
// Check that an error is reported when trying to create an object of a virtual
// class.
module test;
virtual class C;
endclass
C c;
initial begin
c = new; // This should fail
end
endmodule

View File

@ -555,6 +555,7 @@ sv_class_static_prop3 normal,-g2009 ivltests
sv_class_super1 normal,-g2009 ivltests sv_class_super1 normal,-g2009 ivltests
sv_class_super2 normal,-g2009 ivltests sv_class_super2 normal,-g2009 ivltests
sv_class_task1 normal,-g2009 ivltests sv_class_task1 normal,-g2009 ivltests
sv_class_virt_new_fail CE,-g2009 ivltests
sv_darray1 normal,-g2009 ivltests sv_darray1 normal,-g2009 ivltests
sv_darray2 normal,-g2009 ivltests sv_darray2 normal,-g2009 ivltests
sv_darray3 normal,-g2009 ivltests sv_darray3 normal,-g2009 ivltests

View File

@ -116,6 +116,9 @@ class netclass_t : public ivl_type_s {
const NetExpr* get_parameter(Design *des, perm_string name, const NetExpr* get_parameter(Design *des, perm_string name,
ivl_type_t &par_type) const; ivl_type_t &par_type) const;
void set_virtual(bool virtual_class) { virtual_class_ = virtual_class; }
bool is_virtual() const { return virtual_class_; }
private: private:
perm_string name_; perm_string name_;
// If this is derived from another base class, point to it // If this is derived from another base class, point to it
@ -137,6 +140,8 @@ class netclass_t : public ivl_type_s {
// This holds the context for the class type definition. // This holds the context for the class type definition.
NetScope*definition_scope_; NetScope*definition_scope_;
bool virtual_class_;
}; };
inline NetScope*netclass_t::definition_scope(void) inline NetScope*netclass_t::definition_scope(void)

View File

@ -797,7 +797,7 @@ class_declaration /* IEEE1800-2005: A.1.2 */
class_type_t *class_type= new class_type_t(name); class_type_t *class_type= new class_type_t(name);
FILE_NAME(class_type, @4); FILE_NAME(class_type, @4);
pform_set_typedef(@4, name, class_type, nullptr); pform_set_typedef(@4, name, class_type, nullptr);
pform_start_class_declaration(@2, class_type, $5.type, $5.exprs, $3); pform_start_class_declaration(@2, class_type, $5.type, $5.exprs, $3, $1);
} }
class_items_opt K_endclass class_items_opt K_endclass
{ // Process a class. { // Process a class.

View File

@ -173,7 +173,8 @@ extern void pform_start_class_declaration(const struct vlltype&loc,
class_type_t*type, class_type_t*type,
data_type_t*base_type, data_type_t*base_type,
std::list<PExpr*>*base_exprs, std::list<PExpr*>*base_exprs,
LexicalScope::lifetime_t lifetime); LexicalScope::lifetime_t lifetime,
bool virtual_class);
extern void pform_class_property(const struct vlltype&loc, extern void pform_class_property(const struct vlltype&loc,
property_qualifier_t pq, property_qualifier_t pq,
data_type_t*data_type, data_type_t*data_type,

View File

@ -43,7 +43,8 @@ void pform_start_class_declaration(const struct vlltype&loc,
class_type_t*type, class_type_t*type,
data_type_t*base_type, data_type_t*base_type,
list<PExpr*>*base_exprs, list<PExpr*>*base_exprs,
LexicalScope::lifetime_t lifetime) LexicalScope::lifetime_t lifetime,
bool virtual_class)
{ {
PClass*class_scope = pform_push_class_scope(loc, type->name, lifetime); PClass*class_scope = pform_push_class_scope(loc, type->name, lifetime);
class_scope->type = type; class_scope->type = type;
@ -52,6 +53,7 @@ void pform_start_class_declaration(const struct vlltype&loc,
assert(type->base_type == 0); assert(type->base_type == 0);
type->base_type.reset(base_type); type->base_type.reset(base_type);
type->virtual_class = virtual_class;
assert(type->base_args.empty()); assert(type->base_args.empty());
if (base_exprs) { if (base_exprs) {

View File

@ -379,6 +379,8 @@ struct class_type_t : public data_type_t {
std::unique_ptr<data_type_t> base_type; std::unique_ptr<data_type_t> base_type;
std::list<PExpr*>base_args; std::list<PExpr*>base_args;
bool virtual_class;
// This is a map of the properties. Map the name to the type. // This is a map of the properties. Map the name to the type.
struct prop_info_t : public LineInfo { struct prop_info_t : public LineInfo {
inline prop_info_t() : qual(property_qualifier_t::make_none()) { } inline prop_info_t() : qual(property_qualifier_t::make_none()) { }