public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug preprocessor/106767] New: Failure to detect recursive macro calls due to _Pragma(pop_macro)
@ 2022-08-28 21:58 izbyshev at ispras dot ru
2022-08-28 22:01 ` [Bug preprocessor/106767] " pinskia at gcc dot gnu.org
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: izbyshev at ispras dot ru @ 2022-08-28 21:58 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106767
Bug ID: 106767
Summary: Failure to detect recursive macro calls due to
_Pragma(pop_macro)
Product: gcc
Version: 13.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: preprocessor
Assignee: unassigned at gcc dot gnu.org
Reporter: izbyshev at ispras dot ru
CC: amonakov at gcc dot gnu.org
Target Milestone: ---
GCC preprocessor appears to behave as if each _Pragma(pop_macro("m")) creates a
new definition of "m", so, for example, the following code results in infinite
recursion:
#define P(x) _Pragma(#x)
#define f() P(push_macro("f")) P(pop_macro("f")) f()
f()
Naturally, this makes the preprocessor Turing-complete, e.g. it can add
numbers:
#define P(x) _Pragma(#x)
#define PUSH(x) P(push_macro(#x))
#define POP(x) P(pop_macro(#x))
#define R(f) PUSH(f) POP(f)
#define C(x, y) x ## y
#define ADD0(...) __VA_ARGS__
#define ADD1(...) 1, R(ADD) ADD(__VA_ARGS__)
#define ADD(x, ...) C(ADD, x)(__VA_ARGS__)
// 1 + 2 (zero-terminated unary numbers)
ADD(1, 0, 1, 1, 0)
// Outputs 1, 1, 1, 0 with "gcc -E -P"
The earliest GCC with this behavior on https://godbolt.org is 4.4.7.
Clang detects recursion correctly.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug preprocessor/106767] Failure to detect recursive macro calls due to _Pragma(pop_macro)
2022-08-28 21:58 [Bug preprocessor/106767] New: Failure to detect recursive macro calls due to _Pragma(pop_macro) izbyshev at ispras dot ru
@ 2022-08-28 22:01 ` pinskia at gcc dot gnu.org
2022-08-28 22:27 ` izbyshev at ispras dot ru
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-08-28 22:01 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106767
--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
How does msvc handle this? Since gcc is trying to be compatible with msvc here.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug preprocessor/106767] Failure to detect recursive macro calls due to _Pragma(pop_macro)
2022-08-28 21:58 [Bug preprocessor/106767] New: Failure to detect recursive macro calls due to _Pragma(pop_macro) izbyshev at ispras dot ru
2022-08-28 22:01 ` [Bug preprocessor/106767] " pinskia at gcc dot gnu.org
@ 2022-08-28 22:27 ` izbyshev at ispras dot ru
2022-08-28 23:39 ` izbyshev at ispras dot ru
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: izbyshev at ispras dot ru @ 2022-08-28 22:27 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106767
--- Comment #2 from Alexey Izbyshev <izbyshev at ispras dot ru> ---
Old MSVC doesn't support _Pragma, and I can make newer one recognize _Pragma
only by unquoting the string literal, so the first test case becomes:
// Removed stringizing in _Pragma
#define P(x) _Pragma(x)
#define f() P(push_macro("f")) P(pop_macro("f")) f()
f()
Recursion is detected properly:
> cl /E test.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29910 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
test.c
#line 1 "test.c"
f()
The second test case modified in the same way also works:
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29910 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
add.c
#line 1 "add.c"
1, ADD(0, 1, 1, 0)
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug preprocessor/106767] Failure to detect recursive macro calls due to _Pragma(pop_macro)
2022-08-28 21:58 [Bug preprocessor/106767] New: Failure to detect recursive macro calls due to _Pragma(pop_macro) izbyshev at ispras dot ru
2022-08-28 22:01 ` [Bug preprocessor/106767] " pinskia at gcc dot gnu.org
2022-08-28 22:27 ` izbyshev at ispras dot ru
@ 2022-08-28 23:39 ` izbyshev at ispras dot ru
2022-08-29 8:44 ` rguenth at gcc dot gnu.org
2022-08-29 9:44 ` izbyshev at ispras dot ru
4 siblings, 0 replies; 6+ messages in thread
From: izbyshev at ispras dot ru @ 2022-08-28 23:39 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106767
--- Comment #3 from Alexey Izbyshev <izbyshev at ispras dot ru> ---
> I can make newer one recognize _Pragma only by unquoting the string literal
I've investigated this strange behavior because MSVC docs do claim that C99
_Pragma is properly supported[1].
It turned out that /E (preprocess) MSVC option is semi-broken and its output
can't be trusted. When it's specified, ill-formed _Pragma with arguments that
are tokens instead of a string literal appears to behave like simple #pragma:
> type test.c
#define X 1
_Pragma(push_macro("X"))
#undef X
#define X 2
_Pragma(pop_macro("X"))
int x = X;
> cl /E /std:c11 test.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29910 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
test.c
#line 1 "test.c"
int x = 1 ;
And correct _Pragma with a string literal is only expanded to MSVC-internal
__pragma, without actually "executing" it, so X is expanded incorrectly below:
> type test.c
#define X 1
_Pragma("push_macro(\"X\")")
#undef X
#define X 2
_Pragma("pop_macro(\"X\")")
int x = X;
> cl /E /std:c11 test.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29910 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
test.c
#line 1 "test.c"
__pragma(push_macro("X"))
__pragma(pop_macro("X"))
int x = 2 ;
However, without /E it works as expected: ill-formed _Pragma is a syntax error,
and proper _Pragma is processed, e.g. with the previous example X is expanded
to 1:
>cl /c /Facon /std:c11 test.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29910 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
test.c
; Listing generated by Microsoft (R) Optimizing Compiler Version 19.28.29910.0
include listing.inc
INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES
PUBLIC x
_DATA SEGMENT
x DD 01H
_DATA ENDS
END
Nothing of the above changes the fact that macro recursion is detected properly
by MSVC, so Clang and MSVC behave the same way in this regard.
[1]
https://docs.microsoft.com/en-us/cpp/preprocessor/pragma-directives-and-the-pragma-keyword?view=msvc-170
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug preprocessor/106767] Failure to detect recursive macro calls due to _Pragma(pop_macro)
2022-08-28 21:58 [Bug preprocessor/106767] New: Failure to detect recursive macro calls due to _Pragma(pop_macro) izbyshev at ispras dot ru
` (2 preceding siblings ...)
2022-08-28 23:39 ` izbyshev at ispras dot ru
@ 2022-08-29 8:44 ` rguenth at gcc dot gnu.org
2022-08-29 9:44 ` izbyshev at ispras dot ru
4 siblings, 0 replies; 6+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-08-29 8:44 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106767
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jsm28 at gcc dot gnu.org,
| |ktietz at gcc dot gnu.org
Ever confirmed|0 |1
Status|UNCONFIRMED |NEW
Last reconfirmed| |2022-08-29
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
Not sure if Kai is still active but he contributed push/pop_macro support.
Is there a public specification of the Microsoft extension and how it is
supposed to behave with recursion or is the recursion behavior specified
by the C standard?
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug preprocessor/106767] Failure to detect recursive macro calls due to _Pragma(pop_macro)
2022-08-28 21:58 [Bug preprocessor/106767] New: Failure to detect recursive macro calls due to _Pragma(pop_macro) izbyshev at ispras dot ru
` (3 preceding siblings ...)
2022-08-29 8:44 ` rguenth at gcc dot gnu.org
@ 2022-08-29 9:44 ` izbyshev at ispras dot ru
4 siblings, 0 replies; 6+ messages in thread
From: izbyshev at ispras dot ru @ 2022-08-29 9:44 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106767
--- Comment #5 from Alexey Izbyshev <izbyshev at ispras dot ru> ---
(In reply to Richard Biener from comment #4)
> Is there a public specification of the Microsoft extension and how it is
> supposed to behave with recursion or is the recursion behavior specified
> by the C standard?
I would be surprised if anything that could be called "a public specification"
exists. The Clang patch[1] from 2010 cites only the rudimentary MSDN
documentation[2].
I've modified the first test case to be compilable to assembler to avoid
relying on broken /E:
#define P(x) _Pragma(#x)
#define f() P(push_macro("f")) P(pop_macro("f")) f()
int f() {
return 42;
}
and have checked that:
* All x64 MSVC versions supporting C99 _Pragma and available at godbolt
(19.25-19.33/latest) successfully compile it (with and without /Zc:preprocessor
option which enables standard-conforming preprocessor, where it's supported).
The only exception is 19.26 with /Zc:preprocessor: it emits strange syntax
errors, but that's likely a bug in the new preprocessor (19.26 is the first
version supporting it).
* All x64 MSVC versions available at godbolt (19.0, 19.10, 19.14-19.33/latest)
successfully compile the same test case with _Pragma(#x) replaced with
MSVC-specific __pragma(x) equivalent (again, with and without /Zc:preprocessor
where supported).
This suggests that push/pop_macro isn't supposed to interfere with recursion
detection.
[1]
https://github.com/llvm/llvm-project/commit/c0a585d63c6cf700ea01f1fe30c9f4cd51c1e97b
[2] https://docs.microsoft.com/en-us/cpp/preprocessor/push-macro
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2022-08-29 9:44 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-28 21:58 [Bug preprocessor/106767] New: Failure to detect recursive macro calls due to _Pragma(pop_macro) izbyshev at ispras dot ru
2022-08-28 22:01 ` [Bug preprocessor/106767] " pinskia at gcc dot gnu.org
2022-08-28 22:27 ` izbyshev at ispras dot ru
2022-08-28 23:39 ` izbyshev at ispras dot ru
2022-08-29 8:44 ` rguenth at gcc dot gnu.org
2022-08-29 9:44 ` izbyshev at ispras dot ru
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).