]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
Properly support globals initialized to nil
authorWolfgang Bumiller <blub@speed.at>
Sat, 29 Dec 2012 20:15:59 +0000 (21:15 +0100)
committerWolfgang Bumiller <blub@speed.at>
Sat, 29 Dec 2012 20:15:59 +0000 (21:15 +0100)
ast.c
ast.h
parser.c

diff --git a/ast.c b/ast.c
index fb86b85e3e5514afb0ed8c8e9faf0ff3a92b65ba..5c7d6931323cf702f679016b8fae27b94e72e8bf 100644 (file)
--- 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 eeba63626da652bd9af021801121646ecfb6f772..bf7f6aa3c5cb1abd81811504332456ffe880461b 100644 (file)
--- 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
  *
index 8b7cc7b80f29534d3cfcab4115e8156607af60d7..53220b51d7cb5f7f25a32a63d2cbdb69fb5b1afc 100644 (file)
--- 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 = "<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;