This is an archive of the discontinued LLVM Phabricator instance.

[-Wunsafe-buffer-usage] Add a Fixable for pointer pre-increment
ClosedPublic

Authored by ziqingluo-90 on Feb 17 2023, 3:51 PM.

Details

Summary

For a pointer type expression e of the form ++DRE, if e is under an Unspecified Pointer Context (UPC) and DRE is suppose to be transformed to have span type,
we generate fix-its that transform e to (DRE = DRE.subspan(1)).data().

For reference, the UPC is currently defined as

  • 1. an argument of a function call (except the callee has [[unsafe_buffer_usage]] attribute), or
  • 2. the operand of a cast-to-(Integer or Boolean) operation; or
  • 3. the operand of a pointer subtraction operation; or
  • 4. the operand of a pointer comparison operation;

We may extend the definition of UPC by adding more cases later.

Diff Detail

Event Timeline

ziqingluo-90 created this revision.Feb 17 2023, 3:51 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 17 2023, 3:51 PM
ziqingluo-90 requested review of this revision.Feb 17 2023, 3:51 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 17 2023, 3:51 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
ziqingluo-90 retitled this revision from [WIP][-Wunsafe-buffer-usage] Add a Fixable for pointer pre-increment to [-Wunsafe-buffer-usage] Add a Fixable for pointer pre-increment.Feb 22 2023, 2:40 PM
NoQ added inline comments.Mar 7 2023, 3:24 PM
clang/lib/Analysis/UnsafeBufferUsage.cpp
142–145

Oh interesting, so hasOperatorName wasn't sufficient, because operators ++ and ++ have the same "name"?

Yeah, sounds like a universally useful matcher, we should commit it to ASTMatchers.h for everybody to use.

657

You're not checking whether the operand is a variable. This isn't incorrect, given that the fixable will be thrown away if it doesn't claim any variables. However, for performance it makes sense to never match things that don't act on variables, so that to never construct the fixable object in the first place. The check for the variable being an actual VarDecl is also useful and can be made here instead of the getFixit method.

I think this is something we should do consistently: if it's not the right code, stop doing things with it as early as possible. Premature optimizations are evil, but in these cases it's not much of an optimization really, it's just easier to write code this way from the start.

It also makes the code easier to read: you can easily see which patterns the gadget covers, by just reading the matcher() method.

clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-pre-increment.cpp
26

It's probably a good idea to explicitly say FIXME: if we think these cases should eventually be fixed.

ziqingluo-90 added inline comments.Mar 7 2023, 6:02 PM
clang/lib/Analysis/UnsafeBufferUsage.cpp
657

aha, I agree with you and I like your last sentence the most! Treating the matcher() methods as documents, i.e., we are guaranteed that a matched node conforms to the "description" of the matcher(). So that we can get rid of defensive checks. For example, the
if (auto DRE = dyn_cast<DeclRefExpr>(Node->getSubExpr())) statement at line 671 could be a defensive check.

Rebased and addressed comments.

NoQ accepted this revision.Apr 4 2023, 1:12 PM

LGTM!

clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-addressof-arraysubscript.cpp
19 ↗(On Diff #503928)

These changes look unrelated, probably accidentally included from another patch 🤔

clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp
37 ↗(On Diff #503928)

These also seem unrelated.

This revision is now accepted and ready to land.Apr 4 2023, 1:12 PM
ziqingluo-90 marked an inline comment as done.Apr 4 2023, 3:56 PM
ziqingluo-90 added inline comments.
clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-addressof-arraysubscript.cpp
19 ↗(On Diff #503928)

oh yes, need a rebase.

This revision was landed with ongoing or failed builds.Apr 12 2023, 3:00 PM
This revision was automatically updated to reflect the committed changes.