[analyzer] Dynamic type information for non-class pointers (void*, nonloc::LocAsInteger ...)

Hello! :slight_smile:

In short: Is it possible to obtain the type of the region a void* or nonloc::LocAsInteger object points to? Note that this is a C+±only checker.

In detail:

I’m working on numerous fixes to UninitializedObjectChecker. I am however stuck at two of them:

  • instead of ignoring void pointer types, I intend to obtain the object it points to by first acquiring the dynamic type of the pointer
  • handle nonloc::LocAsInteger, where I’ll also need obtain a dynamic type.

However, after carefully reading Artem Degrachev’s (absolutely outstanding!) guide “Clang Static Analyzer – A Checker Developer’s Guide”, in section 4.3.6 (about check::Bind) I found this statement:
“Not every memory region has a type; for example, any void pointer points to a certain memory region, but the analyzer cannot afford making assumptions about the type of values stored in such region.”.

I have looked around in the code, have found getDynamicTypeInfo, and tried various other methods, but I start to think that this hasn’t changed since the time that statement was written. Is this correct?

Best regards,
Kristóf Umann

Let’s discriminate between void*-typed regions and expressions.

Ex.1:

void foo(void *p) {
p; // ???
}

Ex.2:

void foo() {
int x;
void *p = &x;
p; // ???
}

In example 1, assuming foo() is the top frame of the analysis, we have a symbolic region based on an external pointer about which we know literally nothing. The region is untyped and you won’t ever be able to obtain any type information about its contents. This is example of a memory region that doesn’t have a type.

In example 2, we have a void*-typed expression that evaluates to a variable-region ‘&x’. The expression has type ‘void *’, but the analyzer knows that the “dynamic type” of the object pointed to by ‘p’ is ‘int’. You can retrieve that type by casting the region to TypedValueRegion and taking the value type, or conveniently via the getDynamicTypeInfo() API, which additionally knows about other potential sources of type information (not only the region object’s type) (in fact, i believe that the region’s type should have been a trait, not property of the region, to begin with).

So i encourage you to look at region types rather than at variable/field/expression types because the former are [not always but] often richer.

One thing you’re totally right about, though, is that none of this has changed since the statement was written :slight_smile: