c: improvements to address space diagnostics
This adds a clarifying "note" to address space mismatch diagnostics. For example, it improves the diagnostic for gcc.target/i386/addr-space-typeck-2.c from: addr-space-typeck-2.c: In function 'test_bad_call': addr-space-typeck-2.c:12:22: error: passing argument 2 of 'expects_seg_gs' from pointer to non-enclosed address space 12 | expects_seg_gs (0, ptr, 1); | ^~~ to: addr-space-typeck-2.c: In function 'test_bad_call': addr-space-typeck-2.c:12:22: error: passing argument 2 of 'expects_seg_gs' from pointer to non-enclosed address space 12 | expects_seg_gs (0, ptr, 1); | ^~~ addr-space-typeck-2.c:7:51: note: expected '__seg_gs void *' but argument is of type 'void *' 7 | extern void expects_seg_gs (int i, void __seg_gs *param, int j); | ~~~~~~~~~~~~~~~^~~~~ I took the liberty of adding the test coverage to i386 since we need a specific target to test this on. gcc/c/ChangeLog: * c-typeck.cc (build_c_cast): Quote names of address spaces in diagnostics. (convert_for_assignment): Add a note to address space mismatch diagnostics, specifying the expected and actual types. gcc/testsuite/ChangeLog: * gcc.target/i386/addr-space-typeck-1.c: New test. * gcc.target/i386/addr-space-typeck-2.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This commit is contained in:
parent
ffd12be139
commit
e8bc6918b3
3 changed files with 66 additions and 8 deletions
|
@ -6032,18 +6032,18 @@ build_c_cast (location_t loc, tree type, tree expr)
|
|||
if (!addr_space_superset (as_to, as_from, &as_common))
|
||||
{
|
||||
if (ADDR_SPACE_GENERIC_P (as_from))
|
||||
warning_at (loc, 0, "cast to %s address space pointer "
|
||||
warning_at (loc, 0, "cast to %qs address space pointer "
|
||||
"from disjoint generic address space pointer",
|
||||
c_addr_space_name (as_to));
|
||||
|
||||
else if (ADDR_SPACE_GENERIC_P (as_to))
|
||||
warning_at (loc, 0, "cast to generic address space pointer "
|
||||
"from disjoint %s address space pointer",
|
||||
"from disjoint %qs address space pointer",
|
||||
c_addr_space_name (as_from));
|
||||
|
||||
else
|
||||
warning_at (loc, 0, "cast to %s address space pointer "
|
||||
"from disjoint %s address space pointer",
|
||||
warning_at (loc, 0, "cast to %qs address space pointer "
|
||||
"from disjoint %qs address space pointer",
|
||||
c_addr_space_name (as_to),
|
||||
c_addr_space_name (as_from));
|
||||
}
|
||||
|
@ -7252,6 +7252,8 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
|
|||
if (!null_pointer_constant_p (rhs)
|
||||
&& asr != asl && !targetm.addr_space.subset_p (asr, asl))
|
||||
{
|
||||
auto_diagnostic_group d;
|
||||
bool diagnosed = true;
|
||||
switch (errtype)
|
||||
{
|
||||
case ic_argpass:
|
||||
|
@ -7259,7 +7261,8 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
|
|||
const char msg[] = G_("passing argument %d of %qE from "
|
||||
"pointer to non-enclosed address space");
|
||||
if (warnopt)
|
||||
warning_at (expr_loc, warnopt, msg, parmnum, rname);
|
||||
diagnosed
|
||||
= warning_at (expr_loc, warnopt, msg, parmnum, rname);
|
||||
else
|
||||
error_at (expr_loc, msg, parmnum, rname);
|
||||
break;
|
||||
|
@ -7269,7 +7272,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
|
|||
const char msg[] = G_("assignment from pointer to "
|
||||
"non-enclosed address space");
|
||||
if (warnopt)
|
||||
warning_at (location, warnopt, msg);
|
||||
diagnosed = warning_at (location, warnopt, msg);
|
||||
else
|
||||
error_at (location, msg);
|
||||
break;
|
||||
|
@ -7280,7 +7283,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
|
|||
const char msg[] = G_("initialization from pointer to "
|
||||
"non-enclosed address space");
|
||||
if (warnopt)
|
||||
warning_at (location, warnopt, msg);
|
||||
diagnosed = warning_at (location, warnopt, msg);
|
||||
else
|
||||
error_at (location, msg);
|
||||
break;
|
||||
|
@ -7290,7 +7293,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
|
|||
const char msg[] = G_("return from pointer to "
|
||||
"non-enclosed address space");
|
||||
if (warnopt)
|
||||
warning_at (location, warnopt, msg);
|
||||
diagnosed = warning_at (location, warnopt, msg);
|
||||
else
|
||||
error_at (location, msg);
|
||||
break;
|
||||
|
@ -7298,6 +7301,14 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
|
|||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
if (diagnosed)
|
||||
{
|
||||
if (errtype == ic_argpass)
|
||||
inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype);
|
||||
else
|
||||
inform (location, "expected %qT but pointer is of type %qT",
|
||||
type, rhstype);
|
||||
}
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
|
|
22
gcc/testsuite/gcc.target/i386/addr-space-typeck-1.c
Normal file
22
gcc/testsuite/gcc.target/i386/addr-space-typeck-1.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/* { dg-options "-std=gnu90" } */
|
||||
|
||||
void *
|
||||
test_gs_to_generic (void __seg_gs *p)
|
||||
{
|
||||
return p; /* { dg-error "return from pointer to non-enclosed address space" "error" } */
|
||||
/* { dg-message "expected 'void \\*' but pointer is of type '__seg_gs void \\*'" "note" { target *-*-* } .-1 } */
|
||||
}
|
||||
|
||||
void __seg_gs *
|
||||
test_generic_to_gs (void *q)
|
||||
{
|
||||
return q; /* { dg-error "return from pointer to non-enclosed address space" "error" } */
|
||||
/* { dg-message "expected '__seg_gs void \\*' but pointer is of type 'void \\*'" "note" { target *-*-* } .-1 } */
|
||||
}
|
||||
|
||||
extern void use_double_deref (char __seg_gs **buffer);
|
||||
|
||||
void test_double_deref (char __seg_gs *buf)
|
||||
{
|
||||
use_double_deref (&buf);
|
||||
}
|
25
gcc/testsuite/gcc.target/i386/addr-space-typeck-2.c
Normal file
25
gcc/testsuite/gcc.target/i386/addr-space-typeck-2.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* Tests of C frontend's address space type-checking. */
|
||||
/* { dg-options "-std=gnu90 -fdiagnostics-show-caret" } */
|
||||
|
||||
/* Verify that we emit helpful diagnostics at a mismatching address space
|
||||
at a function call, and that the underlined locations are correct. */
|
||||
|
||||
extern void expects_seg_gs (int i, void __seg_gs *param, int j); /* { dg-line "decl_line" } */
|
||||
|
||||
void
|
||||
test_bad_call (void *ptr)
|
||||
{
|
||||
expects_seg_gs (0, ptr, 1); /* { dg-line "err_line" } */
|
||||
}
|
||||
|
||||
/* { dg-error "passing argument 2 of 'expects_seg_gs' from pointer to non-enclosed address space" "" { target *-*-* } err_line } */
|
||||
/* { dg-begin-multiline-output "" }
|
||||
expects_seg_gs (0, ptr, 1);
|
||||
^~~
|
||||
{ dg-end-multiline-output "" } */
|
||||
|
||||
/* { dg-message "expected '__seg_gs void \\*' but argument is of type 'void \\*'" "" { target *-*-* } decl_line } */
|
||||
/* { dg-begin-multiline-output "" }
|
||||
extern void expects_seg_gs (int i, void __seg_gs *param, int j);
|
||||
~~~~~~~~~~~~~~~^~~~~
|
||||
{ dg-end-multiline-output "" } */
|
Loading…
Add table
Reference in a new issue