[cfe-dev] [analyzer]

Artem Dergachev via cfe-dev cfe-dev at lists.llvm.org
Wed Oct 24 19:32:48 PDT 2018


Your overall plan sounds good, and i believe that such checker will be 
very useful, i'd love to have such check in the analyzer. If you want to 
post it upstream, i encourage you to start early by publishing 
prototypes on Phabricator for code reviews, even when you think they're 
not ready, just because code reviews are cool!

Path-sensitive analysis is indeed useful here because sometimes it's not 
immediately obvious from the code which values are possible for the 
sub-expression. Defining the buggy state can be a bit annoying because 
enum values can be non-contiguous and/or numerous; the former means that 
you'll potentially need to make a lot of State->assume(...) calls and 
see if none of the states with assumptions are null; the latter means 
that you'll need to make sure you identify segments of values to avoid 
calling assume() for *every* enum item. I also recommend 
ConstraintManager::assumeInclusiveRange() for direct assumptions over 

Your questions so far are AST questions, not specific to the analyzer. 
First of all, notice that every expression has a (qualified) type, which 
is the type of the value it evaluates to, and it can always be obtained 
via Expr::getType(). It may be void (eg., call expression for a function 
that returns void), but it's always there.

For cast-expression, as you might have already guessed, the type of the 
expression is the target type of the cast. Because, well, that's the 
whole point of the cast. This takes care of question 2.

Most functions return not raw Types but QualType objects that are types 
with qualifiers. You can always use the overloaded operator->() on the 
QualType to access the underlying Type; there's also 
QualType::getTypePtr(), but if you think you need it - most likely you 

Now, types, like statements or declarations, are a hierarchy. Some types 
are integer types, some are array or structure types, some are enum 
types. Enum types are represented by the EnumType class, to which you 
can try to dyn_cast<>() your type. Or, even better, use Type::getAs<>(), 
which can be accessed directly with operator->() on QualType.

If dyn_cast<>()/getAs<>() is successful - your type is an enum and you 
have a pointer to an EnumType object, so you can call 
EnumType::getDecl() to find the *declaration* of the enum in the code.

Also if the enum hides under a typedef, then the type wouldn't be an 
EnumType but it'd be a TypedefType, so the cast would fail. The easy way 
to get rid of typedefs is to do QualType::getCanonicalType().

Some declarations are forward declarations. You might need to do 
EnumDecl::getDefinition() to find the actual definition. Maybe you don't 
need that: i don't remember what operations are allowed on incomplete 
enum types.

Once you have your EnumDecl that is the definition, you can iterate over 
EnumDecl::enumerators() to see what values are present.

In Clang there are a lot more cast kinds of expressions than you 
probably expect, so you might want to take a look at the list of casts 
in clang/AST/OperationKinds.def and see which ones do you need; i don't 
think it'll be important at first, but just in case.

In order to quickly catch up on the basics, i also recommend the AST 
tutorial by Manuel Klimek at https://www.youtube.com/watch?v=VqCkCDFLSsc

On 10/24/18 5:16 PM, Alexander Zaitsev via cfe-dev wrote:
> Hello. I am newbie in Clang Static Analyzer and I am trying to write 
> new Clang Static Analyzer check, which is aimed to find issues with 
> casting values to enum: if we cast anything which is no presented in 
> target enum it will be unspecified/undefined behavior(depends on C++ 
> version).
> So my plan is:
>  1. Find all casts in source code. Seems like
>     'check::PreStmt<CastExpr>>' it's what I need.
>  2. In my implementation of `checkPreStmt` method I must get target
>     type from CastExpr, but I don't know, how to do it - can you help
>     with it?
>  3. Then if target type in Cast is Enum, I must get all values from
>     this Enum and compare it with all possible values which can be
>     presented by CastExpr->getSubExpr() - here I don't know how to
>     evaluate CastExpr->getSubExpr() and how to get all values from Enum.
> Do you have any ideas?
> -- 
> Best regards,
> Alexander Zaitsev
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

More information about the cfe-dev mailing list