[C++ PATCH] Fix -std=c++11 -std=gnu++11 option handling (PR c++/77948)

Jakub Jelinek jakub@redhat.com
Sat Oct 29 16:09:00 GMT 2016


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  <jakub@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
-------------- next part --------------
2016-10-29  Jakub Jelinek  <jakub@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" }
+}


More information about the Gcc-patches mailing list