mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-02-20 18:32:01 +00:00
Properly support globals initialized to nil
This commit is contained in:
parent
432a29e4d9
commit
755ee5462f
3 changed files with 35 additions and 17 deletions
5
ast.c
5
ast.c
|
@ -209,8 +209,11 @@ bool ast_compare_type(ast_expression *a, ast_expression *b)
|
|||
return false;
|
||||
if (vec_size(a->expression.params) != vec_size(b->expression.params))
|
||||
return false;
|
||||
if (a->expression.flags != b->expression.flags)
|
||||
if ((a->expression.flags & AST_FLAG_TYPE_MASK) !=
|
||||
(b->expression.flags & AST_FLAG_TYPE_MASK) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (vec_size(a->expression.params)) {
|
||||
size_t i;
|
||||
for (i = 0; i < vec_size(a->expression.params); ++i) {
|
||||
|
|
2
ast.h
2
ast.h
|
@ -143,6 +143,8 @@ typedef struct
|
|||
#define AST_FLAG_VARIADIC (1<<0)
|
||||
#define AST_FLAG_NORETURN (1<<1)
|
||||
#define AST_FLAG_INLINE (1<<2)
|
||||
#define AST_FLAG_INITIALIZED (1<<3)
|
||||
#define AST_FLAG_TYPE_MASK (AST_FLAG_VARIADIC | AST_FLAG_NORETURN)
|
||||
|
||||
/* Value
|
||||
*
|
||||
|
|
45
parser.c
45
parser.c
|
@ -4812,8 +4812,12 @@ skipvar:
|
|||
|
||||
if (!localblock) {
|
||||
cval = (ast_value*)cexp;
|
||||
if (!ast_istype(cval, ast_value) || ((!cval->hasvalue || cval->cvq != CV_CONST) && !cval->isfield))
|
||||
if (cval != parser->nil &&
|
||||
(!ast_istype(cval, ast_value) || ((!cval->hasvalue || cval->cvq != CV_CONST) && !cval->isfield))
|
||||
)
|
||||
{
|
||||
parseerror(parser, "cannot initialize a global constant variable with a non-constant expression");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (opts.standard != COMPILER_GMQCC &&
|
||||
|
@ -4822,14 +4826,19 @@ skipvar:
|
|||
{
|
||||
var->cvq = CV_CONST;
|
||||
}
|
||||
var->hasvalue = true;
|
||||
if (cval->expression.vtype == TYPE_STRING)
|
||||
var->constval.vstring = parser_strdup(cval->constval.vstring);
|
||||
else if (cval->expression.vtype == TYPE_FIELD)
|
||||
var->constval.vfield = cval;
|
||||
if (cval == parser->nil)
|
||||
var->expression.flags |= AST_FLAG_INITIALIZED;
|
||||
else
|
||||
memcpy(&var->constval, &cval->constval, sizeof(var->constval));
|
||||
ast_unref(cval);
|
||||
{
|
||||
var->hasvalue = true;
|
||||
if (cval->expression.vtype == TYPE_STRING)
|
||||
var->constval.vstring = parser_strdup(cval->constval.vstring);
|
||||
else if (cval->expression.vtype == TYPE_FIELD)
|
||||
var->constval.vfield = cval;
|
||||
else
|
||||
memcpy(&var->constval, &cval->constval, sizeof(var->constval));
|
||||
ast_unref(cval);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int cvq;
|
||||
|
@ -5064,6 +5073,7 @@ bool parser_init()
|
|||
empty_ctx.file = "<internal>";
|
||||
empty_ctx.line = 0;
|
||||
parser->nil = ast_value_new(empty_ctx, "nil", TYPE_NIL);
|
||||
parser->nil->cvq = CV_CONST;
|
||||
if (OPTS_FLAG(UNTYPED_NIL))
|
||||
util_htset(parser->htglobals, "nil", (void*)parser->nil);
|
||||
return true;
|
||||
|
@ -5263,14 +5273,17 @@ bool parser_finish(const char *output)
|
|||
if (!ast_istype(parser->globals[i], ast_value))
|
||||
continue;
|
||||
asvalue = (ast_value*)(parser->globals[i]);
|
||||
if (asvalue->cvq == CV_CONST && !asvalue->hasvalue)
|
||||
(void)!compile_warning(ast_ctx(asvalue), WARN_UNINITIALIZED_CONSTANT,
|
||||
"uninitialized constant: `%s`",
|
||||
asvalue->name);
|
||||
else if ((asvalue->cvq == CV_NONE || asvalue->cvq == CV_CONST) && !asvalue->hasvalue)
|
||||
(void)!compile_warning(ast_ctx(asvalue), WARN_UNINITIALIZED_GLOBAL,
|
||||
"uninitialized global: `%s`",
|
||||
asvalue->name);
|
||||
if (!(asvalue->expression.flags & AST_FLAG_INITIALIZED))
|
||||
{
|
||||
if (asvalue->cvq == CV_CONST && !asvalue->hasvalue)
|
||||
(void)!compile_warning(ast_ctx(asvalue), WARN_UNINITIALIZED_CONSTANT,
|
||||
"uninitialized constant: `%s`",
|
||||
asvalue->name);
|
||||
else if ((asvalue->cvq == CV_NONE || asvalue->cvq == CV_CONST) && !asvalue->hasvalue)
|
||||
(void)!compile_warning(ast_ctx(asvalue), WARN_UNINITIALIZED_GLOBAL,
|
||||
"uninitialized global: `%s`",
|
||||
asvalue->name);
|
||||
}
|
||||
if (!ast_generate_accessors(asvalue, ir)) {
|
||||
ir_builder_delete(ir);
|
||||
return false;
|
||||
|
|
Loading…
Reference in a new issue