Bug 82335 - Incorrect _Pragma expansion if macro passed to another macro
Summary: Incorrect _Pragma expansion if macro passed to another macro
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: preprocessor (show other bugs)
Version: 5.4.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2017-09-27 01:32 UTC by Petr Skocik
Modified: 2023-10-19 13:12 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2023-10-02 00:00:00


Attachments
reproducer for "Incorrect _Pragma expansion in complex macro expressions"; compile with -Wall -Wextra (314 bytes, text/plain)
2017-09-27 01:32 UTC, Petr Skocik
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Petr Skocik 2017-09-27 01:32:36 UTC
Created attachment 42239 [details]
reproducer for "Incorrect _Pragma expansion  in complex macro expressions"; compile with -Wall -Wextra

Basically, _Pragma's expansions (as shown with gcc -E) seem to get shifted out of some slightly "more complex" macro expressions, which renders them ineffective.

Attached is one piece of code that reproduces the problem. When compiled with `-Wall -Wextra`, the warning which should've been silenced isn't, because the #pragma push-pop pair gets shifted out of the expression.

It's hard to pinpoint exactly what causes this, and the problem goes away with minor complexity reductions (such as replacing a macro (e.g., the tof macro) with what it expands to), but it seems to stick in more complex contexts.

clang handles everything fine.
Comment 1 Petr Skocik 2018-11-16 09:19:15 UTC
This problem still persists in gcc 7.3.0. It appears pasting a macro containing `_Pragma`s into
another macro is what's causing the displacement of the generated `#pragma`s.

I've cleaned up the example to make it clearer:


	#define PRAGMA(...) _Pragma(#__VA_ARGS__)
	#define PASTE(Expr)      Expr
	#define PUSH_IGN(X) PRAGMA(GCC diagnostic push) PRAGMA(GCC diagnostic ignored X)
	#define POP() PRAGMA(GCC diagnostic pop)

	#define SIGNED_EH(X) \
		({ PUSH_IGN("-Wtype-limits") \
		_Bool SIGNED_EH = ((__typeof(X))-1 < 0); \
		 POP() \
		 SIGNED_EH; })

	int main();
	{
		unsigned x;
		SIGNED_EH(x);       //OK; #pragmas generated around the assignment:
	#if 0 //generated:
			 ({
				#pragma GCC diagnostic push
				#pragma GCC diagnostic ignored "-Wtype-limits"
			  _Bool SIGNED_EH = ((__typeof(x))-1 < 0);
				#pragma GCC diagnostic pop
			  SIGNED_EH; });
	#endif


		PASTE(SIGNED_EH(x)); //OOPS generates:

	#if 0 //generated:
			#pragma GCC diagnostic push
			#pragma GCC diagnostic ignored "-Wtype-limits"
			#pragma GCC diagnostic pop
			 ({ _Bool SIGNED_EH = ((__typeof(x))-1 < 0); SIGNED_EH; });
	#endif
	}

Clang's preprocessor generates correct code even for the `PASTE(SIGNED_EH(x))` case.
Comment 2 Lewis Hyatt 2023-10-02 22:26:09 UTC
Depending which variant of the test you look at, this ended up getting resolved by r12-4797 and/or by r12-5454. It is the same issue as bug 102409 and bug 90400. The testcase from this PR seems worth adding in addition, so I will do that prior to closing this one. Patch adding the testcase submitted for review here: https://gcc.gnu.org/pipermail/gcc-patches/2023-October/631814.html
Comment 3 CVS Commits 2023-10-19 13:11:25 UTC
The master branch has been updated by Lewis Hyatt <lhyatt@gcc.gnu.org>:

https://gcc.gnu.org/g:202a214d6859d91af5a95aa989321c5d2173c40a

commit r14-4747-g202a214d6859d91af5a95aa989321c5d2173c40a
Author: Lewis Hyatt <lhyatt@gmail.com>
Date:   Mon Oct 2 14:56:58 2023 -0400

    libcpp: testsuite: Add test for fixed _Pragma bug [PR82335]
    
    This PR was fixed by r12-4797 and r12-5454. Add test coverage from the PR
    that is not represented elsewhere.
    
    gcc/testsuite/ChangeLog:
    
            PR preprocessor/82335
            * c-c++-common/cpp/diagnostic-pragma-3.c: New test.
Comment 4 Lewis Hyatt 2023-10-19 13:12:59 UTC
Closing it now that the testcase has been added.