diff options
Diffstat (limited to 'clang/lib/StaticAnalyzer')
11 files changed, 202 insertions, 54 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp index b304350..7cc146e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp @@ -246,7 +246,7 @@ public: bool Find(const TypedValueRegion *R) { QualType T = R->getValueType(); if (const RecordType *RT = T->getAsStructureType()) { - const RecordDecl *RD = RT->getOriginalDecl()->getDefinition(); + const RecordDecl *RD = RT->getDecl()->getDefinition(); assert(RD && "Referred record has no definition"); for (const auto *I : RD->fields()) { if (I->isUnnamedBitField()) diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp index 17af1ae..5e75c1c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp @@ -154,15 +154,15 @@ void WalkAST::VisitCallExpr(CallExpr *CE) { .Case("mkstemp", &WalkAST::checkCall_mkstemp) .Case("mkdtemp", &WalkAST::checkCall_mkstemp) .Case("mkstemps", &WalkAST::checkCall_mkstemp) - .Cases("strcpy", "__strcpy_chk", &WalkAST::checkCall_strcpy) - .Cases("strcat", "__strcat_chk", &WalkAST::checkCall_strcat) - .Cases("sprintf", "vsprintf", "scanf", "wscanf", "fscanf", "fwscanf", - "vscanf", "vwscanf", "vfscanf", "vfwscanf", + .Cases({"strcpy", "__strcpy_chk"}, &WalkAST::checkCall_strcpy) + .Cases({"strcat", "__strcat_chk"}, &WalkAST::checkCall_strcat) + .Cases({"sprintf", "vsprintf", "scanf", "wscanf", "fscanf", "fwscanf", + "vscanf", "vwscanf", "vfscanf", "vfwscanf"}, &WalkAST::checkDeprecatedOrUnsafeBufferHandling) - .Cases("sscanf", "swscanf", "vsscanf", "vswscanf", "swprintf", - "snprintf", "vswprintf", "vsnprintf", "memcpy", "memmove", + .Cases({"sscanf", "swscanf", "vsscanf", "vswscanf", "swprintf", + "snprintf", "vswprintf", "vsnprintf", "memcpy", "memmove"}, &WalkAST::checkDeprecatedOrUnsafeBufferHandling) - .Cases("strncpy", "strncat", "memset", "fprintf", + .Cases({"strncpy", "strncat", "memset", "fprintf"}, &WalkAST::checkDeprecatedOrUnsafeBufferHandling) .Case("drand48", &WalkAST::checkCall_rand) .Case("erand48", &WalkAST::checkCall_rand) @@ -766,12 +766,14 @@ void WalkAST::checkDeprecatedOrUnsafeBufferHandling(const CallExpr *CE, int ArgIndex = llvm::StringSwitch<int>(Name) - .Cases("scanf", "wscanf", "vscanf", "vwscanf", 0) - .Cases("fscanf", "fwscanf", "vfscanf", "vfwscanf", "sscanf", - "swscanf", "vsscanf", "vswscanf", 1) - .Cases("sprintf", "vsprintf", "fprintf", 1) - .Cases("swprintf", "snprintf", "vswprintf", "vsnprintf", "memcpy", - "memmove", "memset", "strncpy", "strncat", DEPR_ONLY) + .Cases({"scanf", "wscanf", "vscanf", "vwscanf"}, 0) + .Cases({"fscanf", "fwscanf", "vfscanf", "vfwscanf", "sscanf", + "swscanf", "vsscanf", "vswscanf"}, + 1) + .Cases({"sprintf", "vsprintf", "fprintf"}, 1) + .Cases({"swprintf", "snprintf", "vswprintf", "vsnprintf", "memcpy", + "memmove", "memset", "strncpy", "strncat"}, + DEPR_ONLY) .Default(UNKNOWN_CALL); assert(ArgIndex != UNKNOWN_CALL && "Unsupported function"); diff --git a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp index 395d724..37f5ec3 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp @@ -19,6 +19,7 @@ #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/raw_ostream.h" using namespace clang; @@ -39,9 +40,10 @@ public: class DereferenceChecker : public CheckerFamily<check::Location, check::Bind, + check::PreStmt<BinaryOperator>, EventDispatcher<ImplicitNullDerefEvent>> { - void reportBug(const DerefBugType &BT, ProgramStateRef State, const Stmt *S, - CheckerContext &C) const; + void reportDerefBug(const DerefBugType &BT, ProgramStateRef State, + const Stmt *S, CheckerContext &C) const; bool suppressReport(CheckerContext &C, const Expr *E) const; @@ -50,6 +52,7 @@ public: CheckerContext &C) const; void checkBind(SVal L, SVal V, const Stmt *S, bool AtDeclInit, CheckerContext &C) const; + void checkPreStmt(const BinaryOperator *Op, CheckerContext &C) const; static void AddDerefSource(raw_ostream &os, SmallVectorImpl<SourceRange> &Ranges, @@ -57,7 +60,7 @@ public: const LocationContext *LCtx, bool loadedFrom = false); - CheckerFrontend NullDerefChecker, FixedDerefChecker; + CheckerFrontend NullDerefChecker, FixedDerefChecker, NullPointerArithmChecker; const DerefBugType NullBug{&NullDerefChecker, "Dereference of null pointer", "a null pointer dereference", "a dereference of a null pointer"}; @@ -72,9 +75,22 @@ public: const DerefBugType FixedAddressBug{&FixedDerefChecker, "Dereference of a fixed address", "a dereference of a fixed address"}; + const BugType NullPointerArithmBug{ + &NullPointerArithmChecker, + "Possibly undefined arithmetic operation involving a null pointer"}; StringRef getDebugTag() const override { return "DereferenceChecker"; } }; + +struct ValueDescStr { + SmallVectorImpl<SourceRange> &Ranges; + const Expr *Ex; + const ProgramState *State; + const LocationContext *LCtx; + bool IsPointer; + ConditionTruthVal IsNull; +}; + } // end anonymous namespace void @@ -173,9 +189,9 @@ static bool isDeclRefExprToReference(const Expr *E) { return false; } -void DereferenceChecker::reportBug(const DerefBugType &BT, - ProgramStateRef State, const Stmt *S, - CheckerContext &C) const { +void DereferenceChecker::reportDerefBug(const DerefBugType &BT, + ProgramStateRef State, const Stmt *S, + CheckerContext &C) const { if (&BT == &FixedAddressBug) { if (!FixedDerefChecker.isEnabled()) // Deliberately don't add a sink node if check is disabled. @@ -249,9 +265,8 @@ void DereferenceChecker::reportBug(const DerefBugType &BT, bugreporter::trackExpressionValue(N, bugreporter::getDerefExpr(S), *BR); - for (SmallVectorImpl<SourceRange>::iterator - I = Ranges.begin(), E = Ranges.end(); I!=E; ++I) - BR->addRange(*I); + for (const auto &R : Ranges) + BR->addRange(R); C.emitReport(std::move(BR)); } @@ -262,7 +277,7 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S, if (l.isUndef()) { const Expr *DerefExpr = getDereferenceExpr(S); if (!suppressReport(C, DerefExpr)) - reportBug(UndefBug, C.getState(), DerefExpr, C); + reportDerefBug(UndefBug, C.getState(), DerefExpr, C); return; } @@ -283,7 +298,7 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S, // we call an "explicit" null dereference. const Expr *expr = getDereferenceExpr(S); if (!suppressReport(C, expr)) { - reportBug(NullBug, nullState, expr, C); + reportDerefBug(NullBug, nullState, expr, C); return; } } @@ -301,7 +316,7 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S, if (location.isConstant()) { const Expr *DerefExpr = getDereferenceExpr(S, isLoad); if (!suppressReport(C, DerefExpr)) - reportBug(FixedAddressBug, notNullState, DerefExpr, C); + reportDerefBug(FixedAddressBug, notNullState, DerefExpr, C); return; } @@ -317,7 +332,7 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S, // One should never write to label addresses. if (auto Label = L.getAs<loc::GotoLabel>()) { - reportBug(LabelBug, C.getState(), S, C); + reportDerefBug(LabelBug, C.getState(), S, C); return; } @@ -338,7 +353,7 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S, if (!StNonNull) { const Expr *expr = getDereferenceExpr(S, /*IsBind=*/true); if (!suppressReport(C, expr)) { - reportBug(NullBug, StNull, expr, C); + reportDerefBug(NullBug, StNull, expr, C); return; } } @@ -356,7 +371,7 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S, if (V.isConstant()) { const Expr *DerefExpr = getDereferenceExpr(S, true); if (!suppressReport(C, DerefExpr)) - reportBug(FixedAddressBug, State, DerefExpr, C); + reportDerefBug(FixedAddressBug, State, DerefExpr, C); return; } @@ -379,6 +394,96 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S, C.addTransition(State, this); } +namespace llvm { +template <> struct format_provider<ValueDescStr> { + static void format(const ValueDescStr &V, raw_ostream &Stream, + StringRef Style) { + static const char *ValueStr[2][3] = { + {"zero", "nonzero integer value", "probably nonzero integer value"}, + {"null pointer", "non-null pointer", "probably non-null pointer"}, + }; + Stream + << ValueStr[V.IsPointer][V.IsNull.isConstrainedTrue() + ? 0 + : (V.IsNull.isConstrainedFalse() ? 1 : 2)]; + DereferenceChecker::AddDerefSource(Stream, V.Ranges, V.Ex, V.State, V.LCtx, + false); + } +}; +} // namespace llvm + +void DereferenceChecker::checkPreStmt(const BinaryOperator *Op, + CheckerContext &C) const { + if (!Op->isAdditiveOp() || !NullPointerArithmChecker.isEnabled()) + return; + const Expr *E1 = Op->getLHS(); + const Expr *E2 = Op->getRHS(); + QualType T1 = E1->getType().getCanonicalType(); + QualType T2 = E2->getType().getCanonicalType(); + bool T1IsPointer = T1->isPointerType(); + bool T2IsPointer = T2->isPointerType(); + if (T1->isIntegerType() && T2->isIntegerType()) + return; + if (!T1IsPointer && !T1->isIntegerType() && !T2IsPointer && + !T2->isIntegerType()) + return; + + ProgramStateRef State = C.getState(); + ConditionTruthVal V1IsNull = State->isNull(C.getSVal(E1)); + ConditionTruthVal V2IsNull = State->isNull(C.getSVal(E2)); + bool IsConstrained = true; + + // Check cases 'NULL + x' and 'NULL - x' + if (T1IsPointer && !T2IsPointer) { + if (!V1IsNull.isConstrainedTrue() || V2IsNull.isConstrainedTrue()) + return; + IsConstrained = V2IsNull.isConstrainedFalse(); + } + + // Check case 'x + NULL' + if (!T1IsPointer && T2IsPointer) { + if (V1IsNull.isConstrainedTrue() || !V2IsNull.isConstrainedTrue()) + return; + IsConstrained = V1IsNull.isConstrainedFalse(); + } + + // Check case 'NULL - p' or 'p - NULL' + if (T1IsPointer && T2IsPointer) { + if (!V1IsNull.isConstrainedTrue() && !V2IsNull.isConstrainedTrue()) + return; + if (V1IsNull.isConstrainedTrue() && V2IsNull.isConstrainedTrue()) + return; + IsConstrained = + V1IsNull.isConstrainedFalse() || V2IsNull.isConstrainedFalse(); + } + + SmallVector<SourceRange, 2> Ranges; + const char *OpcodeStr = + Op->getOpcode() == BO_Add ? "Addition" : "Subtraction"; + const char *ResultStr = IsConstrained ? "results" : "may result"; + ValueDescStr DerefArg1{ + Ranges, E1, State.get(), C.getLocationContext(), T1IsPointer, V1IsNull}; + ValueDescStr DerefArg2{ + Ranges, E2, State.get(), C.getLocationContext(), T2IsPointer, V2IsNull}; + std::string Msg = + llvm::formatv("{0} of a {1} and a {2} {3} in undefined behavior", + OpcodeStr, DerefArg1, DerefArg2, ResultStr); + + ExplodedNode *N = C.generateErrorNode(State); + if (!N) + return; + auto BR = + std::make_unique<PathSensitiveBugReport>(NullPointerArithmBug, Msg, N); + if (V1IsNull.isConstrainedTrue()) + bugreporter::trackExpressionValue(N, E1, *BR); + if (V2IsNull.isConstrainedTrue()) + bugreporter::trackExpressionValue(N, E2, *BR); + for (const auto &R : Ranges) + BR->addRange(R); + + C.emitReport(std::move(BR)); +} + void ento::registerNullDereferenceChecker(CheckerManager &Mgr) { Mgr.getChecker<DereferenceChecker>()->NullDerefChecker.enable(Mgr); } @@ -395,3 +500,11 @@ bool ento::shouldRegisterFixedAddressDereferenceChecker( const CheckerManager &) { return true; } + +void ento::registerNullPointerArithmChecker(CheckerManager &Mgr) { + Mgr.getChecker<DereferenceChecker>()->NullPointerArithmChecker.enable(Mgr); +} + +bool ento::shouldRegisterNullPointerArithmChecker(const CheckerManager &) { + return true; +} diff --git a/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp index b1a7cd7..bc67391 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp @@ -148,9 +148,8 @@ void NonNullParamChecker::checkPreCall(const CallEvent &Call, QualType T = ArgE->getType(); const RecordType *UT = T->getAsUnionType(); - if (!UT || !UT->getOriginalDecl() - ->getMostRecentDecl() - ->hasAttr<TransparentUnionAttr>()) + if (!UT || + !UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) continue; auto CSV = DV->getAs<nonloc::CompoundVal>(); diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp index c1a5000..419d263 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp @@ -164,7 +164,9 @@ bool tryToFindPtrOrigin( auto Name = safeGetName(callee); if (Name == "__builtin___CFStringMakeConstantString" || - Name == "NSClassFromString") + Name == "NSStringFromSelector" || Name == "NSSelectorFromString" || + Name == "NSStringFromClass" || Name == "NSClassFromString" || + Name == "NSStringFromProtocol" || Name == "NSProtocolFromString") return callback(E, true); } else if (auto *CalleeE = call->getCallee()) { if (auto *E = dyn_cast<DeclRefExpr>(CalleeE->IgnoreParenCasts())) { @@ -182,7 +184,7 @@ bool tryToFindPtrOrigin( if (auto *Subst = dyn_cast<SubstTemplateTypeParmType>(RetType)) { if (auto *SubstType = Subst->desugar().getTypePtr()) { if (auto *RD = dyn_cast<RecordType>(SubstType)) { - if (auto *CXX = dyn_cast<CXXRecordDecl>(RD->getOriginalDecl())) + if (auto *CXX = dyn_cast<CXXRecordDecl>(RD->getDecl())) if (isSafePtr(CXX)) return callback(E, true); } @@ -202,6 +204,8 @@ bool tryToFindPtrOrigin( !Selector.getNumArgs()) return callback(E, true); } + if (auto *ObjCProtocol = dyn_cast<ObjCProtocolExpr>(E)) + return callback(ObjCProtocol, true); if (auto *ObjCDict = dyn_cast<ObjCDictionaryLiteral>(E)) return callback(ObjCDict, true); if (auto *ObjCArray = dyn_cast<ObjCArrayLiteral>(E)) diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ForwardDeclChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/ForwardDeclChecker.cpp index d8539ea..1d4e6dd 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ForwardDeclChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ForwardDeclChecker.cpp @@ -263,18 +263,43 @@ public: void visitCallArg(const Expr *Arg, const ParmVarDecl *Param, const Decl *DeclWithIssue) const { auto *ArgExpr = Arg->IgnoreParenCasts(); - if (auto *InnerCE = dyn_cast<CallExpr>(Arg)) { - auto *InnerCallee = InnerCE->getDirectCallee(); - if (InnerCallee && InnerCallee->isInStdNamespace() && - safeGetName(InnerCallee) == "move" && InnerCE->getNumArgs() == 1) { - ArgExpr = InnerCE->getArg(0); - if (ArgExpr) - ArgExpr = ArgExpr->IgnoreParenCasts(); + while (ArgExpr) { + ArgExpr = ArgExpr->IgnoreParenCasts(); + if (auto *InnerCE = dyn_cast<CallExpr>(ArgExpr)) { + auto *InnerCallee = InnerCE->getDirectCallee(); + if (InnerCallee && InnerCallee->isInStdNamespace() && + safeGetName(InnerCallee) == "move" && InnerCE->getNumArgs() == 1) { + ArgExpr = InnerCE->getArg(0); + continue; + } + } + if (auto *UO = dyn_cast<UnaryOperator>(ArgExpr)) { + auto OpCode = UO->getOpcode(); + if (OpCode == UO_Deref || OpCode == UO_AddrOf) { + ArgExpr = UO->getSubExpr(); + continue; + } } + break; } + + if (auto *MemberCallExpr = dyn_cast<CXXMemberCallExpr>(ArgExpr)) { + if (isOwnerPtrType(MemberCallExpr->getObjectType())) + return; + } + + if (auto *OpCE = dyn_cast<CXXOperatorCallExpr>(ArgExpr)) { + auto *Method = dyn_cast_or_null<CXXMethodDecl>(OpCE->getDirectCallee()); + if (Method && isOwnerPtr(safeGetName(Method->getParent()))) { + if (OpCE->getOperator() == OO_Star && OpCE->getNumArgs() == 1) + return; + } + } + if (isNullPtr(ArgExpr) || isa<IntegerLiteral>(ArgExpr) || isa<CXXDefaultArgExpr>(ArgExpr)) return; + if (auto *DRE = dyn_cast<DeclRefExpr>(ArgExpr)) { if (auto *ValDecl = DRE->getDecl()) { if (isa<ParmVarDecl>(ValDecl)) diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp index e5c74bb..d3d1f13 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp @@ -138,6 +138,11 @@ bool isCheckedPtr(const std::string &Name) { return Name == "CheckedPtr" || Name == "CheckedRef"; } +bool isOwnerPtr(const std::string &Name) { + return isRefType(Name) || isCheckedPtr(Name) || Name == "unique_ptr" || + Name == "UniqueRef" || Name == "LazyUniqueRef"; +} + bool isSmartPtrClass(const std::string &Name) { return isRefType(Name) || isCheckedPtr(Name) || isRetainPtrOrOSPtr(Name) || Name == "WeakPtr" || Name == "WeakPtrFactory" || @@ -206,10 +211,7 @@ bool isRetainPtrOrOSPtrType(const clang::QualType T) { } bool isOwnerPtrType(const clang::QualType T) { - return isPtrOfType(T, [](auto Name) { - return isRefType(Name) || isCheckedPtr(Name) || Name == "unique_ptr" || - Name == "UniqueRef" || Name == "LazyUniqueRef"; - }); + return isPtrOfType(T, [](auto Name) { return isOwnerPtr(Name); }); } std::optional<bool> isUncounted(const QualType T) { @@ -255,7 +257,7 @@ void RetainTypeChecker::visitTypedef(const TypedefDecl *TD) { return; } - for (auto *Redecl : RT->getOriginalDecl()->getMostRecentDecl()->redecls()) { + for (auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) { if (Redecl->getAttr<ObjCBridgeAttr>() || Redecl->getAttr<ObjCBridgeMutableAttr>()) { CFPointees.insert(RT); @@ -296,7 +298,7 @@ std::optional<bool> isUnretained(const QualType T, bool IsARCEnabled) { auto *Record = PointeeType->getAsStructureType(); if (!Record) return false; - auto *Decl = Record->getOriginalDecl(); + auto *Decl = Record->getDecl(); if (!Decl) return false; auto TypeName = Decl->getName(); diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h index 8300a6c..12e2e2d 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h @@ -143,6 +143,10 @@ bool isCheckedPtr(const std::string &Name); /// \returns true if \p Name is RetainPtr or its variant, false if not. bool isRetainPtrOrOSPtr(const std::string &Name); +/// \returns true if \p Name is an owning smar pointer such as Ref, CheckedPtr, +/// and unique_ptr. +bool isOwnerPtr(const std::string &Name); + /// \returns true if \p Name is a smart pointer type name, false if not. bool isSmartPtrClass(const std::string &Name); diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp index 6f3a280..c6421f8 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp @@ -121,13 +121,13 @@ public: return true; } } else if (auto *RD = dyn_cast<RecordType>(PointeeType)) { - if (declaresSameEntity(RD->getOriginalDecl(), ClassDecl)) + if (declaresSameEntity(RD->getDecl(), ClassDecl)) return true; } else if (auto *ST = dyn_cast<SubstTemplateTypeParmType>(PointeeType)) { auto Type = ST->getReplacementType(); if (auto *RD = dyn_cast<RecordType>(Type)) { - if (declaresSameEntity(RD->getOriginalDecl(), ClassDecl)) + if (declaresSameEntity(RD->getDecl(), ClassDecl)) return true; } } diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp index 06ba015..62460cc 100644 --- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -89,7 +89,7 @@ static bool isCallback(QualType T) { T = T->getPointeeType(); if (const RecordType *RT = T->getAsStructureType()) { - const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); + const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf(); for (const auto *I : RD->fields()) { QualType FieldT = I->getType(); if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType()) @@ -391,9 +391,8 @@ bool CallEvent::isVariadic(const Decl *D) { static bool isTransparentUnion(QualType T) { const RecordType *UT = T->getAsUnionType(); - return UT && UT->getOriginalDecl() - ->getMostRecentDecl() - ->hasAttr<TransparentUnionAttr>(); + return UT && + UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>(); } // In some cases, symbolic cases should be transformed before we associate diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index af0ef52..2838533 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -2457,7 +2457,7 @@ NonLoc RegionStoreManager::createLazyBinding(RegionBindingsConstRef B, SVal RegionStoreManager::getBindingForStruct(RegionBindingsConstRef B, const TypedValueRegion *R) { const RecordDecl *RD = - R->getValueType()->castAsCanonical<RecordType>()->getOriginalDecl(); + R->getValueType()->castAsCanonical<RecordType>()->getDecl(); if (!RD->getDefinition()) return UnknownVal(); |