This is an archive of the discontinued LLVM Phabricator instance.

Refactor MemRegionManager::getVarRegion to call two new functions, improving readability
Needs ReviewPublic

Authored by ariccio on Feb 3 2016, 5:56 PM.

Details

Summary

Instead of one long function, MemRegionManager::getVarRegion now calls getMemRegionGloballyStored for global, non-static variables, and getMemRegionStaticLocal for static locals. The behavior of MemRegionManager::getVarRegion is thus clearer, and easier to reason about.

Diff Detail

Event Timeline

ariccio updated this revision to Diff 46848.Feb 3 2016, 5:56 PM
ariccio retitled this revision from to Refactor MemRegionManager::getVarRegion to call two new functions, improving readability.
ariccio updated this object.
ariccio added reviewers: aaron.ballman, dcoughlin.
ariccio added a subscriber: cfe-commits.

Thanks ariccio! Some inline comments are below.

llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
1186

How about make these helper functions return const MemSpaceRegion * to make their signatures more meaningful?

llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
834

get[Global/StaticLocal]MemSpaceForVariable?

853

const MemSpaceRegion *StorageSpace?

Responded to comments.

Will happily make changes when questions are answered.

llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
1186

Would that change their behavior functionally?

llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
834

Ahh, that might make more sense. I did this refactoring without any sense of context, as the unnecessary complexity was a hindrance thereto.

834

How about getGlobalMemSpaceForGlobalVariable? I'm hesitant to drop the second global, to be clear about the scope of the variable that's stored globally. Is that a reasonable concern, or is that redundant?

853

Same question as above: Would that change their behavior functionally?

(if not, then I'll happily change it)

dcoughlin edited edge metadata.Feb 4 2016, 4:25 PM

I guess this is a reasonable refactoring. Although someone with different tastes might come along and inline it back in since the two extracted functions each only have single callers.

llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
1185

I think describing this as taking a "globally stored, non-static local, VarDecl" is ambiguous. This method operates on global variables. It does not act on local variables (static or otherwise). How about "Retrieve or create the memory region associated with a VarDecl for a global variable."

Also, the recommended style these days is to not prefix the doc comment with the name of the member, so I would remove "getMemRegionGloballyStored - " even though getVarRegion() has the same thing. The doc comment style in this file is sufficiently mismatched that I think it is better to do the now-recommend thing rather than try to match its surrounding context.

llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
834

The rest of the method in class follow a pattern of getAdjectiveNoun, so I would suggest something like getGlobalVarRegion() and getLocalVarRegion()

838–839

It looks to me like this function operates on both locals *and* static locals. I would change the name to reflect that.

858

This comment was wrong before and very misleading. I would just remove it so no one else trips on it!

a.sidorin added inline comments.Feb 5 2016, 12:50 AM
llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
1186

No, it will not change it. You will need to change static_cast type to const MemSpaceRegion *, however (lines 809-810). There is const MemSpaceRegion * and its children classes everywhere in return statements already.

llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
853

No, this will not.

a.sidorin added inline comments.Feb 5 2016, 1:17 AM
llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
845

Oops.
Lines above should stay in the caller function or be refactored. Otherwise, we'll get the subregion of V.get<const VarRegion * instead of returning it directly. This looks like a behaviour change. (And this is the only place where return type is not a const MemSpaceRegion *, btw).
This issue may also obsolete my comments about return type.

ariccio marked 9 inline comments as done.Feb 5 2016, 8:56 PM

Whoops, I didn't submit my comments.

llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
1185

I like that. Done.

1186

What're the static_cast<const MemRegion*>s for anyways? Shouldn't the const StackArgumentsSpaceRegion*s convert to const MemRegion* automatically?

StackArgumentsSpaceRegion derives from StackSpaceRegion:

class StackArgumentsSpaceRegion : public StackSpaceRegion

...StackSpaceRegion derives from MemSpaceRegion:

class StackSpaceRegion : public MemSpaceRegion

...and MemSpaceRegion derives from MemRegion:

class MemSpaceRegion : public MemRegion

...which I think should work, because of the kooky rules of covariant return types (or something)?

llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
834

Whatever. I've changed the global one to getGlobalVarRegion.

838–839

So, getMemRegionStaticLocalOrLocal?

845

Nice catch! That's exactly why we do code review :)

This issue may also obsolete my comments about return type.

We might not want to change the return type, I see.

ariccio marked 11 inline comments as done.Feb 5 2016, 8:58 PM

Marked some inline comments as done.

Bump?

llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
838–839

Bump?

I think Aleksei is right and I was wrong.

If you follow his advice and move the call to getStackOrCaptureRegionForDeclContext() to getVarRegion() and then pass the StackFrameContext to what you currently name "getMemRegionStaticLocal" then both methods have the very nice property that they return memory space regions and all the VarRegion stuff is kept in the caller.

In my opinion getMemSpaceForGlobalVariable() and getMemSpaceForLocalVariable() are good names for these two new methods. If you prefer 'getMemSpaceForStaticLocalOrLocalVariable()' I think that would be fine too.

ariccio marked 3 inline comments as done.Feb 7 2016, 9:56 PM

Alrighty, will update the diff momentarily.

ariccio updated this revision to Diff 47161.Feb 7 2016, 9:57 PM
ariccio edited edge metadata.

Responded to comments (fixed the bug noticed in review), and changed names.

All clear. Ready for landing?

a.sidorin added inline comments.Feb 8 2016, 1:37 AM
llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
792

That needs to be formatted. Also, you may pass const StackFrameContext * instead of PointerUnion (as Devin pointed) because it is only used once to get SFC.
And I still think that making these function return const MemSpaceRegion * is a good idea.

One of two comments addressed, one question asked.

llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
792

If I change it to a MemSpaceRegion*, do I need to change the static_casts, from:

? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
: static_cast<const MemRegion*>(getStackLocalsRegion(STC)));

to:

? static_cast<const MemSpaceRegion*>(getStackArgumentsRegion(STC))
: static_cast<const MemSpaceRegion*>(getStackLocalsRegion(STC)));

...?

I'm still not quite sure what they're for in the first place?

ariccio updated this revision to Diff 47289.Feb 8 2016, 7:25 PM
ariccio marked 2 inline comments as done.Feb 8 2016, 7:38 PM

I've reformatted, and changed the PointerUnion to a const StackFrameContext*.

Built successfully, etc...

(I hope I don't sound too pushy!)

llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
792

I'm sorry, I think you're right, but I wanna get this patch over with, so I can move on to other things. Some other time, maybe?

Hello Alexander,

Yes, types in static_cast should be changed. So, you need only to change return type and types in static_cast, and it should work.

Alexander, could you update status of this review?

ariccio marked an inline comment as done.Mar 11 2016, 1:17 PM

Alexander, could you update status of this review?

It's become a zombie review. I should just abandon it, as I'll be away for two weeks starting tomorrow.