diff options
| -rw-r--r-- | source/slang/slang-preprocessor.cpp | 19 | ||||
| -rw-r--r-- | tests/preprocessor/if-macro-token-paste.slang | 17 |
2 files changed, 28 insertions, 8 deletions
diff --git a/source/slang/slang-preprocessor.cpp b/source/slang/slang-preprocessor.cpp index 41b2c5bdf..f233d46f0 100644 --- a/source/slang/slang-preprocessor.cpp +++ b/source/slang/slang-preprocessor.cpp @@ -1348,23 +1348,27 @@ static PreprocessorExpressionValue ParseAndEvaluateExpression(PreprocessorDirect // Parse a unary (prefix) expression inside of a preprocessor directive. static PreprocessorExpressionValue ParseAndEvaluateUnaryExpression(PreprocessorDirectiveContext* context) { - switch (PeekTokenType(context)) + if( PeekTokenType(context) == TokenType::EndOfDirective ) + { + GetSink(context)->diagnose(PeekLoc(context), Diagnostics::syntaxErrorInPreprocessorExpression); + return 0; + } + + auto token = AdvanceToken(context); + switch (token.type) { // handle prefix unary ops case TokenType::OpSub: - AdvanceToken(context); return -ParseAndEvaluateUnaryExpression(context); case TokenType::OpNot: - AdvanceToken(context); return !ParseAndEvaluateUnaryExpression(context); case TokenType::OpBitNot: - AdvanceToken(context); return ~ParseAndEvaluateUnaryExpression(context); // handle parenthized sub-expression case TokenType::LParent: { - Token leftParen = AdvanceToken(context); + Token leftParen = token; PreprocessorExpressionValue value = ParseAndEvaluateExpression(context); if (!Expect(context, TokenType::RParent, Diagnostics::expectedTokenInPreprocessorExpression)) { @@ -1374,11 +1378,10 @@ static PreprocessorExpressionValue ParseAndEvaluateUnaryExpression(PreprocessorD } case TokenType::IntegerLiteral: - return StringToInt(AdvanceToken(context).getContent()); + return StringToInt(token.getContent()); case TokenType::Identifier: { - Token token = AdvanceToken(context); if (token.getContent() == "defined") { // handle `defined(someName)` @@ -1419,7 +1422,7 @@ static PreprocessorExpressionValue ParseAndEvaluateUnaryExpression(PreprocessorD } default: - GetSink(context)->diagnose(PeekLoc(context), Diagnostics::syntaxErrorInPreprocessorExpression); + GetSink(context)->diagnose(token.loc, Diagnostics::syntaxErrorInPreprocessorExpression); return 0; } } diff --git a/tests/preprocessor/if-macro-token-paste.slang b/tests/preprocessor/if-macro-token-paste.slang new file mode 100644 index 000000000..da6a45fdc --- /dev/null +++ b/tests/preprocessor/if-macro-token-paste.slang @@ -0,0 +1,17 @@ +// if-macro.slang + +//TEST:SIMPLE: + +// Test that a `#if` test can invoke a function-like macro. +// +// Note: this test is a reproducer for a bug reported by a user. + +#define is_valid_TEST 1 +#define isValid(name) (is_valid_##name != 0) +int test() { +#if isValid(TEST) + return 1; +#else + return NO_SUCH_SYMBOL; +#endif +}
\ No newline at end of file |
