Skip to content

Commit a2420d7

Browse files
committed
Fix double lookup
1 parent 0226494 commit a2420d7

File tree

2 files changed

+16
-16
lines changed

2 files changed

+16
-16
lines changed

clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -690,9 +690,10 @@ class CXXInstanceCall : public AnyFunctionCall {
690690
ValueList &Values,
691691
RegionAndSymbolInvalidationTraits *ETraits) const override;
692692

693-
/// Returns the decl refered to by the "dynamic type" of the current object.
694-
/// This may be null.
695-
const CXXRecordDecl *getDeclForDynamicType() const;
693+
/// Returns the decl refered to by the "dynamic type" of the current object
694+
/// and if the class can be a sub-class or not.
695+
/// If the Pointer is null, the flag has no meaning.
696+
std::pair<const CXXRecordDecl *, bool> getDeclForDynamicType() const;
696697

697698
public:
698699
/// Returns the expression representing the implicit 'this' object.

clang/lib/StaticAnalyzer/Core/CallEvent.cpp

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,7 @@ void CXXInstanceCall::getExtraInvalidatedValues(
715715
// Get the record decl for the class of 'This'. D->getParent() may return
716716
// a base class decl, rather than the class of the instance which needs to
717717
// be checked for mutable fields.
718-
const CXXRecordDecl *ParentRecord = getDeclForDynamicType();
718+
const CXXRecordDecl *ParentRecord = getDeclForDynamicType().first;
719719
if (!ParentRecord || !ParentRecord->hasDefinition())
720720
return;
721721

@@ -747,17 +747,19 @@ SVal CXXInstanceCall::getCXXThisVal() const {
747747
return ThisVal;
748748
}
749749

750-
const CXXRecordDecl *CXXInstanceCall::getDeclForDynamicType() const {
750+
std::pair<const CXXRecordDecl *, bool>
751+
CXXInstanceCall::getDeclForDynamicType() const {
751752
const MemRegion *R = getCXXThisVal().getAsRegion();
752753
if (!R)
753-
return nullptr;
754+
return {};
754755

755756
DynamicTypeInfo DynType = getDynamicTypeInfo(getState(), R);
756757
if (!DynType.isValid())
757-
return nullptr;
758+
return {};
758759

759760
assert(!DynType.getType()->getPointeeType().isNull());
760-
return DynType.getType()->getPointeeCXXRecordDecl();
761+
return {DynType.getType()->getPointeeCXXRecordDecl(),
762+
DynType.canBeASubClass()};
761763
}
762764

763765
RuntimeDefinition CXXInstanceCall::getRuntimeDefinition() const {
@@ -771,7 +773,7 @@ RuntimeDefinition CXXInstanceCall::getRuntimeDefinition() const {
771773
if (!MD->isVirtual())
772774
return AnyFunctionCall::getRuntimeDefinition();
773775

774-
const CXXRecordDecl *RD = getDeclForDynamicType();
776+
auto [RD, CanBeSubClass] = getDeclForDynamicType();
775777
if (!RD || !RD->hasDefinition())
776778
return {};
777779

@@ -795,23 +797,20 @@ RuntimeDefinition CXXInstanceCall::getRuntimeDefinition() const {
795797
return {};
796798
}
797799

798-
const MemRegion *R = getCXXThisVal().getAsRegion();
799-
DynamicTypeInfo DynType = getDynamicTypeInfo(getState(), R);
800-
assert(DynType.isValid() && "ensured by getDeclForDynamicType()");
801-
802800
// Does the decl that we found have an implementation?
803801
const FunctionDecl *Definition;
804802
if (!Result->hasBody(Definition)) {
805-
if (!DynType.canBeASubClass())
803+
if (!CanBeSubClass)
806804
return AnyFunctionCall::getRuntimeDefinition();
807805
return {};
808806
}
809807

810808
// We found a definition. If we're not sure that this devirtualization is
811809
// actually what will happen at runtime, make sure to provide the region so
812810
// that ExprEngine can decide what to do with it.
813-
if (DynType.canBeASubClass())
814-
return RuntimeDefinition(Definition, R->StripCasts());
811+
if (CanBeSubClass)
812+
return RuntimeDefinition(Definition,
813+
getCXXThisVal().getAsRegion()->StripCasts());
815814
return RuntimeDefinition(Definition, /*DispatchRegion=*/nullptr);
816815
}
817816

0 commit comments

Comments
 (0)