diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h @@ -72,9 +72,6 @@ /// 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 @@ SVal evalCastSubKind(nonloc::PointerToMember V, QualType CastTy, QualType OriginalTy); -public: - // FIXME: Make these protected again once RegionStoreManager correctly - // handles loads from different 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 --- a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp @@ -107,7 +107,7 @@ return val; } - return evalCastFromNonLoc(val.castAs(), 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 --- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -22,11 +22,6 @@ 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 @@ 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()) - return val; - - if (Optional LI = val.getAs()) { - 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 - // different 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()) - return UnknownVal(); - - // Handle casts to a boolean type. - if (castTy->isBooleanType()) { - bool b = val.castAs().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().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().getRegion(); - if (const FunctionCodeRegion *FTR = dyn_cast(R)) - if (const FunctionDecl *FD = dyn_cast(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()) - return makeLocAsInteger(val, BitWidth); - - llvm::APSInt i = val.castAs().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 @@ } // 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 @@ 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 @@ 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 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 @@ 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 ResultVal = lhs.castAs().evalBinOp(BasicVals, op, *rInt); if (Optional Result = ResultVal.getAs()) - return evalCastFromNonLoc(*Result, resultTy); + return evalCast(*Result, resultTy, QualType{}); assert(!ResultVal.getAs() && "Loc-Loc ops should not produce Locs"); return UnknownVal(); @@ -950,11 +818,11 @@ // 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 l = evalCast(lhs, boolType, QualType{}).castAs(); NonLoc r = makeTruthVal(false, boolType).castAs(); return evalBinOpNN(state, op, l, r, resultTy); } @@ -1036,7 +904,7 @@ Optional LeftIndex = LeftIndexVal.getAs(); if (!LeftIndex) return UnknownVal(); - LeftIndexVal = evalCastFromNonLoc(*LeftIndex, ArrayIndexTy); + LeftIndexVal = evalCast(*LeftIndex, ArrayIndexTy, QualType{}); LeftIndex = LeftIndexVal.getAs(); if (!LeftIndex) return UnknownVal(); @@ -1046,7 +914,7 @@ Optional RightIndex = RightIndexVal.getAs(); if (!RightIndex) return UnknownVal(); - RightIndexVal = evalCastFromNonLoc(*RightIndex, ArrayIndexTy); + RightIndexVal = evalCast(*RightIndex, ArrayIndexTy, QualType{}); RightIndex = RightIndexVal.getAs(); if (!RightIndex) return UnknownVal();