PR testsuite/88098 - FAIL: gcc.dg/Wbuiltin-declaration-mismatch-4.c (test for warnings

gcc/c/ChangeLog:

	PR testsuite/88098
	* c-typeck.c (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 266284)
+++ gcc/c/c-typeck.c	(working copy)
@@ -6461,7 +6461,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 266284)
+++ 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.  */
@@ -95,7 +95,7 @@ double fabs ();           /* { dg-message "built-i
 /* Expect a warning for fabsf below because even a float argument promotes
    to double.  Unfortunately, invalid calls to fabsf() are not diagnosed.  */
 float fabsf ();           /* { dg-warning "conflicting types for built-in function .fabsf.; expected .float\\\(float\\\)." } */
-long double fabsl ();     /* { dg-message "built-in .fabsl. declared here" } */
+long double fabsl ();     /* { dg-message "built-in .fabsl. declared here" "large long double" { target large_long_double } } */
 
 void test_real_conversion_fabs (void)
 {
@@ -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);
@@ -117,9 +118,9 @@ void test_real_conversion_fabs (void)
 
   d = fabsf (c);    /* { dg-warning ".fabsf. argument 1 promotes to .int. where .float. is expected in a call to built-in function declared without prototype" "pr87890" { xfail *-*-* } } */
 
-  d = fabsl (c);    /* { dg-warning ".fabsl. argument 1 promotes to .int. where .long double. is expected in a call to built-in function declared without prototype" } */
+  d = fabsl (c);    /* { dg-warning ".fabsl. argument 1 promotes to .int. where .long double. is expected in a call to built-in function declared without prototype" "large long double" { target large_long_double } } */
 
-  d = fabsl (f);    /* { dg-warning ".fabsl. argument 1 promotes to .double. where .long double. is expected in a call to built-in function declared without prototype" } */
+  d = fabsl (f);    /* { dg-warning ".fabsl. argument 1 promotes to .double. where .long double. is expected in a call to built-in function declared without prototype" "large long double" { target large_long_double } } */
 
   /* Verify that the same call as above but to the built-in doesn't
      trigger a warning.  */
Index: gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-5.c
===================================================================
--- gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-5.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-5.c	(working copy)
@@ -0,0 +1,19 @@
+/* PR testsuite/88098 - FAIL: gcc.dg/Wbuiltin-declaration-mismatch-4.c
+   { dg-do compile }
+   { dg-options "-Wbuiltin-declaration-mismatch -fshort-enums" } */
+
+int abs ();
+double fabs ();     /* { dg-message "built-in .fabs. declared here" } */
+
+enum E { e0 } e;
+
+int i;
+double d;
+
+void test_short_enums (void)
+{
+  /* enum e promotes to int.  */
+  i = abs (e);
+
+  d = fabs (e);     /* { dg-warning ".fabs. argument 1 promotes to .int. where .double. is expected in a call to built-in function declared without prototype" } */
+}
