Comments (3)
6.10.3.4 Rescanning and further replacement
After all parameters in the replacement list have been substituted and # and ## processing has
taken place, all placemarker preprocessing tokens are removed. The resulting preprocessing token
sequence is then rescanned, along with all subsequent preprocessing tokens of the source file, for
more macro names to replace.
If the name of the macro being replaced is found during this scan of the replacement list (not
including the rest of the source fileβs preprocessing tokens), it is not replaced. Furthermore, if any
nested replacements encounter the name of the macro being replaced, it is not replaced. These
nonreplaced macro name preprocessing tokens are no longer available for further replacement even
if they are later (re)examined in contexts in which that macro name preprocessing token would
otherwise have been replaced.
Pasting the relevant piece of the standard here for future reference. Going from this description to the actual algorithm is very tricky, a lot is implict (in my opinion, it's borderline underspecified).
In thi case, this is how i would imagine the expansion sequence to be like:
^|REC_1$
^REC_1|$
^|REC_DEFER(REC_0_HOOK)()$
^REC_DEFER|(REC_0_HOOK)()$
^|REC_0_HOOK REC_EMPTY()$
^REC_0_HOOK| REC_EMPTY()$
REC_0_HOOK^ REC_EMPTY|()$
REC_0_HOOK^|()$
REC_0_HOOK^()|$
REC_0_HOOK()^|$
legend:
- ^ is
start_idx
+advance_idx
- $ is
moving_end_idx
- | is
idx
where I'm referring to the variables used in the expansion and scanning phase in Preprocessor.zig
So, initially my code didn't have theadvance_idx
concept. The sequence was always rescanned beginning from the first expansion point.
The standard is not very clear about this point, but inferring from gcc and clang, I decided to advance thestart_idx
when all the tokens to its left are expanded and there's no opportunity of further expanding them in the current context.
The relevant logic is:
Lines 953 to 955 in 76a1066
And this is correct.
Unfortunately, when the preprocessor findsREC_0_HOOK
, it sees that is could be a macro call, but in the end it turns out it isn't because there are no () after it, so this is the codepath taken:
Lines 876 to 878 in 76a1066
The continue prevents the logic that increasesadvance_idx
to be run.
I'm pretty busy with uni atm, if anybody else wants to pick up the fix from here feel free to do so.
from arocc.
Weird, I had fixed a very similar test case when rewriting the expansion logic.
I will look into it tomorrow, I hope it's not the usual undefined behavior expansion
from arocc.
Here is the ppstep
output in case that helps:
pp (started)> s
[preproc.c:8:1]: REC_1
pp (called)> s
[preproc.c:8:1]: REC_DEFER ( REC_0_HOOK ) ( )
pp (expanded)> s
[preproc.c:8:1]: REC_DEFER ( REC_0_HOOK ) ( )
pp (called)> s
[preproc.c:8:1]: REC_0_HOOK REC_EMPTY ( )
pp (expanded)> s
[preproc.c:8:1]: REC_0_HOOK REC_EMPTY ( )
pp (called)> s
[preproc.c:8:1]: REC_0_HOOK ( )
pp (expanded)> s
[preproc.c:8:1]: REC_0_HOOK ( )
pp (rescanned)> s
[preproc.c:8:1]: REC_0_HOOK ( )
pp (rescanned)> s
[preproc.c:8:6]: REC_0_HOOK ( )
pp (lexed)> s
[preproc.c:10:1]: REC_0_HOOK ( )
pp (complete)> s
from arocc.
Related Issues (20)
- Crash: bitwise XOR
- Crash: assign boolean or result to float HOT 1
- Crash: address of invalid type
- Crash: concatenate different char-size strings with improper encoding
- Crash: assign imaginary float to unsigned
- Crash: record with oversize array HOT 1
- Crash: assign to pointer to incomplete enum
- Enums types with fixed underlying type should compare equal to underlying type
- Fixed-underlying-type enums should enforce non-enum integral underlying type
- Crash: non-evaluated floating point comparison in boolean `or`
- Preprocessor allows extraneous tokens in preprocessor expression
- Integer literal promotion rules should emulate chosen compiler
- Incorrect sizeof for typeof incomplete array HOT 1
- Memory leak in preprocessor - indirect invocation of macro with incorrect number of arguments
- Print _BitInt size in diagnostics
- Warn if implicit integer conversion truncates value
- Crash: redefining variable as `__auto_type` and assigning to self
- Crash: array subscript with string
- Crash: initializing pointer to typeof-invalid
- `__TIMESTAMP__` macro has incorrect value
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from arocc.