Hi! As the testcases show, we mishandle e.g. -std=c++11 -std=gnu++14 or -std=c++11 -std=c++98, in that earlier -std=c++{1[147yz],0x} disables -fext-numeric-literals and nothing turns this again on, unless enabled explicitly, eventhough such option combinations should just ignore the earlier -std= options (last one should win).
Apparently the driver reorders the options, -std=* options come before all -f* options, so both of the following patches work the same, except when cc1plus is invoked by hand. The first (inlined) patch solves it more in line how e.g. -fgnu-keywords and similar options are handled, so I think it is preferrable (and I've successfully bootstrapped/regtested it on x86_64-linux and i686-linux). The second (attached) patch handles it by not clearing -fext-numeric-literals during option processing for -std=* options, just in post option handling clears it for the strict c++11+ modes if the option is not specified explicitly. If the driver wouldn't reorder the options, it would handle better cases like -fext-numeric-literals -std=c++11 to mean the same thing as -std=c++11 -fext-numeric-literals etc., but due to the reordering it isn't needed and for consistency we'd also need to change -fgnu-keywords etc. Ok for trunk (the first patch, or second)? 2016-10-29 Jakub Jelinek <ja...@redhat.com> PR c++/77948 * c-opts.c (c_common_handle_option): Don't clear cpp_opts->ext_numeric_literals for -std=c++{11,14,1z} here. (set_std_c89, set_std_c99, set_std_c11): Fix up formatting. (set_std_cxx11, set_std_cxx14, set_std_cxx1z): Likewise. Set cpp_opts->ext_numeric_literals to !iso. (set_std_cxx98): Fix up formatting. Set cpp_opts->ext_numeric_literals to 1. * g++.dg/cpp0x/pr77948-1.C: New test. * g++.dg/cpp0x/pr77948-2.C: New test. * g++.dg/cpp0x/pr77948-3.C: New test. * g++.dg/cpp0x/pr77948-4.C: New test. * g++.dg/cpp0x/pr77948-5.C: New test. * g++.dg/cpp0x/pr77948-6.C: New test. --- gcc/c-family/c-opts.c.jj 2016-10-20 20:32:12.000000000 +0200 +++ gcc/c-family/c-opts.c 2016-10-29 12:10:29.864347364 +0200 @@ -624,31 +624,19 @@ c_common_handle_option (size_t scode, co case OPT_std_c__11: case OPT_std_gnu__11: if (!preprocessing_asm_p) - { - set_std_cxx11 (code == OPT_std_c__11 /* ISO */); - if (code == OPT_std_c__11) - cpp_opts->ext_numeric_literals = 0; - } + set_std_cxx11 (code == OPT_std_c__11 /* ISO */); break; case OPT_std_c__14: case OPT_std_gnu__14: if (!preprocessing_asm_p) - { - set_std_cxx14 (code == OPT_std_c__14 /* ISO */); - if (code == OPT_std_c__14) - cpp_opts->ext_numeric_literals = 0; - } + set_std_cxx14 (code == OPT_std_c__14 /* ISO */); break; case OPT_std_c__1z: case OPT_std_gnu__1z: if (!preprocessing_asm_p) - { - set_std_cxx1z (code == OPT_std_c__1z /* ISO */); - if (code == OPT_std_c__1z) - cpp_opts->ext_numeric_literals = 0; - } + set_std_cxx1z (code == OPT_std_c__1z /* ISO */); break; case OPT_std_c90: @@ -1500,7 +1488,7 @@ cb_dir_change (cpp_reader * ARG_UNUSED ( static void set_std_c89 (int c94, int iso) { - cpp_set_lang (parse_in, c94 ? CLK_STDC94: iso ? CLK_STDC89: CLK_GNUC89); + cpp_set_lang (parse_in, c94 ? CLK_STDC94 : iso ? CLK_STDC89 : CLK_GNUC89); flag_iso = iso; flag_no_asm = iso; flag_no_gnu_keywords = iso; @@ -1515,7 +1503,7 @@ set_std_c89 (int c94, int iso) static void set_std_c99 (int iso) { - cpp_set_lang (parse_in, iso ? CLK_STDC99: CLK_GNUC99); + cpp_set_lang (parse_in, iso ? CLK_STDC99 : CLK_GNUC99); flag_no_asm = iso; flag_no_nonansi_builtin = iso; flag_iso = iso; @@ -1529,7 +1517,7 @@ set_std_c99 (int iso) static void set_std_c11 (int iso) { - cpp_set_lang (parse_in, iso ? CLK_STDC11: CLK_GNUC11); + cpp_set_lang (parse_in, iso ? CLK_STDC11 : CLK_GNUC11); flag_no_asm = iso; flag_no_nonansi_builtin = iso; flag_iso = iso; @@ -1543,12 +1531,13 @@ set_std_c11 (int iso) static void set_std_cxx98 (int iso) { - cpp_set_lang (parse_in, iso ? CLK_CXX98: CLK_GNUCXX); + cpp_set_lang (parse_in, iso ? CLK_CXX98 : CLK_GNUCXX); flag_no_gnu_keywords = iso; flag_no_nonansi_builtin = iso; flag_iso = iso; flag_isoc94 = 0; flag_isoc99 = 0; + cpp_opts->ext_numeric_literals = 1; cxx_dialect = cxx98; lang_hooks.name = "GNU C++98"; } @@ -1557,13 +1546,14 @@ set_std_cxx98 (int iso) static void set_std_cxx11 (int iso) { - cpp_set_lang (parse_in, iso ? CLK_CXX11: CLK_GNUCXX11); + cpp_set_lang (parse_in, iso ? CLK_CXX11 : CLK_GNUCXX11); flag_no_gnu_keywords = iso; flag_no_nonansi_builtin = iso; flag_iso = iso; /* C++11 includes the C99 standard library. */ flag_isoc94 = 1; flag_isoc99 = 1; + cpp_opts->ext_numeric_literals = !iso; cxx_dialect = cxx11; lang_hooks.name = "GNU C++11"; } @@ -1572,13 +1562,14 @@ set_std_cxx11 (int iso) static void set_std_cxx14 (int iso) { - cpp_set_lang (parse_in, iso ? CLK_CXX14: CLK_GNUCXX14); + cpp_set_lang (parse_in, iso ? CLK_CXX14 : CLK_GNUCXX14); flag_no_gnu_keywords = iso; flag_no_nonansi_builtin = iso; flag_iso = iso; /* C++11 includes the C99 standard library. */ flag_isoc94 = 1; flag_isoc99 = 1; + cpp_opts->ext_numeric_literals = !iso; cxx_dialect = cxx14; lang_hooks.name = "GNU C++14"; } @@ -1587,7 +1578,7 @@ set_std_cxx14 (int iso) static void set_std_cxx1z (int iso) { - cpp_set_lang (parse_in, iso ? CLK_CXX1Z: CLK_GNUCXX1Z); + cpp_set_lang (parse_in, iso ? CLK_CXX1Z : CLK_GNUCXX1Z); flag_no_gnu_keywords = iso; flag_no_nonansi_builtin = iso; flag_iso = iso; @@ -1595,6 +1586,7 @@ set_std_cxx1z (int iso) flag_isoc94 = 1; flag_isoc99 = 1; flag_isoc11 = 1; + cpp_opts->ext_numeric_literals = !iso; cxx_dialect = cxx1z; lang_hooks.name = "GNU C++14"; /* Pretend C++14 till standarization. */ } --- gcc/testsuite/g++.dg/cpp0x/pr77948-1.C.jj 2016-10-29 11:11:42.714443044 +0200 +++ gcc/testsuite/g++.dg/cpp0x/pr77948-1.C 2016-10-29 11:58:10.658589912 +0200 @@ -0,0 +1,10 @@ +// PR c++/77948 +// { dg-do compile } +// { dg-options "-std=c++11 -std=gnu++11" } + +void +foo () +{ + auto qfp = 1.0q; // { dg-error "unsupported" "" { target { ! has_q_floating_suffix } } } + auto Qfp = 1.0Q; // { dg-error "unsupported" "" { target { ! has_q_floating_suffix } } } +} --- gcc/testsuite/g++.dg/cpp0x/pr77948-2.C.jj 2016-10-29 11:15:21.095708907 +0200 +++ gcc/testsuite/g++.dg/cpp0x/pr77948-2.C 2016-10-29 11:58:17.189508367 +0200 @@ -0,0 +1,10 @@ +// PR c++/77948 +// { dg-do compile } +// { dg-options "-std=gnu++11 -std=c++11" } + +void +foo () +{ + auto qfp = 1.0q; // { dg-error "unable to find numeric literal operator" } + auto Qfp = 1.0Q; // { dg-error "unable to find numeric literal operator" } +} --- gcc/testsuite/g++.dg/cpp0x/pr77948-3.C.jj 2016-10-29 12:13:57.465754014 +0200 +++ gcc/testsuite/g++.dg/cpp0x/pr77948-3.C 2016-10-29 12:14:18.593490087 +0200 @@ -0,0 +1,10 @@ +// PR c++/77948 +// { dg-do compile } +// { dg-options "-std=c++11 -std=gnu++98" } + +void +foo () +{ + double qfp = 1.0q; // { dg-error "unsupported" "" { target { ! has_q_floating_suffix } } } + double Qfp = 1.0Q; // { dg-error "unsupported" "" { target { ! has_q_floating_suffix } } } +} --- gcc/testsuite/g++.dg/cpp0x/pr77948-4.C.jj 2016-10-29 12:14:27.576377873 +0200 +++ gcc/testsuite/g++.dg/cpp0x/pr77948-4.C 2016-10-29 12:14:40.250219552 +0200 @@ -0,0 +1,10 @@ +// PR c++/77948 +// { dg-do compile } +// { dg-options "-std=c++11 -std=c++98" } + +void +foo () +{ + double qfp = 1.0q; // { dg-error "unsupported" "" { target { ! has_q_floating_suffix } } } + double Qfp = 1.0Q; // { dg-error "unsupported" "" { target { ! has_q_floating_suffix } } } +} --- gcc/testsuite/g++.dg/cpp0x/pr77948-5.C.jj 2016-10-29 12:15:23.044684965 +0200 +++ gcc/testsuite/g++.dg/cpp0x/pr77948-5.C 2016-10-29 12:15:08.650864772 +0200 @@ -0,0 +1,10 @@ +// PR c++/77948 +// { dg-do compile } +// { dg-options "-std=gnu++98 -std=c++11" } + +void +foo () +{ + auto qfp = 1.0q; // { dg-error "unable to find numeric literal operator" } + auto Qfp = 1.0Q; // { dg-error "unable to find numeric literal operator" } +} --- gcc/testsuite/g++.dg/cpp0x/pr77948-6.C.jj 2016-10-29 12:15:30.296594374 +0200 +++ gcc/testsuite/g++.dg/cpp0x/pr77948-6.C 2016-10-29 12:15:37.841500123 +0200 @@ -0,0 +1,10 @@ +// PR c++/77948 +// { dg-do compile } +// { dg-options "-std=c++98 -std=c++11" } + +void +foo () +{ + auto qfp = 1.0q; // { dg-error "unable to find numeric literal operator" } + auto Qfp = 1.0Q; // { dg-error "unable to find numeric literal operator" } +} Jakub
2016-10-29 Jakub Jelinek <ja...@redhat.com> PR c++/77948 * c.opt (fext-numeric-literals): Add Var and Init. * c-opts.c (c_common_handle_option): Don't clear cpp_opts->ext_numeric_literals for -std=c++{11,14,1z}. (c_common_post_options): Clear it here if not set explicitly. * g++.dg/cpp0x/pr77948-1.C: New test. * g++.dg/cpp0x/pr77948-2.C: New test. * g++.dg/cpp0x/pr77948-3.C: New test. * g++.dg/cpp0x/pr77948-4.C: New test. * g++.dg/cpp0x/pr77948-5.C: New test. * g++.dg/cpp0x/pr77948-6.C: New test. --- gcc/c-family/c.opt.jj 2016-10-20 20:32:12.000000000 +0200 +++ gcc/c-family/c.opt 2016-10-29 10:03:12.697952740 +0200 @@ -1705,7 +1705,7 @@ C ObjC C++ ObjC++ Joined -femit-struct-debug-detailed=<spec-list> Detailed reduced debug info for structs. fext-numeric-literals -C++ ObjC++ +C++ ObjC++ Var(flag_ext_numeric_literals) Init(1) Interpret imaginary, fixed-point, or other gnu number suffix as the corresponding number literal rather than a user-defined number literal. --- gcc/c-family/c-opts.c.jj 2016-10-20 20:32:12.000000000 +0200 +++ gcc/c-family/c-opts.c 2016-10-29 11:59:13.040810346 +0200 @@ -624,31 +624,19 @@ c_common_handle_option (size_t scode, co case OPT_std_c__11: case OPT_std_gnu__11: if (!preprocessing_asm_p) - { - set_std_cxx11 (code == OPT_std_c__11 /* ISO */); - if (code == OPT_std_c__11) - cpp_opts->ext_numeric_literals = 0; - } + set_std_cxx11 (code == OPT_std_c__11 /* ISO */); break; case OPT_std_c__14: case OPT_std_gnu__14: if (!preprocessing_asm_p) - { - set_std_cxx14 (code == OPT_std_c__14 /* ISO */); - if (code == OPT_std_c__14) - cpp_opts->ext_numeric_literals = 0; - } + set_std_cxx14 (code == OPT_std_c__14 /* ISO */); break; case OPT_std_c__1z: case OPT_std_gnu__1z: if (!preprocessing_asm_p) - { - set_std_cxx1z (code == OPT_std_c__1z /* ISO */); - if (code == OPT_std_c__1z) - cpp_opts->ext_numeric_literals = 0; - } + set_std_cxx1z (code == OPT_std_c__1z /* ISO */); break; case OPT_std_c90: @@ -923,6 +911,11 @@ c_common_post_options (const char **pfil if (warn_narrowing == -1) warn_narrowing = 1; + + /* Unless -f{,no-}ext-numeric-literals has been used explicitly, + for -std=c++{11,14,1z} default to -fno-ext-numeric-literals. */ + if (flag_iso && !global_options_set.x_flag_ext_numeric_literals) + cpp_opts->ext_numeric_literals = 0; } else if (warn_narrowing == -1) warn_narrowing = 0; --- gcc/testsuite/g++.dg/cpp0x/pr77948-1.C.jj 2016-10-29 11:11:42.714443044 +0200 +++ gcc/testsuite/g++.dg/cpp0x/pr77948-1.C 2016-10-29 11:58:10.658589912 +0200 @@ -0,0 +1,10 @@ +// PR c++/77948 +// { dg-do compile } +// { dg-options "-std=c++11 -std=gnu++11" } + +void +foo () +{ + auto qfp = 1.0q; // { dg-error "unsupported" "" { target { ! has_q_floating_suffix } } } + auto Qfp = 1.0Q; // { dg-error "unsupported" "" { target { ! has_q_floating_suffix } } } +} --- gcc/testsuite/g++.dg/cpp0x/pr77948-2.C.jj 2016-10-29 11:15:21.095708907 +0200 +++ gcc/testsuite/g++.dg/cpp0x/pr77948-2.C 2016-10-29 11:58:17.189508367 +0200 @@ -0,0 +1,10 @@ +// PR c++/77948 +// { dg-do compile } +// { dg-options "-std=gnu++11 -std=c++11" } + +void +foo () +{ + auto qfp = 1.0q; // { dg-error "unable to find numeric literal operator" } + auto Qfp = 1.0Q; // { dg-error "unable to find numeric literal operator" } +} --- gcc/testsuite/g++.dg/cpp0x/pr77948-3.C.jj 2016-10-29 12:13:57.465754014 +0200 +++ gcc/testsuite/g++.dg/cpp0x/pr77948-3.C 2016-10-29 12:14:18.593490087 +0200 @@ -0,0 +1,10 @@ +// PR c++/77948 +// { dg-do compile } +// { dg-options "-std=c++11 -std=gnu++98" } + +void +foo () +{ + double qfp = 1.0q; // { dg-error "unsupported" "" { target { ! has_q_floating_suffix } } } + double Qfp = 1.0Q; // { dg-error "unsupported" "" { target { ! has_q_floating_suffix } } } +} --- gcc/testsuite/g++.dg/cpp0x/pr77948-4.C.jj 2016-10-29 12:14:27.576377873 +0200 +++ gcc/testsuite/g++.dg/cpp0x/pr77948-4.C 2016-10-29 12:14:40.250219552 +0200 @@ -0,0 +1,10 @@ +// PR c++/77948 +// { dg-do compile } +// { dg-options "-std=c++11 -std=c++98" } + +void +foo () +{ + double qfp = 1.0q; // { dg-error "unsupported" "" { target { ! has_q_floating_suffix } } } + double Qfp = 1.0Q; // { dg-error "unsupported" "" { target { ! has_q_floating_suffix } } } +} --- gcc/testsuite/g++.dg/cpp0x/pr77948-5.C.jj 2016-10-29 12:15:23.044684965 +0200 +++ gcc/testsuite/g++.dg/cpp0x/pr77948-5.C 2016-10-29 12:15:08.650864772 +0200 @@ -0,0 +1,10 @@ +// PR c++/77948 +// { dg-do compile } +// { dg-options "-std=gnu++98 -std=c++11" } + +void +foo () +{ + auto qfp = 1.0q; // { dg-error "unable to find numeric literal operator" } + auto Qfp = 1.0Q; // { dg-error "unable to find numeric literal operator" } +} --- gcc/testsuite/g++.dg/cpp0x/pr77948-6.C.jj 2016-10-29 12:15:30.296594374 +0200 +++ gcc/testsuite/g++.dg/cpp0x/pr77948-6.C 2016-10-29 12:15:37.841500123 +0200 @@ -0,0 +1,10 @@ +// PR c++/77948 +// { dg-do compile } +// { dg-options "-std=c++98 -std=c++11" } + +void +foo () +{ + auto qfp = 1.0q; // { dg-error "unable to find numeric literal operator" } + auto Qfp = 1.0Q; // { dg-error "unable to find numeric literal operator" } +}