PR c/88091 - c-c++-common/Wconversion-real.c etc. FAIL
authorMartin Sebor <msebor@redhat.com>
Thu, 29 Nov 2018 18:03:18 +0000 (18:03 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Thu, 29 Nov 2018 18:03:18 +0000 (11:03 -0700)
gcc/c/ChangeLog:

PR c/88091
* c-typeck.c (convert_argument): Add a parameter.  Adjust indentation.
(convert_arguments): Add comments.  Pass additional argument to
the function above.

From-SVN: r266634

gcc/c/ChangeLog
gcc/c/c-typeck.c

index 4ed5b4bd8f530bab85efc4b7b2ba6d6dbfa65a34..c82f47bbab8d29f6ea82626d342afdd92a50dd18 100644 (file)
@@ -1,3 +1,10 @@
+2018-11-29  Martin Sebor  <msebor@redhat.com>
+
+       PR c/88091
+       * c-typeck.c (convert_argument): Add a parameter.  Adjust indentation.
+       (convert_arguments): Add comments.  Pass additional argument to
+       the function above.
+
 2018-11-29  Martin Sebor  <msebor@redhat.com>
 
        PR c/88172
index 81c520ade3942b1897241bb051884c82fa4f0012..8fbecfce956c0d55ebe19ccacd50eba17fe9fc26 100644 (file)
@@ -3186,182 +3186,187 @@ c_build_function_call_vec (location_t loc, vec<location_t> arg_loc,
 \f
 /* Helper for convert_arguments called to convert the VALue of argument
    number ARGNUM from ORIGTYPE to the corresponding parameter number
-   PARMNUL and TYPE.  */
+   PARMNUM and TYPE.
+   PLOC is the location where the conversion is being performed.
+   FUNCTION and FUNDECL are the same as in convert_arguments.
+   VALTYPE is the original type of VAL before the conversion and,
+   for EXCESS_PRECISION_EXPR, the operand of the expression.
+   NPC is true if VAL represents the null pointer constant (VAL itself
+   will have been folded to an integer constant).
+   RNAME is the same as FUNCTION except in Objective C when it's
+   the function selector.
+   EXCESS_PRECISION is true when VAL was originally represented
+   as EXCESS_PRECISION_EXPR.
+   WARNOPT is the same as in convert_for_assignment.  */
 
 static tree
 convert_argument (location_t ploc, tree function, tree fundecl,
-                 tree type, tree origtype, tree val, bool npc,
-                 tree rname, int parmnum, int argnum,
+                 tree type, tree origtype, tree val, tree valtype,
+                 bool npc, tree rname, int parmnum, int argnum,
                  bool excess_precision, int warnopt)
 {
-  tree valtype = TREE_TYPE (val);
-
-  tree parmval;
-
   /* Formal parm type is specified by a function prototype.  */
 
   if (type == error_mark_node || !COMPLETE_TYPE_P (type))
     {
       error_at (ploc, "type of formal parameter %d is incomplete",
                parmnum + 1);
-      parmval = val;
+      return val;
     }
-  else
-    {
-      /* Optionally warn about conversions that differ from the default
-        conversions.  */
-      if (warn_traditional_conversion || warn_traditional)
-       {
-         unsigned int formal_prec = TYPE_PRECISION (type);
 
-         if (INTEGRAL_TYPE_P (type)
-             && TREE_CODE (valtype) == REAL_TYPE)
-           warning_at (ploc, OPT_Wtraditional_conversion,
-                       "passing argument %d of %qE as integer rather "
-                       "than floating due to prototype",
+  /* Optionally warn about conversions that differ from the default
+     conversions.  */
+  if (warn_traditional_conversion || warn_traditional)
+    {
+      unsigned int formal_prec = TYPE_PRECISION (type);
+
+      if (INTEGRAL_TYPE_P (type)
+         && TREE_CODE (valtype) == REAL_TYPE)
+       warning_at (ploc, OPT_Wtraditional_conversion,
+                   "passing argument %d of %qE as integer rather "
+                   "than floating due to prototype",
+                   argnum, rname);
+      if (INTEGRAL_TYPE_P (type)
+         && TREE_CODE (valtype) == COMPLEX_TYPE)
+       warning_at (ploc, OPT_Wtraditional_conversion,
+                   "passing argument %d of %qE as integer rather "
+                   "than complex due to prototype",
+                   argnum, rname);
+      else if (TREE_CODE (type) == COMPLEX_TYPE
+              && TREE_CODE (valtype) == REAL_TYPE)
+       warning_at (ploc, OPT_Wtraditional_conversion,
+                   "passing argument %d of %qE as complex rather "
+                   "than floating due to prototype",
+                   argnum, rname);
+      else if (TREE_CODE (type) == REAL_TYPE
+              && INTEGRAL_TYPE_P (valtype))
+       warning_at (ploc, OPT_Wtraditional_conversion,
+                   "passing argument %d of %qE as floating rather "
+                   "than integer due to prototype",
+                   argnum, rname);
+      else if (TREE_CODE (type) == COMPLEX_TYPE
+              && INTEGRAL_TYPE_P (valtype))
+       warning_at (ploc, OPT_Wtraditional_conversion,
+                   "passing argument %d of %qE as complex rather "
+                   "than integer due to prototype",
+                   argnum, rname);
+      else if (TREE_CODE (type) == REAL_TYPE
+              && TREE_CODE (valtype) == COMPLEX_TYPE)
+       warning_at (ploc, OPT_Wtraditional_conversion,
+                   "passing argument %d of %qE as floating rather "
+                   "than complex due to prototype",
+                   argnum, rname);
+      /* ??? At some point, messages should be written about
+        conversions between complex types, but that's too messy
+        to do now.  */
+      else if (TREE_CODE (type) == REAL_TYPE
+              && TREE_CODE (valtype) == REAL_TYPE)
+       {
+         /* Warn if any argument is passed as `float',
+            since without a prototype it would be `double'.  */
+         if (formal_prec == TYPE_PRECISION (float_type_node)
+             && type != dfloat32_type_node)
+           warning_at (ploc, 0,
+                       "passing argument %d of %qE as %<float%> "
+                       "rather than %<double%> due to prototype",
                        argnum, rname);
-         if (INTEGRAL_TYPE_P (type)
-             && TREE_CODE (valtype) == COMPLEX_TYPE)
-           warning_at (ploc, OPT_Wtraditional_conversion,
-                       "passing argument %d of %qE as integer rather "
-                       "than complex due to prototype",
-                       argnum, rname);
-         else if (TREE_CODE (type) == COMPLEX_TYPE
-                  && TREE_CODE (valtype) == REAL_TYPE)
-           warning_at (ploc, OPT_Wtraditional_conversion,
-                       "passing argument %d of %qE as complex rather "
-                       "than floating due to prototype",
-                       argnum, rname);
-         else if (TREE_CODE (type) == REAL_TYPE
-                  && INTEGRAL_TYPE_P (valtype))
+
+         /* Warn if mismatch between argument and prototype
+            for decimal float types.  Warn of conversions with
+            binary float types and of precision narrowing due to
+            prototype.  */
+         else if (type != valtype
+                  && (type == dfloat32_type_node
+                      || type == dfloat64_type_node
+                      || type == dfloat128_type_node
+                      || valtype == dfloat32_type_node
+                      || valtype == dfloat64_type_node
+                      || valtype == dfloat128_type_node)
+                  && (formal_prec
+                      <= TYPE_PRECISION (valtype)
+                      || (type == dfloat128_type_node
+                          && (valtype
+                              != dfloat64_type_node
+                              && (valtype
+                                  != dfloat32_type_node)))
+                      || (type == dfloat64_type_node
+                          && (valtype
+                              != dfloat32_type_node))))
+           warning_at (ploc, 0,
+                       "passing argument %d of %qE as %qT "
+                       "rather than %qT due to prototype",
+                       argnum, rname, type, valtype);
+
+       }
+      /* Detect integer changing in width or signedness.
+        These warnings are only activated with
+        -Wtraditional-conversion, not with -Wtraditional.  */
+      else if (warn_traditional_conversion
+              && INTEGRAL_TYPE_P (type)
+              && INTEGRAL_TYPE_P (valtype))
+       {
+         tree would_have_been = default_conversion (val);
+         tree type1 = TREE_TYPE (would_have_been);
+
+         if (val == error_mark_node)
+           /* VAL could have been of incomplete type.  */;
+         else if (TREE_CODE (type) == ENUMERAL_TYPE
+                  && (TYPE_MAIN_VARIANT (type)
+                      == TYPE_MAIN_VARIANT (valtype)))
+           /* No warning if function asks for enum
+              and the actual arg is that enum type.  */
+           ;
+         else if (formal_prec != TYPE_PRECISION (type1))
            warning_at (ploc, OPT_Wtraditional_conversion,
-                       "passing argument %d of %qE as floating rather "
-                       "than integer due to prototype",
+                       "passing argument %d of %qE "
+                       "with different width due to prototype",
                        argnum, rname);
-         else if (TREE_CODE (type) == COMPLEX_TYPE
-                  && INTEGRAL_TYPE_P (valtype))
+         else if (TYPE_UNSIGNED (type) == TYPE_UNSIGNED (type1))
+           ;
+         /* Don't complain if the formal parameter type
+            is an enum, because we can't tell now whether
+            the value was an enum--even the same enum.  */
+         else if (TREE_CODE (type) == ENUMERAL_TYPE)
+           ;
+         else if (TREE_CODE (val) == INTEGER_CST
+                  && int_fits_type_p (val, type))
+           /* Change in signedness doesn't matter
+              if a constant value is unaffected.  */
+           ;
+         /* If the value is extended from a narrower
+            unsigned type, it doesn't matter whether we
+            pass it as signed or unsigned; the value
+            certainly is the same either way.  */
+         else if (TYPE_PRECISION (valtype) < TYPE_PRECISION (type)
+                  && TYPE_UNSIGNED (valtype))
+           ;
+         else if (TYPE_UNSIGNED (type))
            warning_at (ploc, OPT_Wtraditional_conversion,
-                       "passing argument %d of %qE as complex rather "
-                       "than integer due to prototype",
+                       "passing argument %d of %qE "
+                       "as unsigned due to prototype",
                        argnum, rname);
-         else if (TREE_CODE (type) == REAL_TYPE
-                  && TREE_CODE (valtype) == COMPLEX_TYPE)
+         else
            warning_at (ploc, OPT_Wtraditional_conversion,
-                       "passing argument %d of %qE as floating rather "
-                       "than complex due to prototype",
+                       "passing argument %d of %qE "
+                       "as signed due to prototype",
                        argnum, rname);
-         /* ??? At some point, messages should be written about
-            conversions between complex types, but that's too messy
-            to do now.  */
-         else if (TREE_CODE (type) == REAL_TYPE
-                  && TREE_CODE (valtype) == REAL_TYPE)
-           {
-             /* Warn if any argument is passed as `float',
-                since without a prototype it would be `double'.  */
-             if (formal_prec == TYPE_PRECISION (float_type_node)
-                 && type != dfloat32_type_node)
-               warning_at (ploc, 0,
-                           "passing argument %d of %qE as %<float%> "
-                           "rather than %<double%> due to prototype",
-                           argnum, rname);
-
-             /* Warn if mismatch between argument and prototype
-                for decimal float types.  Warn of conversions with
-                binary float types and of precision narrowing due to
-                prototype.  */
-             else if (type != valtype
-                      && (type == dfloat32_type_node
-                          || type == dfloat64_type_node
-                          || type == dfloat128_type_node
-                          || valtype == dfloat32_type_node
-                          || valtype == dfloat64_type_node
-                          || valtype == dfloat128_type_node)
-                      && (formal_prec
-                          <= TYPE_PRECISION (valtype)
-                          || (type == dfloat128_type_node
-                              && (valtype
-                                  != dfloat64_type_node
-                                  && (valtype
-                                      != dfloat32_type_node)))
-                          || (type == dfloat64_type_node
-                              && (valtype
-                                  != dfloat32_type_node))))
-               warning_at (ploc, 0,
-                           "passing argument %d of %qE as %qT "
-                           "rather than %qT due to prototype",
-                           argnum, rname, type, valtype);
-
-           }
-         /* Detect integer changing in width or signedness.
-            These warnings are only activated with
-            -Wtraditional-conversion, not with -Wtraditional.  */
-         else if (warn_traditional_conversion
-                  && INTEGRAL_TYPE_P (type)
-                  && INTEGRAL_TYPE_P (valtype))
-           {
-             tree would_have_been = default_conversion (val);
-             tree type1 = TREE_TYPE (would_have_been);
-
-             if (val == error_mark_node)
-               /* VAL could have been of incomplete type.  */;
-             else if (TREE_CODE (type) == ENUMERAL_TYPE
-                      && (TYPE_MAIN_VARIANT (type)
-                          == TYPE_MAIN_VARIANT (valtype)))
-               /* No warning if function asks for enum
-                  and the actual arg is that enum type.  */
-               ;
-             else if (formal_prec != TYPE_PRECISION (type1))
-               warning_at (ploc, OPT_Wtraditional_conversion,
-                           "passing argument %d of %qE "
-                           "with different width due to prototype",
-                           argnum, rname);
-             else if (TYPE_UNSIGNED (type) == TYPE_UNSIGNED (type1))
-               ;
-             /* Don't complain if the formal parameter type
-                is an enum, because we can't tell now whether
-                the value was an enum--even the same enum.  */
-             else if (TREE_CODE (type) == ENUMERAL_TYPE)
-               ;
-             else if (TREE_CODE (val) == INTEGER_CST
-                      && int_fits_type_p (val, type))
-               /* Change in signedness doesn't matter
-                  if a constant value is unaffected.  */
-               ;
-             /* If the value is extended from a narrower
-                unsigned type, it doesn't matter whether we
-                pass it as signed or unsigned; the value
-                certainly is the same either way.  */
-             else if (TYPE_PRECISION (valtype) < TYPE_PRECISION (type)
-                      && TYPE_UNSIGNED (valtype))
-               ;
-             else if (TYPE_UNSIGNED (type))
-               warning_at (ploc, OPT_Wtraditional_conversion,
-                           "passing argument %d of %qE "
-                           "as unsigned due to prototype",
-                           argnum, rname);
-             else
-               warning_at (ploc, OPT_Wtraditional_conversion,
-                           "passing argument %d of %qE "
-                           "as signed due to prototype",
-                           argnum, rname);
-           }
        }
+    }
 
-      /* Possibly restore an EXCESS_PRECISION_EXPR for the
-        sake of better warnings from convert_and_check.  */
-      if (excess_precision)
-       val = build1 (EXCESS_PRECISION_EXPR, valtype, val);
+  /* Possibly restore an EXCESS_PRECISION_EXPR for the
+     sake of better warnings from convert_and_check.  */
+  if (excess_precision)
+    val = build1 (EXCESS_PRECISION_EXPR, valtype, val);
 
-      parmval = convert_for_assignment (ploc, ploc, type,
-                                       val, origtype, ic_argpass,
-                                       npc, fundecl, function,
-                                       parmnum + 1, warnopt);
+  tree parmval = convert_for_assignment (ploc, ploc, type,
+                                        val, origtype, ic_argpass,
+                                        npc, fundecl, function,
+                                        parmnum + 1, warnopt);
 
-      if (targetm.calls.promote_prototypes (fundecl ? TREE_TYPE (fundecl) : 0)
-         && INTEGRAL_TYPE_P (type)
-         && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
-       parmval = default_conversion (parmval);
-    }
+  if (targetm.calls.promote_prototypes (fundecl ? TREE_TYPE (fundecl) : 0)
+      && INTEGRAL_TYPE_P (type)
+      && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
+    parmval = default_conversion (parmval);
 
   return parmval;
 }
@@ -3457,8 +3462,8 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist,
          }
     }
 
-  /* Scan the given expressions and types, producing individual
-     converted arguments.  */
+  /* Scan the given expressions (VALUES) and types (TYPELIST), producing
+     individual converted arguments.  */
 
   tree typetail, builtin_typetail, val;
   for (typetail = typelist,
@@ -3467,14 +3472,23 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist,
        values && values->iterate (parmnum, &val);
        ++parmnum)
     {
+      /* The type of the function parameter (if it was declared with one).  */
       tree type = typetail ? TREE_VALUE (typetail) : NULL_TREE;
+      /* The type of the built-in function parameter (if the function
+        is a built-in).  Used to detect type incompatibilities in
+        calls to built-ins declared without a prototype.  */
       tree builtin_type = (builtin_typetail
                           ? TREE_VALUE (builtin_typetail) : NULL_TREE);
+      /* The original type of the argument being passed to the function.  */
       tree valtype = TREE_TYPE (val);
+      /* The called function (or function selector in Objective C).  */
       tree rname = function;
       int argnum = parmnum + 1;
       const char *invalid_func_diag;
+      /* Set for EXCESS_PRECISION_EXPR arguments.  */
       bool excess_precision = false;
+      /* The value of the argument after conversion to the type
+        of the function parameter it is passed to.  */
       tree parmval;
       /* Some __atomic_* builtins have additional hidden argument at
         position 0.  */
@@ -3558,7 +3572,7 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist,
        {
          tree origtype = (!origtypes) ? NULL_TREE : (*origtypes)[parmnum];
          parmval = convert_argument (ploc, function, fundecl, type, origtype,
-                                     val, npc, rname, parmnum, argnum,
+                                     val, valtype, npc, rname, parmnum, argnum,
                                      excess_precision, 0);
        }
       else if (promote_float_arg)
@@ -3610,7 +3624,8 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist,
             above by applying default conversions instead.  */
          tree origtype = (!origtypes) ? NULL_TREE : (*origtypes)[parmnum];
          convert_argument (ploc, function, fundecl, builtin_type, origtype,
-                           val, npc, rname, parmnum, argnum, excess_precision,
+                           val, valtype, npc, rname, parmnum, argnum,
+                           excess_precision,
                            OPT_Wbuiltin_declaration_mismatch);
        }