This is an archive of the discontinued LLVM Phabricator instance.

[clang-tidy] Add check cppcoreguidelines-pro-bounds-pointer-arithmetic
ClosedPublic

Authored by mgehre on Sep 30 2015, 3:27 PM.

Details

Summary

This check flags all usage of pointer arithmetic, because it could lead to an
invalid pointer.
Subtraction of two pointers is not flagged by this check.

Pointers should only refer to single objects, and pointer arithmetic is
fragile and easy to get wrong. array_view is a bounds-checked, safe type
for accessing arrays of data.

This rule is part of the "Bounds safety" profile of the C++ Core
Guidelines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-bounds1-dont-use-pointer-arithmetic-use-array_view-instead

Depends on D13313

Diff Detail

Repository
rL LLVM

Event Timeline

mgehre updated this revision to Diff 36152.Sep 30 2015, 3:27 PM
mgehre retitled this revision from to [clang-tidy] Add check misc-pointer-arithmetic.
mgehre updated this object.
mgehre updated this revision to Diff 36153.Sep 30 2015, 3:33 PM

Simplified matcher

Eugene.Zelenko set the repository for this revision to rL LLVM.
mgehre updated this revision to Diff 36300.Oct 1 2015, 2:40 PM

Port to cppcoreguidelines module.
Add checks for post/pre increment/decrement and array access.

mgehre updated this revision to Diff 36305.Oct 1 2015, 2:47 PM

Remove inclusion of misc-no-reinterpret-cast in this patch set

mgehre updated this object.Oct 1 2015, 2:50 PM
mgehre added reviewers: sbenza, bkramer, aaron.ballman.
mgehre retitled this revision from [clang-tidy] Add check misc-pointer-arithmetic to [clang-tidy] Add check cppcoreguidelines-pro-bounds-pointer-arithmetic.
sbenza added inline comments.Oct 2 2015, 8:27 AM
clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
38 ↗(On Diff #36305)

What is that implicitCastExpr() matching?
Did you mean to use ignoringImpCasts() instead?

test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
17 ↗(On Diff #36305)

You don't need to specify the whole message on each hit.
Use the first hit to verify the whole message.
Strip the tail of the rest to let them fit in a single line.

24 ↗(On Diff #36305)

Why just literals/enums? Maybe one of these should use i/j to make sure variables also work.

aaron.ballman added inline comments.Oct 2 2015, 9:11 AM
clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
48 ↗(On Diff #36305)

Can elide the parenthetical.

clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
18 ↗(On Diff #36305)

This could be a bit more usefully descriptive. ;-)

test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
36 ↗(On Diff #36305)

How does this check handle code like:

struct S {
  operator int() const;  
};

void f(S &s) {
  int *i;
  i = i + s;
}
38 ↗(On Diff #36305)

s/okey/okay

;-)

mgehre set the repository for this revision to rL LLVM.Oct 2 2015, 9:23 AM
mgehre updated this revision to Diff 36403.Oct 2 2015, 3:30 PM
mgehre marked 7 inline comments as done.

Incorporated comments
Simplied matcher: Instead of checking argument types, just check that the result of the arithmetic operation is a pointer

mgehre added a comment.Oct 2 2015, 3:30 PM

Thank you for the review comments!

clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
38 ↗(On Diff #36305)

The AST for

int* p = 0;
int i;
i = p[1];

is

-BinaryOperator 0x22dd770 <line:52:3, col:10> 'int' lvalue '='
   |-DeclRefExpr 0x22dd6a8 <col:3> 'int' lvalue Var 0x227fca0 'i' 'int'
   `-ImplicitCastExpr 0x22dd758 <col:7, col:10> 'int' <LValueToRValue>
     `-ArraySubscriptExpr 0x22dd730 <col:7, col:10> 'int' lvalue
       |-ImplicitCastExpr 0x22dd718 <col:7> 'int *' <LValueToRValue>
       | `-DeclRefExpr 0x22dd6d0 <col:7> 'int *' lvalue Var 0x227fdf0 'p' 'int *'
       `-IntegerLiteral 0x22dd6f8 <col:9> 'int' 1

I guess you are right about ignoringImpCasts(), though.

mgehre updated this revision to Diff 36404.Oct 2 2015, 3:32 PM

Fix typo

sbenza added inline comments.Oct 5 2015, 9:06 AM
clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
35 ↗(On Diff #36404)

Space after //

test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
68 ↗(On Diff #36404)

Space after //

mgehre updated this revision to Diff 36564.Oct 5 2015, 3:02 PM

Fixed space after //

aaron.ballman added inline comments.Oct 6 2015, 6:45 AM
test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
37 ↗(On Diff #36564)

I don't think this comment is "done" yet. I still don't know how this check is intended to handle code like that. Does it currently diagnose? Does it not diagnose? Should it diagnose?

51 ↗(On Diff #36564)

How well does this handle code like:

void f(int i[], size_t s) {
  i[s - 1] = 0;
}

Does it diagnose, and should it?

mgehre marked 2 inline comments as done.Oct 6 2015, 2:31 PM
mgehre added inline comments.
test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
37 ↗(On Diff #36564)

I had added your code, see line 55 of this file.
It should diagnose, because an arithmetic operation (+) is used, which results in a (possibly) changed pointer.
It does diagnose, as the CHECK-MESSAGE shows.

51 ↗(On Diff #36564)
aaron.ballman accepted this revision.Oct 7 2015, 5:54 AM
aaron.ballman edited edge metadata.

On Tue, Oct 6, 2015 at 5:31 PM, Matthias Gehre <M.Gehre@gmx.de> wrote:

mgehre marked 2 inline comments as done.

Comment at: test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp:37
@@ +36,3 @@
+ q -= i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic

+ q -= ENUM_LITERAL;

aaron.ballman wrote:

I don't think this comment is "done" yet. I still don't know how this check is intended to handle code like that. Does it currently diagnose? Does it not diagnose? Should it diagnose?

I had added your code, see line 55 of this file.

I am pretty sure I missed this by accidentally fiddling with a Phab knob, because this is definitely in there this morning, but wasn't last night. Sorry for the noise!

It should diagnose, because an arithmetic operation (+) is used, which results in a (possibly) changed pointer.
It does diagnose, as the CHECK-MESSAGE shows.

Great, thank you!

Comment at: test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp:51
@@ +50,3 @@
+
+ i = p[1];

+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use pointer arithmetic

aaron.ballman wrote:

How well does this handle code like:

void f(int i[], size_t s) {
  i[s - 1] = 0;
}

Does it diagnose, and should it?

Good point, I'll ask at https://github.com/isocpp/CppCoreGuidelines/issues/299

Thanks! The answer to this question should not hold up this patch, IMO.

LGTM!

~Aaron

This revision is now accepted and ready to land.Oct 7 2015, 5:54 AM
This revision was automatically updated to reflect the committed changes.