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
#pragma are considered statements.
(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?
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.
When compiled with Clang, it returns 0 by the way.
(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.
#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.
*** Bug 63612 has been marked as a duplicate of this bug. ***
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.
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.
(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.
(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'?
(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).
Related bug: PR42979
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.
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.
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.
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:
(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.
(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.
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
(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.
*** Bug 71787 has been marked as a duplicate of this bug. ***
Can the bug be marked as resolved?
No. We need at least some warning where non-OpenMP/OpenACC pragmas are in spots where it causes surprises to users.
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)
*** Bug 94367 has been marked as a duplicate of this bug. ***
Hi David, Do you have plans to submit this patch for review when stage 1 of gcc 11 opens ? Cheers, Romain
GCC 10.1 has been released.
GCC 10.2 is released, adjusting target milestone.
GCC 10.3 is being released, retargeting bugs to GCC 10.4.
*** Bug 101538 has been marked as a duplicate of this bug. ***
GCC 10.4 is being released, retargeting bugs to GCC 10.5.
*** Bug 111758 has been marked as a duplicate of this bug. ***
*** Bug 113587 has been marked as a duplicate of this bug. ***