[analyzer] Modeling a function with an out parameter pointer in check::PostCall

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

[analyzer] Modeling a function with an out parameter pointer in check::PostCall

Vassil Vassilev via cfe-dev
Hi list,

I am writing a static analyzer checker and trying to model a function of the following type in check::PostCall:

void func(bool* outParam) {
    assert(outParam);
    *outParam = true;
}

(in real life there are some other inputs that determine the value stored in the out parameter, and a return value indicating whether there was an error, but let's use this for the sake of a simple example)

Suppose I want my PostCall callback to store "true" in *outParam. Is this possible to achieve with ProgramState::BindExpr or ProgramState::bindLoc? How do I get the SVal for the memory pointed to by CallEvent::getArgSVal(0)?

I thought of "synthesizing" a UnaryOperator expression using UO_Deref on CallEvent::getArgExpr(0) and passing that to ProgramState::BindExpr, but it seems that getArgExpr returns a const Expr* and a non-const one is required to construct a UnaryOperator expression.

Best regards,
--
Philip

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: [analyzer] Modeling a function with an out parameter pointer in check::PostCall

Vassil Vassilev via cfe-dev
> Is this possible to achieve with ProgramState::BindExpr or ProgramState::bindLoc

Yes, ProgramState::bindLoc does literally what you want. Take the parameter region and bind the true value into that. Also if it's really a bool you can ProgramState::assume it to be true (but you can't do anything more specific that way).

> How do I get the SVal for the memory pointed to by CallEvent::getArgSVal(0)?

ProgramState::getSVal (the overload that accepts the location/region).

> I thought of "synthesizing" a UnaryOperator expression using UO_Deref on CallEvent::getArgExpr(0) and passing that to ProgramState::BindExpr

Apart from "don't do this", another thing you should know about C/C++ is that operator * (aka UO_Deref) does not dereference a pointer! - it simply converts the rvalue of the pointer into an lvalue it points to. From the perspective of the actual behavior of the program (or, for that matter, the static analyzer) operator * is a no-op as both values are simply "the address of the object". In order to actually perform a dereference you have to perform an implicit lvalue-to-rvalue conversion on that lvalue. The same applies to operator & that is the opposite of operator *.

In any case, even if you could synthesize ASTs, i wouldn't recommend that unless you've already been developing Sema for many years.

Also BindExpr does nothing unless it's the expression that you're currently evaluating.

Generally i recommend checking out a few links at the bottom of http://clang-analyzer.llvm.org/checker_dev_manual.html

14.06.2020 12:05 AM, via cfe-dev wrote:
Hi list,

I am writing a static analyzer checker and trying to model a function of the following type in check::PostCall:

void func(bool* outParam) {
    assert(outParam);
    *outParam = true;
}

