Fix QuakeWorld compilation by treating assignment to constants as a warning when...
authorDale Weiler <killfieldengine@gmail.com>
Tue, 24 Sep 2013 11:31:53 +0000 (07:31 -0400)
committerDale Weiler <killfieldengine@gmail.com>
Tue, 24 Sep 2013 11:31:53 +0000 (07:31 -0400)
doc/gmqcc.1
gmqcc.ini.example
opts.c
opts.def
parser.c

index f3f6517..185092e 100644 (file)
@@ -327,10 +327,15 @@ it can happen that incompatible types are passed to functions. This
 enables several warnings when static typechecking cannot guarantee
 consistent behavior.
 .It Fl W Ns Cm breakdef
-When compiling original id1 QC, there is a definition for `break`
+When compiling original id1 QC there is a definition for `break`
 which conflicts with the 'break' keyword in GMQCC. Enabling this
-warning will print a warning when the definition occurs. The
-definition is ignored for both cases.
+will print a warning when the definition occurs. The definition is
+ignored for both cases.
+.It Fl W Ns Cm const-overwrite
+When compiling original QuakeWorld QC there are instances where
+code overwrites constants. This is considered an error, however
+for QuakeWorld to compile it needs to be treated as a warning
+instead, as such this warning only works when -std=qcc.
 .El
 .Sh COMPILE FLAGS
 .Bl -tag -width Ds
index 9dbb6fb..7fc19fd 100644 (file)
@@ -31,7 +31,7 @@
     #write a ticket.
 
     FTEPP = true
-    
+
 
     #Enable some predefined macros. This only works in combination
     #with '-fftepp' and is currently not included by '-std=fteqcc'.
     UNSAFE_TYPES = true
 
 
-    #When compiling original id1 QC, there is a definition for `break`
+    #When compiling original id1 QC there is a definition for `break`
     #which conflicts with the 'break' keyword in GMQCC. Enabling this
-    #warning will print a warning when the definition occurs. The
-    #definition is ignored for both cases.
+    #print a warning when the definition occurs. The definition is
+    #ignored for both cases.
 
     BREAKDEF = true
 
+
+    #When compiling original QuakeWorld QC there are instances where
+    #code overwrites constants. This is considered an error, however
+    #for QuakeWorld to compile it needs to be treated as a warning
+    #instead, as such this warning only works when -std=qcc.
+
+    CONST_OVERWRITE = true
+
 [optimizations]
     #Some general peephole optimizations. For instance the code `a = b
     #+ c` typically generates 2 instructions, an ADD and a STORE. This
 
     LOCAL_TEMPS = true
 
+
     #Causes temporary values which do not need to be backed up on a
     #CALL to not be stored in the function's locals-area. With this, a
     #CALL to a function may need to back up fewer values and thus exe‐
diff --git a/opts.c b/opts.c
index 3e7e207..9aa8f63 100644 (file)
--- a/opts.c
+++ b/opts.c
@@ -90,6 +90,7 @@ static void opts_setdefault(void) {
     opts_set(opts.warn,  WARN_UNINITIALIZED_CONSTANT,    true);
     opts_set(opts.warn,  WARN_DEPRECATED,                true);
     opts_set(opts.warn,  WARN_PARENTHESIS,               true);
+    opts_set(opts.warn,  WARN_CONST_OVERWRITE,           true);
 
     /* flags */
     opts_set(opts.flags, ADJUST_VECTOR_FIELDS,           true);
index ee40cf5..f4d01e6 100644 (file)
--- a/opts.def
+++ b/opts.def
@@ -94,6 +94,7 @@
     GMQCC_DEFINE_FLAG(PARENTHESIS)
     GMQCC_DEFINE_FLAG(UNSAFE_TYPES)
     GMQCC_DEFINE_FLAG(BREAKDEF)
+    GMQCC_DEFINE_FLAG(CONST_OVERWRITE)
 #endif
 
 #ifdef GMQCC_TYPE_OPTIMIZATIONS
index e3b4d9a..e0f46a4 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -287,10 +287,18 @@ static bool check_write_to(lex_ctx_t ctx, ast_expression *expr)
     if (ast_istype(expr, ast_value)) {
         ast_value *val = (ast_value*)expr;
         if (val->cvq == CV_CONST) {
-            if (val->name[0] == '#')
+            if (val->name[0] == '#') {
                 compile_error(ctx, "invalid assignment to a literal constant");
-            else
+                return false;
+            }
+            /*
+             * To work around quakeworld we must elide the error and make it
+             * a warning instead.
+             */
+            if (OPTS_OPTION_U32(OPTION_STANDARD) != COMPILER_QCC)
                 compile_error(ctx, "assignment to constant `%s`", val->name);
+            else
+                (void)!compile_warning(ctx, WARN_CONST_OVERWRITE, "assignment to constant `%s`", val->name);
             return false;
         }
     }