[cfe-dev] [analyzer]

Gábor Horváth via cfe-dev cfe-dev at lists.llvm.org
Thu Oct 25 02:55:17 PDT 2018

Given the lack of recent activity feel free to commandeer the revision. I
think it should be quite close to be merged.

On Thu, 25 Oct 2018 at 10:30, Alexander Zaitsev <zamazan4ik at tut.by> wrote:

> Didn't know that this check is already implemented. I think I can continue
> this work (seems like original author of the change don't work on it now).
> What do you think?
> 25.10.2018 6:34, Gábor Horváth пишет:
> Hi!
> Do you have something in mind like this: https://reviews.llvm.org/D33672 ?
> Regards,
> Gábor
> Artem Dergachev via cfe-dev <cfe-dev at lists.llvm.org> ezt írta (időpont:
> 2018. okt. 25., Cs 4:32):
>> Hi,
>> 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
>> segments.
>> 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
>> don't.
>> 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
>> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
> --
> Best regards,
> Alexander Zaitsev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20181025/379c355d/attachment.html>

More information about the cfe-dev mailing list