Check for double-chaining of types.

Chaining a type twice will form a loop in the type list, causing find_type
to go into an infinite loop.
This commit is contained in:
Bill Currie 2012-11-08 16:13:00 +09:00
parent 950a3aa83d
commit 7e293a38e8
4 changed files with 19 additions and 4 deletions

View File

@ -74,6 +74,7 @@ typedef struct type_s {
} t; } t;
struct type_s *next; struct type_s *next;
int freeable; int freeable;
int allocated;
const char *encoding; ///< Objective-QC encoding const char *encoding; ///< Objective-QC encoding
struct def_s *type_def; ///< offset of qfo encodoing struct def_s *type_def; ///< offset of qfo encodoing
} type_t; } type_t;

View File

@ -336,7 +336,10 @@ get_class (symbol_t *sym, int create)
c = calloc (sizeof (class_t), 1); c = calloc (sizeof (class_t), 1);
if (sym) if (sym)
c->name = sym->name; c->name = sym->name;
new = type_Class; memset (&new, 0, sizeof (new));
new.type = ev_invalid;
new.name = c->name;
new.meta = ty_class;
new.t.class = c; new.t.class = c;
c->type = find_type (&new); c->type = find_type (&new);
c->methods = new_methodlist (); c->methods = new_methodlist ();

View File

@ -124,10 +124,13 @@ static void
InitData (void) InitData (void)
{ {
pr_lineno_t *line; pr_lineno_t *line;
type_t *type; type_t *type, *ntype;
for (type = pr.types; type; type = type->next) for (type = pr.types; type; type = ntype) {
ntype = type->next;
free_type (type);
type->type_def = 0; type->type_def = 0;
}
if (pr.code) { if (pr.code) {
codespace_delete (pr.code); codespace_delete (pr.code);

View File

@ -39,6 +39,7 @@
#endif #endif
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <ctype.h>
#include "QF/dstring.h" #include "QF/dstring.h"
#include "QF/hash.h" #include "QF/hash.h"
@ -113,6 +114,8 @@ low_level_type (type_t *type)
void void
chain_type (type_t *type) chain_type (type_t *type)
{ {
if (type->next)
internal_error (0, "type already chained");
type->next = pr.types; type->next = pr.types;
pr.types = type; pr.types = type;
if (!type->encoding) { if (!type->encoding) {
@ -135,13 +138,18 @@ new_type (void)
type_t *type; type_t *type;
ALLOC (1024, type_t, types, type); ALLOC (1024, type_t, types, type);
type->freeable = 1; type->freeable = 1;
type->allocated = 1;
return type; return type;
} }
void void
free_type (type_t *type) free_type (type_t *type)
{ {
if (!type || !type->freeable) if (!type)
return;
if (!type->allocated) // for statically allocated types
type->next = 0;
if (!type->freeable)
return; return;
switch (type->type) { switch (type->type) {
case ev_void: case ev_void: