Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

?: operator broken for vector condition #214

Open
divVerent opened this issue Jan 23, 2025 · 2 comments
Open

?: operator broken for vector condition #214

divVerent opened this issue Jan 23, 2025 · 2 comments

Comments

@divVerent
Copy link
Contributor

Code:

void print(string s) = #1;

void bar(vector v) {
        print(v ? "t\n" : "f\n");
};
void barf(vector v) {
        if (v)
                print("t\n");
        else
                print("f\n");
};
void blarf(vector v) {
        if (!v)
                print("f\n");
        else
                print("t\n");
};

Command:

./gmqcc -std=gmqcc -Wdebug foo.qc && ./qcvm -disasm progs.dat

Output:

FUNCTION "print" = builtin #1
FUNCTION "bar"
 <> IFNOT       [@53] 0,                    5
 <> STORE_S     [@38] IMMEDIATE "t\n",      [@56] (null),               (none)
 <> STORE_S     [@56] (null),               [@4] (null),                (none)
 <> CALL1       [@28] print (1),            
 <> RETURN      <null>,                     <null>,                     <null>,                     
 <> STORE_S     [@39] IMMEDIATE "f\n",      [@56] (null),               (none)
 <> GOTO        -4
FUNCTION "barf"
 <> NOT_V       [@57] 0,                    <null>,                     [@60] 0,                    
 <> IFNOT       [@60] 0,                    4
 <> STORE_S     [@39] IMMEDIATE "f\n",      [@4] (null),                (none)
 <> CALL1       [@28] print (1),            
 <> RETURN      <null>,                     <null>,                     <null>,                     
 <> STORE_S     [@38] IMMEDIATE "t\n",      [@4] (null),                (none)
 <> CALL1       [@28] print (1),            
 <> GOTO        -3
FUNCTION "blarf"
 <> NOT_V       [@61] 0,                    <null>,                     [@64] 0,                    
 <> IFNOT       [@64] 0,                    4
 <> STORE_S     [@39] IMMEDIATE "f\n",      [@4] (null),                (none)
 <> CALL1       [@28] print (1),            
 <> RETURN      <null>,                     <null>,                     <null>,                     
 <> STORE_S     [@38] IMMEDIATE "t\n",      [@4] (null),                (none)
 <> CALL1       [@28] print (1),            
 <> GOTO        -3

Note how bar doesn't use NOT_V but calls IFNOT on the vector directly. This just looks at its x component.

I suspect the bug is that exprs[0] in parser.cpp's call to new ast_ternary has not been fed through process_condition first, which is what normally takes care of inserting NOT_V for vector conditions. Probably a simple fix.

@divVerent
Copy link
Contributor Author

divVerent commented Jan 23, 2025

Affected Xonotic code:

https://gitlab.com/xonotic/xonotic-data.pk3dir/-/blob/master/qcsrc/common/monsters/sv_monsters.qc?ref_type=heads#L864

	this.steerto = steerlib_attract2(this, ((this.monster_face) ? this.monster_face : this.moveto), 0.5, 500, 0.95);

@divVerent
Copy link
Contributor Author

Confirmed that entire process_condition logic is missing, by changing the type to string and running the compiler with -ffalse-empty-strings -fno-true-empty-strings:

FUNCTION "print" = builtin #1
FUNCTION "bar"
 <> IFNOT       [@51] 0,                    5
 <> STORE_S     [@38] IMMEDIATE "t\n",      [@52] (null),               (none)
 <> STORE_S     [@52] (null),               [@4] (null),                (none)
 <> CALL1       [@28] print (1),            
 <> RETURN      <null>,                     <null>,                     <null>,                     
 <> STORE_S     [@39] IMMEDIATE "f\n",      [@52] (null),               (none)
 <> GOTO        -4
FUNCTION "barf"
 <> NOT_S       [@53] 0,                    <null>,                     [@54] 0,                    
 <> IFNOT       [@54] 0,                    4
 <> STORE_S     [@39] IMMEDIATE "f\n",      [@4] (null),                (none)
 <> CALL1       [@28] print (1),            
 <> RETURN      <null>,                     <null>,                     <null>,                     
 <> STORE_S     [@38] IMMEDIATE "t\n",      [@4] (null),                (none)
 <> CALL1       [@28] print (1),            
 <> GOTO        -3
FUNCTION "blarf"
 <> NOT_S       [@55] 0,                    <null>,                     [@56] 0,                    
 <> IFNOT       [@56] 0,                    4
 <> STORE_S     [@39] IMMEDIATE "f\n",      [@4] (null),                (none)
 <> CALL1       [@28] print (1),            
 <> RETURN      <null>,                     <null>,                     <null>,                     
 <> STORE_S     [@38] IMMEDIATE "t\n",      [@4] (null),                (none)
 <> CALL1       [@28] print (1),            
 <> GOTO        -3

bar ignores those options too, whereas the others then use NOT_S.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant