On Wed, 12 Nov 2014, Thomas Preud'homme wrote:
> In several occasions (see [1][2] people requested a switch to tell GCC
> that a given compilation unit should not contain any float and that GCC
> should warn about any violation of this assumption. Such a switch would
> ensure that no softfloat library is going to be pulled in by the linker
> and would also allow to notify the linker that the resulting file is
> float ABI independent (a feature useful for [3]). A previous patch was
> posted here [4] and this patch tries to address all the comments that
> were done.
>
> [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60070
> [2] https://answers.launchpad.net/gcc-arm-embedded/+question/254345
> [3] http://jira.arm.com/browse/GCC32RM-276
> [4] https://gcc.gnu.org/ml/gcc-patches/2014-08/msg01099.html
>
> This patch modifies the C parser to give an error if:
> - any variable or function parameter is declared with a float type or
> a type containing a float (prototype are ignored)
But if you ignore prototypes at the time of declaration, don't you need to
diagnose if a function with a floating-point parameter or return type gets
called? I don't see anything to do that. (This includes the
__builtin_sqrt case from the previous discussion.)
> specified by user and a float litteral is found.
"literal" (throughout).
> @@ -1874,6 +1925,12 @@ c_parser_declaration_or_fndef (c_parser *parser, bool
> fndef_ok,
> }
> else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
> {
> + /* Forbidden declaration of floating point variable. */
> + if (flag_no_float && declarator->kind != cdk_function
> + && contains_floating_point_type (specs->type))
> + error_at (specs->locations[cdw_typespec],
> + "use of floating point data types forbidden in this "
> + "translation unit");
> c_parser_consume_token (parser);
> return;
> }
No, this is wrong. (a) By tying this to CPP_SEMICOLON you'll only catch
it if the variable is last in the list of declarators (consider "float f,
g (void);", where what comes before the semicolon is a function
declaration); better to check on each declarator, not just the last. (b)
declarator->kind reflects the outermost declarator, but what determines
whether it's a function declaration is the innermost declarator (other
than cdk_id or cdk_attrs declarators), so this looks like it would give an
error for "float *f(void);" (wrongly treating it as a variable because the
outermost declarator is cdk_pointer), but not for "float (*f)(void);"
(wrongly treating it as a function because the outermost declarator is
cdk_function ... you could of course decide that function pointers
involving floating-point types are OK if you want). (c) specs->type only
covers the type specifiers, so if you want to diagnose function pointer
variables you need to allow for "int (*f)(float);" where the declaration's
type involves floating point but the type specifiers don't. (d) What do
you want to do with typedef declarations (right now it looks like they'll
be handled as variables, but your testcases don't consider them)?
I'd also suggest some refactoring: have a function that takes as arguments
a location and a type, and does the
if (flag_no_float && contains_floating_point_type (type))
error_at (loc, ...);
to avoid repeating that pattern in several places.
--
Joseph S. Myers
[email protected]