From 755ee5462fb3d59b181da79d7c7f7eeba32bda2c Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Sat, 29 Dec 2012 21:15:59 +0100 Subject: [PATCH] Properly support globals initialized to nil --- ast.c | 5 ++++- ast.h | 2 ++ parser.c | 45 +++++++++++++++++++++++++++++---------------- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/ast.c b/ast.c index fb86b85..5c7d693 100644 --- a/ast.c +++ b/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) { diff --git a/ast.h b/ast.h index eeba636..bf7f6aa 100644 --- a/ast.h +++ b/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 * diff --git a/parser.c b/parser.c index 8b7cc7b..53220b5 100644 --- a/parser.c +++ b/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 = ""; 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; -- 2.39.2