re PR c/70859 (Bad column number in type-generic function errors)
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
This commit is contained in:
parent
402e89f598
commit
79ce98bcef
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 *);
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
10
gcc/input.c
10
gcc/input.c
@ -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)
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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.
|
||||
|
18
gcc/testsuite/gcc.dg/pr70859-2.c
Normal file
18
gcc/testsuite/gcc.dg/pr70859-2.c
Normal file
@ -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" } */
|
||||
}
|
69
gcc/testsuite/gcc.dg/pr70859.c
Normal file
69
gcc/testsuite/gcc.dg/pr70859.c
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user