On 11/20/2018 11:02 AM, Martin Sebor wrote:
Would the updated comments in the attached patch more accurately
describe the purpose of the IMPLICIT_P flag and
the builtin_decl_explicit() and builtin_decl_implicit() functions?
I ended up here while trying to understand the differences between
the functions on different targets and decide which one should be
used to diagnose bugs like the one below:
long double fabsl (); // missing prototype
long double f (int x)
{
return fabsl (x); // want a warning here
}
I think we want the warning regardless of IMPLICIT_P so the warning
code should call builtin_decl_explicit() to obtain fabsl's expected
type, even if the target's runtime doesn't support the function on
the basis of the comment:
When a program uses floorf we may assume that the floorf function
has the expected meaning
Actually, some more testing suggests the comment in builtins.def
(either the original or the patched one) isn't entirely accurate
or helpful to understanding the purpose of the flag:
IMPLICIT specifies condition when the builtin can be produced by
compiler. For instance C90 reserves floorf function, but does not
define it's meaning. When user uses floorf we may assume that the
floorf has the meaning we expect, but we can't produce floorf by
simplifying floor((double)float) since the runtime need not
implement it.
Given the following code:
float floorf ();
void f (void)
{
if (floorf (0.0f))
__builtin_abort ();
}
in C90 mode, BUILT_IN_FLOORF's IMPLICIT flag is clear and GCC
doesn't seem to assume anything about the call to the function,
contrary to the comment ("we may assume the meaning we expect").
The comment also doesn't explain when IMPLICIT may be set.
I've updated the comment a bit more to more accurately describe
when I think the flag is set or clear, and how it's used.
Corrections or further clarification are appreciated.
Thanks
Martin
gcc/ChangeLog:
* builtins.def (DEF_BUILTIN): Update comment..
* tree.h (builtin_decl_explicit): Same.
(builtin_decl_implicit): Same.
Index: gcc/tree.h
===================================================================
--- gcc/tree.h (revision 266320)
+++ gcc/tree.h (working copy)
@@ -5220,7 +5220,9 @@ is_lang_specific (const_tree t)
#define BUILTIN_VALID_P(FNCODE) \
(IN_RANGE ((int)FNCODE, ((int)BUILT_IN_NONE) + 1, ((int) END_BUILTINS) - 1))
-/* Return the tree node for an explicit standard builtin function or NULL. */
+/* Return the tree node for the built-in function declaration corresponding
+ to FNCODE or NULL. */
+
static inline tree
builtin_decl_explicit (enum built_in_function fncode)
{
@@ -5229,7 +5231,12 @@ builtin_decl_explicit (enum built_in_function fnco
return builtin_info[(size_t)fncode].decl;
}
-/* Return the tree node for an implicit builtin function or NULL. */
+/* Return the tree node for the built-in function declaration corresponding
+ to FNCODE if its IMPLICIT_P flag has been set or NULL otherwise.
+ IMPLICIT_P is clear for library built-ins that GCC implements but that
+ may not be implemented in the runtime library on the target. See also
+ the DEF_BUILTIN macro in builtins.def. */
+
static inline tree
builtin_decl_implicit (enum built_in_function fncode)
{
Index: gcc/builtins.def
===================================================================
--- gcc/builtins.def (revision 266320)
+++ gcc/builtins.def (working copy)
@@ -54,12 +54,18 @@ along with GCC; see the file COPYING3. If not see
ATTRs is an attribute list as defined in builtin-attrs.def that
describes the attributes of this builtin function.
- IMPLICIT specifies condition when the builtin can be produced by
- compiler. For instance C90 reserves floorf function, but does not
- define it's meaning. When user uses floorf we may assume that the
- floorf has the meaning we expect, but we can't produce floorf by
- simplifying floor((double)float) since the runtime need not implement
- it.
+ IMPLICIT specifies the condition when calls to a library builtin
+ may be introduced by GCC. For instance, C90 defines the floor
+ function but only reserves floorf without defining its meaning.
+ Thus, IMPLICIT is set for floor but clear for floorf. GCC can
+ safely substitute calls to floor for equivalent expressions but
+ the most it can do for floorf is assume that explicit calls to
+ it in a program are those to the reserved function. It cannot
+ introduce calls to the function that do not exist in the source
+ code of the program. This prevents trasformations that might be
+ possibe otherwise, such as turning the call floor((double)flt)
+ into one to floorf(flt) because the runtime library can be assumed
+ to implement the latter function.
The builtins is registered only if COND is true. */