Bug 63326 (GCC-pragma) - whether a #pragma is a statement depends on the type of pragma
Summary: whether a #pragma is a statement depends on the type of pragma
Status: ASSIGNED
Alias: GCC-pragma
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.9.1
: P3 normal
Target Milestone: ---
Assignee: David Malcolm
URL:
Keywords: deferred
: 63612 71787 94367 101538 111758 113587 (view as bug list)
Depends on:
Blocks:
 
Reported: 2014-09-22 06:36 UTC by Dietmar Schindler
Modified: 2024-01-24 17:27 UTC (History)
10 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2014-09-24 00:00:00


Attachments
preprocessed file (139 bytes, text/plain)
2014-09-22 06:36 UTC, Dietmar Schindler
Details
Work-in-progress patch for a new warning for this (for GCC 10 stage 1) (4.29 KB, patch)
2019-02-12 17:30 UTC, David Malcolm
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dietmar Schindler 2014-09-22 06:36:56 UTC
Created attachment 33530 [details]
preprocessed file

The following command generates wrong code, returning 1 instead of 0 (as if the pragma line ended the statement in which it is placed).

raeksrv1:~/bin/so/c> /tmp/usr/local/bin/gcc -v -save-temps bug.c -o bug         
Using built-in specs.
COLLECT_GCC=/tmp/usr/local/bin/gcc
COLLECT_LTO_WRAPPER=/tmp/usr/local/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.9.1/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-4.9.1/configure --enable-plugin --disable-libsanitizer : (reconfigured) ../gcc-4.9.1/configure --enable-plugin --enable-languages=c --disable-libsanitizer : (reconfigured) ../gcc-4.9.1/configure --enable-plugin --enable-languages=c --disable-libsanitizer --disable-libcilkrts
Thread model: posix
gcc version 4.9.1 (GCC) 
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'bug' '-mtune=generic' '-march=x86-64'
 /tmp/usr/local/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.9.1/cc1 -E -quiet -v -iprefix /tmp/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.9.1/ bug.c -mtune=generic -march=x86-64 -fpch-preprocess -o bug.i
ignoring nonexistent directory "/tmp/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.9.1/../../../../x86_64-unknown-linux-gnu/include"
ignoring duplicate directory "/tmp/usr/local/bin/../lib/gcc/../../lib/gcc/x86_64-unknown-linux-gnu/4.9.1/include"
ignoring duplicate directory "/tmp/usr/local/bin/../lib/gcc/../../lib/gcc/x86_64-unknown-linux-gnu/4.9.1/include-fixed"
ignoring nonexistent directory "/tmp/usr/local/bin/../lib/gcc/../../lib/gcc/x86_64-unknown-linux-gnu/4.9.1/../../../../x86_64-unknown-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /tmp/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.9.1/include
 /tmp/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.9.1/include-fixed
 /usr/local/include
 /usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'bug' '-mtune=generic' '-march=x86-64'
 /tmp/usr/local/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.9.1/cc1 -fpreprocessed bug.i -quiet -dumpbase bug.c -mtune=generic -march=x86-64 -auxbase bug -version -o bug.s
GNU C (GCC) version 4.9.1 (x86_64-unknown-linux-gnu)
        compiled by GNU C version 4.9.1, GMP version 4.3.2, MPFR version 2.4.2, MPC version 0.8.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C (GCC) version 4.9.1 (x86_64-unknown-linux-gnu)
        compiled by GNU C version 4.9.1, GMP version 4.3.2, MPFR version 2.4.2, MPC version 0.8.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: aa505e323dbffe0cb500ba62f983d917
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'bug' '-mtune=generic' '-march=x86-64'
 as -v --64 -o bug.o bug.s
GNU assembler version 2.20.1 (i486-linux-gnu) using BFD version (GNU Binutils for Debian) 2.20.1-system.20100303
COMPILER_PATH=/tmp/usr/local/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.9.1/:/tmp/usr/local/bin/../libexec/gcc/
LIBRARY_PATH=/tmp/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.9.1/:/tmp/usr/local/bin/../lib/gcc/:/tmp/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.9.1/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/tmp/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.9.1/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'bug' '-mtune=generic' '-march=x86-64'
 /tmp/usr/local/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.9.1/collect2 --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o bug /usr/lib/../lib64/crt1.o /usr/lib/../lib64/crti.o /tmp/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.9.1/crtbegin.o -L/tmp/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.9.1 -L/tmp/usr/local/bin/../lib/gcc -L/tmp/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.9.1/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/tmp/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.9.1/../../.. bug.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /tmp/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.9.1/crtend.o /usr/lib/../lib64/crtn.o
