Skip to content

Commit

Permalink
Issue a warning on gnu void pointer arithmetic
Browse files Browse the repository at this point in the history
  • Loading branch information
wrongnull authored Oct 1, 2024
1 parent 406f323 commit ecd5c72
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/aro/Diagnostics.zig
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ pub const Options = struct {
@"pointer-bool-conversion": Kind = .default,
@"string-conversion": Kind = .default,
@"gnu-auto-type": Kind = .default,
@"gnu-pointer-arith": Kind = .default,
@"gnu-union-cast": Kind = .default,
@"pointer-sign": Kind = .default,
@"fuse-ld-path": Kind = .default,
Expand Down
6 changes: 6 additions & 0 deletions src/aro/Diagnostics/messages.def
Original file line number Diff line number Diff line change
Expand Up @@ -2165,6 +2165,12 @@ auto_type_extension
.kind = .off
.pedantic = true

gnu_pointer_arith
.msg = "arithmetic on pointers to void is a GNU extension"
.opt = W("gnu-pointer-arith")
.kind = .off
.pedantic = true

auto_type_not_allowed
.msg = "'__auto_type' not allowed in {s}"
.kind = .@"error"
Expand Down
14 changes: 14 additions & 0 deletions src/aro/Parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5492,6 +5492,9 @@ pub const Result = struct {
// if both aren't arithmetic one should be pointer and the other an integer
if (a_ptr == b_ptr or a_int == b_int) return a.invalidBinTy(tok, b, p);

if (a.ty.isVoidStar() or b.ty.isVoidStar())
try p.errTok(.gnu_pointer_arith, tok);

// Do integer promotions but nothing else
if (a_int) try a.intCast(p, a.ty.integerPromotion(p.comp), tok);
if (b_int) try b.intCast(p, b.ty.integerPromotion(p.comp), tok);
Expand All @@ -5504,6 +5507,9 @@ pub const Result = struct {
// if both aren't arithmetic then either both should be pointers or just a
if (!a_ptr or !(b_ptr or b_int)) return a.invalidBinTy(tok, b, p);

if (a.ty.isVoidStar())
try p.errTok(.gnu_pointer_arith, tok);

if (a_ptr and b_ptr) {
if (!a.ty.eql(b.ty, p.comp, false)) try p.errStr(.incompatible_pointers, tok, try p.typePairStr(a.ty, b.ty));
a.ty = p.comp.types.ptrdiff;
Expand Down Expand Up @@ -7150,6 +7156,8 @@ fn unExpr(p: *Parser) Error!Result {

var operand = try p.castExpr();
try operand.expect(p);
if (operand.ty.isVoidStar())
try p.errTok(.gnu_pointer_arith, tok);
if (!operand.ty.isScalar())
try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
if (operand.ty.isComplex())
Expand All @@ -7176,6 +7184,8 @@ fn unExpr(p: *Parser) Error!Result {

var operand = try p.castExpr();
try operand.expect(p);
if (operand.ty.isVoidStar())
try p.errTok(.gnu_pointer_arith, tok);
if (!operand.ty.isScalar())
try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
if (operand.ty.isComplex())
Expand Down Expand Up @@ -7475,6 +7485,8 @@ fn suffixExpr(p: *Parser, lhs: Result) Error!Result {
defer p.tok_i += 1;

var operand = lhs;
if (operand.ty.isVoidStar())
try p.errTok(.gnu_pointer_arith, p.tok_i);
if (!operand.ty.isScalar())
try p.errStr(.invalid_argument_un, p.tok_i, try p.typeStr(operand.ty));
if (operand.ty.isComplex())
Expand All @@ -7493,6 +7505,8 @@ fn suffixExpr(p: *Parser, lhs: Result) Error!Result {
defer p.tok_i += 1;

var operand = lhs;
if (operand.ty.isVoidStar())
try p.errTok(.gnu_pointer_arith, p.tok_i);
if (!operand.ty.isScalar())
try p.errStr(.invalid_argument_un, p.tok_i, try p.typeStr(operand.ty));
if (operand.ty.isComplex())
Expand Down
19 changes: 19 additions & 0 deletions test/cases/gnu pointer arith.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//aro-args -Wgnu-pointer-arith

void foo(void *a, void *b) {
b - a;
a - 1;
a + 1;
++a;
--a;
b++;
b--;
}

#define EXPECTED_ERRORS "gnu pointer arith.c:4:7: warning: arithmetic on pointers to void is a GNU extension [-Wgnu-pointer-arith]"\
"gnu pointer arith.c:5:7: warning: arithmetic on pointers to void is a GNU extension [-Wgnu-pointer-arith]"\
"gnu pointer arith.c:6:7: warning: arithmetic on pointers to void is a GNU extension [-Wgnu-pointer-arith]"\
"gnu pointer arith.c:7:5: warning: arithmetic on pointers to void is a GNU extension [-Wgnu-pointer-arith]"\
"gnu pointer arith.c:8:5: warning: arithmetic on pointers to void is a GNU extension [-Wgnu-pointer-arith]"\
"gnu pointer arith.c:9:6: warning: arithmetic on pointers to void is a GNU extension [-Wgnu-pointer-arith]"\
"gnu pointer arith.c:10:6: warning: arithmetic on pointers to void is a GNU extension [-Wgnu-pointer-arith]"

0 comments on commit ecd5c72

Please sign in to comment.