[llvm-dev] How static casts work between Stmt and its inheritors in clang?

Saurabh Jha via llvm-dev llvm-dev at lists.llvm.org
Tue Mar 2 12:10:49 PST 2021


Hi LLVM people,

I am new to clang/llvm and have been hacking on it for about three weeks
now.  I am trying to implement compound assignment operators, +=, -=, and
*=, for matrices. Here are the bug details
<https://bugs.llvm.org/show_bug.cgi?id=46164>.

I have a lit test that tries to do a "a += b" for matrices a and b. Here's
its trace <https://godbolt.org/z/eM7x1q> (courtesy Florian Hahn). Clang
fails on this assertion
<https://github.com/llvm/llvm-project/blob/ca5247bb1770a1dfa56b78303d99f1cc9a0a06ee/clang/include/clang/AST/Type.h#L677>.
And this is because when we do a static cast from a Stmt instance to a
CompoundAssignOperator here
<https://github.com/llvm/llvm-project/blob/ca5247bb1770a1dfa56b78303d99f1cc9a0a06ee/clang/include/clang/AST/StmtVisitor.h#L76>,
we
are not assigning the correct QualType to the LHS. Concretely, here's what
I found in my debugging.

# printing out S
(lldb) p S
(std::__add_pointer_helper<clang::Stmt, true>::type) $0 = 0x0000000011621f70

# cast S to CompoundAssignOperator
(lldb) p ((CompoundAssignOperator *) S)
(clang::CompoundAssignOperator *) $1 = 0x0000000011621f70

# access ComputationLHSType attribute of casted S. The QualType is NULL.
(lldb) p ((CompoundAssignOperator *) S)->ComputationLHSType
(clang::QualType) $2 = {
  Value = (Value = 0)
}

# access ComputationResultType attribute of casted S.
(lldb) p ((CompoundAssignOperator *) S)->ComputationResultType
(clang::QualType) $3 = {
  Value = (Value = 291641504)
}

So I think it's working correctly for ComputationResultType but is somehow
assigning null to ComputationLHSType's QualType.Value. This is interesting
because if I try to cast S to something like BinaryOperator and cast its
operands to Expr, the types are coming out correctly.

# Cast S to BinaryOperator
(lldb) p ((BinaryOperator *) S)
(clang::BinaryOperator *) $9 = 0x0000000011621f70

# Cast first operand to Expr and get its type.
(lldb) p ((Expr *) ((BinaryOperator *) S)->SubExprs[0])->TR
(clang::QualType) $13 = {
  Value = (Value = 291641504)
}

# Cast second operand to Expr and get its type.
(lldb) p ((Expr *) ((BinaryOperator *) S)->SubExprs[1])->TR
(clang::QualType) $14 = {
  Value = (Value = 291641504)
}

I suspect that these static casts to children classes are connected to the
traversal of AST where classes of child nodes are in the inheritance
hierarchy of the class of the parent. What I am trying to understand though
is the mechanics of these casting. What do I need to look at in order to do
that Stmt -> CompoundAssignOperator correctly. I was going through the
static_cast C++ reference doc
<https://en.cppreference.com/w/cpp/language/static_cast> but I suspect that
I am missing something specific to the codebase.

Does anyone have any thoughts on where I can go from here?

Many thanks,
Saurabh
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210302/42f53efc/attachment.html>


More information about the llvm-dev mailing list