};
} // namespace
-static QualType getRecordType(QualType Ty) {
- Ty = Ty.getCanonicalType();
-
- if (Ty->isPointerType())
- Ty = Ty->getPointeeType();
-
- if (Ty->isReferenceType())
- Ty = Ty.getNonReferenceType();
-
- return Ty.getUnqualifiedType();
-}
-
static bool isInfeasibleCast(const DynamicCastInfo *CastInfo,
bool CastSucceeds) {
if (!CastInfo)
QualType CastToTy, const Expr *Object,
bool CastSucceeds, bool IsKnownCast) {
std::string CastToName =
- CastInfo ? CastInfo->to()->getAsCXXRecordDecl()->getNameAsString()
- : CastToTy->getAsCXXRecordDecl()->getNameAsString();
+ CastInfo ? CastInfo->to()->getPointeeCXXRecordDecl()->getNameAsString()
+ : CastToTy->getPointeeCXXRecordDecl()->getNameAsString();
Object = Object->IgnoreParenImpCasts();
return C.getNoteTag(
const Expr *Object;
QualType CastFromTy;
- QualType CastToTy = getRecordType(Call.getResultType());
+ QualType CastToTy = Call.getResultType();
if (Call.getNumArgs() > 0) {
Object = Call.getArgExpr(0);
- CastFromTy = getRecordType(Call.parameters()[0]->getType());
+ CastFromTy = Call.parameters()[0]->getType();
} else {
Object = cast<CXXInstanceCall>(&Call)->getCXXThisExpr();
- CastFromTy = getRecordType(Object->getType());
+ CastFromTy = Object->getType();
}
const MemRegion *MR = DV.getAsRegion();
bool IsKnownCast = CastInfo || IsCheckedCast || CastFromTy == CastToTy;
if (!IsKnownCast || IsCheckedCast)
State = setDynamicTypeAndCastInfo(State, MR, CastFromTy, CastToTy,
- Call.getResultType(), CastSucceeds);
+ CastSucceeds);
SVal V = CastSucceeds ? DV : C.getSValBuilder().makeNull();
C.addTransition(
ProgramStateRef State, CheckerContext &C,
bool IsInstanceOf) {
const FunctionDecl *FD = Call.getDecl()->getAsFunction();
+ QualType CastFromTy = Call.parameters()[0]->getType();
QualType CastToTy = FD->getTemplateSpecializationArgs()->get(0).getAsType();
- QualType CastFromTy = getRecordType(Call.parameters()[0]->getType());
+ if (CastFromTy->isPointerType())
+ CastToTy = C.getASTContext().getPointerType(CastToTy);
+ else if (CastFromTy->isLValueReferenceType() &&
+ CastFromTy.isConstQualified()) {
+ CastToTy.addConst();
+ CastToTy = C.getASTContext().getLValueReferenceType(CastToTy);
+ } else if (CastFromTy->isLValueReferenceType())
+ CastToTy = C.getASTContext().getLValueReferenceType(CastToTy);
+ else if (CastFromTy->isRValueReferenceType())
+ CastToTy = C.getASTContext().getRValueReferenceType(CastToTy);
+ else
+ return;
const MemRegion *MR = DV.getAsRegion();
const DynamicCastInfo *CastInfo =
bool IsKnownCast = CastInfo || CastFromTy == CastToTy;
if (!IsKnownCast)
State = setDynamicTypeAndCastInfo(State, MR, CastFromTy, CastToTy,
- Call.getResultType(), IsInstanceOf);
+ IsInstanceOf);
C.addTransition(
State->BindExpr(Call.getOriginExpr(), C.getLocationContext(),
const CastCheck &Check = Lookup->first;
CallKind Kind = Lookup->second;
- // We need to obtain the record type of the call's result to model it.
- if (Kind != CallKind::InstanceOf &&
- !getRecordType(Call.getResultType())->isRecordType())
- return false;
-
Optional<DefinedOrUnknownSVal> DV;
switch (Kind) {