(in real life there are some other inputs that determine the value stored in the out parameter, and a return value indicating whether there was an error, but let's use this for the sake of a simple example)

Suppose I want my PostCall callback to store "true" in *outParam. Is this possible to achieve with ProgramState::BindExpr or ProgramState::bindLoc? How do I get the SVal for the memory pointed to by CallEvent::getArgSVal(0)?

I thought of "synthesizing" a UnaryOperator expression using UO_Deref on CallEvent::getArgExpr(0) and passing that to ProgramState::BindExpr, but it seems that getArgExpr returns a const Expr* and a non-const one is required to construct a UnaryOperator expression.

Best regards,
--
Philip

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev


_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: [analyzer] Modeling a function with an out parameter pointer in check::PostCall

Vassil Vassilev via cfe-dev
On Sun, Jun 14, 2020 at 2:05 AM Artem Dergachev <[hidden email]> wrote:
> How do I get the SVal for the memory pointed to by CallEvent::getArgSVal(0)?

ProgramState::getSVal (the overload that accepts the location/region).

Thanks, that was it. I would never have thought that SVal -> SVal::getAsRegion() -> ProgramState::getSVal() would have ended up with anything but the original SVal, but there it is!

Generally i recommend checking out a few links at the bottom of http://clang-analyzer.llvm.org/checker_dev_manual.html

Speaking of that... would you be interested in merging my PR https://github.com/haoNoQ/clang-analyzer-guide/pull/5 and some of the other open PRs on the handbook, and releasing a new version? Depending on how much of a hassle it is, I might be interested to make it publish as HTML to GitHub Pages automatically so you wouldn't have to release PDFs...

14.06.2020 12:05 AM, via cfe-dev wrote:
Hi list,

I am writing a static analyzer checker and trying to model a function of the following type in check::PostCall:

void func(bool* outParam) {
    assert(outParam);
    *outParam = true;
}

(in real life there are some other inputs that determine the value stored in the out parameter, and a return value indicating whether there was an error, but let's use this for the sake of a simple example)

Suppose I want my PostCall callback to store "true" in *outParam. Is this possible to achieve with ProgramState::BindExpr or ProgramState::bindLoc? How do I get the SVal for the memory pointed to by CallEvent::getArgSVal(0)?

I thought of "synthesizing" a UnaryOperator expression using UO_Deref on CallEvent::getArgExpr(0) and passing that to ProgramState::BindExpr, but it seems that getArgExpr returns a const Expr* and a non-const one is required to construct a UnaryOperator expression.

Best regards,
--
Philip

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev


Regards,
--
Philip

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: [analyzer] Modeling a function with an out parameter pointer in check::PostCall

Vassil Vassilev via cfe-dev


On 6/16/20 3:56 AM, [hidden email] wrote:
On Sun, Jun 14, 2020 at 2:05 AM Artem Dergachev <[hidden email]> wrote:
> How do I get the SVal for the memory pointed to by CallEvent::getArgSVal(0)?

ProgramState::getSVal (the overload that accepts the location/region).

Thanks, that was it. I would never have thought that SVal -> SVal::getAsRegion() -> ProgramState::getSVal() would have ended up with anything but the original SVal, but there it is!

Generally i recommend checking out a few links at the bottom of http://clang-analyzer.llvm.org/checker_dev_manual.html

Speaking of that... would you be interested in merging my PR https://github.com/haoNoQ/clang-analyzer-guide/pull/5 and some of the other open PRs on the handbook, and releasing a new version? Depending on how much of a hassle it is, I might be interested to make it publish as HTML to GitHub Pages automatically so you wouldn't have to release PDFs...

Ugh, there are countless more outdated paragraphs in there. There are even bugs documented that had to be fixed rather than documented. I emitted it as an artifact that would have been created anyway at some point but i'm personally not planning to maintain it further because it's not the right way to do documentation (we'd rather have doxygen / rst documentation). Please feel free to fork but i'd much rather have it converted to into in-tree documentation (say, documentation in chapter 5 could be torn into individual doxygen comments).

14.06.2020 12:05 AM, via cfe-dev wrote:
Hi list,

I am writing a static analyzer checker and trying to model a function of the following type in check::PostCall:

void func(bool* outParam) {
    assert(outParam);
    *outParam = true;
}

(in real life there are some other inputs that determine the value stored in the out parameter, and a return value indicating whether there was an error, but let's use this for the sake of a simple example)

Suppose I want my PostCall callback to store "true" in *outParam. Is this possible to achieve with ProgramState::BindExpr or ProgramState::bindLoc? How do I get the SVal for the memory pointed to by CallEvent::getArgSVal(0)?

I thought of "synthesizing" a UnaryOperator expression using UO_Deref on CallEvent::getArgExpr(0) and passing that to ProgramState::BindExpr, but it seems that getArgExpr returns a const Expr* and a non-const one is required to construct a UnaryOperator expression.

Best regards,
--
Philip

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev


Regards,
--
Philip


_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: [analyzer] Modeling a function with an out parameter pointer in check::PostCall

Vassil Vassilev via cfe-dev
On Sun, Jun 21, 2020 at 2:03 AM Artem Dergachev <[hidden email]> wrote:


On 6/16/20 3:56 AM, [hidden email] wrote:
On Sun, Jun 14, 2020 at 2:05 AM Artem Dergachev <[hidden email]> wrote:
> How do I get the SVal for the memory pointed to by CallEvent::getArgSVal(0)?

ProgramState::getSVal (the overload that accepts the location/region).

Thanks, that was it. I would never have thought that SVal -> SVal::getAsRegion() -> ProgramState::getSVal() would have ended up with anything but the original SVal, but there it is!

Generally i recommend checking out a few links at the bottom of http://clang-analyzer.llvm.org/checker_dev_manual.html

Speaking of that... would you be interested in merging my PR https://github.com/haoNoQ/clang-analyzer-guide/pull/5 and some of the other open PRs on the handbook, and releasing a new version? Depending on how much of a hassle it is, I might be interested to make it publish as HTML to GitHub Pages automatically so you wouldn't have to release PDFs...

Ugh, there are countless more outdated paragraphs in there. There are even bugs documented that had to be fixed rather than documented. I emitted it as an artifact that would have been created anyway at some point but i'm personally not planning to maintain it further because it's not the right way to do documentation (we'd rather have doxygen / rst documentation). Please feel free to fork but i'd much rather have it converted to into in-tree documentation (say, documentation in chapter 5 could be torn into individual doxygen comments).

I can't honestly say that in-tree documentation would be more useful for people like me trying to develop checker plugins against a released version of clang... is there a middle ground where it could live in-tree but get rendered into something else than doxygen? The doxygen pages are super slow to load (especially if you accidentally load a large one) and difficult to search (nearly impossible if you don't already know what you're looking for). By 'rst' documentation do you mean this page? https://clang-analyzer.llvm.org/checker_dev_manual.html

Regards,
--
Philip

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: [analyzer] Modeling a function with an out parameter pointer in check::PostCall

Vassil Vassilev via cfe-dev

On 6/23/20 8:15 AM, [hidden email] wrote:
On Sun, Jun 21, 2020 at 2:03 AM Artem Dergachev <[hidden email]> wrote:


On 6/16/20 3:56 AM, [hidden email] wrote:
On Sun, Jun 14, 2020 at 2:05 AM Artem Dergachev <[hidden email]> wrote:
> How do I get the SVal for the memory pointed to by CallEvent::getArgSVal(0)?

ProgramState::getSVal (the overload that accepts the location/region).

Thanks, that was it. I would never have thought that SVal -> SVal::getAsRegion() -> ProgramState::getSVal() would have ended up with anything but the original SVal, but there it is!

Generally i recommend checking out a few links at the bottom of http://clang-analyzer.llvm.org/checker_dev_manual.html

Speaking of that... would you be interested in merging my PR https://github.com/haoNoQ/clang-analyzer-guide/pull/5 and some of the other open PRs on the handbook, and releasing a new version? Depending on how much of a hassle it is, I might be interested to make it publish as HTML to GitHub Pages automatically so you wouldn't have to release PDFs...

Ugh, there are countless more outdated paragraphs in there. There are even bugs documented that had to be fixed rather than documented. I emitted it as an artifact that would have been created anyway at some point but i'm personally not planning to maintain it further because it's not the right way to do documentation (we'd rather have doxygen / rst documentation). Please feel free to fork but i'd much rather have it converted to into in-tree documentation (say, documentation in chapter 5 could be torn into individual doxygen comments).

I can't honestly say that in-tree documentation would be more useful for people like me trying to develop checker plugins against a released version of clang... is there a middle ground where it could live in-tree but get rendered into something else than doxygen? The doxygen pages are super slow to load (especially if you accidentally load a large one) and difficult to search (nearly impossible if you don't already know what you're looking for).

Mmm, strange. As a person who regularly googles class names in llvm.org doxygen, i've never had these problems. Say, https://clang.llvm.org/doxygen/classclang_1_1Decl.html loads instantly for me. I don't know how could that be slow aside from llvm.org servers suddenly being slow or a poor internet connection. Those are plain old static pages. Of course you have to know the class name in advance; doxygen is not great for tutorials. You can also always build doxygen locally and grep it (but that's not necessarily better than reading source code).

By 'rst' documentation do you mean this page? https://clang-analyzer.llvm.org/checker_dev_manual.html

I mean something like this: https://clang.llvm.org/docs/LibASTMatchersTutorial.html

This would be better for step-by-step-tutorial-like material and doxygen would be better for documentation on individual classes and methods.

Regards,
--
Philip


_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: [analyzer] Modeling a function with an out parameter pointer in check::PostCall

Vassil Vassilev via cfe-dev
On Wed, Jun 24, 2020 at 1:58 AM Artem Dergachev <[hidden email]> wrote:

On 6/23/20 8:15 AM, [hidden email] wrote:
On Sun, Jun 21, 2020 at 2:03 AM Artem Dergachev <[hidden email]> wrote:


On 6/16/20 3:56 AM, [hidden email] wrote:
On Sun, Jun 14, 2020 at 2:05 AM Artem Dergachev <[hidden email]> wrote:
> How do I get the SVal for the memory pointed to by CallEvent::getArgSVal(0)?

ProgramState::getSVal (the overload that accepts the location/region).

Thanks, that was it. I would never have thought that SVal -> SVal::getAsRegion() -> ProgramState::getSVal() would have ended up with anything but the original SVal, but there it is!

Generally i recommend checking out a few links at the bottom of http://clang-analyzer.llvm.org/checker_dev_manual.html

Speaking of that... would you be interested in merging my PR https://github.com/haoNoQ/clang-analyzer-guide/pull/5 and some of the other open PRs on the handbook, and releasing a new version? Depending on how much of a hassle it is, I might be interested to make it publish as HTML to GitHub Pages automatically so you wouldn't have to release PDFs...

Ugh, there are countless more outdated paragraphs in there. There are even bugs documented that had to be fixed rather than documented. I emitted it as an artifact that would have been created anyway at some point but i'm personally not planning to maintain it further because it's not the right way to do documentation (we'd rather have doxygen / rst documentation). Please feel free to fork but i'd much rather have it converted to into in-tree documentation (say, documentation in chapter 5 could be torn into individual doxygen comments).

I can't honestly say that in-tree documentation would be more useful for people like me trying to develop checker plugins against a released version of clang... is there a middle ground where it could live in-tree but get rendered into something else than doxygen? The doxygen pages are super slow to load (especially if you accidentally load a large one) and difficult to search (nearly impossible if you don't already know what you're looking for).

Mmm, strange. As a person who regularly googles class names in llvm.org doxygen, i've never had these problems. Say, https://clang.llvm.org/doxygen/classclang_1_1Decl.html loads instantly for me. I don't know how could that be slow aside from llvm.org servers suddenly being slow or a poor internet connection. Those are plain old static pages. Of course you have to know the class name in advance; doxygen is not great for tutorials. You can also always build doxygen locally and grep it (but that's not necessarily better than reading source code).

I took a look at this, it's less bad than I remembered, but the slow-to-load ones have always been https://llvm.org/doxygen/namespacellvm.html and https://clang.llvm.org/doxygen/namespaceclang.html because they are so large. I'm thinking maybe I confused "slow to load" with "difficult to find the information I need" :-)
Cheers,
--
Philip

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev