Fix QuakeWorld compilation by treating assignment to constants as a warning when -std=qcc.

This commit is contained in:
Dale Weiler 2013-09-24 07:31:53 -04:00
parent f25fff1e3d
commit 73eca0848c
5 changed files with 33 additions and 10 deletions

View file

@ -327,10 +327,15 @@ it can happen that incompatible types are passed to functions. This
enables several warnings when static typechecking cannot guarantee enables several warnings when static typechecking cannot guarantee
consistent behavior. consistent behavior.
.It Fl W Ns Cm breakdef .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 which conflicts with the 'break' keyword in GMQCC. Enabling this
warning will print a warning when the definition occurs. The will print a warning when the definition occurs. The definition is
definition is ignored for both cases. 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 .El
.Sh COMPILE FLAGS .Sh COMPILE FLAGS
.Bl -tag -width Ds .Bl -tag -width Ds

View file

@ -516,13 +516,21 @@
UNSAFE_TYPES = true 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 #which conflicts with the 'break' keyword in GMQCC. Enabling this
#warning will print a warning when the definition occurs. The #print a warning when the definition occurs. The definition is
#definition is ignored for both cases. #ignored for both cases.
BREAKDEF = true 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] [optimizations]
#Some general peephole optimizations. For instance the code `a = b #Some general peephole optimizations. For instance the code `a = b
#+ c` typically generates 2 instructions, an ADD and a STORE. This #+ c` typically generates 2 instructions, an ADD and a STORE. This

1
opts.c
View file

@ -90,6 +90,7 @@ static void opts_setdefault(void) {
opts_set(opts.warn, WARN_UNINITIALIZED_CONSTANT, true); opts_set(opts.warn, WARN_UNINITIALIZED_CONSTANT, true);
opts_set(opts.warn, WARN_DEPRECATED, true); opts_set(opts.warn, WARN_DEPRECATED, true);
opts_set(opts.warn, WARN_PARENTHESIS, true); opts_set(opts.warn, WARN_PARENTHESIS, true);
opts_set(opts.warn, WARN_CONST_OVERWRITE, true);
/* flags */ /* flags */
opts_set(opts.flags, ADJUST_VECTOR_FIELDS, true); opts_set(opts.flags, ADJUST_VECTOR_FIELDS, true);

View file

@ -94,6 +94,7 @@
GMQCC_DEFINE_FLAG(PARENTHESIS) GMQCC_DEFINE_FLAG(PARENTHESIS)
GMQCC_DEFINE_FLAG(UNSAFE_TYPES) GMQCC_DEFINE_FLAG(UNSAFE_TYPES)
GMQCC_DEFINE_FLAG(BREAKDEF) GMQCC_DEFINE_FLAG(BREAKDEF)
GMQCC_DEFINE_FLAG(CONST_OVERWRITE)
#endif #endif
#ifdef GMQCC_TYPE_OPTIMIZATIONS #ifdef GMQCC_TYPE_OPTIMIZATIONS

View file

@ -287,10 +287,18 @@ static bool check_write_to(lex_ctx_t ctx, ast_expression *expr)
if (ast_istype(expr, ast_value)) { if (ast_istype(expr, ast_value)) {
ast_value *val = (ast_value*)expr; ast_value *val = (ast_value*)expr;
if (val->cvq == CV_CONST) { if (val->cvq == CV_CONST) {
if (val->name[0] == '#') if (val->name[0] == '#') {
compile_error(ctx, "invalid assignment to a literal constant"); 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); 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; return false;
} }
} }