Clang static analyzer checker seems to stop after seeing "typeid()"

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

Clang static analyzer checker seems to stop after seeing "typeid()"

Nathan Ridge via cfe-dev
Hi all,

I've been using the unix.Malloc checker to detect memory management issues in our code base. But we found the checker seems to stop exploring after seeing a call to typeid(). Below is a bad code example and unix.Malloc should warn about a double-free. But if I uncomment the line calling typeid(), the checker doesn't report any bug.

This prevents it from checking some of our templated functions that call typeid(). Could someone please let me know why this happens and how do I make the checker continue to work after seeing typeid()?

Thank you!
Torry

void double_free(int size) {
  char *data = (char *)malloc(size);

  for (int i = 0; i < size; i++)
    data[i] = i;

  // auto tname = typeid(uint64_t).name(); // typeid() seems to stop analyzer
  // printf("Type name is %s\n", tname);

  free(data);
  free(data); // Should warn: Attempt to free released memory
}

int main(int argc, char** argv) {
  double_free(argc);

  return 0;
}


_______________________________________________
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: Clang static analyzer checker seems to stop after seeing "typeid()"

Nathan Ridge via cfe-dev
Yes, indeed, this is simply unimplemented. Like, so much unimplemented that the analyzer is unable to figure out how to handle CXXTypeidExpr so it gives up on the current execution path. See ExprEngine::Visit, the top part of the switch.

It shouldn't be that hard to implement in a reasonable manner. I guess, the values that it returns would always be symbolic (as in, an invalidated structure), but consistent as long as we know the type (and it should probably produce a new value every time we don't know the type on the current path).

On 6/10/19 6:26 PM, Torry Chen via cfe-dev wrote:
Hi all,

I've been using the unix.Malloc checker to detect memory management issues in our code base. But we found the checker seems to stop exploring after seeing a call to typeid(). Below is a bad code example and unix.Malloc should warn about a double-free. But if I uncomment the line calling typeid(), the checker doesn't report any bug.

This prevents it from checking some of our templated functions that call typeid(). Could someone please let me know why this happens and how do I make the checker continue to work after seeing typeid()?

Thank you!
Torry

void double_free(int size) {
  char *data = (char *)malloc(size);

  for (int i = 0; i < size; i++)
    data[i] = i;

  // auto tname = typeid(uint64_t).name(); // typeid() seems to stop analyzer
  // printf("Type name is %s\n", tname);

  free(data);
  free(data); // Should warn: Attempt to free released memory
}

int main(int argc, char** argv) {
  double_free(argc);

  return 0;
}


_______________________________________________
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: Clang static analyzer checker seems to stop after seeing "typeid()"

Nathan Ridge via cfe-dev
Thank you! I will investigate how to implement that.

As a dirty hack, will it be fine to simply ignore typeid() as follows? There aren't many calls to it in our code base.
case Stmt::CXXTypeidExprClass:
  break;  

On Mon, 10 Jun 2019 at 19:38, Artem Dergachev <[hidden email]> wrote:
Yes, indeed, this is simply unimplemented. Like, so much unimplemented that the analyzer is unable to figure out how to handle CXXTypeidExpr so it gives up on the current execution path. See ExprEngine::Visit, the top part of the switch.

It shouldn't be that hard to implement in a reasonable manner. I guess, the values that it returns would always be symbolic (as in, an invalidated structure), but consistent as long as we know the type (and it should probably produce a new value every time we don't know the type on the current path).

On 6/10/19 6:26 PM, Torry Chen via cfe-dev wrote:
Hi all,

I've been using the unix.Malloc checker to detect memory management issues in our code base. But we found the checker seems to stop exploring after seeing a call to typeid(). Below is a bad code example and unix.Malloc should warn about a double-free. But if I uncomment the line calling typeid(), the checker doesn't report any bug.

This prevents it from checking some of our templated functions that call typeid(). Could someone please let me know why this happens and how do I make the checker continue to work after seeing typeid()?

Thank you!
Torry

void double_free(int size) {
  char *data = (char *)malloc(size);

  for (int i = 0; i < size; i++)
    data[i] = i;

  // auto tname = typeid(uint64_t).name(); // typeid() seems to stop analyzer
  // printf("Type name is %s\n", tname);

  free(data);
  free(data); // Should warn: Attempt to free released memory
}

int main(int argc, char** argv) {
  double_free(argc);

  return 0;
}


_______________________________________________
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: Clang static analyzer checker seems to stop after seeing "typeid()"

Nathan Ridge via cfe-dev
As a quick-and-dirty solution i'd rather recommend moving this 'case:'
to the list of

   1301     // Cases not handled yet; but will handle some day.


On 6/11/19 12:43 AM, Torry Chen wrote:

> Thank you! I will investigate how to implement that.
>
> As a dirty hack, will it be fine to simply ignore typeid() as follows?
> There aren't many calls to it in our code base.
> case Stmt::CXXTypeidExprClass:
>   break;
>
> On Mon, 10 Jun 2019 at 19:38, Artem Dergachev <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Yes, indeed, this is simply unimplemented. Like, so much
>     unimplemented that the analyzer is unable to figure out how to
>     handle CXXTypeidExpr so it gives up on the current execution path.
>     See ExprEngine::Visit, the top part of the switch.
>
>     It shouldn't be that hard to implement in a reasonable manner. I
>     guess, the values that it returns would always be symbolic (as in,
>     an invalidated structure), but consistent as long as we know the
>     type (and it should probably produce a new value every time we
>     don't know the type on the current path).
>
>     On 6/10/19 6:26 PM, Torry Chen via cfe-dev wrote:
>>     Hi all,
>>
>>     I've been using the unix.Malloc checker to detect memory
>>     management issues in our code base. But we found the checker
>>     seems to stop exploring after seeing a call to typeid(). Below is
>>     a bad code example and unix.Malloc should warn about a
>>     double-free. But if I uncomment the line calling typeid(), the
>>     checker doesn't report any bug.
>>
>>     This prevents it from checking some of our templated functions
>>     that call typeid(). Could someone please let me know why this
>>     happens and how do I make the checker continue to work after
>>     seeing typeid()?
>>
>>     Thank you!
>>     Torry
>>
>>     void double_free(int size) {
>>       char *data = (char *)malloc(size);
>>
>>       for (int i = 0; i < size; i++)
>>         data[i] = i;
>>
>>       // auto tname = typeid(uint64_t).name(); // typeid() seems to
>>     stop analyzer
>>       // printf("Type name is %s\n", tname);
>>
>>       free(data);
>>       free(data); // Should warn: Attempt to free released memory
>>     }
>>
>>     int main(int argc, char** argv) {
>>       double_free(argc);
>>
>>       return 0;
>>     }
>>
>>     _______________________________________________
>>     cfe-dev mailing list
>>     [hidden email]  <mailto:[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