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 <[email protected]>
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 <[email protected]>
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" }
+}