Added __assume support for MSVC compatibility
authorRobert Pengelly <robertapengelly@hotmail.com>
Sun, 23 Aug 2026 00:01:38 +0000 (01:01 +0100)
committerRobert Pengelly <robertapengelly@hotmail.com>
Sun, 23 Aug 2026 00:01:38 +0000 (01:01 +0100)
amd64.c
i386.c
token.c
token.h

diff --git a/amd64.c b/amd64.c
index d2f8245d741da307e265e3ca7d8db813140e5a4b..f10a3b7132914f30ac899cf5489d5b2f5108939a 100644 (file)
--- a/amd64.c
+++ b/amd64.c
@@ -37084,6 +37084,63 @@ static void parse_statement (void) {
     statement_ends_control_flow = 0;
     flush_pending_statement_labels ();
     
+    if (tok.kind == TOK_ASSUME) {
+    
+        const char *assume_start = tok.start;
+        const char *assume_caret = tok.caret;
+        
+        unsigned long assume_line = get_line_number ();
+        FILE *saved_ofp;
+        
+        int assumption_known;
+        int assumption_value;
+        
+        get_token ();
+        
+        if (tok.kind != TOK_LPAREN) {
+        
+            report_line_at (get_filename (), assume_line, REPORT_ERROR, assume_start, assume_caret, "expected ( after __assume");
+            return;
+        
+        }
+        
+        get_token ();
+        
+        if (tok.kind == TOK_RPAREN) {
+        
+            report_line_at (get_filename (), assume_line, REPORT_ERROR, assume_start, assume_caret, "__assume requires an expression");
+            
+            get_token ();
+            expect_semi_or_recover ();
+            
+            return;
+        
+        }
+        
+        saved_ofp = state->ofp;
+        state->ofp = 0;
+        
+        emit_statement_jump_if_false (0);
+        state->ofp = saved_ofp;
+        
+        assumption_known = statement_condition_constant_known;
+        assumption_value = statement_condition_constant_value;
+        
+        if (tok.kind != TOK_RPAREN) {
+            skip_balanced_until (TOK_RPAREN, TOK_SEMI, TOK_EOF);
+        }
+        
+        expect (TOK_RPAREN, ")");
+        expect_semi_or_recover ();
+        
+        if (assumption_known && !assumption_value) {
+            statement_ends_control_flow = 1;
+        }
+        
+        return;
+    
+    }
+    
     if (parse_inline_asm_statement ()) {
         return;
     }
diff --git a/i386.c b/i386.c
index 9b3212a76d3b658c7e7e3128cbad644ff2ae5335..08b88a568d8ea2ba55aa7f65484e5e96df5eb736 100644 (file)
--- a/i386.c
+++ b/i386.c
@@ -34555,6 +34555,63 @@ static void parse_statement (void) {
     statement_ends_control_flow = 0;
     flush_pending_statement_labels ();
     
+    if (tok.kind == TOK_ASSUME) {
+    
+        const char *assume_start = tok.start;
+        const char *assume_caret = tok.caret;
+        
+        unsigned long assume_line = get_line_number ();
+        FILE *saved_ofp;
+        
+        int assumption_known;
+        int assumption_value;
+        
+        get_token ();
+        
+        if (tok.kind != TOK_LPAREN) {
+        
+            report_line_at (get_filename (), assume_line, REPORT_ERROR, assume_start, assume_caret, "expected ( after __assume");
+            return;
+        
+        }
+        
+        get_token ();
+        
+        if (tok.kind == TOK_RPAREN) {
+        
+            report_line_at (get_filename (), assume_line, REPORT_ERROR, assume_start, assume_caret, "__assume requires an expression");
+            
+            get_token ();
+            expect_semi_or_recover ();
+            
+            return;
+        
+        }
+        
+        saved_ofp = state->ofp;
+        state->ofp = 0;
+        
+        emit_statement_jump_if_false (0);
+        state->ofp = saved_ofp;
+        
+        assumption_known = statement_condition_constant_known;
+        assumption_value = statement_condition_constant_value;
+        
+        if (tok.kind != TOK_RPAREN) {
+            skip_balanced_until (TOK_RPAREN, TOK_SEMI, TOK_EOF);
+        }
+        
+        expect (TOK_RPAREN, ")");
+        expect_semi_or_recover ();
+        
+        if (assumption_known && !assumption_value) {
+            statement_ends_control_flow = 1;
+        }
+        
+        return;
+    
+    }
+    
     if (parse_inline_asm_statement ()) {
         return;
     }
diff --git a/token.c b/token.c
index 4632141a5aceea14d7850b102e496a2062430edc..e5f01a106ca8497dc5312efa6d85be0ecca1a37d 100755 (executable)
--- a/token.c
+++ b/token.c
@@ -1065,6 +1065,7 @@ static int find_kind (const char *start, const char *caret, const char *p) {
     static struct keyword kws[] = {
     
         /* Compiler Specific keywords */
+        {   "__assume",                 -1,     VERSION,    TOK_ASSUME              },
         {   "__builtin_unreachable",    -1,     VERSION,    TOK_BUILTIN_UNREACHABLE },
         {   "__scc_builtin_va_arg",     -1,     VERSION,    TOK_SCC_BUILTIN_VA_ARG  },
         
diff --git a/token.h b/token.h
index 5a0432ee071d704335a9c37c2e786498aca0ca55..18db011401e9a1c8d23876e202ef2116bf3b81a1 100755 (executable)
--- a/token.h
+++ b/token.h
@@ -67,6 +67,7 @@ enum token_kind {
     
     /* Start of keywords. */
     TOK_ASM = 256,
+    TOK_ASSUME,
     TOK_ATTRIBUTE,
     TOK_AUTO,
     TOK_BREAK,