By calling builtin_decl_explicit rather than builtin_decl_implicit the updated patch in the attachment avoids test failures due to missing warnings on targets with support for long double but whose libc doesn't support C99 functions like fabsl (such as apparently aarch64-linux).
Martin On 11/19/2018 02:37 PM, Martin Sebor wrote:
The gcc.dg/Wbuiltin-declaration-mismatch-4.c test added with the recent -Wbuiltin-declaration-mismatch enhancement to detect calls with incompatible arguments to built-ins declared without a prototype fails on a few targets due to incorrect assumptions hardcoded into the test. Besides removing those assumptions (or adding appropriate { target } attributes, the attached patch also adjusts the implementation of the warning to avoid triggering for enum promotion to int on short_enums targets. Since the fix is trivial I plan to commit it tomorrow if there are no concerns. Tested on x86_64-linux and with an arm-none-eabi cross-compiler. I also did a little bit of testing with sparc-solaris2.11 cross compiler but there the test harness fails due to the -m32 option so the Wbuiltin-declaration-mismatch-4.c still has unexpected FAILs. I've raised bug 88104 for the outstanding problem on sparc-solaris2.11. Martin
PR testsuite/88098 - FAIL: gcc.dg/Wbuiltin-declaration-mismatch-4.c gcc/c/ChangeLog: PR testsuite/88098 * c-typeck.c (convert_arguments): Call builtin_decl_explicit instead. (maybe_warn_builtin_no_proto_arg): Handle short enum to int promotion. gcc/testsuite/ChangeLog: PR testsuite/88098 * gcc.dg/Wbuiltin-declaration-mismatch-4.c: Adjust. * gcc.dg/Wbuiltin-declaration-mismatch-5.c: New test. Index: gcc/c/c-typeck.c =================================================================== --- gcc/c/c-typeck.c (revision 266320) +++ gcc/c/c-typeck.c (working copy) @@ -3422,7 +3422,10 @@ convert_arguments (location_t loc, vec<location_t> built_in_function code = DECL_FUNCTION_CODE (fundecl); if (C_DECL_BUILTIN_PROTOTYPE (fundecl)) { - if (tree bdecl = builtin_decl_implicit (code)) + /* For a call to a built-in function declared without a prototype + use the types of the parameters of the internal built-in to + match those of the arguments to. */ + if (tree bdecl = builtin_decl_explicit (code)) builtin_typelist = TYPE_ARG_TYPES (TREE_TYPE (bdecl)); } @@ -6461,7 +6464,9 @@ maybe_warn_builtin_no_proto_arg (location_t loc, t && TYPE_MODE (parmtype) == TYPE_MODE (argtype)) return; - if (parmcode == argcode + if ((parmcode == argcode + || (parmcode == INTEGER_TYPE + && argcode == ENUMERAL_TYPE)) && TYPE_MAIN_VARIANT (parmtype) == TYPE_MAIN_VARIANT (promoted)) return; Index: gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-4.c =================================================================== --- gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-4.c (revision 266320) +++ gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-4.c (working copy) @@ -77,9 +77,9 @@ void test_integer_conversion_memset (void *d) /* Passing a ptrdiff_t where size_t is expected may not be unsafe but because GCC may emits suboptimal code for such calls warning for them helps improve efficiency. */ - memset (d, 0, diffi); /* { dg-warning ".memset. argument 3 promotes to .ptrdiff_t. {aka .long int.} where .long unsigned int. is expected" } */ + memset (d, 0, diffi); /* { dg-warning ".memset. argument 3 promotes to .ptrdiff_t. {aka .\(long \)?int.} where .\(long \)?unsigned int. is expected" } */ - memset (d, 0, 2.0); /* { dg-warning ".memset. argument 3 type is .double. where 'long unsigned int' is expected" } */ + memset (d, 0, 2.0); /* { dg-warning ".memset. argument 3 type is .double. where '\(long \)?unsigned int' is expected" } */ /* Verify that the same call as above but to the built-in doesn't trigger a warning. */ @@ -108,7 +108,8 @@ void test_real_conversion_fabs (void) /* In C, the type of an enumeration constant is int. */ d = fabs (e0); /* { dg-warning ".fabs. argument 1 type is .int. where .double. is expected in a call to built-in function declared without prototype" } */ - d = fabs (e); /* { dg-warning ".fabs. argument 1 type is .enum E. where .double. is expected in a call to built-in function declared without prototype" } */ + d = fabs (e); /* { dg-warning ".fabs. argument 1 type is .enum E. where .double. is expected in a call to built-in function declared without prototype" "ordinary enum" { target { ! short_enums } } } */ + /* { dg-warning ".fabs. argument 1 promotes to .int. where .double. is expected in a call to built-in function declared without prototype" "size 1 enum" { target short_enums } .-1 } */ /* No warning here since float is promoted to double. */ d = fabs (f);