Message ID | 20160107171127.GK31604@redhat.com |
---|---|
State | New |
Headers | show |
On Thu, 7 Jan 2016, Marek Polacek wrote: > This PR points out that we issue a wrong warning message when assigning > two pointers when one of them is plain char. In that case, the compiler > currently says that pointer targets differ in signedness. But that is > not correct; char is a separate type from (un)signed char and is not > compatible with either. So we should instead say that the pointer types > are not compatible. > > This effectively means that I'm turning a -Wpointer-sign warning into > a -Wincompatible-pointer-types warning. But -Wincompatible-pointer-types > is a warning that is enabled by default and -Wpointer-sign is enabled by > -Wpedantic || -Wall. So with this, we'd be more verbose and would warn > by default on e.g. "unsigned char *p = "foo";." Not sure if that is > desirable at this stage, so I'm leaning towards pushing this patch for > GCC7. I don't think it's desirable to raise the warning for this case under different conditions from the warning for other signedness cases. The targets do differ in signedness - it's just that the difference is between "plain" and "signed" or "plain" and "unsigned", not between signed and unsigned. Maybe the warning message should be more specific in this case, but not a less-specific "incompatible" which is what this patch would achieve.
On 01/07/2016 02:19 PM, Joseph Myers wrote: > On Thu, 7 Jan 2016, Marek Polacek wrote: > >> This PR points out that we issue a wrong warning message when assigning >> two pointers when one of them is plain char. In that case, the compiler >> currently says that pointer targets differ in signedness. But that is >> not correct; char is a separate type from (un)signed char and is not >> compatible with either. So we should instead say that the pointer types >> are not compatible. >> >> This effectively means that I'm turning a -Wpointer-sign warning into >> a -Wincompatible-pointer-types warning. But -Wincompatible-pointer-types >> is a warning that is enabled by default and -Wpointer-sign is enabled by >> -Wpedantic || -Wall. So with this, we'd be more verbose and would warn >> by default on e.g. "unsigned char *p = "foo";." Not sure if that is >> desirable at this stage, so I'm leaning towards pushing this patch for >> GCC7. > > I don't think it's desirable to raise the warning for this case under > different conditions from the warning for other signedness cases. The > targets do differ in signedness - it's just that the difference is between > "plain" and "signed" or "plain" and "unsigned", not between signed and > unsigned. I'm sorry Joseph but I don't quite follow this argument. Plain char is neither a signed [integer] type nor an unsigned [integer] type, so it can never differ in signedness from any other type. It seems to me that by the interpretation you suggest, converting a signed int* to unsigned long* should be controlled by -Wpointer- sign when int and long have the same representation, and by -Wincompatible-pointer-types otherwise. (Which is not what GCC does.) In my view, Marek's change makes perfect sense because it the most closely reflects the properties of the type. Martin
On 01/07/2016 10:19 PM, Joseph Myers wrote: > I don't think it's desirable to raise the warning for this case under > different conditions from the warning for other signedness cases. The > targets do differ in signedness - it's just that the difference is between > "plain" and "signed" or "plain" and "unsigned", not between signed and > unsigned. Maybe the warning message should be more specific in this case, > but not a less-specific "incompatible" which is what this patch would > achieve. I was going to voice the same opinion yesterday but forgot to hit Send. If you consider signedness of char a tri-state, then there's nothing wrong with the warning message. Bernd
On Fri, Jan 08, 2016 at 06:54:32PM +0100, Bernd Schmidt wrote: > On 01/07/2016 10:19 PM, Joseph Myers wrote: > > >I don't think it's desirable to raise the warning for this case under > >different conditions from the warning for other signedness cases. The > >targets do differ in signedness - it's just that the difference is between > >"plain" and "signed" or "plain" and "unsigned", not between signed and > >unsigned. Maybe the warning message should be more specific in this case, > >but not a less-specific "incompatible" which is what this patch would > >achieve. > > I was going to voice the same opinion yesterday but forgot to hit Send. If > you consider signedness of char a tri-state, then there's nothing wrong with > the warning message. Well, it's been discussed at length in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=23087 It seems sort of weird to me to say that 'char' and 'signed char' do differ in signedness when I know that my machine uses signed chars by default. But I'm wary of raising the warning -- it's likely to cause more uproar. At this point I don't know if I actually want to pursue this further, likely not. Yet I'd like to resolve this very old PR one way or another. Marek
On Fri, 8 Jan 2016, Martin Sebor wrote: > > I don't think it's desirable to raise the warning for this case under > > different conditions from the warning for other signedness cases. The > > targets do differ in signedness - it's just that the difference is between > > "plain" and "signed" or "plain" and "unsigned", not between signed and > > unsigned. > > I'm sorry Joseph but I don't quite follow this argument. Plain > char is neither a signed [integer] type nor an unsigned [integer] > type, so it can never differ in signedness from any other type. Signedness of char (and of bit-fields) is a tristate, "signed", "unsigned" and "". My claim is that a difference between any two of those three values is essentially the same kind of difference. And so at most the wording should be adjusted (or maybe an inform ("%<char%> and %<signed char%> are different types" added), not the conditions for some such warning to be given. > It seems to me that by the interpretation you suggest, converting > a signed int* to unsigned long* should be controlled by -Wpointer- > sign when int and long have the same representation, and by > -Wincompatible-pointer-types otherwise. (Which is not what GCC > does.) No, because those differ between "int" and "long", not between "signed" and "" or "unsigned" and "" as signedness.
> Signedness of char (and of bit-fields) is a tristate, "signed", "unsigned" > and "". My claim is that a difference between any two of those three > values is essentially the same kind of difference. And so at most the > wording should be adjusted (or maybe an inform ("%<char%> and %<signed > char%> are different types" added), not the conditions for some such > warning to be given. This explanation isn't grounded in the C definition of the types (which is fine if you want to use some other definition of "signedness"). In C, plain char type is neither a signed nor an unsigned integer type, whether or not it has a sign bit. It's a distinct type that's incompatible with both signed char and unsigned char, and pointers to the three types are incompatible with one another. The only thing char, signed char, and unsigned char have in common other than the word "char" is that they are classified as "character types." (Plain "char" might as well be called "character.") >> It seems to me that by the interpretation you suggest, converting >> a signed int* to unsigned long* should be controlled by -Wpointer- >> sign when int and long have the same representation, and by >> -Wincompatible-pointer-types otherwise. (Which is not what GCC >> does.) > > No, because those differ between "int" and "long", not between "signed" > and "" or "unsigned" and "" as signedness. int and long differ because they're not compatible according to the C definition of the term, even if they have the same size, representation, and alignment (e.g., in ILP32). "char" and "signed char" are also incompatible, even if they otherwise have identical properties, for the same reason (i.e., because the standard says they're not). I believe the answer here hinges on the definition of the term "signedness." If we use the same definition as the standard, the text of the warning is strictly speaking incorrect, and the proposed change makes it correct. If we define signedness differently, say as "having a sign bit," then the warning is appropriate in one of the two cases in the bug but not in the other. Which one depends on the the setting of -fsigned-char: signed char *ps = "signed"; // okay with -fsigned-char unsigned char *pu = "unsigned"; // okay with -fno-signed-char and ditto for: extern char *p; ps = p; // okay with -fsigned-char pu = p; // okay with -fno-signed-char However, this definition of signedness would imply that the warning should not be issued for the code below (for example) when int and long have the same size, representation, and alignment: int *p = (long*)0; Perhaps there is another definition according to which the text of the warning would be correct in all cases. If there is one, it should be outlined in the documentation. (I would recommend using the standard definition since that's what most users are either already familiar with or can easily look it up.) Martin
On Fri, 8 Jan 2016, Martin Sebor wrote: > > Signedness of char (and of bit-fields) is a tristate, "signed", "unsigned" > > and "". My claim is that a difference between any two of those three > > values is essentially the same kind of difference. And so at most the > > wording should be adjusted (or maybe an inform ("%<char%> and %<signed > > char%> are different types" added), not the conditions for some such > > warning to be given. > > This explanation isn't grounded in the C definition of the types > (which is fine if you want to use some other definition of > "signedness"). > > In C, plain char type is neither a signed nor an unsigned integer > type, whether or not it has a sign bit. It's a distinct type that's Exactly. "signed type", "unsigned type" and "type that is neither signed nor unsigned" are the three cases in the tristate. ("type that is both signed and unsigned" doesn't exist.) The point of this warning is that there are certain cases of incompatible types that are less serious than others - namely, those where the only aspect of the type that is different is its signedness. Those get a more specific warning, which is given under more restrictive conditions. ISO C specifically envisages such differences as being less serious when it allows variation between pointers to character types and void when passing arguments to unprototyped functions. > However, this definition of signedness would imply that the > warning should not be issued for the code below (for example) > when int and long have the same size, representation, and > alignment: > > int *p = (long*)0; And of course the signedness warning isn't issued - the other generic warning about incompatible types is issued, because this is one of the more serious cases of incompatibility, where there is a difference other than signedness.
> The point of this warning is that there are certain cases of incompatible > types that are less serious than others - namely, those where the only > aspect of the type that is different is its signedness. Those get a more > specific warning, which is given under more restrictive conditions. I see. It means the warnings aren't based on the C definitions of signedness or compatibility but rather on our perception of the likely correctness of the code we've seen violate the constraints implied by the definitions. FWIW, I have no objection to treating the three character types as special as you suggest. But I also feel that -Wincompatible- pointer-types is more appropriate than -Wpointer-sign, not only for the reason stated in the bug but also because it more closely corresponds to the C definitions of the terms. Perhaps tweaking the patch by adding an option, say -Wincompatible-char, to make it possible to enable and disable the warning for the character types, would be an acceptable compromise. It would satisfy the user's request and avoid the potential fallout you and Marek are concerned about. Martin
On 01/08/2016 06:21 PM, Martin Sebor wrote: >> The point of this warning is that there are certain cases of incompatible >> types that are less serious than others - namely, those where the only >> aspect of the type that is different is its signedness. Those get a more >> specific warning, which is given under more restrictive conditions. FWIW, below is a survey of a few popular compilers I have access to and how they treat the problem and under what option. The C code I used to test is: void foo (char *p, signed char *q) { q = p; } Clang (controlled by -Wpointer-sign, enabled by default): warning: assigning to 'signed char *' from 'char *' converts between pointers to integer types with different sign [-Wpointer-sign] EDG eccp (warns by default): warning: a value of type "char *" cannot be assigned to an entity of type "signed char *" Intel ICC (requires -Wpointer-sign): warning #556: a value of type "char *" cannot be assigned to an entity of type "signed char *" Oracle CC (warns by default): warning: assignment type mismatch: pointer to signed char "=" pointer to char IBM XLC (warns by default): 1506-068 (W) Operation between types "signed char*" and "char*" is not allowed. Visual C (rejects code by default): error C2440: '=': cannot convert from 'char *' to 'signed char *' note: Types pointed to are unrelated; Martin
diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c index 952041b..36001d2 100644 --- gcc/c/c-typeck.c +++ gcc/c/c-typeck.c @@ -6434,7 +6434,11 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, == c_common_unsigned_type (mvr)) && (c_common_signed_type (mvl) == c_common_signed_type (mvr)) - && TYPE_ATOMIC (mvl) == TYPE_ATOMIC (mvr))) + && TYPE_ATOMIC (mvl) == TYPE_ATOMIC (mvr) + /* char is a separate type and not compatible with signed char + or unsigned char. */ + && mvl != char_type_node + && mvr != char_type_node)) { /* Warn about loss of qualifers from pointers to arrays with qualifiers on the element type. */ diff --git gcc/testsuite/gcc.dg/Wno-pointer-sign.c gcc/testsuite/gcc.dg/Wno-pointer-sign.c index 780c9d4..c9f02a4 100644 --- gcc/testsuite/gcc.dg/Wno-pointer-sign.c +++ gcc/testsuite/gcc.dg/Wno-pointer-sign.c @@ -17,10 +17,10 @@ int main() f1(ulp); /* { dg-bogus " differ in signedness" } */ f2(lp); /* { dg-bogus " differ in signedness" } */ - cp = ucp; /* { dg-bogus " pointer targets in assignment differ in signedness" } */ - cp = scp; /* { dg-bogus " pointer targets in assignment differ in signedness" } */ + cp = ucp; /* { dg-warning "assignment from incompatible pointer type" } */ + cp = scp; /* { dg-warning "assignment from incompatible pointer type" } */ ucp = scp; /* { dg-bogus " pointer targets in assignment differ in signedness" } */ - ucp = cp; /* { dg-bogus " pointer targets in assignment differ in signedness" } */ + ucp = cp; /* { dg-warning "assignment from incompatible pointer type" } */ scp = ucp; /* { dg-bogus " pointer targets in assignment differ in signedness" } */ - scp = cp; /* { dg-bogus " pointer targets in assignment differ in signedness" } */ + scp = cp; /* { dg-warning "assignment from incompatible pointer type" } */ } diff --git gcc/testsuite/gcc.dg/assign-warn-1.c gcc/testsuite/gcc.dg/assign-warn-1.c index f26a544..ce540cb 100644 --- gcc/testsuite/gcc.dg/assign-warn-1.c +++ gcc/testsuite/gcc.dg/assign-warn-1.c @@ -60,29 +60,29 @@ TESTASS(usc, unsigned int *, int *); /* { dg-warning "pointer targets in assignm TESTINI(usd, unsigned int *, int *); /* { dg-warning "pointer targets in initialization differ in signedness" } */ TESTRET(use, unsigned int *, int *); /* { dg-warning "pointer targets in return differ in signedness" } */ -TESTARG(cua, char *, unsigned char *); /* { dg-warning "pointer targets in passing argument 1 of 'cuaF' differ in signedness" } */ -TESTARP(cub, char *, unsigned char *); /* { dg-warning "pointer targets in passing argument 1 of 'cubFp.x' differ in signedness" } */ -TESTASS(cuc, char *, unsigned char *); /* { dg-warning "pointer targets in assignment differ in signedness" } */ -TESTINI(cud, char *, unsigned char *); /* { dg-warning "pointer targets in initialization differ in signedness" } */ -TESTRET(cue, char *, unsigned char *); /* { dg-warning "pointer targets in return differ in signedness" } */ - -TESTARG(uca, unsigned char *, char *); /* { dg-warning "pointer targets in passing argument 1 of 'ucaF' differ in signedness" } */ -TESTARP(ucb, unsigned char *, char *); /* { dg-warning "pointer targets in passing argument 1 of 'ucbFp.x' differ in signedness" } */ -TESTASS(ucc, unsigned char *, char *); /* { dg-warning "pointer targets in assignment differ in signedness" } */ -TESTINI(ucd, unsigned char *, char *); /* { dg-warning "pointer targets in initialization differ in signedness" } */ -TESTRET(uce, unsigned char *, char *); /* { dg-warning "pointer targets in return differ in signedness" } */ - -TESTARG(csa, char *, signed char *); /* { dg-warning "pointer targets in passing argument 1 of 'csaF' differ in signedness" } */ -TESTARP(csb, char *, signed char *); /* { dg-warning "pointer targets in passing argument 1 of 'csbFp.x' differ in signedness" } */ -TESTASS(csc, char *, signed char *); /* { dg-warning "pointer targets in assignment differ in signedness" } */ -TESTINI(csd, char *, signed char *); /* { dg-warning "pointer targets in initialization differ in signedness" } */ -TESTRET(cse, char *, signed char *); /* { dg-warning "pointer targets in return differ in signedness" } */ - -TESTARG(sca, signed char *, char *); /* { dg-warning "pointer targets in passing argument 1 of 'scaF' differ in signedness" } */ -TESTARP(scb, signed char *, char *); /* { dg-warning "pointer targets in passing argument 1 of 'scbFp.x' differ in signedness" } */ -TESTASS(scc, signed char *, char *); /* { dg-warning "pointer targets in assignment differ in signedness" } */ -TESTINI(scd, signed char *, char *); /* { dg-warning "pointer targets in initialization differ in signedness" } */ -TESTRET(sce, signed char *, char *); /* { dg-warning "pointer targets in return differ in signedness" } */ +TESTARG(cua, char *, unsigned char *); /* { dg-warning "passing argument 1 of 'cuaF' from incompatible pointer type" } */ +TESTARP(cub, char *, unsigned char *); /* { dg-warning "passing argument 1 of 'cubFp.x' from incompatible pointer type" } */ +TESTASS(cuc, char *, unsigned char *); /* { dg-warning "assignment from incompatible pointer type" } */ +TESTINI(cud, char *, unsigned char *); /* { dg-warning "initialization from incompatible pointer type" } */ +TESTRET(cue, char *, unsigned char *); /* { dg-warning "return from incompatible pointer type" } */ + +TESTARG(uca, unsigned char *, char *); /* { dg-warning "passing argument 1 of 'ucaF' from incompatible pointer type" } */ +TESTARP(ucb, unsigned char *, char *); /* { dg-warning "passing argument 1 of 'ucbFp.x' from incompatible pointer type" } */ +TESTASS(ucc, unsigned char *, char *); /* { dg-warning "assignment from incompatible pointer type" } */ +TESTINI(ucd, unsigned char *, char *); /* { dg-warning "initialization from incompatible pointer type" } */ +TESTRET(uce, unsigned char *, char *); /* { dg-warning "return from incompatible pointer type" } */ + +TESTARG(csa, char *, signed char *); /* { dg-warning "passing argument 1 of 'csaF' from incompatible pointer type" } */ +TESTARP(csb, char *, signed char *); /* { dg-warning "passing argument 1 of 'csbFp.x' from incompatible pointer type" } */ +TESTASS(csc, char *, signed char *); /* { dg-warning "assignment from incompatible pointer type" } */ +TESTINI(csd, char *, signed char *); /* { dg-warning "initialization from incompatible pointer type" } */ +TESTRET(cse, char *, signed char *); /* { dg-warning "return from incompatible pointer type" } */ + +TESTARG(sca, signed char *, char *); /* { dg-warning "passing argument 1 of 'scaF' from incompatible pointer type" } */ +TESTARP(scb, signed char *, char *); /* { dg-warning "passing argument 1 of 'scbFp.x' from incompatible pointer type" } */ +TESTASS(scc, signed char *, char *); /* { dg-warning "assignment from incompatible pointer type" } */ +TESTINI(scd, signed char *, char *); /* { dg-warning "initialization from incompatible pointer type" } */ +TESTRET(sce, signed char *, char *); /* { dg-warning "return from incompatible pointer type" } */ TESTARG(cia, char *, int *); /* { dg-warning "passing argument 1 of 'ciaF' from incompatible pointer type" } */ TESTARP(cib, char *, int *); /* { dg-warning "passing argument 1 of 'cibFp.x' from incompatible pointer type" } */ diff --git gcc/testsuite/gcc.dg/assign-warn-2.c gcc/testsuite/gcc.dg/assign-warn-2.c index 1e5eb1c..51c2e92 100644 --- gcc/testsuite/gcc.dg/assign-warn-2.c +++ gcc/testsuite/gcc.dg/assign-warn-2.c @@ -61,29 +61,29 @@ TESTASS(usc, unsigned int *, int *); /* { dg-error "pointer targets in assignmen TESTINI(usd, unsigned int *, int *); /* { dg-error "pointer targets in initialization differ in signedness" } */ TESTRET(use, unsigned int *, int *); /* { dg-error "pointer targets in return differ in signedness" } */ -TESTARG(cua, char *, unsigned char *); /* { dg-error "pointer targets in passing argument 1 of 'cuaF' differ in signedness" } */ -TESTARP(cub, char *, unsigned char *); /* { dg-error "pointer targets in passing argument 1 of 'cubFp.x' differ in signedness" } */ -TESTASS(cuc, char *, unsigned char *); /* { dg-error "pointer targets in assignment differ in signedness" } */ -TESTINI(cud, char *, unsigned char *); /* { dg-error "pointer targets in initialization differ in signedness" } */ -TESTRET(cue, char *, unsigned char *); /* { dg-error "pointer targets in return differ in signedness" } */ - -TESTARG(uca, unsigned char *, char *); /* { dg-error "pointer targets in passing argument 1 of 'ucaF' differ in signedness" } */ -TESTARP(ucb, unsigned char *, char *); /* { dg-error "pointer targets in passing argument 1 of 'ucbFp.x' differ in signedness" } */ -TESTASS(ucc, unsigned char *, char *); /* { dg-error "pointer targets in assignment differ in signedness" } */ -TESTINI(ucd, unsigned char *, char *); /* { dg-error "pointer targets in initialization differ in signedness" } */ -TESTRET(uce, unsigned char *, char *); /* { dg-error "pointer targets in return differ in signedness" } */ - -TESTARG(csa, char *, signed char *); /* { dg-error "pointer targets in passing argument 1 of 'csaF' differ in signedness" } */ -TESTARP(csb, char *, signed char *); /* { dg-error "pointer targets in passing argument 1 of 'csbFp.x' differ in signedness" } */ -TESTASS(csc, char *, signed char *); /* { dg-error "pointer targets in assignment differ in signedness" } */ -TESTINI(csd, char *, signed char *); /* { dg-error "pointer targets in initialization differ in signedness" } */ -TESTRET(cse, char *, signed char *); /* { dg-error "pointer targets in return differ in signedness" } */ - -TESTARG(sca, signed char *, char *); /* { dg-error "pointer targets in passing argument 1 of 'scaF' differ in signedness" } */ -TESTARP(scb, signed char *, char *); /* { dg-error "pointer targets in passing argument 1 of 'scbFp.x' differ in signedness" } */ -TESTASS(scc, signed char *, char *); /* { dg-error "pointer targets in assignment differ in signedness" } */ -TESTINI(scd, signed char *, char *); /* { dg-error "pointer targets in initialization differ in signedness" } */ -TESTRET(sce, signed char *, char *); /* { dg-error "pointer targets in return differ in signedness" } */ +TESTARG(cua, char *, unsigned char *); /* { dg-error "passing argument 1 of 'cuaF' from incompatible pointer type" } */ +TESTARP(cub, char *, unsigned char *); /* { dg-error "passing argument 1 of 'cubFp.x' from incompatible pointer type" } */ +TESTASS(cuc, char *, unsigned char *); /* { dg-error "assignment from incompatible pointer type" } */ +TESTINI(cud, char *, unsigned char *); /* { dg-error "initialization from incompatible pointer type" } */ +TESTRET(cue, char *, unsigned char *); /* { dg-error "return from incompatible pointer type" } */ + +TESTARG(uca, unsigned char *, char *); /* { dg-error "passing argument 1 of 'ucaF' from incompatible pointer type" } */ +TESTARP(ucb, unsigned char *, char *); /* { dg-error "passing argument 1 of 'ucbFp.x' from incompatible pointer type" } */ +TESTASS(ucc, unsigned char *, char *); /* { dg-error "assignment from incompatible pointer type" } */ +TESTINI(ucd, unsigned char *, char *); /* { dg-error "initialization from incompatible pointer type" } */ +TESTRET(uce, unsigned char *, char *); /* { dg-error "return from incompatible pointer type" } */ + +TESTARG(csa, char *, signed char *); /* { dg-error "passing argument 1 of 'csaF' from incompatible pointer type" } */ +TESTARP(csb, char *, signed char *); /* { dg-error "passing argument 1 of 'csbFp.x' from incompatible pointer type" } */ +TESTASS(csc, char *, signed char *); /* { dg-error "assignment from incompatible pointer type" } */ +TESTINI(csd, char *, signed char *); /* { dg-error "initialization from incompatible pointer type" } */ +TESTRET(cse, char *, signed char *); /* { dg-error "return from incompatible pointer type" } */ + +TESTARG(sca, signed char *, char *); /* { dg-error "passing argument 1 of 'scaF' from incompatible pointer type" } */ +TESTARP(scb, signed char *, char *); /* { dg-error "passing argument 1 of 'scbFp.x' from incompatible pointer type" } */ +TESTASS(scc, signed char *, char *); /* { dg-error "assignment from incompatible pointer type" } */ +TESTINI(scd, signed char *, char *); /* { dg-error "initialization from incompatible pointer type" } */ +TESTRET(sce, signed char *, char *); /* { dg-error "return from incompatible pointer type" } */ TESTARG(cia, char *, int *); /* { dg-error "passing argument 1 of 'ciaF' from incompatible pointer type" } */ TESTARP(cib, char *, int *); /* { dg-error "passing argument 1 of 'cibFp.x' from incompatible pointer type" } */ diff --git gcc/testsuite/gcc.dg/conv-2.c gcc/testsuite/gcc.dg/conv-2.c index 388dee3..7c8c89d 100644 --- gcc/testsuite/gcc.dg/conv-2.c +++ gcc/testsuite/gcc.dg/conv-2.c @@ -17,10 +17,10 @@ int main() f1(ulp); /* { dg-warning " differ in signedness" } */ f2(lp); /* { dg-warning " differ in signedness" } */ - cp = ucp; /* { dg-warning " pointer targets in assignment differ in signedness" } */ - cp = scp; /* { dg-warning " pointer targets in assignment differ in signedness" } */ + cp = ucp; /* { dg-warning "assignment from incompatible pointer type" } */ + cp = scp; /* { dg-warning "assignment from incompatible pointer type" } */ ucp = scp; /* { dg-warning " pointer targets in assignment differ in signedness" } */ - ucp = cp; /* { dg-warning " pointer targets in assignment differ in signedness" } */ + ucp = cp; /* { dg-warning "assignment from incompatible pointer type" } */ scp = ucp; /* { dg-warning " pointer targets in assignment differ in signedness" } */ - scp = cp; /* { dg-warning " pointer targets in assignment differ in signedness" } */ + scp = cp; /* { dg-warning "assignment from incompatible pointer type" } */ } diff --git gcc/testsuite/gcc.dg/pr23087.c gcc/testsuite/gcc.dg/pr23087.c index e69de29..4bb45bb 100644 --- gcc/testsuite/gcc.dg/pr23087.c +++ gcc/testsuite/gcc.dg/pr23087.c @@ -0,0 +1,64 @@ +/* PR c/23087 */ +/* { dg-do compile } */ +/* { dg-options "-Wpointer-sign" } */ + +/* char is a separate type from the other two [signed char and unsigned char] + and is not compatible with either. */ + +void +fn1 (void) +{ + char *pc = 0; + char *pc2 = pc; + signed char *psc = pc; /* { dg-warning "initialization from incompatible pointer type" } */ + unsigned char *puc = pc; /* { dg-warning "initialization from incompatible pointer type" } */ +} + +void +fn2 (void) +{ + signed char *psc = 0; + char *pc = psc; /* { dg-warning "initialization from incompatible pointer type" } */ + signed char *psc2 = psc; + unsigned char *puc = psc; /* { dg-warning "pointer targets in initialization differ in signedness" } */ +} + +void +fn3 (void) +{ + unsigned char *puc = 0; + char *pc = puc; /* { dg-warning "initialization from incompatible pointer type" } */ + signed char *psc = puc; /* { dg-warning "pointer targets in initialization differ in signedness" } */ + unsigned char *puc2 = puc; +} + +/* String literals have type "char []". */ + +void +fn4 (void) +{ + char *p = ""; + signed char *ps = ""; /* { dg-warning "initialization from incompatible pointer type" } */ + unsigned char *pu = ""; /* { dg-warning "initialization from incompatible pointer type" } */ +} + +void +fn5 (void) +{ + const char *pcc = 0; + char *pc = pcc; /* { dg-warning "initialization discards" } */ + signed char *psc = pcc; /* { dg-warning "initialization from incompatible pointer type" } */ + unsigned char *puc = pcc; /* { dg-warning "initialization from incompatible pointer type" } */ +} + +void +fn6 (void) +{ + char *pc = 0; + char *pc2; + unsigned char *puc; + signed char *psc; + pc2 = pc; + puc = pc; /* { dg-warning "assignment from incompatible pointer type" } */ + psc = pc; /* { dg-warning "assignment from incompatible pointer type" } */ +} diff --git gcc/testsuite/gcc.dg/pr28726.c gcc/testsuite/gcc.dg/pr28726.c index 11232ac..76bd7cf 100644 --- gcc/testsuite/gcc.dg/pr28726.c +++ gcc/testsuite/gcc.dg/pr28726.c @@ -11,7 +11,7 @@ static double my_loop(void) __attribute__((noinline)); static double my_loop(void) { double retval = 0.0; - const unsigned char *start = "\005\b\000"; + const unsigned char *start = "\005\b\000"; /* { dg-warning "initialization from incompatible pointer type" } */ const unsigned char *const end = start + 2; while (start < end) diff --git gcc/testsuite/gcc.dg/torture/pr49603.c gcc/testsuite/gcc.dg/torture/pr49603.c index 9bde989..d7e3ba1 100644 --- gcc/testsuite/gcc.dg/torture/pr49603.c +++ gcc/testsuite/gcc.dg/torture/pr49603.c @@ -6,7 +6,7 @@ struct gl_visual { struct gl_context { struct gl_visual *Visual; }; -void foo (char *); +void foo (unsigned char *); void quickdraw_rgb( struct gl_context * ctx, int width, int height) { diff --git gcc/testsuite/gcc.dg/torture/pr64853.c gcc/testsuite/gcc.dg/torture/pr64853.c index 620f99d..aa8cfbd 100644 --- gcc/testsuite/gcc.dg/torture/pr64853.c +++ gcc/testsuite/gcc.dg/torture/pr64853.c @@ -7,7 +7,7 @@ struct S static struct S a = { 1 }; char b; -static unsigned char *c = &b; +static unsigned char *c = &b; /* { dg-warning "initialization from incompatible pointer type" } */ int d, e, f; int diff --git gcc/testsuite/gcc.target/i386/avx2-mpsadbw-2.c gcc/testsuite/gcc.target/i386/avx2-mpsadbw-2.c index 18118e4..6b43908 100644 --- gcc/testsuite/gcc.target/i386/avx2-mpsadbw-2.c +++ gcc/testsuite/gcc.target/i386/avx2-mpsadbw-2.c @@ -21,8 +21,8 @@ compute_mpsadbw (int *i1, int *i2, int mask, int *r) unsigned char s[4]; int i, j; int offs1, offs2; - unsigned char *v1 = (char *) i1; - unsigned char *v2 = (char *) i2; + unsigned char *v1 = (unsigned char *) i1; + unsigned char *v2 = (unsigned char *) i2; unsigned short *ret = (unsigned short *) r; memset (ret, 0, 32); diff --git gcc/testsuite/gcc.target/i386/avx2-vpaddusb-2.c gcc/testsuite/gcc.target/i386/avx2-vpaddusb-2.c index 68ad4f0..d9c652a 100644 --- gcc/testsuite/gcc.target/i386/avx2-vpaddusb-2.c +++ gcc/testsuite/gcc.target/i386/avx2-vpaddusb-2.c @@ -31,6 +31,6 @@ avx2_test (void) e[i] = tmp; } - if (check_union256i_b (u, e)) + if (check_union256i_b (u, (char *) e)) abort (); } diff --git gcc/testsuite/gcc.target/i386/avx2-vpavgb-2.c gcc/testsuite/gcc.target/i386/avx2-vpavgb-2.c index 8519e9b..14a69aa 100644 --- gcc/testsuite/gcc.target/i386/avx2-vpavgb-2.c +++ gcc/testsuite/gcc.target/i386/avx2-vpavgb-2.c @@ -25,6 +25,6 @@ avx2_test (void) for (i = 0; i < 32; i++) e[i] = ((unsigned char) s1.a[i] + (unsigned char) s2.a[i] + 1) >> 1; - if (check_union256i_b (u, e)) + if (check_union256i_b (u, (char *) e)) abort (); } diff --git gcc/testsuite/gcc.target/i386/avx2-vpmaxub-2.c gcc/testsuite/gcc.target/i386/avx2-vpmaxub-2.c index f0654e0..a7ce05a 100644 --- gcc/testsuite/gcc.target/i386/avx2-vpmaxub-2.c +++ gcc/testsuite/gcc.target/i386/avx2-vpmaxub-2.c @@ -34,7 +34,7 @@ avx2_test (void) compute_pmaxub256 ((unsigned char *) s1.a, (unsigned char *) s2.a, (unsigned char *) res_ref); - fail += check_union256i_b (res, res_ref); + fail += check_union256i_b (res, (char *) res_ref); } if (fail != 0) diff --git gcc/testsuite/gcc.target/i386/avx2-vpminub-2.c gcc/testsuite/gcc.target/i386/avx2-vpminub-2.c index 16c5f76..8f5a7f2 100644 --- gcc/testsuite/gcc.target/i386/avx2-vpminub-2.c +++ gcc/testsuite/gcc.target/i386/avx2-vpminub-2.c @@ -34,7 +34,7 @@ avx2_test (void) compute_pminub256 ((unsigned char *) s1.a, (unsigned char *) s2.a, (unsigned char *) res_ref); - fail += check_union256i_b (res, res_ref); + fail += check_union256i_b (res, (char *) res_ref); } if (fail != 0) diff --git gcc/testsuite/gcc.target/i386/avx2-vpmovzxbd-2.c gcc/testsuite/gcc.target/i386/avx2-vpmovzxbd-2.c index 7a212c8..ac2c21c 100644 --- gcc/testsuite/gcc.target/i386/avx2-vpmovzxbd-2.c +++ gcc/testsuite/gcc.target/i386/avx2-vpmovzxbd-2.c @@ -24,7 +24,7 @@ avx2_test (void) res.x = _mm256_cvtepu8_epi32 (s.x); - compute_movzxbd (s.a, res_ref); + compute_movzxbd ((unsigned char *) s.a, res_ref); if (check_union256i_d (res, res_ref)) abort (); diff --git gcc/testsuite/gcc.target/i386/avx2-vpmovzxbq-2.c gcc/testsuite/gcc.target/i386/avx2-vpmovzxbq-2.c index c09c21d..5e36bd3 100644 --- gcc/testsuite/gcc.target/i386/avx2-vpmovzxbq-2.c +++ gcc/testsuite/gcc.target/i386/avx2-vpmovzxbq-2.c @@ -24,7 +24,7 @@ avx2_test (void) res.x = _mm256_cvtepu8_epi64 (s.x); - compute_movzxbq (s.a, res_ref); + compute_movzxbq ((unsigned char *) s.a, res_ref); if (check_union256i_q (res, res_ref)) abort (); diff --git gcc/testsuite/gcc.target/i386/avx2-vpmovzxbw-2.c gcc/testsuite/gcc.target/i386/avx2-vpmovzxbw-2.c index 5ef4b15..3d46933 100644 --- gcc/testsuite/gcc.target/i386/avx2-vpmovzxbw-2.c +++ gcc/testsuite/gcc.target/i386/avx2-vpmovzxbw-2.c @@ -24,7 +24,7 @@ avx2_test (void) res.x = _mm256_cvtepu8_epi16 (s.x); - compute_movzxbw (s.a, res_ref); + compute_movzxbw ((unsigned char *) s.a, res_ref); if (check_union256i_w (res, res_ref)) abort (); diff --git gcc/testsuite/gcc.target/i386/avx2-vpsadbw-2.c gcc/testsuite/gcc.target/i386/avx2-vpsadbw-2.c index 3926136..bf367a9 100644 --- gcc/testsuite/gcc.target/i386/avx2-vpsadbw-2.c +++ gcc/testsuite/gcc.target/i386/avx2-vpsadbw-2.c @@ -47,7 +47,7 @@ avx2_test (void) } res.x = _mm256_sad_epu8 (s1.x, s2.x);; - compute_sadbw256 (s1.a, s2.a, res_ref); + compute_sadbw256 ((unsigned char *) s1.a, (unsigned char *) s2.a, res_ref); fail += check_union256i_w (res, res_ref); } diff --git gcc/testsuite/gcc.target/i386/avx2-vpsubusb-2.c gcc/testsuite/gcc.target/i386/avx2-vpsubusb-2.c index bffb5b6f..7921404 100644 --- gcc/testsuite/gcc.target/i386/avx2-vpsubusb-2.c +++ gcc/testsuite/gcc.target/i386/avx2-vpsubusb-2.c @@ -31,6 +31,6 @@ avx2_test (void) e[i] = tmp; } - if (check_union256i_b (u, e)) + if (check_union256i_b (u, (char *) e)) abort (); } diff --git gcc/testsuite/gcc.target/i386/avx512f-vpmovusdb-2.c gcc/testsuite/gcc.target/i386/avx512f-vpmovusdb-2.c index 5a201d3..5aad21e 100644 --- gcc/testsuite/gcc.target/i386/avx512f-vpmovusdb-2.c +++ gcc/testsuite/gcc.target/i386/avx512f-vpmovusdb-2.c @@ -62,7 +62,7 @@ TEST (void) INTRINSIC (_mask_cvtusepi32_storeu_epi8) (res4, mask, src.x); CALC (res_ref2, src.a, 1); - MASK_MERGE (i_b) (res_ref2, mask, SIZE); - if (checkVc (res4, res_ref2, 16)) + MASK_MERGE (i_b) ((char *) res_ref2, mask, SIZE); + if (checkVc ((char *) res4, (char *) res_ref2, 16)) abort (); }