Comment 1 Andrew Pinski 2014-09-22 06:41:30 UTC
#pragma are considered statements.
Comment 2 Dietmar Schindler 2014-09-24 11:46:50 UTC
(In reply to Andrew Pinski from comment #1)
> #pragma are considered statements.

This can't be entirely true, since #pragma can be used where statements cannot (outside of functions), and #pragma STDC certainly isn't considered a statement.
At least, this implementation-defined behaviour has to be documented (hasn't it?), and I couldn't find mention of it in the documentation. Would you recommend filing a separate documentation bug report?
Comment 3 Manuel López-Ibáñez 2014-09-24 14:36:18 UTC
If you use #pragma GCC system_header, you get a different result, so this seems a bug to me (whatever the behavior, it should not depend on the type of #pragma). At the very least, GCC could give a warning if the #pragma is the only statement in a if/else/while/do/for body, since this is probably a bug.
Comment 4 Manuel López-Ibáñez 2014-09-24 14:38:12 UTC
When compiled with Clang, it returns 0 by the way.
Comment 5 Andrew Pinski 2014-09-24 15:40:53 UTC
(In reply to Manuel López-Ibáñez from comment #4)
> When compiled with Clang, it returns 0 by the way.

So ...
Pragma that are not recognized are ignored.
Comment 6 jsm-csl@polyomino.org.uk 2014-09-24 15:52:21 UTC
#pragma STDC is functionally a declaration (it can only occur "either 
outside external declarations or preceding all explicit declarations and 
statements inside a compound statement" - each such pragma has the same 
wording, including FENV_ROUND in TS 18661-1).  Thus, while those pragmas 
are not currently implemented in GCC, treating them as syntactical 
entities at the same level as declarations and statements would be fully 
in accordance with the standard.
Comment 7 Andrew Pinski 2014-10-21 23:20:24 UTC
*** Bug 63612 has been marked as a duplicate of this bug. ***
Comment 8 Richard Biener 2014-10-22 08:24:31 UTC
Maybe we should also warn about

  if (...)
#pragma STDC ...
    foo ();

both if we are treating the #pragma as stmt and if not.  That is, if the
#pragma appears in a place where that would make a difference.
Comment 9 Jakub Jelinek 2014-10-22 09:01:14 UTC
Note, we already error out on OpenMP pragmas in such places, because the OpenMP standard requires that the pragmas aren't used in contexts where accepting them as statements or ignoring them would make a difference for parsing the function:
"For C/C++, a stand-alone directive may not be used in place of the statement following an if, while, do, switch, or label. See Appendix B for the formal grammar."
so for other pragmas we could use similar conditions.
Comment 10 Manuel López-Ibáñez 2014-10-22 12:39:42 UTC
(In reply to steveren from comment #6)
> Seems the consensus is that it's not contrary to Standard, but it's agreed
> to be confusing and undesirable by everyone except the gcc maintainers :-)

Not sure how you reached such conclusion, but it clearly misinterprets reality, otherwise this PR would be closed as INVALID already.

I'm pretty sure if you submitted a patch making the behavior of all pragmas consistent with comment #9, this will be fixed by next week. (https://gcc.gnu.org/wiki/GettingStarted#Basics:_Contributing_to_GCC_in_10_easy_steps)

> I'll take a lot of persuading that this isn't a reasonable thing to want to
> do. (Flagging the nasty, that is; purists who say you should never /do/
> anything you need to warn people about need not apply :-) )

I'm not sure to which "purists" you are referring but, from my experience, GCC welcomes warnings that help people to write better code and prevent mistakes as long as patches are written and tested properly and do not generate too many hard-to-work-around false positives. New warnings are added in every release. Thus, I would encourage you to submit a patch and see for yourself.
Comment 11 steveren 2014-10-22 13:51:58 UTC
(In reply to Manuel López-Ibáñez from comment #10)
> (In reply to steveren from comment #6)
> > Seems the consensus is that it's not contrary to Standard, but it's agreed
> > to be confusing and undesirable by everyone except the gcc maintainers :-)
> 
> Not sure how you reached such conclusion, but it clearly misinterprets
> reality, otherwise this PR would be closed as INVALID already.

Ok, my apologies. However, this bug /was/ closed as invalid before being reopened, and my own report was closed as invalid before being marked as a dupe of this one, so it's not entirely clear that there's a general feeling of a real problem that needs to be addressed.

> I'm pretty sure if you submitted a patch making the behavior of all pragmas 
> consistent with comment #9,

But I don't /want/ behaviour consistent with #9 (ie, warning that the usage is invalid), I want the usage to be valid /and/ sensible - ie, the same as other compilers. I suspect that's more difficult...

Don't get me wrong - I'm not whingeing that other people should solve my problems for me without being prepared to get involved myself, but if this is WAD in the eyes of the majority, then I'll live with it sooner than create my own fork!

So assuming it's not actually beyond somebody completely unfamiliar with the innards of gcc, what would be the response to a patch which changed #pragma message from 'statement' to 'not-a-statement'?
Comment 12 Manuel López-Ibáñez 2014-10-22 14:10:02 UTC
(In reply to steveren from comment #11)
> So assuming it's not actually beyond somebody completely unfamiliar with the
> innards of gcc, what would be the response to a patch which changed #pragma
> message from 'statement' to 'not-a-statement'?

I think that even if not a definitive solution, it would be a positive step towards understanding what would it take to change the behavior for specific #pragmas (since we cannot change how OMP #pragmas behave).
Comment 13 Manuel López-Ibáñez 2015-10-29 00:49:18 UTC
Related bug: PR42979
Comment 14 Chen Gang 2015-11-21 09:06:27 UTC
For gcc version 6.0.0 20151121 (experimental) (GCC), this issue is still existant. I shall try to fix it within this month (2015-11-30).

Hope I can succeed.
Comment 15 Chen Gang 2015-11-21 13:10:22 UTC
For me, comment #9 is the reasonable fixing way. In real world, C/C++ programmers will/should not use #pragma in this way (use #pragma in place of the statement following an if, while, do, switch, or label).

Another compilers maybe support #pragma in this way and check every #pragma details to determine to be as a statement or not, but in real world, this feature is useless (never need be used) for C/C++ programmers. It is worthless for gcc to support it.

Could any members tell me the related usage cases in real world?

Thanks.
Comment 16 Chen Gang 2015-11-21 14:37:10 UTC
Our C++ has no this issue. For precisely saying: cc1 has the issue, but cc1plus has no the issue (if use g++ build c programs, it has no issue; if use gcc build c++ programs, it has no issue, either).

But still, for me, it is worthless for gcc and g++ to support this feature.
Comment 17 Chen Gang 2015-11-22 22:18:37 UTC
I guess the diff below should be OK, I shall give a make check test.

diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 7b10764..2666657 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -5170,7 +5170,9 @@ c_parser_statement_after_labels (c_parser *parser, vec<tree> *chain)
       c_parser_consume_token (parser);
       break;
     case CPP_PRAGMA:
-      c_parser_pragma (parser, pragma_stmt);
+      c_parser_error (parser,
+                     "don't allow if, while, do, swith, or label"
+                    );
       break;
     default:
     expr_stmt:
Comment 18 Andrew Pinski 2015-11-23 01:13:21 UTC
(In reply to Chen Gang from comment #17)
> I guess the diff below should be OK, I shall give a make check test.

I would rather have the C front-end behavior for C++ rather than the opposite way around.  Because _Pragma are considered statements.
Comment 19 Chen Gang 2015-11-23 14:26:51 UTC
(In reply to Andrew Pinski from comment #18)
> (In reply to Chen Gang from comment #17)
> > I guess the diff below should be OK, I shall give a make check test.
> 
> I would rather have the C front-end behavior for C++ rather than the
> opposite way around.  Because _Pragma are considered statements.

For me, this bug is related with the demands (language definition), and C need not be part of C++.

 - For me, what cc1plus has done is OK: C++ looks that it always 'likes' more new features, and want to let the users (C++ programmer) use the language freely and in common sense.

 - But for C, if one feature is in discussing, it should not be treated as a common features (C standard is more stricter than C++). So we need not care about this 'bug' quite much (In real world, C programmers need not use #pragma in this way).

In our case (this cc1 'bug'), Instead of returning the 'anbisous' result (it may cause misunderstanding for C/C++ programmers more or less), cc1 need report error during compiling.
Comment 20 Chen Gang 2015-11-23 14:27:53 UTC
(In reply to Andrew Pinski from comment #18)
> (In reply to Chen Gang from comment #17)
> > I guess the diff below should be OK, I shall give a make check test.
> 
> I would rather have the C front-end behavior for C++ rather than the
> opposite way around.  Because _Pragma are considered statements.

For me, this bug is related with the demands (language definition), and C need not be part of C++.

 - For me, what cc1plus has done is OK: C++ looks that it always 'likes' more new features, and want to let the users (C++ programmer) use the language freely and in common sense.

 - But for C, if one feature is in discussing, it should not be treated as a common features (C standard is more stricter than C++). So we need not care about this 'bug' quite much (In real world, C programmers need not use #pragma in this way).

In our case (this cc1 'bug'), Instead of returning the 'anbisous' result (it may cause misunderstanding for C/C++ programmers more or less), cc1 need report error during compiling.
Comment 21 Jakub Jelinek 2015-11-27 09:00:27 UTC
Author: jakub
Date: Fri Nov 27 08:59:55 2015
New Revision: 230999

URL: https://gcc.gnu.org/viewcvs?rev=230999&root=gcc&view=rev
Log:
	PR c/63326
	* c-parser.c (c_parser_compound_statement_nostart): If
	last_label is true, use pragma_stmt instead of pragma_compound
	as second c_parser_pragma argument.
	(c_parser_omp_ordered, c_parser_omp_target_update,
	c_parser_omp_target_enter_data, c_parser_omp_target_exit_data): Pass
	false as second argument to c_parser_skip_to_pragma_eol after
	diagnosing standalone directives used in pragma_stmt context.

	* parser.c (cp_parser_statement): Clear in_compound after labels.

	* gcc.dg/gomp/barrier-2.c (f2): Expect another error after label.
	* c-c++-common/gomp/pr63326.c: New test.

	* testsuite/libgomp.c/cancel-parallel-2.c (foo): Add semicolon
	in between case label and OpenMP standalone directives.
	* testsuite/libgomp.c++/cancel-parallel-2.C (foo): Likewise.

Added:
    trunk/gcc/testsuite/c-c++-common/gomp/pr63326.c
Modified:
    trunk/gcc/c/ChangeLog
    trunk/gcc/c/c-parser.c
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/parser.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gcc.dg/gomp/barrier-2.c
    trunk/libgomp/ChangeLog
    trunk/libgomp/testsuite/libgomp.c++/cancel-parallel-2.C
    trunk/libgomp/testsuite/libgomp.c/cancel-parallel-2.c
Comment 22 Chen Gang 2015-11-28 01:37:57 UTC
(In reply to Jakub Jelinek from comment #21)
> Author: jakub
> Date: Fri Nov 27 08:59:55 2015
> New Revision: 230999
> 
> URL: https://gcc.gnu.org/viewcvs?rev=230999&root=gcc&view=rev

This way looks OK to me.

But for C++, it has no pr63326 issue, do we still need to modify gcc/cp/parser.c?

pr42979 is related with this issue, more or less. May this patch also fix pr42979 by the way? If this patch really fix pr42979, we will still need gcc/cp/parser.c (both C and C++ have pr42979 issue).


Thanks.
Comment 23 Manuel López-Ibáñez 2016-07-07 06:37:11 UTC
*** Bug 71787 has been marked as a duplicate of this bug. ***
Comment 24 Martin Liška 2018-11-19 13:11:25 UTC
Can the bug be marked as resolved?
Comment 25 Jakub Jelinek 2018-11-19 13:18:38 UTC
No.  We need at least some warning where non-OpenMP/OpenACC pragmas are in spots where it causes surprises to users.
Comment 26 David Malcolm 2019-02-12 17:30:45 UTC
Created attachment 45674 [details]
Work-in-progress patch for a new warning for this (for GCC 10 stage 1)

(I plan to post this to the mailing list once gcc 10 stage 1 opens)
Comment 27 Andrew Pinski 2020-03-27 18:40:02 UTC
*** Bug 94367 has been marked as a duplicate of this bug. ***
Comment 28 Romain Geissler 2020-03-27 18:47:47 UTC
Hi David,

Do you have plans to submit this patch for review when stage 1 of gcc 11 opens ?

Cheers,
Romain
Comment 29 Jakub Jelinek 2020-05-07 11:56:31 UTC
GCC 10.1 has been released.
Comment 30 Richard Biener 2020-07-23 06:51:52 UTC
GCC 10.2 is released, adjusting target milestone.
Comment 31 Richard Biener 2021-04-08 12:02:11 UTC
GCC 10.3 is being released, retargeting bugs to GCC 10.4.
Comment 32 Martin Sebor 2021-07-20 19:40:31 UTC
*** Bug 101538 has been marked as a duplicate of this bug. ***
Comment 33 Jakub Jelinek 2022-06-28 10:31:08 UTC
GCC 10.4 is being released, retargeting bugs to GCC 10.5.
Comment 34 Andrew Pinski 2023-10-10 12:13:47 UTC
*** Bug 111758 has been marked as a duplicate of this bug. ***
Comment 35 Andrew Pinski 2024-01-24 17:27:47 UTC
*** Bug 113587 has been marked as a duplicate of this bug. ***