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
jos...@codesourcery.com

Reply via email to