Author: Denys Petrov Date: 2021-04-13T18:56:04+03:00 New Revision: 01ddfa95bd14b35c5706cc5d69fe64b4b60526e3
URL: https://github.com/llvm/llvm-project/commit/01ddfa95bd14b35c5706cc5d69fe64b4b60526e3 DIFF: https://github.com/llvm/llvm-project/commit/01ddfa95bd14b35c5706cc5d69fe64b4b60526e3.diff LOG: [analyzer] [NFC] Eliminate dispatchCast, evalCastFromNonLoc and evalCastFromLoc functions from SValBuilder Summary: Remove dispatchCast, evalCastFromNonLoc and evalCastFromLoc functions since their functionality has been moved to common evalCast function. Use evalCast instead. Post-clean up patch for https://reviews.llvm.org/D96090 patch. The patch shall not change any behavior. Differential Revision: https://reviews.llvm.org/D97277 Added: Modified: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h clang/lib/StaticAnalyzer/Core/SValBuilder.cpp clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp Removed: ################################################################################ diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h index 2358d2d66b30..99277e91ed06 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h @@ -72,9 +72,6 @@ class SValBuilder { /// The width of the scalar type used for array indices. const unsigned ArrayIndexWidth; - virtual SVal evalCastFromNonLoc(NonLoc val, QualType castTy) = 0; - virtual SVal evalCastFromLoc(Loc val, QualType castTy) = 0; - SVal evalCastKind(UndefinedVal V, QualType CastTy, QualType OriginalTy); SVal evalCastKind(UnknownVal V, QualType CastTy, QualType OriginalTy); SVal evalCastKind(Loc V, QualType CastTy, QualType OriginalTy); @@ -97,11 +94,6 @@ class SValBuilder { SVal evalCastSubKind(nonloc::PointerToMember V, QualType CastTy, QualType OriginalTy); -public: - // FIXME: Make these protected again once RegionStoreManager correctly - // handles loads from diff erent bound value types. - virtual SVal dispatchCast(SVal val, QualType castTy) = 0; - public: SValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context, ProgramStateManager &stateMgr) diff --git a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp index 9a9edb25f2d7..a49099384d2a 100644 --- a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp @@ -107,7 +107,7 @@ SVal SValBuilder::convertToArrayIndex(SVal val) { return val; } - return evalCastFromNonLoc(val.castAs<NonLoc>(), ArrayIndexTy); + return evalCast(val, ArrayIndexTy, QualType{}); } nonloc::ConcreteInt SValBuilder::makeBoolVal(const CXXBoolLiteralExpr *boolean){ diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index 7fe2374c9914..e57d92fbcebb 100644 --- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -22,11 +22,6 @@ using namespace ento; namespace { class SimpleSValBuilder : public SValBuilder { -protected: - SVal dispatchCast(SVal val, QualType castTy) override; - SVal evalCastFromNonLoc(NonLoc val, QualType castTy) override; - SVal evalCastFromLoc(Loc val, QualType castTy) override; - public: SimpleSValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context, ProgramStateManager &stateMgr) @@ -61,134 +56,6 @@ SValBuilder *ento::createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc, return new SimpleSValBuilder(alloc, context, stateMgr); } -//===----------------------------------------------------------------------===// -// Transfer function for Casts. -//===----------------------------------------------------------------------===// - -// FIXME: This function should be eliminated and replaced with `evalCast` -SVal SimpleSValBuilder::dispatchCast(SVal Val, QualType CastTy) { - return evalCast(Val, CastTy, QualType{}); -} - -// FIXME: This function should be eliminated and replaced with `evalCast` -SVal SimpleSValBuilder::evalCastFromNonLoc(NonLoc val, QualType castTy) { - bool isLocType = Loc::isLocType(castTy); - if (val.getAs<nonloc::PointerToMember>()) - return val; - - if (Optional<nonloc::LocAsInteger> LI = val.getAs<nonloc::LocAsInteger>()) { - if (isLocType) - return LI->getLoc(); - // FIXME: Correctly support promotions/truncations. - unsigned castSize = Context.getIntWidth(castTy); - if (castSize == LI->getNumBits()) - return val; - return makeLocAsInteger(LI->getLoc(), castSize); - } - - if (SymbolRef se = val.getAsSymbol()) { - QualType T = Context.getCanonicalType(se->getType()); - // If types are the same or both are integers, ignore the cast. - // FIXME: Remove this hack when we support symbolic truncation/extension. - // HACK: If both castTy and T are integers, ignore the cast. This is - // not a permanent solution. Eventually we want to precisely handle - // extension/truncation of symbolic integers. This prevents us from losing - // precision when we assign 'x = y' and 'y' is symbolic and x and y are - // diff erent integer types. - if (haveSameType(T, castTy)) - return val; - - if (!isLocType) - return makeNonLoc(se, T, castTy); - return UnknownVal(); - } - - // If value is a non-integer constant, produce unknown. - if (!val.getAs<nonloc::ConcreteInt>()) - return UnknownVal(); - - // Handle casts to a boolean type. - if (castTy->isBooleanType()) { - bool b = val.castAs<nonloc::ConcreteInt>().getValue().getBoolValue(); - return makeTruthVal(b, castTy); - } - - // Only handle casts from integers to integers - if val is an integer constant - // being cast to a non-integer type, produce unknown. - if (!isLocType && !castTy->isIntegralOrEnumerationType()) - return UnknownVal(); - - llvm::APSInt i = val.castAs<nonloc::ConcreteInt>().getValue(); - BasicVals.getAPSIntType(castTy).apply(i); - - if (isLocType) - return makeIntLocVal(i); - else - return makeIntVal(i); -} - -// FIXME: This function should be eliminated and replaced with `evalCast` -SVal SimpleSValBuilder::evalCastFromLoc(Loc val, QualType castTy) { - - // Casts from pointers -> pointers, just return the lval. - // - // Casts from pointers -> references, just return the lval. These - // can be introduced by the frontend for corner cases, e.g - // casting from va_list* to __builtin_va_list&. - // - if (Loc::isLocType(castTy) || castTy->isReferenceType()) - return val; - - // FIXME: Handle transparent unions where a value can be "transparently" - // lifted into a union type. - if (castTy->isUnionType()) - return UnknownVal(); - - // Casting a Loc to a bool will almost always be true, - // unless this is a weak function or a symbolic region. - if (castTy->isBooleanType()) { - switch (val.getSubKind()) { - case loc::MemRegionValKind: { - const MemRegion *R = val.castAs<loc::MemRegionVal>().getRegion(); - if (const FunctionCodeRegion *FTR = dyn_cast<FunctionCodeRegion>(R)) - if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(FTR->getDecl())) - if (FD->isWeak()) - // FIXME: Currently we are using an extent symbol here, - // because there are no generic region address metadata - // symbols to use, only content metadata. - return nonloc::SymbolVal(SymMgr.getExtentSymbol(FTR)); - - if (const SymbolicRegion *SymR = R->getSymbolicBase()) - return makeNonLoc(SymR->getSymbol(), BO_NE, - BasicVals.getZeroWithPtrWidth(), castTy); - - // FALL-THROUGH - LLVM_FALLTHROUGH; - } - - case loc::GotoLabelKind: - // Labels and non-symbolic memory regions are always true. - return makeTruthVal(true, castTy); - } - } - - if (castTy->isIntegralOrEnumerationType()) { - unsigned BitWidth = Context.getIntWidth(castTy); - - if (!val.getAs<loc::ConcreteInt>()) - return makeLocAsInteger(val, BitWidth); - - llvm::APSInt i = val.castAs<loc::ConcreteInt>().getValue(); - BasicVals.getAPSIntType(castTy).apply(i); - return makeIntVal(i); - } - - // All other cases: return 'UnknownVal'. This includes casting pointers - // to floats, which is probably badness it itself, but this is a good - // intermediate solution until we do something better. - return UnknownVal(); -} - //===----------------------------------------------------------------------===// // Transfer function for unary operators. //===----------------------------------------------------------------------===// @@ -277,10 +144,10 @@ SVal SimpleSValBuilder::MakeSymIntVal(const SymExpr *LHS, } // Idempotent ops (like a*1) can still change the type of an expression. - // Wrap the LHS up in a NonLoc again and let evalCastFromNonLoc do the + // Wrap the LHS up in a NonLoc again and let evalCast do the // dirty work. if (isIdempotent) - return evalCastFromNonLoc(nonloc::SymbolVal(LHS), resultTy); + return evalCast(nonloc::SymbolVal(LHS), resultTy, QualType{}); // If we reach this point, the expression cannot be simplified. // Make a SymbolVal for the entire expression, after converting the RHS. @@ -526,10 +393,11 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state, case BO_Sub: if (resultTy->isIntegralOrEnumerationType()) return makeIntVal(0, resultTy); - return evalCastFromNonLoc(makeIntVal(0, /*isUnsigned=*/false), resultTy); + return evalCast(makeIntVal(0, /*isUnsigned=*/false), resultTy, + QualType{}); case BO_Or: case BO_And: - return evalCastFromNonLoc(lhs, resultTy); + return evalCast(lhs, resultTy, QualType{}); } while (1) { @@ -646,12 +514,12 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state, case BO_Shr: // (~0)>>a if (LHSValue.isAllOnesValue() && LHSValue.isSigned()) - return evalCastFromNonLoc(lhs, resultTy); + return evalCast(lhs, resultTy, QualType{}); LLVM_FALLTHROUGH; case BO_Shl: // 0<<a and 0>>a if (LHSValue == 0) - return evalCastFromNonLoc(lhs, resultTy); + return evalCast(lhs, resultTy, QualType{}); return makeSymExprValNN(op, InputLHS, InputRHS, resultTy); case BO_Div: // 0 / x == 0 @@ -868,7 +736,7 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state, default: break; case BO_Sub: - return evalCastFromLoc(lhs, resultTy); + return evalCast(lhs, resultTy, QualType{}); case BO_EQ: case BO_LE: case BO_LT: @@ -905,7 +773,7 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state, SVal ResultVal = lhs.castAs<loc::ConcreteInt>().evalBinOp(BasicVals, op, *rInt); if (Optional<NonLoc> Result = ResultVal.getAs<NonLoc>()) - return evalCastFromNonLoc(*Result, resultTy); + return evalCast(*Result, resultTy, QualType{}); assert(!ResultVal.getAs<Loc>() && "Loc-Loc ops should not produce Locs"); return UnknownVal(); @@ -950,11 +818,11 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state, // to be non-NULL. if (rInt->isZeroConstant()) { if (op == BO_Sub) - return evalCastFromLoc(lhs, resultTy); + return evalCast(lhs, resultTy, QualType{}); if (BinaryOperator::isComparisonOp(op)) { QualType boolType = getContext().BoolTy; - NonLoc l = evalCastFromLoc(lhs, boolType).castAs<NonLoc>(); + NonLoc l = evalCast(lhs, boolType, QualType{}).castAs<NonLoc>(); NonLoc r = makeTruthVal(false, boolType).castAs<NonLoc>(); return evalBinOpNN(state, op, l, r, resultTy); } @@ -1036,7 +904,7 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state, Optional<NonLoc> LeftIndex = LeftIndexVal.getAs<NonLoc>(); if (!LeftIndex) return UnknownVal(); - LeftIndexVal = evalCastFromNonLoc(*LeftIndex, ArrayIndexTy); + LeftIndexVal = evalCast(*LeftIndex, ArrayIndexTy, QualType{}); LeftIndex = LeftIndexVal.getAs<NonLoc>(); if (!LeftIndex) return UnknownVal(); @@ -1046,7 +914,7 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state, Optional<NonLoc> RightIndex = RightIndexVal.getAs<NonLoc>(); if (!RightIndex) return UnknownVal(); - RightIndexVal = evalCastFromNonLoc(*RightIndex, ArrayIndexTy); + RightIndexVal = evalCast(*RightIndex, ArrayIndexTy, QualType{}); RightIndex = RightIndexVal.getAs<NonLoc>(); if (!RightIndex) return UnknownVal(); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits