Patchwork fix PR 45038, bad interaction between __DBL_MIN__ and -Wold-style-cast

login
register
mail settings
Submitter Nathan Froyd
Date Nov. 9, 2010, 10:10 p.m.
Message ID <20101109221019.GI7991@nightcrawler>
Download mbox | patch
Permalink /patch/70580/
State New
Headers show

Comments

Nathan Froyd - Nov. 9, 2010, 10:10 p.m.
Builtin double-precision floating-point constants defined by the
preprocessor get defined as `((double)VAL)'; this style causes problems
with -Wold-style-cast.  The patch below tweaks the definition of such
constants to use static_cast when compiling for C++.

Tested on x86_64-unknown-linux-gnu.  OK to commit?

-Nathan

gcc/c-family/
	PR preprocessor/45038
	* c-cppbuiltin.c (c_cpp_builtins): Adjust cast values passed to
	builtin_define_float_constants.
	(builtin_define_with_hex_fp_value): Use static_cast if compiling
	for C++.

gcc/testsuite/
	PR preprocessor/45038
	* g++/pr45038.C: New test.
Gabriel Dos Reis - Nov. 9, 2010, 11:06 p.m.
On Tue, Nov 9, 2010 at 4:10 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> Builtin double-precision floating-point constants defined by the
> preprocessor get defined as `((double)VAL)'; this style causes problems
> with -Wold-style-cast.  The patch below tweaks the definition of such
> constants to use static_cast when compiling for C++.

Did  you consider the function style cast

     double(VAL)

instead ?

-- Gaby
Nathan Froyd - Nov. 10, 2010, 1:14 p.m.
On Tue, Nov 09, 2010 at 05:06:52PM -0600, Gabriel Dos Reis wrote:
> On Tue, Nov 9, 2010 at 4:10 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> > Builtin double-precision floating-point constants defined by the
> > preprocessor get defined as `((double)VAL)'; this style causes problems
> > with -Wold-style-cast.  The patch below tweaks the definition of such
> > constants to use static_cast when compiling for C++.
> 
> Did  you consider the function style cast
> 
>      double(VAL)
> 
> instead ?

No, I didn't.  My C++-fu in this area is weak.  Is the function style
cast preferred?

-Nathan

Patch

diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
index 7b5a14d..f0d35fc 100644
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -653,14 +653,14 @@  c_cpp_builtins (cpp_reader *pfile)
   builtin_define_with_int_value ("__DEC_EVAL_METHOD__",
                                  TARGET_DEC_EVAL_METHOD);
 
-  builtin_define_float_constants ("FLT", "F", "%s", "F", float_type_node);
+  builtin_define_float_constants ("FLT", "F", NULL, "F", float_type_node);
   /* Cast the double precision constants.  This is needed when single
      precision constants are specified or when pragma FLOAT_CONST_DECIMAL64
      is used.  The correct result is computed by the compiler when using
      macros that include a cast.  */
-  builtin_define_float_constants ("DBL", "L", "((double)%s)", "",
+  builtin_define_float_constants ("DBL", "L", "double", "",
 				  double_type_node);
-  builtin_define_float_constants ("LDBL", "L", "%s", "L",
+  builtin_define_float_constants ("LDBL", "L", NULL, "L",
 				  long_double_type_node);
 
   /* For decfloat.h.  */
@@ -983,7 +983,12 @@  builtin_define_with_hex_fp_value (const char *macro,
       struct cpp_hashnode *node;
       if (lazy_hex_fp_value_count == 0)
 	cpp_get_callbacks (parse_in)->user_builtin_macro = lazy_hex_fp_value;
-      sprintf (buf2, fp_cast, "1.1");
+      if (fp_cast == NULL)
+	sprintf (buf2, "1.1");
+      else if (c_dialect_cxx ())
+	sprintf (buf2, "static_cast<%s>(1.1)", fp_cast);
+      else
+	sprintf (buf2, "((%s)1.1)", fp_cast);
       sprintf (buf1, "%s=%s", macro, buf2);
       cpp_define (parse_in, buf1);
       node = C_CPP_HASHNODE (get_identifier (macro));
@@ -1014,11 +1019,14 @@  builtin_define_with_hex_fp_value (const char *macro,
   real_to_decimal_for_mode (dec_str, &real, sizeof (dec_str), digits, 0,
 			    TYPE_MODE (type));
 
-  /* Assemble the macro in the following fashion
-     macro = fp_cast [dec_str fp_suffix] */
-  sprintf (buf1, "%s%s", dec_str, fp_suffix);
-  sprintf (buf2, fp_cast, buf1);
-  sprintf (buf1, "%s=%s", macro, buf2);
+  /* Avoid issues with -Wold-style-cast if FP_CAST is specified.  */
+  if (fp_cast == NULL)
+    sprintf (buf1, "%s=%s%s", macro, dec_str, fp_suffix);
+  else if (c_dialect_cxx ())
+    sprintf (buf1, "%s=static_cast<%s>(%s%s)", macro, fp_cast, dec_str,
+	     fp_suffix);
+  else
+    sprintf (buf1, "%s=((%s)%s%s)", macro, fp_cast, dec_str, fp_suffix);
 
   cpp_define (parse_in, buf1);
 }
diff --git a/gcc/testsuite/g++.dg/pr45038.C b/gcc/testsuite/g++.dg/pr45038.C
new file mode 100644
index 0000000..57c0c44
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr45038.C
@@ -0,0 +1,9 @@ 
+// PR preprocessor/45038
+// { dg-do compile }
+// { dg-options "-Werror -Wold-style-cast" }
+
+double f(void)
+{
+  // We used to produce old-style casts for this.
+  return __DBL_MIN__;
+}