On 11/27/18 10:47 AM, Joseph Myers wrote:
On Mon, 26 Nov 2018, Martin Sebor wrote:

Ping: https://gcc.gnu.org/ml/gcc-patches/2018-11/msg01674.html

This patch needs an update to the comment on convert_argument to explain
the semantics of the new valtype parameter and how it differs from the
previously used TREE_TYPE (val).

I've added comments for all the function arguments.

FWIW, none of these were documented before and I hadn't really
taken the time to study them all carefully to understand how
each of them was being used (I just took the undocumented local
variables and made them arguments).  So it took a bit of effort
to figure out.  Hopefully it's close enough.

Martin
PR c/88091 - c-c++-common/Wconversion-real.c etc. FAIL

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.

Index: gcc/c/c-typeck.c
===================================================================
--- gcc/c/c-typeck.c	(revision 266594)
+++ gcc/c/c-typeck.c	(working copy)
@@ -3186,18 +3186,25 @@ c_build_function_call_vec (location_t loc, vec<loc
 
 /* 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))
@@ -3204,164 +3211,162 @@ convert_argument (location_t ploc, tree function,
     {
       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)
     {
-      /* 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)
 	{
-	  unsigned int formal_prec = TYPE_PRECISION (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) == REAL_TYPE)
+	  /* 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 integer rather "
-			"than floating due to prototype",
+			"passing argument %d of %qE "
+			"with different width due to prototype",
 			argnum, rname);
-	  if (INTEGRAL_TYPE_P (type)
-	      && TREE_CODE (valtype) == COMPLEX_TYPE)
+	  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 integer rather "
-			"than complex due to prototype",
+			"passing argument %d of %qE "
+			"as unsigned due to prototype",
 			argnum, rname);
-	  else if (TREE_CODE (type) == COMPLEX_TYPE
-		   && TREE_CODE (valtype) == REAL_TYPE)
+	  else
 	    warning_at (ploc, OPT_Wtraditional_conversion,
-			"passing argument %d of %qE as complex rather "
-			"than floating due to prototype",
+			"passing argument %d of %qE "
+			"as signed 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);
-
-	      /* 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>
 	  }
     }
 
-  /* 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>
        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>
 	{
 	  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>
 	     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);
 	}
 
Index: gcc/c/c-typeck.c
===================================================================
--- gcc/c/c-typeck.c    (revision 266594)
+++ gcc/c/c-typeck.c    (working copy)
@@ -3186,18 +3186,25 @@
 
 /* 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))
@@ -3204,10 +3211,9 @@
     {
       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)
@@ -3352,7 +3358,7 @@
       if (excess_precision)
        val = build1 (EXCESS_PRECISION_EXPR, valtype, val);
 
-      parmval = convert_for_assignment (ploc, ploc, type,
+  tree parmval = convert_for_assignment (ploc, ploc, type,
                                        val, origtype, ic_argpass,
                                        npc, fundecl, function,
                                        parmnum + 1, warnopt);
@@ -3361,7 +3367,6 @@
          && INTEGRAL_TYPE_P (type)
          && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
        parmval = default_conversion (parmval);
-    }
 
   return parmval;
 }
@@ -3457,8 +3462,8 @@
          }
     }
 
-  /* 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 @@
        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 @@
        {
          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 @@
             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);
        }
 

Reply via email to