[PATCH] D96976: [analyzer] Fix reinterpret_cast handling for pointer-to-member
Deep Majumder via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 26 06:30:35 PST 2021
RedDocMD added a comment.
> So here you are implying that for reinterpret casts, the `CastE->path_begin()-end()` range is empty? And that is why you need to manually come up with a //possible// CXXBaseSpecifier list?
@steakhal, Yes. For illustration, the following code:
struct Base {
int field;
};
struct Derived : public Base {};
struct DoubleDerived : public Derived {};
int f() {
int DoubleDerived::*ddf = &Derived::field;
int Base::*bf1 = static_cast<int Base::*>(ddf);
int Base::*bf2 = reinterpret_cast<int Base::*>(ddf);
}
produces the following (truncated) AST dump
-FunctionDecl 0x12f3890 <line:8:1, line:12:1> line:8:5 f 'int ()'
`-CompoundStmt 0x12f3ec0 <col:9, line:12:1>
|-DeclStmt 0x12f3b70 <line:9:3, col:44>
| `-VarDecl 0x12f3a18 <col:3, col:39> col:23 used ddf 'int DoubleDerived::*' cinit
| `-ImplicitCastExpr 0x12f3b48 <col:29, col:39> 'int DoubleDerived::*' <BaseToDerivedMemberPointer (Derived -> Base)>
| `-UnaryOperator 0x12f3b30 <col:29, col:39> 'int Base::*' prefix '&' cannot overflow
| `-DeclRefExpr 0x12f3ad0 <col:30, col:39> 'int' lvalue Field 0x12f33d0 'field' 'int'
|-DeclStmt 0x12f3d20 <line:10:3, col:49>
| `-VarDecl 0x12f3bf0 <col:3, col:48> col:14 bf1 'int Base::*' cinit
| `-CXXStaticCastExpr 0x12f3ce0 <col:20, col:48> 'int Base::*' static_cast<int struct Base::*> <DerivedToBaseMemberPointer (Derived -> Base)>
| `-ImplicitCastExpr 0x12f3cc8 <col:45> 'int DoubleDerived::*' <LValueToRValue> part_of_explicit_cast
| `-DeclRefExpr 0x12f3c60 <col:45> 'int DoubleDerived::*' lvalue Var 0x12f3a18 'ddf' 'int DoubleDerived::*'
`-DeclStmt 0x12f3ea8 <line:11:3, col:54>
`-VarDecl 0x12f3d88 <col:3, col:53> col:14 bf2 'int Base::*' cinit
`-CXXReinterpretCastExpr 0x12f3e78 <col:20, col:53> 'int Base::*' reinterpret_cast<int struct Base::*> <ReinterpretMemberPointer>
`-ImplicitCastExpr 0x12f3e60 <col:50> 'int DoubleDerived::*' <LValueToRValue> part_of_explicit_cast
`-DeclRefExpr 0x12f3df8 <col:50> 'int DoubleDerived::*' lvalue Var 0x12f3a18 'ddf' 'int DoubleDerived::*'
If you compare the three cases:
1. The first statement has an implicit cast inserted during parsing, and so we need not calculate the path manually
2. The second statement has a `static_cast` and it also supplies a path, except that we need to remove these bases instead of adding. (Ref to D95877 <https://reviews.llvm.org/D95877>).
3. The third statement has no path provided, because it is a `reinterpret_cast` and the parser cannot produce a path in all cases (if you cast to an integer for an instance) - so it doesn't produce any path
With the parser not providing us with info, we have to figure it out in a different way.
Also, it is not one //possible// path but the //only// possible path. If there are multiple acceptable paths then it is illegal to define such a member-pointer and the frontend will reject it as such.
> I strongly encourage you to find a better alternative to this manual graph search.
> This information must be available somewhere.
>
> Have you looked at `CXXRecordDecl::isDerivedFrom()`? Or any other member functions of that class?
Unfortunately, all the methods on CXXRecordDecl, like the one you mentioned, are for querying and thus returns a `bool`, while I need the entire path.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D96976/new/
https://reviews.llvm.org/D96976
More information about the cfe-commits
mailing list