From 2eb135506a492888355483c7d169eaaf8e57c8cb Mon Sep 17 00:00:00 2001 From: John Kessenich <cepheus@frii.com> Date: Wed, 7 Jun 2017 17:15:38 -0600 Subject: [PATCH] GLSL: Fix #396: Error when 'defined' comes from macro expansion. --- Test/baseResults/cppSimple.vert.out | 4 +++- Test/cppSimple.vert | 10 ++++++++++ glslang/MachineIndependent/preprocessor/Pp.cpp | 8 ++++++++ glslang/MachineIndependent/preprocessor/PpContext.h | 3 +++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Test/baseResults/cppSimple.vert.out b/Test/baseResults/cppSimple.vert.out index 5b8794149..1b6e6b50d 100644 --- a/Test/baseResults/cppSimple.vert.out +++ b/Test/baseResults/cppSimple.vert.out @@ -90,8 +90,10 @@ ERROR: 12:9504: '#if' : unexpected tokens following directive ERROR: 12:9506: '#error' : \ 377 ERROR: 12:9507: '#error' : \ 376 ERROR: 12:9508: '#error' : \ 377 +ERROR: 12:9602: 'defined' : cannot use in preprocessor expression when expanded from macros +ERROR: 12:9603: '#error' : DEF_DEFINED then ERROR: 12:10002: '' : missing #endif -ERROR: 88 compilation errors. No code generated. +ERROR: 90 compilation errors. No code generated. Shader version: 400 diff --git a/Test/cppSimple.vert b/Test/cppSimple.vert index 198203a69..fdd14221b 100644 --- a/Test/cppSimple.vert +++ b/Test/cppSimple.vert @@ -337,6 +337,16 @@ int aoeua = FOOOM; #error \ 376 #error \377 +// ERROR for macro expansion to yield 'defined' +#line 9600 +#define DEF_MAC +#define DEF_DEFINED defined +#if DEF_DEFINED DEF_MAC +#error DEF_DEFINED then +#else +#error DEF_DEFINED else +#endif + #line 10000 #if 1 #else diff --git a/glslang/MachineIndependent/preprocessor/Pp.cpp b/glslang/MachineIndependent/preprocessor/Pp.cpp index da432bd54..5c6e24797 100644 --- a/glslang/MachineIndependent/preprocessor/Pp.cpp +++ b/glslang/MachineIndependent/preprocessor/Pp.cpp @@ -393,6 +393,14 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo TSourceLoc loc = ppToken->loc; // because we sometimes read the newline before reporting the error if (token == PpAtomIdentifier) { if (strcmp("defined", ppToken->name) == 0) { + if (isMacroInput()) { + if (parseContext.relaxedErrors()) + parseContext.ppWarn(ppToken->loc, "nonportable when expanded from macros for preprocessor expression", + "defined", ""); + else + parseContext.ppError(ppToken->loc, "cannot use in preprocessor expression when expanded from macros", + "defined", ""); + } bool needclose = 0; token = scanToken(ppToken); if (token == '(') { diff --git a/glslang/MachineIndependent/preprocessor/PpContext.h b/glslang/MachineIndependent/preprocessor/PpContext.h index a459d9a2a..de48e2794 100644 --- a/glslang/MachineIndependent/preprocessor/PpContext.h +++ b/glslang/MachineIndependent/preprocessor/PpContext.h @@ -200,6 +200,7 @@ public: virtual void ungetch() = 0; virtual bool peekPasting() { return false; } // true when about to see ## virtual bool endOfReplacementList() { return false; } // true when at the end of a macro replacement list (RHS of #define) + virtual bool isMacroInput() { return false; } // Will be called when we start reading tokens from this instance virtual void notifyActivated() {} @@ -306,6 +307,7 @@ protected: void ungetChar() { inputStack.back()->ungetch(); } bool peekPasting() { return !inputStack.empty() && inputStack.back()->peekPasting(); } bool endOfReplacementList() { return inputStack.empty() || inputStack.back()->endOfReplacementList(); } + bool isMacroInput() { return inputStack.size() > 0 && inputStack.back()->isMacroInput(); } static const int maxIfNesting = 64; @@ -329,6 +331,7 @@ protected: virtual void ungetch() override { assert(0); } bool peekPasting() override { return prepaste; } bool endOfReplacementList() override { return mac->body.atEnd(); } + bool isMacroInput() override { return true; } MacroSymbol *mac; TVector<TokenStream*> args; -- GitLab