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);

Reply via email to