re PR c/70859 (Bad column number in type-generic function errors)
authorMarek Polacek <polacek@redhat.com>
Tue, 3 May 2016 18:03:42 +0000 (18:03 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Tue, 3 May 2016 18:03:42 +0000 (18:03 +0000)
PR c/70859
* input.c (expansion_point_location): New function.
* input.h (expansion_point_location): Declare.

* c-common.c (builtin_function_validate_nargs): Add location
parameter.  Use it.
(check_builtin_function_arguments): Add location and arguments
parameters.  Use them.
* c-common.h (check_builtin_function_arguments): Update declaration.

* c-typeck.c (build_function_call_vec): Pass LOC and ARG_LOC down to
check_builtin_function_arguments.

* call.c (build_cxx_call): Pass location and vNULL down to
check_builtin_function_arguments.

* gcc.dg/pr70859.c: New test.
* gcc.dg/pr70859-2.c: New test.

From-SVN: r235832

13 files changed:
gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/c-family/c-common.h
gcc/c/ChangeLog
gcc/c/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/input.c
gcc/input.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr70859-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr70859.c [new file with mode: 0644]

index 1a85213eca6bc4504fe5179d5d368f2cba9c0e2d..69db5dbee7bbd7e7d0507a3446b295e1b6346ba8 100644 (file)
@@ -1,3 +1,9 @@
+2016-05-03  Marek Polacek  <polacek@redhat.com>
+
+       PR c/70859
+       * input.c (expansion_point_location): New function.
+       * input.h (expansion_point_location): Declare.
+
 2016-05-03  Pierre-Marie de Rodat  <derodat@adacore.com>
 
        * dwarf2out.c (resolve_args_picking_1): Replace the frame_offset
index b34e8ed82c9451ff417ea9d3bef3d3e972502ff9..09a72e39e864b7f93cb10eaca6380a3357ac98ba 100644 (file)
@@ -1,3 +1,12 @@
+2016-05-03  Marek Polacek  <polacek@redhat.com>
+
+       PR c/70859
+       * c-common.c (builtin_function_validate_nargs): Add location
+       parameter.  Use it.
+       (check_builtin_function_arguments): Add location and arguments
+       parameters.  Use them.
+       * c-common.h (check_builtin_function_arguments): Update declaration.
+
 2016-05-03  Richard Biener  <rguenther@suse.de>
 
        * cilk.c (cilk_gimplify_call_params_in_spawned_fn): Do not
index d45bf1b67f6b1eba7cb64444fe9f108d819c0f25..63a18c866ebd3f270b9a97f667d99d670d092e34 100644 (file)
@@ -9797,31 +9797,39 @@ check_function_arguments_recurse (void (*callback)
 /* Checks for a builtin function FNDECL that the number of arguments
    NARGS against the required number REQUIRED and issues an error if
    there is a mismatch.  Returns true if the number of arguments is
-   correct, otherwise false.  */
+   correct, otherwise false.  LOC is the location of FNDECL.  */
 
 static bool
-builtin_function_validate_nargs (tree fndecl, int nargs, int required)
+builtin_function_validate_nargs (location_t loc, tree fndecl, int nargs,
+                                int required)
 {
   if (nargs < required)
     {
-      error_at (input_location,
-               "not enough arguments to function %qE", fndecl);
+      error_at (loc, "not enough arguments to function %qE", fndecl);
       return false;
     }
   else if (nargs > required)
     {
-      error_at (input_location,
-               "too many arguments to function %qE", fndecl);
+      error_at (loc, "too many arguments to function %qE", fndecl);
       return false;
     }
   return true;
 }
 
+/* Helper macro for check_builtin_function_arguments.  */
+#define ARG_LOCATION(N)                                        \
+  (arg_loc.is_empty ()                                 \
+   ? EXPR_LOC_OR_LOC (args[(N)], input_location)       \
+   : expansion_point_location (arg_loc[(N)]))
+
 /* Verifies the NARGS arguments ARGS to the builtin function FNDECL.
-   Returns false if there was an error, otherwise true.  */
+   Returns false if there was an error, otherwise true.  LOC is the
+   location of the function; ARG_LOC is a vector of locations of the
+   arguments.  */
 
 bool
-check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
+check_builtin_function_arguments (location_t loc, vec<location_t> arg_loc,
+                                 tree fndecl, int nargs, tree *args)
 {
   if (!DECL_BUILT_IN (fndecl)
       || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
@@ -9843,21 +9851,21 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
        /* The maximum alignment in bits corresponding to the same
           maximum in bytes enforced in check_user_alignment().  */
        unsigned maxalign = (UINT_MAX >> 1) + 1;
-  
+
        /* Reject invalid alignments.  */
        if (align < BITS_PER_UNIT || maxalign < align)
          {
-           error_at (EXPR_LOC_OR_LOC (args[1], input_location),
+           error_at (ARG_LOCATION (1),
                      "second argument to function %qE must be a constant "
                      "integer power of 2 between %qi and %qu bits",
                      fndecl, BITS_PER_UNIT, maxalign);
            return false;
          }
-      return true;
+       return true;
       }
 
     case BUILT_IN_CONSTANT_P:
-      return builtin_function_validate_nargs (fndecl, nargs, 1);
+      return builtin_function_validate_nargs (loc, fndecl, nargs, 1);
 
     case BUILT_IN_ISFINITE:
     case BUILT_IN_ISINF:
@@ -9865,12 +9873,12 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
     case BUILT_IN_ISNAN:
     case BUILT_IN_ISNORMAL:
     case BUILT_IN_SIGNBIT:
-      if (builtin_function_validate_nargs (fndecl, nargs, 1))
+      if (builtin_function_validate_nargs (loc, fndecl, nargs, 1))
        {
          if (TREE_CODE (TREE_TYPE (args[0])) != REAL_TYPE)
            {
-             error ("non-floating-point argument in call to "
-                    "function %qE", fndecl);
+             error_at (ARG_LOCATION (0), "non-floating-point argument in "
+                       "call to function %qE", fndecl);
              return false;
            }
          return true;
@@ -9883,7 +9891,7 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
     case BUILT_IN_ISLESSEQUAL:
     case BUILT_IN_ISLESSGREATER:
     case BUILT_IN_ISUNORDERED:
-      if (builtin_function_validate_nargs (fndecl, nargs, 2))
+      if (builtin_function_validate_nargs (loc, fndecl, nargs, 2))
        {
          enum tree_code code0, code1;
          code0 = TREE_CODE (TREE_TYPE (args[0]));
@@ -9892,8 +9900,8 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
                || (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
                || (code0 == INTEGER_TYPE && code1 == REAL_TYPE)))
            {
-             error ("non-floating-point arguments in call to "
-                    "function %qE", fndecl);
+             error_at (loc, "non-floating-point arguments in call to "
+                       "function %qE", fndecl);
              return false;
            }
          return true;
@@ -9901,22 +9909,20 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
       return false;
 
     case BUILT_IN_FPCLASSIFY:
-      if (builtin_function_validate_nargs (fndecl, nargs, 6))
+      if (builtin_function_validate_nargs (loc, fndecl, nargs, 6))
        {
-         unsigned i;
-
-         for (i=0; i<5; i++)
+         for (unsigned int i = 0; i < 5; i++)
            if (TREE_CODE (args[i]) != INTEGER_CST)
              {
-               error ("non-const integer argument %u in call to function %qE",
-                      i+1, fndecl);
+               error_at (ARG_LOCATION (i), "non-const integer argument %u in "
+                         "call to function %qE", i + 1, fndecl);
                return false;
              }
 
          if (TREE_CODE (TREE_TYPE (args[5])) != REAL_TYPE)
            {
-             error ("non-floating-point argument in call to function %qE",
-                    fndecl);
+             error_at (ARG_LOCATION (5), "non-floating-point argument in "
+                       "call to function %qE", fndecl);
              return false;
            }
          return true;
@@ -9924,11 +9930,12 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
       return false;
 
     case BUILT_IN_ASSUME_ALIGNED:
-      if (builtin_function_validate_nargs (fndecl, nargs, 2 + (nargs > 2)))
+      if (builtin_function_validate_nargs (loc, fndecl, nargs, 2 + (nargs > 2)))
        {
          if (nargs >= 3 && TREE_CODE (TREE_TYPE (args[2])) != INTEGER_TYPE)
            {
-             error ("non-integer argument 3 in call to function %qE", fndecl);
+             error_at (ARG_LOCATION (2), "non-integer argument 3 in call to "
+                       "function %qE", fndecl);
              return false;
            }
          return true;
@@ -9938,21 +9945,21 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
     case BUILT_IN_ADD_OVERFLOW:
     case BUILT_IN_SUB_OVERFLOW:
     case BUILT_IN_MUL_OVERFLOW:
-      if (builtin_function_validate_nargs (fndecl, nargs, 3))
+      if (builtin_function_validate_nargs (loc, fndecl, nargs, 3))
        {
          unsigned i;
          for (i = 0; i < 2; i++)
            if (!INTEGRAL_TYPE_P (TREE_TYPE (args[i])))
              {
-               error ("argument %u in call to function %qE does not have "
-                      "integral type", i + 1, fndecl);
+               error_at (ARG_LOCATION (i), "argument %u in call to function "
+                         "%qE does not have integral type", i + 1, fndecl);
                return false;
              }
          if (TREE_CODE (TREE_TYPE (args[2])) != POINTER_TYPE
              || TREE_CODE (TREE_TYPE (TREE_TYPE (args[2]))) != INTEGER_TYPE)
            {
-             error ("argument 3 in call to function %qE does not have "
-                    "pointer to integer type", fndecl);
+             error_at (ARG_LOCATION (2), "argument 3 in call to function %qE "
+                       "does not have pointer to integer type", fndecl);
              return false;
            }
          return true;
index b12113845893e30b96c6ad4c9ee9f596e93cdc90..4454d0847248f1fde24b08d18ecbc1e08ee7fa00 100644 (file)
@@ -788,7 +788,8 @@ extern void check_function_arguments_recurse (void (*)
                                               unsigned HOST_WIDE_INT),
                                              void *, tree,
                                              unsigned HOST_WIDE_INT);
-extern bool check_builtin_function_arguments (tree, int, tree *);
+extern bool check_builtin_function_arguments (location_t, vec<location_t>,
+                                             tree, int, tree *);
 extern void check_function_format (tree, int, tree *);
 extern tree handle_unused_attribute (tree *, tree, tree, int, bool *);
 extern tree handle_format_attribute (tree *, tree, tree, int, bool *);
index ae6275968c6bf36ea9842c1ae786d7b475159ec2..8ac13e31f424bdd52a8b9d0a0608d6db830ae70c 100644 (file)
@@ -1,3 +1,9 @@
+2016-05-03  Marek Polacek  <polacek@redhat.com>
+
+       PR c/70859
+       * c-typeck.c (build_function_call_vec): Pass LOC and ARG_LOC down to
+       check_builtin_function_arguments.
+
 2016-05-03  Richard Biener  <rguenther@suse.de>
 
        * Make-lang.in (cc1-checksum.c): For stage-final re-use
index 0fa96539b951f525da5ed4ec35abda41b6c5df22..204702e505e17fc2555e3e4c8b6d910a09e7da24 100644 (file)
@@ -3046,7 +3046,8 @@ build_function_call_vec (location_t loc, vec<location_t> arg_loc,
   if (fundecl
       && DECL_BUILT_IN (fundecl)
       && DECL_BUILT_IN_CLASS (fundecl) == BUILT_IN_NORMAL
-      && !check_builtin_function_arguments (fundecl, nargs, argarray))
+      && !check_builtin_function_arguments (loc, arg_loc, fundecl, nargs,
+                                           argarray))
     return error_mark_node;
 
   /* Check that the arguments to the function are valid.  */
index 497bc0ec967bf32ac016d66464fe2efe079b04ec..3bc37e1ba70d6923ebddc31b0be3192ec0d8af3b 100644 (file)
@@ -1,3 +1,9 @@
+2016-05-03  Marek Polacek  <polacek@redhat.com>
+
+       PR c/70859
+       * call.c (build_cxx_call): Pass location and vNULL down to
+       check_builtin_function_arguments.
+
 2016-05-03  Richard Biener  <rguenther@suse.de>
 
        * Make-lang.in (cc1plus-checksum.c): For stage-final re-use
index 476e806d41990821118508069d6a1bb123dd2f6e..e9ebdbc171d8e59a8cf3f6ab4399e64b49313cc3 100644 (file)
@@ -7790,7 +7790,8 @@ build_cxx_call (tree fn, int nargs, tree *argarray,
       for (i = 0; i < nargs; i++)
        argarray[i] = fold_non_dependent_expr (argarray[i]);
 
-      if (!check_builtin_function_arguments (fndecl, nargs, argarray))
+      if (!check_builtin_function_arguments (EXPR_LOCATION (fn), vNULL, fndecl,
+                                            nargs, argarray))
        return error_mark_node;
     }
 
index 9779198720d95dd31c38d6fe58626283e0ff7c56..61b1e4477fc3cd0ed1e80b584983d240ebcd905d 100644 (file)
@@ -789,6 +789,16 @@ expansion_point_location_if_in_system_header (source_location location)
   return location;
 }
 
+/* If LOCATION is a virtual location for a token coming from the expansion
+   of a macro, unwind to the location of the expansion point of the macro.  */
+
+source_location
+expansion_point_location (source_location location)
+{
+  return linemap_resolve_location (line_table, location,
+                                  LRK_MACRO_EXPANSION_POINT, NULL);
+}
+
 #define ONE_K 1024
 #define ONE_M (ONE_K * ONE_K)
 
index 97c43332ee751d4187acf6fae4490eac2c4dbe7b..ae4fecfe11ce69ebeb320ce832ab6d8924eddf5d 100644 (file)
@@ -42,6 +42,7 @@ extern const char *location_get_source_line (const char *file_path, int line,
                                             int *line_size);
 extern expanded_location expand_location_to_spelling_point (source_location);
 extern source_location expansion_point_location_if_in_system_header (source_location);
+extern source_location expansion_point_location (source_location);
 
 /* Historically GCC used location_t, while cpp used source_location.
    This could be removed but it hardly seems worth the effort.  */
index 818a1775c5905021ef63e1ef7f2d85ee2f509418..59e5be84d8c62cb2326a363b9a1f4016637fbe52 100644 (file)
@@ -1,3 +1,9 @@
+2016-05-03  Marek Polacek  <polacek@redhat.com>
+
+       PR c/70859
+       * gcc.dg/pr70859.c: New test.
+       * gcc.dg/pr70859-2.c: New test.
+
 2016-05-03  Pierre-Marie de Rodat  <derodat@adacore.com>
 
        * gnat.dg/debug5.adb: New testcase.
diff --git a/gcc/testsuite/gcc.dg/pr70859-2.c b/gcc/testsuite/gcc.dg/pr70859-2.c
new file mode 100644 (file)
index 0000000..4817852
--- /dev/null
@@ -0,0 +1,18 @@
+/* PR c/70859 */
+/* { dg-do compile } */
+
+#include <stdint.h>
+#define MAX __SIZE_MAX__
+#define MAX2 SIZE_MAX
+#define FIVE 5
+
+static void *p;
+
+void
+fn0 (int n)
+{
+  p = __builtin_alloca_with_align (n, SIZE_MAX); /* { dg-error "39:must be a constant integer" } */
+  p = __builtin_alloca_with_align (n, MAX); /* { dg-error "39:must be a constant integer" } */
+  p = __builtin_alloca_with_align (n, MAX2); /* { dg-error "39:must be a constant integer" } */
+  p = __builtin_alloca_with_align (n, FIVE); /* { dg-error "39:must be a constant integer" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr70859.c b/gcc/testsuite/gcc.dg/pr70859.c
new file mode 100644 (file)
index 0000000..0a3c843
--- /dev/null
@@ -0,0 +1,69 @@
+/* PR c/70859 */
+/* { dg-do compile } */
+
+static void *p;
+static double *d;
+static int r;
+__extension__ static _Bool b;
+
+void
+fn0 (int n)
+{
+  p = __builtin_alloca_with_align (n, 6); /* { dg-error "39:must be a constant integer" } */
+
+  r += __builtin_isfinite (0); /* { dg-error "28:non-floating-point argument in call" } */
+  r += __builtin_isinf (0); /* { dg-error "25:non-floating-point argument in call" } */
+  r += __builtin_isinf_sign (0); /* { dg-error "30:non-floating-point argument in call" } */
+  r += __builtin_isnan (0); /* { dg-error "25:non-floating-point argument in call" } */
+  r += __builtin_isnormal (0); /* { dg-error "28:non-floating-point argument in call" } */
+  r += __builtin_signbit (0); /* { dg-error "27:non-floating-point argument in call" } */
+
+  r += __builtin_isgreater (0, 0); /* { dg-error "8:non-floating-point arguments in call to function" } */
+  r += __builtin_isgreaterequal (0, 0); /* { dg-error "8:non-floating-point arguments in call to function" } */
+  r += __builtin_isless (0, 0); /* { dg-error "8:non-floating-point arguments in call to function" } */
+  r += __builtin_islessequal (0, 0); /* { dg-error "8:non-floating-point arguments in call to function" } */
+  r += __builtin_islessgreater (0, 0); /* { dg-error "8:non-floating-point arguments in call to function" } */
+  r += __builtin_isunordered (0, 0); /* { dg-error "8:non-floating-point arguments in call to function" } */
+
+  r += __builtin_fpclassify (1, 2, n, 4, 5, n); /* { dg-error "36:non-const integer argument 3 in call" } */
+  r += __builtin_fpclassify (1, 2, 3, 4, 5, 6); /* { dg-error "45:non-floating-point argument in call" } */
+
+  d = __builtin_assume_aligned (p, n, p); /* { dg-error "39:non-integer argument 3 in call" } */
+
+  b = __builtin_add_overflow (n, *d, &r); /* { dg-error "34:argument 2 in call to function" } */
+  b = __builtin_add_overflow (n, 5, d); /* { dg-error "37:argument 3 in call" } */
+  b = __builtin_sub_overflow (n, *d, &r); /* { dg-error "34:argument 2 in call to function" } */
+  b = __builtin_sub_overflow (n, 5, d); /* { dg-error "37:argument 3 in call" } */
+  b = __builtin_mul_overflow (n, *d, &r); /* { dg-error "34:argument 2 in call to function" } */
+  b = __builtin_mul_overflow (n, 5, d); /* { dg-error "37:argument 3 in call" } */
+}
+
+int
+fn1 (void)
+{
+  if (__builtin_constant_p ()) /* { dg-error "7:not enough" } */
+    return 0;
+  if (__builtin_constant_p (1, 2)) /* { dg-error "7:too many" } */
+    return 1;
+  if (__builtin_isfinite ()) /* { dg-error "7:not enough" } */
+    return 3;
+  if (__builtin_isfinite (1, 2)) /* { dg-error "7:too many" } */
+    return 4;
+  if (__builtin_isless (0)) /* { dg-error "7:not enough" } */
+    return 5;
+  if (__builtin_isless (1, 2, 3)) /* { dg-error "7:too many" } */
+    return 6;
+  if (__builtin_fpclassify (1, 2, 3, 4, 5)) /* { dg-error "7:not enough" } */
+    return 7;
+  if (__builtin_fpclassify (1, 2, 3, 4, 5, r, 6)) /* { dg-error "7:too many" } */
+    return 8;
+  if (__builtin_assume_aligned (p)) /* { dg-error "7:too few" } */
+    return 9;
+  if (__builtin_assume_aligned (p, r, p, p)) /* { dg-error "7:too many" } */
+    return 10;
+  if (__builtin_add_overflow ()) /* { dg-error "7:not enough" } */
+    return 11;
+  if (__builtin_add_overflow (1, 2, 3, &r)) /* { dg-error "7:too many" } */
+    return 12;
+  return -1;
+}