[Mesa-dev] Bogus use of '#' in a macro definition (was: Re: Mesa (master): 29 new commits)

Carl Worth cworth at cworth.org
Thu Jul 31 11:01:29 PDT 2014


Ian Romanick <idr at freedesktop.org> writes:
> On 07/31/2014 12:14 AM, Michel Dänzer wrote:
>> 
>> FYI, this change broke the game Reaction Quake, see the failure output
>> below. I don't know if this is a bug in this change or in the game, so
>> I'm reporting it here.

Hi Michel,

Thanks very much for reporting this failure. It's certainly an
interesting one.

>> #define USE_DISCARD#line 0
>
> Something is seriously wrong here.

The above line in the shader does seem to be what is triggering the
error you noticed:

>> 0:46(20): preprocessor error: syntax error, unexpected HASH_TOKEN, expecting NEWLINE

Before the referenced commit, "#define foo#bar" would be accepted, (for
some definition of "accepted"[*]) while after the commit, the same input
causes the above error.

It's fairly obvious that that line is not what was intended by the
author of the shader, so a bug should be reported to the game
authors. Michel, can you follow up with that?

Meanwhile, I've looked at the GLSL specification and it's quite clear
that no '#' character is allowed except for introducing a directive, (so
at the beginning of a line, ignoring horizontal whitespace and
comments), or as part of a token-pasting operator in the replacement
list of a macro.

So I do think it's legitimate to generate a syntax error here.

But I also thought it would be worthwhile to look at what other
implementations do in a case like this. For example, given:

	#define foo#bar

gcc's preprocessor emits a diagnostic:

	warning: missing whitespace after the macro name [enabled by default]

and then goes on to behave as if what had been presented was:

	#define foo #bar

(where "#bar" is literal text, and never interpreted as a directive).

For GLSL, we could do that, and if the foo macro is ever actually used,
the appearance of '#' should then generate a syntax error in the
compiler.

This is similar to "#define foo;bar" where gcc also generates the
warning and then defines "foo" to ";bar". For that case, glcpp is
already compatible with gcc, (though not generating the warning).

I also checked that Nvidia's implementation does accept the following
line without an error:

        #define USE_DISCARD#line 0

It appears to be defining a macro USE_DISCARD to a value of "0",
(ignoring the "#line" portion). This isn't compatible with gcc, but
again, we're entirely outside the bounds of any specification with this
input.

I've experimented, and I've come up with a fairly simple patch that
would treat '#' in the same way that ';' is currently treated in a case
like this. That is:

     #define USE_DISCARD#line 0

will define the USE_DISCARD macro to expand to "#line 0", (but not
treating #line as a directive).

Again, like I said above, I don't think that's strictly necessary
here. I believe the syntax error is legitimate, (and perhaps even
helpful---it pointed us to this bug in Reaction Quake's shader, for
example). But it is a possibility.

I'll follow up with that patch.

-Carl

[*] For reference, here's what previous versions of mesa would do with a
line like:

	#define USE_DISCARD#line 0

1. Print a '#' character to stdout while parsing this shader

2. Define the USE_DISCARD macro to the text "line 0"

-- 
carl.d.worth at intel.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20140731/248b3b31/attachment-0001.sig>


More information about the mesa-dev mailing list