Pelles C forum

Pelles C => Bug reports => Topic started by: nemequ on April 12, 2019, 08:09:00 PM

Title: Multiple _Pragmas cause errors
Post by: nemequ on April 12, 2019, 08:09:00 PM
I recently added support for Pelles C to one of my projects (Hedley (http://nemequ.github.io/hedley/)), and I noticed that "calling" _Pragma multiple times on a single line causes errors.  This is particularly annoying in preprocessor macros, so here's a quick test for that:

Code: [Select]
#define FOO_DLLEXPORT \
  _Pragma("warn(push)") \
  _Pragma("warn(disable:2016)") \
  __declspec(dllexport) \
  _Pragma("warn(pop)")

FOO_DLLEXPORT
void foo(void) { }

Results in

pragmas.c(7): error #1017: Syntax error in directive.
pragmas.c(7): warning #2099: Missing type specifier; assuming 'int'.
pragmas.c(7): error #2001: Syntax error: expected ')' but found 'string constant'.
pragmas.c(7): error #2001: Syntax error: expected ';' but found '_Pragma'.
pragmas.c(7): warning #2099: Missing type specifier; assuming 'int'.
pragmas.c(7): error #2001: Syntax error: expected ')' but found 'string constant'.
pragmas.c(7): warning #2117: Old-style function definition for '_Pragma'.
pragmas.c(7): warning #2016: Use of __declspec(dllexport) requires the /Ze option; ignored.
pragmas.c(7): warning #2099: Missing type specifier; assuming 'int'.
pragmas.c(7): error #2001: Syntax error: expected ')' but found 'string constant'.
pragmas.c(8): error #2001: Syntax error: expected ';' but found 'void'.
pragmas.c(8): error #2001: Syntax error: expected ';' but found '{'.
pragmas.c(8): error #2011: Declared parameter 'foo' is missing.
pragmas.c(7): error #2011: Declared parameter '_Pragma' is missing.
error #2001: Syntax error: expected '{' but found 'end of input'.
error #2001: Syntax error: expected '}' but found 'end of input'.


On the other hand, this works:

Code: [Select]
#pragma warn(push)
#pragma warn(disable:2016)
__declspec(dllexport)
#pragma warn(pop)
void foo(void) { }

As does

Code: [Select]
_Pragma("warn(push)")
_Pragma("warn(disable:2016)")
__declspec(dllexport)
_Pragma("warn(pop)")
void foo(void) { }
Title: Re: Multiple _Pragmas cause errors
Post by: frankie on April 13, 2019, 04:35:50 PM
Have you considered that the expansion will give:
Code: [Select]
_Pragma("warn(push)") _Pragma("warn(disable:2016)") __declspec(dllexport) _Pragma("warn(pop)")

not (as probably you wished):
Code: [Select]
_Pragma("warn(push)")
_Pragma("warn(disable:2016)")
__declspec(dllexport)
_Pragma("warn(pop)")

The first is wrong, and for this reason the compiler complains.
For the same reason this shouldn't be a bug.
Title: Re: Multiple _Pragmas cause errors
Post by: nemequ on April 14, 2019, 07:44:33 AM
Yes, that's why I mentioned that the problem was with using _Pragma "multiple times on a single line", and provided an example where the _Pragmas were on multiple lines and worked.  Sorry, I could have made it a bit more explicit, but yeah I agree that the problem occurs when you use multiple _Pragma operators on a single line.

I'm not sure why you think multiple pragma operators on a single line would be wrong, though.  The C11 specification defines the pragma operator in ยง 6.10.9:

Quote
A unary operator expression of the form:
Code: [Select]
_Pragma ( string-literal )is processed as follows: The string literal is destringized by deleting any encoding prefix, deleting the leading and trailing double-quotes, replacing each escape sequence \" by a double-quote, and replacing each escape sequence \\ by a single backslash. The resulting sequence of characters is processed through translation phase 3 to produce preprocessing tokens that are executed as if they were the pp-tokens in a pragma directive. The original four preprocessing tokens in the unary operator expression are removed.

That seems pretty clear to me; the pragmas should be treated separately "as if they were the pp-tokens in a pragma directive", not mapped to an actual pragma directive without a new-line to terminate it.

It does mention that the pragma directive can also be expressed with a pragma operator, but I don't see anything to indicate that the operator should be converted by the compiler to an actual directive, much less one without a terminating new-line.  It's also interesting that the direction of the example is from directive to operator, not operator to directive.
Title: Re: Multiple _Pragmas cause errors
Post by: frankie on April 14, 2019, 05:19:55 PM
I see.
For some reason the compiler stops evaluating _Pragma operator after the first one and try to parse the line remaining as code.
Seems to be a bug.
Title: Re: Multiple _Pragmas cause errors
Post by: Pelle on April 21, 2019, 09:36:24 PM
I will think about it. I don't find the C standard text about _Pragma to be very clear and helpful.
Some other compilers seem to support this, so I might add it, but we'll see...