WerWolv / ImHex

🔍 A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.
https://imhex.werwolv.net
GNU General Public License v2.0
42.79k stars 1.88k forks source link

[Bug] Parse error when last template parameter has its own parameter #1283

Open bgilbert opened 1 year ago

bgilbert commented 1 year ago

Operating System

Linux

What's the issue you encountered?

If the last template parameter to a struct is itself parameterized, parsing fails with a syntax error.

How can the issue be reproduced?

This fails:

#include <std/mem.pat>
struct S<T> {};
S<std::mem::Bytes<5>> a;

with this error:

E: error[P0002]: Unexpected expression
E:   --> <Source Code>:3:23
E: 3 | S<std::mem::Bytes<5>> a;
E:                           ^
E:                           Expected '>' to close template list, got Separator (;).

But this works:

#include <std/mem.pat>
struct S<T, auto C> {};
S<std::mem::Bytes<5>, 2> a;

ImHex Version

1.30.1

ImHex Build Type

Installation type

Fedora (imhex-1.30.1-3.fc38.x86_64)

Additional context?

No response

paxcut commented 1 year ago

This error seems to only occur when non type parameters are the last template parameter of the last template parameter. This also works

S<S<u32>> t;

but this doesn't

#include <std/mem.pat>

struct S<T> {};
struct P<auto n> {};
S<P<5>> t2;

one way to get around the problem is using using

using test = std::mem::Bytes<5>;
S<test> a;

works without errors

github-actions[bot] commented 1 month ago

This issue is marked stale as it has been open for 11 months without activity. Please try the latest ImHex version. (Avaiable here: https://imhex.download/ for release and https://imhex.download/#nightly for development version) If the issue persists on the latest version, please make a comment on this issue again

Without response, this issue will be closed in one month.

bgilbert commented 1 month ago

Test case still fails on 1.35.4.

paxcut commented 1 month ago

I debugged this issue and the problem is that the parser is treating >> as a bit-wise shift operator in the expression S<std::mem::Bytes<5>> a;.

It starts parsing S and std::mem::Bytes properly but when it gets to 5 it parses a mathematical expression which results in 5 >> a. the next token is ; which triggers the error Expected '>' to close template list, got Separator (;). If the last argument in inner template is non-type then it will be a value such that the shift operator can be applied using the variable name as the rest of the operation.

The reason S<S<u32>> t; works is that when parsing type template arguments the parser doesn't call parseMathematicalExpression() so error is avoided

In fixing the bug one must consider also expressions of the form S<S<a>>2>> a; where there is a bit-wise shift operator in the template argument.

One strategy is to check that after parsing the shift mathematical expression there is a closing > if the current template parameter is the last one. if it is not right after the mathematical expression then move the token cursor back to the first > in the shift operator and do nothing otherwise.

I'll implement it and if it works I'll add it to my ongoing pr for patterns editor related issues and enhancements.

paxcut commented 1 month ago

The description of the bug was correct but the way to fix it was not. The parser already had a method to deal with the comparison operators getting treated as template delimiters but the method needed to be extended to include the binary shift operators as well. Once the fix was in place, all tests were successful.

Note that expressions cited above of the form S<P<5>>2>> a; or S<P<10<5>> a; are actually illegal and were correctly identified as such after the fix. The correct forms should be written as S<P<(5>>2)>> a; and S<P<(10<5)>> a; which now give no errors.

Once the fix has been merged I will post a note here asking OP to test, and if tests are working, to close this issue.