PATCHes to help with C++11 bootstrap
One C++11 compatibility issue that turns up a lot in the GCC sources is that in C++98, #define BAR "bar" const char *p = "foo"BAR; is well-formed, giving p the value "foobar". But in C++11 this is a user-defined literal with the suffix BAR, which is ill-formed because there is no BAR suffix defined. -Wc++11-compat didn't warn about this, which I'm fixing with the first patch. The second patch fixes all the occurrences in GCC. The third patch fixes the warning to say "-Wc++11-compat" rather than "-Wc++0x-compat". The fourth patch fixes a few G++ tests that were failing with the compiler defaulting to C++11. Tested x86_64-cp-linux-gnu, applying to trunk. commit 448d6065bcfb24d5d5aa904d93a740b552855aa5 Author: Jason Merrill Date: Fri May 8 22:55:30 2015 -0500 libcpp/ * lex.c (lex_string): Add -Wc++11-compat warning. * include/cpplib.h: Add CPP_W_CXX11_COMPAT. (struct cpp_options): Add cpp_warn_cxx11_compat. * init.c (cpp_create_reader): Initialize it. gcc/c-family/ * c.opt (Wc++0x-compat): Set it. diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 3774a89..8f48d84 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -312,7 +312,7 @@ C ObjC Var(warn_cxx_compat) CPP(warn_cxx_operator_names) CppReason(CPP_W_CXX_OPE Warn about C constructs that are not in the common subset of C and C++ Wc++0x-compat -C++ ObjC++ Var(warn_cxx0x_compat) Warning LangEnabledBy(C++ ObjC++,Wall) +C++ ObjC++ Var(warn_cxx0x_compat) Warning LangEnabledBy(C++ ObjC++,Wall) Init(0) CPP(cpp_warn_cxx11_compat) CppReason(CPP_W_CXX11_COMPAT) Deprecated in favor of -Wc++11-compat Wc++11-compat diff --git a/gcc/testsuite/g++.dg/cpp0x/warn_cxx0x4.C b/gcc/testsuite/g++.dg/cpp0x/warn_cxx0x4.C new file mode 100644 index 000..c3f0cf5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/warn_cxx0x4.C @@ -0,0 +1,4 @@ +// { dg-options "-Wall" } + +#define FOO "foo" +const char *p = "bar"FOO; // { dg-warning "macro" } diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index 5e08014..0152ec8 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -484,6 +484,9 @@ struct cpp_options /* True if warn about differences between C90 and C99. */ signed char cpp_warn_c90_c99_compat; + /* True if warn about differences between C++98 and C++11. */ + bool cpp_warn_cxx11_compat; + /* Dependency generation. */ struct { @@ -960,7 +963,8 @@ enum { CPP_W_LITERAL_SUFFIX, CPP_W_DATE_TIME, CPP_W_PEDANTIC, - CPP_W_C90_C99_COMPAT + CPP_W_C90_C99_COMPAT, + CPP_W_CXX11_COMPAT }; /* Output a diagnostic of some kind. */ diff --git a/libcpp/init.c b/libcpp/init.c index 45a4d13..1ebd709 100644 --- a/libcpp/init.c +++ b/libcpp/init.c @@ -180,6 +180,7 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table, CPP_OPTION (pfile, warn_trigraphs) = 2; CPP_OPTION (pfile, warn_endif_labels) = 1; CPP_OPTION (pfile, cpp_warn_c90_c99_compat) = -1; + CPP_OPTION (pfile, cpp_warn_cxx11_compat) = 0; CPP_OPTION (pfile, cpp_warn_deprecated) = 1; CPP_OPTION (pfile, cpp_warn_long_long) = 0; CPP_OPTION (pfile, dollars_in_ident) = 1; diff --git a/libcpp/lex.c b/libcpp/lex.c index ac96ff8..c7296a1 100644 --- a/libcpp/lex.c +++ b/libcpp/lex.c @@ -1905,6 +1905,12 @@ lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base) ++cur; } } + else if (CPP_OPTION (pfile, cpp_warn_cxx11_compat) + && is_macro (pfile, cur) + && !pfile->state.skipping) +cpp_warning_with_line (pfile, CPP_W_CXX11_COMPAT, + token->src_loc, 0, "C++11 requires a space " + "between string literal and macro"); pfile->buffer->cur = cur; create_literal (pfile, token, base, cur - base, type); commit 48a8ea6553809e0cf7bc4af33f56281fa3908b91 Author: Jason Merrill Date: Fri May 8 09:11:19 2015 -0500 * bitmap.c, c/c-aux-info.c, cfg.c, cfghooks.c, cgraph.c, config/aarch64/aarch64.md config/alpha/vms.h, config/darwin.c, config/darwin.h, config/darwin9.h, config/elfos.h, config/i386/bsd.h, config/ia64/ia64.c, config/lm32/lm32.h, config/microblaze/microblaze.h, config/mips/mips.h, config/mmix/mmix.c, config/msp430/msp430.c, config/nios2/nios2.h, config/nvptx/nvptx.c, config/nvptx/nvptx.h, config/pa/pa.c, config/pa/pa.h, config/rs6000/rs6000.c, config/rs6000/sysv4.h, config/rs6000/xcoff.h, config/rx/rx.h, config/s390/s390.h, config/sparc/sol2.h, config/sparc/sparc.h, config/visium/visium.h, cppbuiltin.c, defaults.h, doc/invoke.texi, dwarf2cfi.c, dwarf2out.c, final.c, gcc.c, gcov-dump.c, gcov.c, ipa-cp.c, ipa-inline.c, ipa-polymorphic-call.c, ipa-profile.c, ipa-prop.c, ira-color.c, ira.c, loop-doloop.c, loop-iv.c, mcf.c, modulo-sched.c, predict.c, profile.c, stor-layout.c, toplev.c, tree-ssa-reassoc.c, value-prof.c, wide-int-print.cc: Add space between string literal and macro name. diff --git a/gcc/bitmap.c b/gcc/bitmap.c index 71d5b11..66066a6 100644
Re: PATCHes to help with C++11 bootstrap
On Sat, 9 May 2015, Jason Merrill wrote: > On 05/09/2015 05:37 AM, Richard Biener wrote: > > Hmm, I wonder if we want to bootstrap with explicit -std=gnu04, our host > > compiler requirement. Otherwise we'll silently sneak in C++11 features when > > that becomes the default? > > I think just for stage 1. When that happens, can we backport a patch to add -std=gnu04 to the gcc5 branch, so at least that version can be compiled with "newer" compilers where C++11 is the default? (This will be an issue with cross-compilers for *all* older releases.) Maybe it's already in and my grep-fu is failing. brgds, H-P
Re: PATCHes to help with C++11 bootstrap
On May 9, 2015 6:30:49 AM GMT+02:00, Jason Merrill wrote: >One C++11 compatibility issue that turns up a lot in the GCC sources is > >that in C++98, > >#define BAR "bar" >const char *p = "foo"BAR; > >is well-formed, giving p the value "foobar". But in C++11 this is a >user-defined literal with the suffix BAR, which is ill-formed because >there is no BAR suffix defined. > >-Wc++11-compat didn't warn about this, which I'm fixing with the first >patch. > >The second patch fixes all the occurrences in GCC. > >The third patch fixes the warning to say "-Wc++11-compat" rather than >"-Wc++0x-compat". > >The fourth patch fixes a few G++ tests that were failing with the >compiler defaulting to C++11. > >Tested x86_64-cp-linux-gnu, applying to trunk. Hmm, I wonder if we want to bootstrap with explicit -std=gnu04, our host compiler requirement. Otherwise we'll silently sneak in C++11 features when that becomes the default? Richard.
Re: PATCHes to help with C++11 bootstrap
On 2015.05.08 at 23:30 -0500, Jason Merrill wrote: > One C++11 compatibility issue that turns up a lot in the GCC sources is > that in C++98, > > #define BAR "bar" > const char *p = "foo"BAR; > > is well-formed, giving p the value "foobar". But in C++11 this is a > user-defined literal with the suffix BAR, which is ill-formed because > there is no BAR suffix defined. > > -Wc++11-compat didn't warn about this, which I'm fixing with the first > patch. > > The second patch fixes all the occurrences in GCC. > > The third patch fixes the warning to say "-Wc++11-compat" rather than > "-Wc++0x-compat". This also enables the following bogus warning: ~ % cat test.cpp template struct X {}; template struct Y { static int const c = 0; }; int main() { return Y>::c; } ~ % g++ -Wall -std=c++11 test.cpp test.cpp: In function ‘int main()’: test.cpp:3:26: warning: ‘>>’ operator is treated as two right angle brackets in C++11 [-Wc++11-compat] int main() { return Y>::c; } ^ test.cpp:3:26: note: suggest parentheses around ‘>>’ expression -- Markus
Re: PATCHes to help with C++11 bootstrap
On 05/09/2015 01:27 PM, Markus Trippelsdorf wrote: This also enables the following bogus warning: ~ % g++ -Wall -std=c++11 test.cpp test.cpp:3:26: warning: ‘>>’ operator is treated as two right angle brackets in C++11 [-Wc++11-compat] Fixed thus: commit 1c492cd18b2869305cc3ee16f84b6464f98f4e4c Author: Jason Merrill Date: Sat May 9 16:16:46 2015 -0500 * c-opts.c (c_common_post_options): Also clear cpp_opts->cpp_warn_cxx11_compat. diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index bd99871..e9eb511 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -905,6 +905,7 @@ c_common_post_options (const char **pfilename) /* If we're allowing C++0x constructs, don't warn about C++98 identifiers which are keywords in C++0x. */ warn_cxx11_compat = 0; + cpp_opts->cpp_warn_cxx11_compat = 0; if (warn_narrowing == -1) warn_narrowing = 1; diff --git a/gcc/testsuite/g++.dg/cpp0x/bracket5.C b/gcc/testsuite/g++.dg/cpp0x/bracket5.C new file mode 100644 index 000..22ac544 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/bracket5.C @@ -0,0 +1,6 @@ +// { dg-options "-Wall" } +// { dg-do compile { target c++11 } } + +template struct X {}; +template struct Y { static int const c = 0; }; +int main() { return Y>::c; }
Re: PATCHes to help with C++11 bootstrap
More patches: The first makes changing the default just a matter of changing two lines (in the compiler and testsuite). The second patch is a minor tidy of c.opt. Tested x86_64-pc-linux-gnu, applying to trunk. commit 8c9891a3828dc6a4c91998b2437ef9fbf8659163 Author: Jason Merrill Date: Fri May 8 17:01:37 2015 -0500 gcc/c-family/ * c-common.h (enum cxx_dialect): Add cxx_unset. * c-common.c (cxx_dialect): Initialize to cxx_unset. * c-opts.c (c_common_post_options): Set C++ dialect to C++98 if unset. gcc/testsuite/ * lib/target-supports.exp (cxx_default): New global. (check_effective_target_c++11_only) (check_effective_target_c++14_only) (check_effective_target_c++98_only) (check_effective_target_c++1z_only): Check it. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 378f237..93b3060 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -256,9 +256,9 @@ const char *constant_string_class_name; int flag_use_repository; -/* The C++ dialect being used. C++98 is the default. */ +/* The C++ dialect being used. Default set in c_common_post_options. */ -enum cxx_dialect cxx_dialect = cxx98; +enum cxx_dialect cxx_dialect = cxx_unset; /* Maximum template instantiation depth. This limit exists to limit the time it takes to notice excessively recursive template instantiations. diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 603d3f0..5c1fa7b 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -671,6 +671,7 @@ extern int flag_use_repository; /* The supported C++ dialects. */ enum cxx_dialect { + cxx_unset, /* C++98 with TC1 */ cxx98, cxx03 = cxx98, diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index 8b17674..bd99871 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -896,6 +896,10 @@ c_common_post_options (const char **pfilename) if (flag_abi_version == 0) flag_abi_version = 8; + /* Set C++ standard to C++98 if not specified on the command line. */ + if (c_dialect_cxx () && cxx_dialect == cxx_unset) +set_std_cxx98 (/*ISO*/false); + if (cxx_dialect >= cxx11) { /* If we're allowing C++0x constructs, don't warn about C++98 diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index d68b48b..3728927 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -5892,15 +5892,23 @@ proc check_effective_target_c++ { } { return 0 } +set cxx_default "c++98" # Check whether the current active language standard supports the features -# of C++11/C++14 by checking for the presence of one of the -std -# flags. This assumes that the default for the compiler is C++98, and that +# of C++11/C++14 by checking for the presence of one of the -std flags. +# This assumes that the default for the compiler is $cxx_default, and that # there will never be multiple -std= arguments on the command line. proc check_effective_target_c++11_only { } { +global cxx_default if ![check_effective_target_c++] { return 0 } -return [check-flags { { } { } { -std=c++0x -std=gnu++0x -std=c++11 -std=gnu++11 } }] +if [check-flags { { } { } { -std=c++0x -std=gnu++0x -std=c++11 -std=gnu++11 } }] { + return 1 +} +if { $cxx_default == "c++11" && [check-flags { { } { } { } { -std=* } }] } { + return 1 +} +return 0 } proc check_effective_target_c++11 { } { if [check_effective_target_c++11_only] { @@ -5912,14 +5920,21 @@ proc check_effective_target_c++11_down { } { if ![check_effective_target_c++] { return 0 } -return ![check_effective_target_c++14] +return [expr ![check_effective_target_c++14] ] } proc check_effective_target_c++14_only { } { +global cxx_default if ![check_effective_target_c++] { return 0 } -return [check-flags { { } { } { -std=c++14 -std=gnu++14 -std=c++14 -std=gnu++14 } }] +if [check-flags { { } { } { -std=c++14 -std=gnu++14 -std=c++14 -std=gnu++14 } }] { + return 1 +} +if { $cxx_default == "c++14" && [check-flags { { } { } { } { -std=* } }] } { + return 1 +} +return 0 } proc check_effective_target_c++14 { } { @@ -5932,21 +5947,35 @@ proc check_effective_target_c++14_down { } { if ![check_effective_target_c++] { return 0 } -return ![check_effective_target_c++1z] +return [expr ![check_effective_target_c++1z] ] } proc check_effective_target_c++98_only { } { +global cxx_default if ![check_effective_target_c++] { return 0 } -return ![check_effective_target_c++11] +if [check-flags { { } { } { -std=c++98 -std=gnu++98 -std=c++03 -std=gnu++03 } }] { + return 1 +} +if { $cxx_default == "c++98" && [check-flags { { } { } { } { -std=* } }] } { + return 1 +} +return 0 } proc check_effective_target_c++1z_only { } { +global cxx_default if ![check_effective_target_c++] { return
Re: PATCHes to help with C++11 bootstrap
On 05/09/2015 05:37 AM, Richard Biener wrote: Hmm, I wonder if we want to bootstrap with explicit -std=gnu04, our host compiler requirement. Otherwise we'll silently sneak in C++11 features when that becomes the default? I think just for stage 1. Jason
Re: PATCHes to help with C++11 bootstrap
On 2015.05.08 at 23:30 -0500, Jason Merrill wrote: > One C++11 compatibility issue that turns up a lot in the GCC sources is > that in C++98, > > #define BAR "bar" > const char *p = "foo"BAR; There was a missing fix for gcc/config/rs6000/option-defaults.h. This broke bootstrap on ppc64. Fix committed as obvious. 2015-05-11 Markus Trippelsdorf PR bootstrap/66105 * config/rs6000/option-defaults.h: Add space between string literal and macro name. diff --git a/gcc/config/rs6000/option-defaults.h b/gcc/config/rs6000/option-defaults.h index 7da2c7c77b86..95a147206186 100644 --- a/gcc/config/rs6000/option-defaults.h +++ b/gcc/config/rs6000/option-defaults.h @@ -39,11 +39,11 @@ #endif #if TARGET_DEFAULT & OPTION_MASK_64BIT -#define OPT_ARCH64 "!"OPT_32 +#define OPT_ARCH64 "!" OPT_32 #define OPT_ARCH32 OPT_32 #else #define OPT_ARCH64 OPT_64 -#define OPT_ARCH32 "!"OPT_64 +#define OPT_ARCH32 "!" OPT_64 #endif /* Support for a compile-time default CPU, et cetera. The rules are: -- Markus
Re: PATCHes to help with C++11 bootstrap
On 05/11/2015 07:30 AM, Markus Trippelsdorf wrote: On 2015.05.08 at 23:30 -0500, Jason Merrill wrote: One C++11 compatibility issue that turns up a lot in the GCC sources is that in C++98, #define BAR "bar" const char *p = "foo"BAR; There was a missing fix for gcc/config/rs6000/option-defaults.h. And a few more. I think this is all of them. commit 851a8cddf2c7cfd6a10a6178be1378ae4e8772fa Author: Jason Merrill Date: Mon May 11 08:59:53 2015 -0500 gcc/ * config/mmix/mmix.c, config/msp430/msp430.c: Add space between string literal and macro name. gcc/ada/ * sigtramp-vxworks.c: Add space between string literal and macro name. diff --git a/gcc/ada/sigtramp-vxworks.c b/gcc/ada/sigtramp-vxworks.c index 2119296..c697626 100644 --- a/gcc/ada/sigtramp-vxworks.c +++ b/gcc/ada/sigtramp-vxworks.c @@ -342,16 +342,16 @@ CR("") \ TCR("# Allocate frame and save the non-volatile") \ TCR("# registers we're going to modify") \ TCR("mov ip, sp") \ -TCR("stmfd sp!, {r"S(CFA_REG)", fp, ip, lr, pc}") \ +TCR("stmfd sp!, {r" S(CFA_REG)", fp, ip, lr, pc}") \ TCR("# Setup CFA_REG = context, which we'll retrieve as our CFA value") \ -TCR("ldr r"S(CFA_REG)", [ip]") \ +TCR("ldr r" S(CFA_REG)", [ip]") \ TCR("") \ TCR("# Call the real handler. The signo, siginfo and sigcontext") \ TCR("# arguments are the same as those we received in r0, r1 and r2") \ TCR("sub fp, ip, #4") \ TCR("blx r3") \ TCR("# Restore our callee-saved items, release our frame and return") \ -TCR("ldmfd sp, {r"S(CFA_REG)", fp, sp, pc}") +TCR("ldmfd sp, {r" S(CFA_REG)", fp, sp, pc}") #else Not_implemented; diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c index 6e99120..e069985 100644 --- a/gcc/config/mmix/mmix.c +++ b/gcc/config/mmix/mmix.c @@ -2520,7 +2520,7 @@ mmix_output_shiftvalue_op_from_str (FILE *stream, if (! mmix_shiftable_wyde_value (value)) { char s[sizeof ("0x")]; - sprintf (s, "%#"PRIx64, value); + sprintf (s, "%#" PRIx64, value); internal_error ("MMIX Internal: %s is not a shiftable int", s); } @@ -2562,7 +2562,7 @@ mmix_output_octa (FILE *stream, int64_t value, int do_begin_end) fprintf (stream, "#" HOST_WIDE_INT_PRINT_HEX_PURE, (HOST_WIDE_INT) value); else /* Need to avoid the hex output; there's no ...WIDEST...HEX_PURE. */ -fprintf (stream, "%"PRIu64, value); +fprintf (stream, "%" PRIu64, value); if (do_begin_end) fprintf (stream, "\n"); @@ -2579,7 +2579,7 @@ mmix_output_shifted_value (FILE *stream, int64_t value) if (! mmix_shiftable_wyde_value (value)) { char s[16+2+1]; - sprintf (s, "%#"PRIx64, value); + sprintf (s, "%#" PRIx64, value); internal_error ("MMIX Internal: %s is not a shiftable int", s); } diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c index bec168c..58d0efe 100644 --- a/gcc/config/msp430/msp430.c +++ b/gcc/config/msp430/msp430.c @@ -2248,7 +2248,7 @@ static struct } const_shift_helpers[] = { -#define CSH(N,C,X,G) { "__mspabi_"N, C, X, gen_##G } +#define CSH(N,C,X,G) { "__mspabi_" N, C, X, gen_##G } CSH ("slli", 1, 1, slli_1), CSH ("slll", 1, 1, slll_1),