* [PATCH, C/C++] Add -fno-float to forbid floating point data types
@ 2014-08-12 9:25 Thomas Preud'homme
2014-08-12 9:34 ` Jakub Jelinek
` (3 more replies)
0 siblings, 4 replies; 11+ messages in thread
From: Thomas Preud'homme @ 2014-08-12 9:25 UTC (permalink / raw)
To: gcc-patches
Hi,
As mentioned in PR60070, there is many cases when a programmer want to ensure
that a program does not use any floating point data type. Other cases to consider
is when a target has several floating point ABI and user want to ensure his/her
is compatible with all available floating point ABI. Adding such a check also provides
an opportunity to adapt the behavior of the compiler based on its result.
This patch adds the new option -fno-float to request gcc to throw an error if any
float or floating point operation is involved. The patch modifies the C and C++
frontend (others could be modified later if people request it) so as to throw an
error whenever a keyword introducing a float type or a float litteral are
encountered. The check is added to frontend rather middle end as this allow to
do the detection as the file is parsed rather than needing a pass. It also limit the
check to only the place where a float can be declared instead of having to look
at all gimple stmts. Finally, it allows to catch some cases that would be absent
of the middle end due to simplification or limited folding that the front end
might do. Note though that things excluded by the preprocessor (think #ifdef)
would not be analyzed.
Note that the tests were written independently of the code so as to have more
confidence in the patch.
ChangeLog are as follows:
*** gcc/ChangeLog ***
2014-08-08 Thomas Preud'homme <thomas.preudhomme@arm.com>
PR middle-end/60070
* doc/invoke.texi (fno-float): Add to the list of C options and explain
its meaning.
*** gcc/c/ChangeLog ***
2014-08-08 Thomas Preud'homme <thomas.preudhomme@arm.com>
PR middle-end/60070
* c-decl.c (finish_declspecs): Throw an error if -fno-float is
specified by user and a default complex is encountered.
* c-parser.c (c_token_starts_typename): Throw an error if -fno-float
is specified by user and a float type name is encountered.
(c_parser_declspecs): Memorize token being tested. Throw an error if
-fno-float is specified by user and a float declaration specifier is
encountered.
(c_parser_postfix_expression): Throw an error if -fno-float is
specified by user and a float litteral is encountered.
*** gcc/c-family/ChangeLog ***
2014-08-08 Thomas Preud'homme <thomas.preudhomme@arm.com>
PR middle-end/60070
* c.opt (ffloat): New option.
*** gcc/cp/ChangeLog ***
2014-08-08 Thomas Preud'homme <thomas.preudhomme@arm.com>
PR middle-end/60070
* decl.c (grokdeclarator): Throw an error if -fno-float is
specified by user and a default complex is encountered.
* parser.c (cp_parser_primary_expression): Throw an error if -fno-float
is specified by user and a float litteral is encountered.
(cp_parser_simple_type_specifier): Throw an error if -fno-float is
specified by user and a float type specifier is encountered.
*** gcc/testsuite/ChangeLog ***
2014-08-08 Thomas Preud'homme <thomas.preudhomme@arm.com>
PR middle-end/60070
* gcc.dg/fno-float.c: New test case.
* g++.dg/diagnostic/fno-float.C: Likewise.
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index c318cad..2d22e15 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1079,6 +1079,10 @@ fnil-receivers
ObjC ObjC++ Var(flag_nil_receivers) Init(1)
Assume that receivers of Objective-C messages may be nil
+ffloat
+C C++ LTO Var(flag_no_float, 0)
+Allow floating point data types to be used in C/C++
+
flocal-ivars
ObjC ObjC++ Var(flag_local_ivars) Init(1)
Allow access to instance variables as if they were local declarations within instance method implementations.
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 2a4b439..e68f0f3 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -10078,6 +10078,10 @@ finish_declspecs (struct c_declspecs *specs)
}
else if (specs->complex_p)
{
+ if (flag_no_float)
+ error_at (specs->locations[cdw_complex],
+ "use of floating points forbidden in this translation "
+ "unit (-fno-float)");
specs->typespec_word = cts_double;
pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
"ISO C does not support plain %<complex%> meaning "
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index e32bf04..74ac945 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -486,6 +486,15 @@ c_token_starts_typename (c_token *token)
case CPP_KEYWORD:
switch (token->keyword)
{
+ case RID_FLOAT:
+ case RID_DOUBLE:
+ case RID_DFLOAT32:
+ case RID_DFLOAT64:
+ case RID_DFLOAT128:
+ if (flag_no_float)
+ error_at (token->location, "use of floating points forbidden in "
+ "this translation unit (-fno-float)");
+ /* Fall through. */
case RID_UNSIGNED:
case RID_LONG:
case RID_INT128:
@@ -494,12 +503,7 @@ c_token_starts_typename (c_token *token)
case RID_COMPLEX:
case RID_INT:
case RID_CHAR:
- case RID_FLOAT:
- case RID_DOUBLE:
case RID_VOID:
- case RID_DFLOAT32:
- case RID_DFLOAT64:
- case RID_DFLOAT128:
case RID_BOOL:
case RID_ENUM:
case RID_STRUCT:
@@ -2188,6 +2192,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
|| (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
{
struct c_typespec t;
+ c_token *token;
tree attrs;
tree align;
location_t loc = c_parser_peek_token (parser)->location;
@@ -2277,7 +2282,8 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
continue;
}
gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
- switch (c_parser_peek_token (parser)->keyword)
+ token = c_parser_peek_token (parser);
+ switch (token->keyword)
{
case RID_STATIC:
case RID_EXTERN:
@@ -2301,6 +2307,15 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
if (!auto_type_ok)
goto out;
/* Fall through. */
+ case RID_FLOAT:
+ case RID_DOUBLE:
+ case RID_DFLOAT32:
+ case RID_DFLOAT64:
+ case RID_DFLOAT128:
+ if (token->keyword != RID_AUTO_TYPE && flag_no_float)
+ error_at (token->location, "use of floating points forbidden in "
+ "this translation unit (-fno-float)");
+ /* Fall through. */
case RID_UNSIGNED:
case RID_LONG:
case RID_INT128:
@@ -2309,12 +2324,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
case RID_COMPLEX:
case RID_INT:
case RID_CHAR:
- case RID_FLOAT:
- case RID_DOUBLE:
case RID_VOID:
- case RID_DFLOAT32:
- case RID_DFLOAT64:
- case RID_DFLOAT128:
case RID_BOOL:
case RID_FRACT:
case RID_ACCUM:
@@ -6996,6 +7006,9 @@ c_parser_postfix_expression (c_parser *parser)
error_at (loc, "fixed-point types not supported for this target");
expr.value = error_mark_node;
}
+ if (flag_no_float && TREE_CODE (expr.value) == REAL_CST)
+ error_at (loc, "use of floating points forbidden in this translation "
+ "unit (-fno-float)");
break;
case CPP_CHAR:
case CPP_CHAR16:
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index aafb917..c2f8f87 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -9292,7 +9292,12 @@ grokdeclarator (const cp_declarator *declarator,
"complex short int". */
else if (defaulted_int && ! longlong && ! explicit_int128
&& ! (long_p || short_p || signed_p || unsigned_p))
- type = complex_double_type_node;
+ {
+ if (flag_no_float)
+ error ("use of floating points forbidden in this translation unit "
+ "(-fno-float)");
+ type = complex_double_type_node;
+ }
else if (type == integer_type_node)
type = complex_integer_type_node;
else if (type == float_type_node)
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 32c7a3f..08207dd 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -4202,6 +4202,9 @@ cp_parser_primary_expression (cp_parser *parser,
"fixed-point types not supported in C++");
return error_mark_node;
}
+ if (flag_no_float && TREE_CODE (token->u.value) == REAL_CST)
+ error_at (token->location, "use of floating points forbidden in this "
+ "translation unit (-fno-float)");
/* Floating-point literals are only allowed in an integral
constant expression if they are cast to an integral or
enumeration type. */
@@ -14787,6 +14790,11 @@ cp_parser_simple_type_specifier (cp_parser* parser,
break;
}
+ if (flag_no_float
+ && (type == float_type_node || type == double_type_node))
+ error_at (token->location, "use of floating points forbidden in this "
+ "translation unit (-fno-float)");
+
/* If token is an already-parsed decltype not followed by ::,
it's a simple-type-specifier. */
if (token->type == CPP_DECLTYPE
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index aaa5a68..e49f120 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -169,7 +169,7 @@ in the following sections.
-aux-info @var{filename} -fallow-parameterless-variadic-functions @gol
-fno-asm -fno-builtin -fno-builtin-@var{function} @gol
-fhosted -ffreestanding -fopenmp -fopenmp-simd -fms-extensions @gol
--fplan9-extensions -trigraphs -traditional -traditional-cpp @gol
+-fno-float -fplan9-extensions -trigraphs -traditional -traditional-cpp @gol
-fallow-single-precision -fcond-mismatch -flax-vector-conversions @gol
-fsigned-bitfields -fsigned-char @gol
-funsigned-bitfields -funsigned-char}
@@ -1920,6 +1920,14 @@ fields within structs/unions}, for details.
Note that this option is off for all targets but i?86 and x86_64
targets using ms-abi.
+
+@item -fno-float
+@opindex fno-float
+Allows the compiler to assume that there is no floating point code in
+the translation unit, any use of floating point types detected being
+treated as an error. Additional action can then be taken, such as
+marking the code unaffected by the choice of floating point ABI.
+
@item -fplan9-extensions
Accept some non-standard constructs used in Plan 9 code.
diff --git a/gcc/testsuite/g++.dg/diagnostic/fno-float.C b/gcc/testsuite/g++.dg/diagnostic/fno-float.C
new file mode 100644
index 0000000..2abd80f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/fno-float.C
@@ -0,0 +1,102 @@
+/* { dg-do compile } */
+/* { dg-options "-fno-float" } */
+
+namespace float_ns { /* { dg-bogus "use of floating points forbidden" } */
+
+ /* Check float detection in global variable declaration. */
+ float f_glob; /* { dg-error "use of floating points forbidden" } */
+ double d_glob; /* { dg-error "use of floating points forbidden" } */
+ long double ld_glob; /* { dg-error "use of floating points forbidden" } */
+ _Complex float cf_glob; /* { dg-error "use of floating points forbidden" } */
+ _Complex double cd_glob; /* { dg-error "use of floating points forbidden" } */
+ _Complex long double cld_glob; /* { dg-error "use of floating points forbidden" } */
+
+ class float_cls { /* { dg-bogus "use of floating points forbidden" } */
+
+ /* Check float detection in attribute declaration. */
+ float f_attr; /* { dg-error "use of floating points forbidden" } */
+ double d_attr; /* { dg-error "use of floating points forbidden" } */
+ long double ld_attr; /* { dg-error "use of floating points forbidden" } */
+ _Complex float cf_attr; /* { dg-error "use of floating points forbidden" } */
+ _Complex double cd_attr; /* { dg-error "use of floating points forbidden" } */
+ _Complex long double cld_attr; /* { dg-error "use of floating points forbidden" } */
+
+ int fct_using_float (void) /* { dg-bogus "use of floating points forbidden" } */
+ {
+ /* Check float detection in local variable declaration. */
+ float f; /* { dg-error "use of floating points forbidden" } */
+ float *f_ptr; /* { dg-error "use of floating points forbidden" } */
+ double d; /* { dg-error "use of floating points forbidden" } */
+ double *d_ptr; /* { dg-error "use of floating points forbidden" } */
+ long double ld; /* { dg-error "use of floating points forbidden" } */
+ long double *ld_ptr; /* { dg-error "use of floating points forbidden" } */
+ _Complex float cf; /* { dg-error "use of floating points forbidden" } */
+ _Complex float *cf_ptr; /* { dg-error "use of floating points forbidden" } */
+ _Complex double cd; /* { dg-error "use of floating points forbidden" } */
+ _Complex double *cd_ptr; /* { dg-error "use of floating points forbidden" } */
+ _Complex long double cld; /* { dg-error "use of floating points forbidden" } */
+ _Complex long double *cld_ptr; /* { dg-error "use of floating points forbidden" } */
+
+float_ops: /* { dg-bogus "use of floating points forbidden" } */
+
+ /* Check float detection in typename. */
+ f += sizeof (float); /* { dg-error "use of floating points forbidden" } */
+ f += sizeof (double); /* { dg-error "use of floating points forbidden" } */
+ f += sizeof (long double); /* { dg-error "use of floating points forbidden" } */
+ f += sizeof (_Complex float); /* { dg-error "use of floating points forbidden" } */
+ f += sizeof (_Complex double); /* { dg-error "use of floating points forbidden" } */
+ f += sizeof (_Complex long double); /* { dg-error "use of floating points forbidden" } */
+
+ /* Check float detection in C-style cast. */
+ f = (float) 4; /* { dg-error "use of floating points forbidden" } */
+ d = (double) 4; /* { dg-error "use of floating points forbidden" } */
+ ld = (long double) 4; /* { dg-error "use of floating points forbidden" } */
+ cf = (_Complex float) cd; /* { dg-error "use of floating points forbidden" } */
+ cd = (_Complex double) cf; /* { dg-error "use of floating points forbidden" } */
+ cld = (_Complex long double) cf; /* { dg-error "use of floating points forbidden" } */
+
+ /* Check float detection in static_cast. */
+ f = static_cast<float>(4); /* { dg-error "use of floating points forbidden" } */
+ d = static_cast<double>(4); /* { dg-error "use of floating points forbidden" } */
+ ld = static_cast<long double>(4); /* { dg-error "use of floating points forbidden" } */
+ cf = static_cast<_Complex float>(cd); /* { dg-error "use of floating points forbidden" } */
+ cd = static_cast<_Complex double>(cf); /* { dg-error "use of floating points forbidden" } */
+ cld = static_cast<_Complex long double>(cf); /* { dg-error "use of floating points forbidden" } */
+
+ /* Check float detection in const_cast. */
+ f_ptr = const_cast<float *>(&f); /* { dg-error "use of floating points forbidden" } */
+ d_ptr = const_cast<double *>(&d); /* { dg-error "use of floating points forbidden" } */
+ ld_ptr = const_cast<long double *>(&ld); /* { dg-error "use of floating points forbidden" } */
+ cf_ptr = const_cast<_Complex float *>(&cf); /* { dg-error "use of floating points forbidden" } */
+ cd_ptr = const_cast<_Complex double *>(&cd); /* { dg-error "use of floating points forbidden" } */
+ cld_ptr = const_cast<_Complex long double *>(&cld); /* { dg-error "use of floating points forbidden" } */
+
+ /* Check float detection in reinterpret_cast. */
+ f_ptr = reinterpret_cast<float *>(4); /* { dg-error "use of floating points forbidden" } */
+ d_ptr = reinterpret_cast<double *>(4); /* { dg-error "use of floating points forbidden" } */
+ ld_ptr = reinterpret_cast<long double *>(4); /* { dg-error "use of floating points forbidden" } */
+ cf_ptr = reinterpret_cast<_Complex float *>(4); /* { dg-error "use of floating points forbidden" } */
+ cd_ptr = reinterpret_cast<_Complex double *>(4); /* { dg-error "use of floating points forbidden" } */
+ cld_ptr = reinterpret_cast<_Complex long double *>(4); /* { dg-error "use of floating points forbidden" } */
+
+ /* Check float detection in litterals. */
+ return (int) 4.5; /* { dg-error "use of floating points forbidden" } */
+ }
+
+ /* Check float detection in function parameter. */
+ int float_param (float a) { return (int) a;} /* { dg-error "use of floating points forbidden" } */
+ int double_param (double a) { return (int) a;} /* { dg-error "use of floating points forbidden" } */
+ int long double_param (long double a) { return (int) a;} /* { dg-error "use of floating points forbidden" } */
+ int complex_float_param (_Complex float a) { return (int) __real__ a;} /* { dg-error "use of floating points forbidden" } */
+ int complex_double_param (_Complex double a) { return (int) __real__ a;} /* { dg-error "use of floating points forbidden" } */
+ int complex_long_double_param (_Complex long double a) { return (int) __real__ a;} /* { dg-error "use of floating points forbidden" } */
+
+ /* Check float detection in function return parameter. */
+ float float_return (void) { return f_attr;} /* { dg-error "use of floating points forbidden" } */
+ double double_return (void) { return d_attr;} /* { dg-error "use of floating points forbidden" } */
+ long double long_double_return (void) { return ld_attr;} /* { dg-error "use of floating points forbidden" } */
+ _Complex float complex_float_return (void) { return cf_attr;} /* { dg-error "use of floating points forbidden" } */
+ _Complex double complex_double_return (void) { return cd_attr;} /* { dg-error "use of floating points forbidden" } */
+ _Complex long double complex_long_double_return (void) { return cld_attr;} /* { dg-error "use of floating points forbidden" } */
+ };
+}
diff --git a/gcc/testsuite/gcc.dg/fno-float.c b/gcc/testsuite/gcc.dg/fno-float.c
new file mode 100644
index 0000000..4d167cd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fno-float.c
@@ -0,0 +1,96 @@
+/* { dg-do compile } */
+/* { dg-options "-fno-float" } */
+/* { dg-prune-output "decimal floating point not supported for this target" } */
+
+/* Check float detection in global declaration. */
+float f_glob; /* { dg-error "use of floating points forbidden" } */
+double d_glob; /* { dg-error "use of floating points forbidden" } */
+long double ld_glob; /* { dg-error "use of floating points forbidden" } */
+_Decimal32 d32_glob; /* { dg-error "use of floating points forbidden" } */
+_Decimal64 d64_glob; /* { dg-error "use of floating points forbidden" } */
+_Decimal128 d128_glob; /* { dg-error "use of floating points forbidden" } */
+_Complex float cf_glob; /* { dg-error "use of floating points forbidden" } */
+_Complex double cd_glob; /* { dg-error "use of floating points forbidden" } */
+_Complex long double cld_glob; /* { dg-error "use of floating points forbidden" } */
+
+/* Check float detection in auto double complex global declaration. */
+_Complex c_glob; /* { dg-error "use of floating points forbidden" } */
+
+int
+fct_using_float (void) /* { dg-bogus "use of floating points forbidden" } */
+{
+ /* Check float detection in local declaration. */
+ float f; /* { dg-error "use of floating points forbidden" } */
+ double d; /* { dg-error "use of floating points forbidden" } */
+ long double ld; /* { dg-error "use of floating points forbidden" } */
+ _Decimal32 d32; /* { dg-error "use of floating points forbidden" } */
+ _Decimal64 d64; /* { dg-error "use of floating points forbidden" } */
+ _Decimal128 d128; /* { dg-error "use of floating points forbidden" } */
+ _Complex float cf; /* { dg-error "use of floating points forbidden" } */
+ _Complex double cd; /* { dg-error "use of floating points forbidden" } */
+ _Complex long double cld; /* { dg-error "use of floating points forbidden" } */
+
+ /* Check float detection in auto double complex local declaration. */
+ _Complex c; /* { dg-error "use of floating points forbidden" } */
+
+float_ops: /* { dg-bogus "use of floating points forbidden" } */
+
+ /* Check float detection in typename. */
+ f += sizeof (float); /* { dg-error "use of floating points forbidden" } */
+ f += sizeof (double); /* { dg-error "use of floating points forbidden" } */
+ f += sizeof (long double); /* { dg-error "use of floating points forbidden" } */
+ f += sizeof (_Decimal32); /* { dg-error "use of floating points forbidden" } */
+ f += sizeof (_Decimal64); /* { dg-error "use of floating points forbidden" } */
+ f += sizeof (_Decimal128); /* { dg-error "use of floating points forbidden" } */
+ f += sizeof (_Complex float); /* { dg-error "use of floating points forbidden" } */
+ f += sizeof (_Complex double); /* { dg-error "use of floating points forbidden" } */
+ f += sizeof (_Complex long double); /* { dg-error "use of floating points forbidden" } */
+
+ /* Check float detection in auto double complex as typename. */
+ f += sizeof (_Complex); /* { dg-error "use of floating points forbidden" } */
+
+ /* Check float detection in cast. */
+ f = (float) 4; /* { dg-error "use of floating points forbidden" } */
+ d = (double) 4; /* { dg-error "use of floating points forbidden" } */
+ ld = (long double) 4; /* { dg-error "use of floating points forbidden" } */
+ f = (_Decimal32) 4; /* { dg-error "use of floating points forbidden" } */
+ f = (_Decimal64) 4; /* { dg-error "use of floating points forbidden" } */
+ f = (_Decimal128) 4; /* { dg-error "use of floating points forbidden" } */
+ cf = (_Complex float) cd; /* { dg-error "use of floating points forbidden" } */
+ cd = (_Complex double) cf; /* { dg-error "use of floating points forbidden" } */
+ cld = (_Complex long double) cf; /* { dg-error "use of floating points forbidden" } */
+
+ /* Check float detection in auto double complex in cast. */
+ __real__ c = (double) 4; /* { dg-error "use of floating points forbidden" } */
+
+ /* Check float detection in litterals. */
+ return (int) 4.5; /* { dg-error "use of floating points forbidden" } */
+}
+
+/* Check float detection in function parameter. */
+int float_param (float a) { return (int) a;} /* { dg-error "use of floating points forbidden" } */
+int double_param (double a) { return (int) a;} /* { dg-error "use of floating points forbidden" } */
+int long_double_param (long double a) { return (int) a;} /* { dg-error "use of floating points forbidden" } */
+int decimal32_param (_Decimal32 a) { return (int) a;} /* { dg-error "use of floating points forbidden" } */
+int decimal64_param (_Decimal64 a) { return (int) a;} /* { dg-error "use of floating points forbidden" } */
+int decimal128_param (_Decimal128 a) { return (int) a;} /* { dg-error "use of floating points forbidden" } */
+int complex_float_param (_Complex float a) { return (int) __real__ a;} /* { dg-error "use of floating points forbidden" } */
+int complex_double_param (_Complex double a) { return (int) __real__ a;} /* { dg-error "use of floating points forbidden" } */
+int complex_long_double_param (_Complex long double a) { return (int) __real__ a;} /* { dg-error "use of floating points forbidden" } */
+
+/* Check float detection in auto double complex in function parameter. */
+int complex_param (_Complex a) { return (int) __real__ a;} /* { dg-error "use of floating points forbidden" } */
+
+/* Check float detection in function return parameter. */
+float float_return (void) { return f_glob;} /* { dg-error "use of floating points forbidden" } */
+double double_return (void) { return d_glob;} /* { dg-error "use of floating points forbidden" } */
+long double long_double_return (void) { return ld_glob;} /* { dg-error "use of floating points forbidden" } */
+_Decimal32 decimal32_return (void) { return f_glob;} /* { dg-error "use of floating points forbidden" } */
+_Decimal64 decimal64_return (void) { return f_glob;} /* { dg-error "use of floating points forbidden" } */
+_Decimal128 decimal128_return (void) { return f_glob;} /* { dg-error "use of floating points forbidden" } */
+_Complex float complex_float_return (void) { return cf_glob;} /* { dg-error "use of floating points forbidden" } */
+_Complex double complex_double_return (void) { return cd_glob;} /* { dg-error "use of floating points forbidden" } */
+_Complex long double complex_long_double_return (void) { return cld_glob;} /* { dg-error "use of floating points forbidden" } */
+
+/* Check float detection in auto double complex in function return parameter. */
+_Complex complex_return (void) { return c_glob;} /* { dg-error "use of floating points forbidden" } */
Is the approach taken correct? If yes, is this ok for trunk?
Best regards,
Thomas
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH, C/C++] Add -fno-float to forbid floating point data types
2014-08-12 9:25 [PATCH, C/C++] Add -fno-float to forbid floating point data types Thomas Preud'homme
@ 2014-08-12 9:34 ` Jakub Jelinek
2014-08-12 9:43 ` Marek Polacek
2014-08-12 9:45 ` Marek Polacek
` (2 subsequent siblings)
3 siblings, 1 reply; 11+ messages in thread
From: Jakub Jelinek @ 2014-08-12 9:34 UTC (permalink / raw)
To: Thomas Preud'homme; +Cc: gcc-patches
On Tue, Aug 12, 2014 at 05:25:25PM +0800, Thomas Preud'homme wrote:
> --- a/gcc/c/c-parser.c
> +++ b/gcc/c/c-parser.c
> @@ -486,6 +486,15 @@ c_token_starts_typename (c_token *token)
> case CPP_KEYWORD:
> switch (token->keyword)
> {
> + case RID_FLOAT:
> + case RID_DOUBLE:
> + case RID_DFLOAT32:
> + case RID_DFLOAT64:
> + case RID_DFLOAT128:
> + if (flag_no_float)
> + error_at (token->location, "use of floating points forbidden in "
> + "this translation unit (-fno-float)");
> + /* Fall through. */
> case RID_UNSIGNED:
> case RID_LONG:
> case RID_INT128:
This looks wrong. c_token_starts_typename is just a function which tells
you if certain token can start a typename, issuing diagnostics there doesn't
make sense, that routine doesn't actually parse the token. You should
diagnose it where you actually parse it.
Jakub
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH, C/C++] Add -fno-float to forbid floating point data types
2014-08-12 9:34 ` Jakub Jelinek
@ 2014-08-12 9:43 ` Marek Polacek
2014-08-14 4:43 ` Thomas Preud'homme
0 siblings, 1 reply; 11+ messages in thread
From: Marek Polacek @ 2014-08-12 9:43 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: Thomas Preud'homme, gcc-patches
On Tue, Aug 12, 2014 at 11:34:35AM +0200, Jakub Jelinek wrote:
> On Tue, Aug 12, 2014 at 05:25:25PM +0800, Thomas Preud'homme wrote:
> > --- a/gcc/c/c-parser.c
> > +++ b/gcc/c/c-parser.c
> > @@ -486,6 +486,15 @@ c_token_starts_typename (c_token *token)
> > case CPP_KEYWORD:
> > switch (token->keyword)
> > {
> > + case RID_FLOAT:
> > + case RID_DOUBLE:
> > + case RID_DFLOAT32:
> > + case RID_DFLOAT64:
> > + case RID_DFLOAT128:
> > + if (flag_no_float)
> > + error_at (token->location, "use of floating points forbidden in "
> > + "this translation unit (-fno-float)");
> > + /* Fall through. */
> > case RID_UNSIGNED:
> > case RID_LONG:
> > case RID_INT128:
>
> This looks wrong. c_token_starts_typename is just a function which tells
> you if certain token can start a typename, issuing diagnostics there doesn't
> make sense, that routine doesn't actually parse the token. You should
> diagnose it where you actually parse it.
I'd say the proper place would be declspecs_add_type.
Marek
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH, C/C++] Add -fno-float to forbid floating point data types
2014-08-12 9:25 [PATCH, C/C++] Add -fno-float to forbid floating point data types Thomas Preud'homme
2014-08-12 9:34 ` Jakub Jelinek
@ 2014-08-12 9:45 ` Marek Polacek
2014-08-12 9:47 ` Marc Glisse
2014-08-12 21:46 ` Hans-Peter Nilsson
3 siblings, 0 replies; 11+ messages in thread
From: Marek Polacek @ 2014-08-12 9:45 UTC (permalink / raw)
To: Thomas Preud'homme; +Cc: gcc-patches
On Tue, Aug 12, 2014 at 05:25:25PM +0800, Thomas Preud'homme wrote:
> @@ -10078,6 +10078,10 @@ finish_declspecs (struct c_declspecs *specs)
> }
> else if (specs->complex_p)
> {
> + if (flag_no_float)
> + error_at (specs->locations[cdw_complex],
> + "use of floating points forbidden in this translation "
> + "unit (-fno-float)");
Please drop the " (-fno-float)" part (and elsewhere too).
Marek
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH, C/C++] Add -fno-float to forbid floating point data types
2014-08-12 9:25 [PATCH, C/C++] Add -fno-float to forbid floating point data types Thomas Preud'homme
2014-08-12 9:34 ` Jakub Jelinek
2014-08-12 9:45 ` Marek Polacek
@ 2014-08-12 9:47 ` Marc Glisse
2014-08-12 9:54 ` Jakub Jelinek
2014-08-12 10:21 ` Thomas Preud'homme
2014-08-12 21:46 ` Hans-Peter Nilsson
3 siblings, 2 replies; 11+ messages in thread
From: Marc Glisse @ 2014-08-12 9:47 UTC (permalink / raw)
To: Thomas Preud'homme; +Cc: gcc-patches
On Tue, 12 Aug 2014, Thomas Preud'homme wrote:
> As mentioned in PR60070, there is many cases when a programmer want to
> ensure that a program does not use any floating point data type. Other
> cases to consider is when a target has several floating point ABI and
> user want to ensure his/her is compatible with all available floating
> point ABI. Adding such a check also provides an opportunity to adapt
> the behavior of the compiler based on its result.
>
> This patch adds the new option -fno-float to request gcc to throw an
> error if any float or floating point operation is involved. The patch
> modifies the C and C++ frontend (others could be modified later if
> people request it) so as to throw an error whenever a keyword
> introducing a float type or a float litteral are encountered. The
> check is added to frontend rather middle end as this allow to do the
> detection as the file is parsed rather than needing a pass. It also
> limit the check to only the place where a float can be declared
> instead of having to look at all gimple stmts. Finally, it allows to
> catch some cases that would be absent of the middle end due to
> simplification or limited folding that the front end might do. Note
> though that things excluded by the preprocessor (think #ifdef) would
> not be analyzed.
Are you sure you want something that strict? If there are floats in the
code but the compiler manages to get rid of them, it won't cause any
trouble with the ABI. Besides, if you #include a header that declares a
function returning a double, but you don't use that function, the
compilation will still fail. And if you only want to forbid float/double
at the source level, grep is a pretty good tool. I can't see a test for
__builtin_sqrt(42). No ObjC?
I am not at all saying the approach is wrong, just making sure that's
what we want.
--
Marc Glisse
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH, C/C++] Add -fno-float to forbid floating point data types
2014-08-12 9:47 ` Marc Glisse
@ 2014-08-12 9:54 ` Jakub Jelinek
2014-08-12 10:21 ` Thomas Preud'homme
1 sibling, 0 replies; 11+ messages in thread
From: Jakub Jelinek @ 2014-08-12 9:54 UTC (permalink / raw)
To: gcc-patches; +Cc: Thomas Preud'homme
On Tue, Aug 12, 2014 at 11:47:28AM +0200, Marc Glisse wrote:
> Are you sure you want something that strict? If there are floats in the
> code but the compiler manages to get rid of them, it won't cause any
> trouble with the ABI. Besides, if you #include a header that declares a
> function returning a double, but you don't use that function, the
> compilation will still fail. And if you only want to forbid float/double
> at the source level, grep is a pretty good tool. I can't see a test for
> __builtin_sqrt(42). No ObjC?
>
> I am not at all saying the approach is wrong, just making sure that's
> what we want.
Yeah. I bet different people need different levels of this.
E.g. if float/double/long double are the same types in all subABIs, just
passing them by value/returning by value changes between different subABIs,
then complaining about sizeof(double), or say double x = 5.0; global var
etc. is unnecessary, all you care about is whether you aren't using those
types in function args/return values you emit into the code.
Somebody else might want to avoid all floating point instructions in their
code (so, static double x = 5.0; is fine, but e.g. initializer that needs
in C++ runtime code to initialize a static double already would not).
Then if some float/double/long double/_Decimal* type actually changes
the layout in between different ABIs, you might want to complain if
it appears in sizeof/__alignof__ etc.
Jakub
^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: [PATCH, C/C++] Add -fno-float to forbid floating point data types
2014-08-12 9:47 ` Marc Glisse
2014-08-12 9:54 ` Jakub Jelinek
@ 2014-08-12 10:21 ` Thomas Preud'homme
2014-08-12 14:54 ` Joseph S. Myers
2014-08-12 14:56 ` Joseph S. Myers
1 sibling, 2 replies; 11+ messages in thread
From: Thomas Preud'homme @ 2014-08-12 10:21 UTC (permalink / raw)
To: gcc-patches
> From: Marc Glisse [mailto:marc.glisse@inria.fr]
> Sent: Tuesday, August 12, 2014 5:47 PM
>
>
> Are you sure you want something that strict? If there are floats in the
> code but the compiler manages to get rid of them, it won't cause any
> trouble with the ABI. Besides, if you #include a header that declares a
> function returning a double, but you don't use that function, the
> compilation will still fail. And if you only want to forbid float/double
> at the source level, grep is a pretty good tool. I can't see a test for
> __builtin_sqrt(42). No ObjC?
You raise some valid points due to the use case in mind when doing the
patch, which is codes that aim to be independent of the float ABI in use
on target with several float ABI. Now, that said, let's consider each point
one by one.
1) Where to do the check
Initially my approach was to detect whether a given execution unit is
affected by the float ABI in use and was thus much less strict. It
worked but needed some new hooks. After some discussion about
this approach it appeared to be too complicated, difficult to make it
target independent and also risky. Most importantly, it seemed
unnecessary as if you don't use float at interface you probably don't
use them at all. Or at least, it shouldn't be difficult to make it so. And
as you can see from the PR mentioned, such approach can be useful
for more use cases.
About doing the test later, I believe it makes the feature a bit less
useful. A float might be eliminated in a build due to an optimization
but still remain in another build. I feel it more useful to tell the user
that such line of code can lead to FPU being used. It also seems more
natural to test such a thing in the frontend, as you process the file.
However it's true that it prevents including math.h for instance.
It might be a good idea to ignore prototypes.
2) Need for such an option at all
Grep might work but it does not give any hint to the compiler that
no float is used and therefore the file is independent of the float ABI.
This is important since it allows the compiler to emit a special
attribute to tell the linker about it.
3) __builtin_sqrt
True, I shall try if it works with builtins. Thanks for the advice.
4) Objective C
As said in the description, I'm not opposed to adding other language.
It's easier to add another language than remove one after the fact
because very few people use it. Therefore I preferred to have
just C and C++ for now which is what I expect most of the users of
such a switch to be interested in. Do you think I should add support
for that language up front or can it wait a later version of the patch
once people started to use it?
>
> I am not at all saying the approach is wrong, just making sure that's
> what we want.
Sure, I appreciate any constructive critics. If you are unconvinced by
my arguments I'd be happy to hear about the reasons.
Best regards,
Thomas
^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: [PATCH, C/C++] Add -fno-float to forbid floating point data types
2014-08-12 10:21 ` Thomas Preud'homme
@ 2014-08-12 14:54 ` Joseph S. Myers
2014-08-12 14:56 ` Joseph S. Myers
1 sibling, 0 replies; 11+ messages in thread
From: Joseph S. Myers @ 2014-08-12 14:54 UTC (permalink / raw)
To: Thomas Preud'homme; +Cc: gcc-patches
On Tue, 12 Aug 2014, Thomas Preud'homme wrote:
> 3) __builtin_sqrt
>
> True, I shall try if it works with builtins. Thanks for the advice.
In addition to built-in functions, you have built-in typedefs. I don't
think your code would catch uses of __fp16, __float128 etc. (such types
are defined as built-in typedefs by back ends at present, not as
keywords).
Rather than making back ends have their own conditionals, the built-in
typedef issue could be dealt with by checking whether the type given by a
sequence of declspecs (in a declaration or type name) is a floating-point
type (in or after c_finish_declspecs - in the __auto_type case, getting a
floating-point type means the initializer has such a type and you should
catch things when handling the initializer).
Also consider built-in typedefs and functions involving vectors of
floating-point types, as well as the simple real and complex types.
> 4) Objective C
>
> As said in the description, I'm not opposed to adding other language.
> It's easier to add another language than remove one after the fact
> because very few people use it. Therefore I preferred to have
> just C and C++ for now which is what I expect most of the users of
> such a switch to be interested in. Do you think I should add support
> for that language up front or can it wait a later version of the patch
> once people started to use it?
The presumption should be that an option for C also applies to Objective-C
(and likewise for C++ options and Objective-C++), unless there is a
concrete reason this is problematic (i.e. an Objective-C feature that
needs special handling to implement the option).
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: [PATCH, C/C++] Add -fno-float to forbid floating point data types
2014-08-12 10:21 ` Thomas Preud'homme
2014-08-12 14:54 ` Joseph S. Myers
@ 2014-08-12 14:56 ` Joseph S. Myers
1 sibling, 0 replies; 11+ messages in thread
From: Joseph S. Myers @ 2014-08-12 14:56 UTC (permalink / raw)
To: Thomas Preud'homme; +Cc: gcc-patches
On Tue, 12 Aug 2014, Thomas Preud'homme wrote:
> However it's true that it prevents including math.h for instance.
And stdlib.h (strtod) and time.h (difftime) and wchar.h (wcstod). Is that
your intent? Note that glibc stdlib.h has an atof inline definition, it's
not just a matter of prototypes.
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH, C/C++] Add -fno-float to forbid floating point data types
2014-08-12 9:25 [PATCH, C/C++] Add -fno-float to forbid floating point data types Thomas Preud'homme
` (2 preceding siblings ...)
2014-08-12 9:47 ` Marc Glisse
@ 2014-08-12 21:46 ` Hans-Peter Nilsson
3 siblings, 0 replies; 11+ messages in thread
From: Hans-Peter Nilsson @ 2014-08-12 21:46 UTC (permalink / raw)
To: Thomas Preud'homme; +Cc: gcc-patches
On Tue, 12 Aug 2014, Thomas Preud'homme wrote:
> As mentioned in PR60070, there is many cases when a programmer want to ensure
> that a program does not use any floating point data type. Other cases to consider
> is when a target has several floating point ABI and user want to ensure his/her
> is compatible with all available floating point ABI.
For the latter, you're too strict, the ABI might not matter
until e.g. functions are inlined and about to be laid out or
"expanded".
> Adding such a check also provides
> an opportunity to adapt the behavior of the compiler based on its result.
The cases I've run into involves a requirement that all
floating-point-operations (typically in code with lots of it)
are converted into integer operations possibly made constant,
e.g. by casting constant expressions possibly involving
builtins. I don't think this use-case is covered by your
implementation (other than trivially forbidding it).
Also, people will likely find a need to constrain code at
compile-time when this option is in effect, so can you please
add a built-in CPP definition activated by -fno-float, for
example __GCC_NO_FLOAT__?
brgds, H-P
^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: [PATCH, C/C++] Add -fno-float to forbid floating point data types
2014-08-12 9:43 ` Marek Polacek
@ 2014-08-14 4:43 ` Thomas Preud'homme
0 siblings, 0 replies; 11+ messages in thread
From: Thomas Preud'homme @ 2014-08-14 4:43 UTC (permalink / raw)
To: 'Marek Polacek', Jakub Jelinek; +Cc: gcc-patches
> From: Marek Polacek [mailto:polacek@redhat.com]
> Sent: Tuesday, August 12, 2014 5:43 PM
> On Tue, Aug 12, 2014 at 11:34:35AM +0200, Jakub Jelinek wrote:
> >
> > This looks wrong. c_token_starts_typename is just a function which tells
> > you if certain token can start a typename, issuing diagnostics there doesn't
> > make sense, that routine doesn't actually parse the token. You should
> > diagnose it where you actually parse it.
>
> I'd say the proper place would be declspecs_add_type.
Wouldn't that miss casts and sizeof for instance? It's true that
c_token_starts_typename is not the place where the token is parsed but it
seemed a more central place: it catches all these cases in one check. Ok
maybe sizeof (float) should be ignored but I suppose if you use that you
intend to store a float later.
On the other hand I do want to distinguish float declared in prototypes from
float declared elsewhere.
Best regards,
Thomas
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2014-08-14 4:43 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-12 9:25 [PATCH, C/C++] Add -fno-float to forbid floating point data types Thomas Preud'homme
2014-08-12 9:34 ` Jakub Jelinek
2014-08-12 9:43 ` Marek Polacek
2014-08-14 4:43 ` Thomas Preud'homme
2014-08-12 9:45 ` Marek Polacek
2014-08-12 9:47 ` Marc Glisse
2014-08-12 9:54 ` Jakub Jelinek
2014-08-12 10:21 ` Thomas Preud'homme
2014-08-12 14:54 ` Joseph S. Myers
2014-08-12 14:56 ` Joseph S. Myers
2014-08-12 21:46 ` Hans-Peter Nilsson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).