]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - parser.c
fixing a crash caused by the correction: setting correct=NULL after freeing so the...
[xonotic/gmqcc.git] / parser.c
index 2d7ebe3941b6010999cd99ec82690ef11c16280b..6c59d3ca7c73cf555aeae84e6cb1a13064de5439 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -75,8 +75,8 @@ typedef struct {
     ht *typedefs;
 
     /* same as above but for the spelling corrector */
-    ht       *correct_variables;
-    size_t ***correct_variables_score;  /* vector of vector of size_t* */
+    correct_trie_t  **correct_variables;
+    size_t         ***correct_variables_score;  /* vector of vector of size_t* */
 
     /* not to be used directly, we use the hash table */
     ast_expression **_locals;
@@ -1642,22 +1642,24 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma
                      * We should also consider adding correction tables for
                      * other things as well.
                      */
-                    for (i = 0; i < vec_size(parser->correct_variables); i++) {
-                        correct = correct_str(parser->correct_variables[i], "ello");
-                        if (strcmp(correct, parser_tokval(parser))) {
-                            break;
-                        } else if (correct) {
-                            mem_d(correct);
+                    if (OPTS_FLAG(ENHANCED_DIAGNOSTICS)) {
+                        for (i = 0; i < vec_size(parser->correct_variables); i++) {
+                            correct = correct_str(parser->correct_variables[i], parser_tokval(parser));
+                            if (strcmp(correct, parser_tokval(parser))) {
+                                break;
+                            } else if (correct) {
+                                mem_d(correct);
+                                correct = NULL;
+                            }
                         }
-                    }
 
-                    if (correct) {
-                        parseerror(parser, "unexpected ident: %s (did you mean %s?)", parser_tokval(parser), correct);
-                        mem_d(correct);
-                    } else {
-                        parseerror(parser, "unexpected ident: %s", parser_tokval(parser));
+                        if (correct) {
+                            parseerror(parser, "unexpected ident: %s (did you mean %s?)", parser_tokval(parser), correct);
+                            mem_d(correct);
+                            goto onerr;
+                        }
                     }
-
+                    parseerror(parser, "unexpected ident: %s", parser_tokval(parser));
                     goto onerr;
                 }
             }
@@ -1998,7 +2000,7 @@ static void parser_enterblock(parser_t *parser)
     vec_push(parser->_block_ctx, parser_ctx(parser));
 
     /* corrector */
-    vec_push(parser->correct_variables, util_htnew(PARSER_HT_SIZE));
+    vec_push(parser->correct_variables, correct_trie_new());
     vec_push(parser->correct_variables_score, NULL);
 }
 
@@ -2164,6 +2166,8 @@ static bool parse_if(parser_t *parser, ast_block *block, ast_expression **out)
         ast_delete(cond);
         return false;
     }
+    if (!ontrue)
+        ontrue = (ast_expression*)ast_block_new(parser_ctx(parser));
     /* check for an else */
     if (!strcmp(parser_tokval(parser), "else")) {
         /* parse into the 'else' branch */
@@ -2641,6 +2645,13 @@ static bool parse_break_continue(parser_t *parser, ast_block *block, ast_express
         return false;
     }
 
+    if (!vec_size(loops)) {
+        if (is_continue)
+            parseerror(parser, "`continue` can only be used inside loops");
+        else
+            parseerror(parser, "`break` can only be used inside loops or switches");
+    }
+
     if (parser->tok == TOKEN_IDENT) {
         if (!OPTS_FLAG(LOOP_LABELS))
             parseerror(parser, "labeled loops not activated, try using -floop-labels");