Exemple #1
0
PathDiagnosticPiece *
ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
                                  const DeclRefExpr *DR,
                                  const bool tookTrue,
                                  BugReporterContext &BRC,
                                  const LocationContext *LC) {

    const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
    if (!VD)
        return 0;

    llvm::SmallString<256> Buf;
    llvm::raw_svector_ostream Out(Buf);

    Out << "Assuming '";
    VD->getDeclName().printName(Out);
    Out << "' is ";

    QualType VDTy = VD->getType();

    if (VDTy->isPointerType())
        Out << (tookTrue ? "non-null" : "null");
    else if (VDTy->isObjCObjectPointerType())
        Out << (tookTrue ? "non-nil" : "nil");
    else if (VDTy->isScalarType())
        Out << (tookTrue ? "not equal to 0" : "0");
    else
        return 0;

    PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LC);
    return new PathDiagnosticEventPiece(Loc, Out.str());
}
static bool isTrackedVar(const VarDecl *vd, const DeclContext *dc) {
  if (vd->isLocalVarDecl() && !vd->hasGlobalStorage() &&
      !vd->isExceptionVariable() &&
      vd->getDeclContext() == dc) {
    QualType ty = vd->getType();
    return ty->isScalarType() || ty->isVectorType();
  }
  return false;
}
Exemple #3
0
bool SymbolManager::canSymbolicate(QualType T) {
  if (Loc::IsLocType(T))
    return true;

  if (T->isIntegerType())
    return T->isScalarType();

  if (T->isRecordType())
    return true;

  return false;
}
Exemple #4
0
bool ExprTypeAnalyser::checkExplicitCast(const ExplicitCastExpr* expr, QualType DestType, QualType SrcType) {
    // C99 6.5.4p2: the cast type needs to be void or scalar and the expression

    if (!DestType.isScalarType()) {
        // Dont allow any cast to non-scalar
        StringBuilder buf1(MAX_LEN_TYPENAME);
        StringBuilder buf2(MAX_LEN_TYPENAME);
        DestType.DiagName(buf1);
        SrcType.DiagName(buf2);
        Diags.Report(expr->getLocation(), diag::err_typecheck_cond_expect_scalar)
                << buf1 << buf2 << expr->getSourceRange();
        return false;
    }

    // If either type is a pointer, the other type has to be either an
    // integer or a pointer
    // TODO decide if Enums are arithmatic types or not (they are in C99, not is C++0x)
    if (DestType.isPointerType()) {
        if (SrcType.isPointerType()) {
            // allow all pointer casts
            return true;
        } else {
            // only allow cast to pointer from uint32/64 (pointer size)
            const BuiltinType* BT = dyncast<BuiltinType>(SrcType.getCanonicalType());
            // TODO use TargetInfo to check if 32-bit
            if (BT && BT->getKind() == BuiltinType::UInt64) return true;

            QualType expected = Type::UInt64();
            StringBuilder buf1(MAX_LEN_TYPENAME);
            expected.DiagName(buf1);
            Diags.Report(expr->getLocation(), diag::err_cast_nonword_to_pointer) << buf1;
        }
    } else {
        if (SrcType.isPointerType()) {
            // only allow cast to uint32/64 (pointer size)
            const BuiltinType* BT = dyncast<BuiltinType>(DestType.getCanonicalType());
            // TODO use TargetInfo to check if 32-bit
            if (BT && BT->getKind() == BuiltinType::UInt64) return true;

            QualType expected = Type::UInt64();
            StringBuilder buf1(MAX_LEN_TYPENAME);
            expected.DiagName(buf1);
            Diags.Report(expr->getLocation(), diag::err_cast_pointer_to_nonword) << buf1;
        } else {
            // check non-pointer to non-pointer type
            // TODO make this top level function? (switch on src-type)
            return checkNonPointerCast(expr, DestType, SrcType);
        }
    }
    return false;
}
bool SymbolManager::canSymbolicate(QualType T) {
  T = T.getCanonicalType();

  if (Loc::isLocType(T))
    return true;

  if (T->isIntegerType())
    return T->isScalarType();

  if (T->isRecordType() && !T->isUnionType())
    return true;

  return false;
}
Exemple #6
0
PathDiagnosticPiece *
ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
                                  const DeclRefExpr *DR,
                                  const bool tookTrue,
                                  BugReporterContext &BRC,
                                  BugReport &report,
                                  const ExplodedNode *N) {

  const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
  if (!VD)
    return 0;
  
  SmallString<256> Buf;
  llvm::raw_svector_ostream Out(Buf);
    
  Out << "Assuming '";
  VD->getDeclName().printName(Out);
  Out << "' is ";
    
  QualType VDTy = VD->getType();
  
  if (VDTy->isPointerType())
    Out << (tookTrue ? "non-null" : "null");
  else if (VDTy->isObjCObjectPointerType())
    Out << (tookTrue ? "non-nil" : "nil");
  else if (VDTy->isScalarType())
    Out << (tookTrue ? "not equal to 0" : "0");
  else
    return 0;
  
  const LocationContext *LCtx = N->getLocationContext();
  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
  PathDiagnosticEventPiece *event =
    new PathDiagnosticEventPiece(Loc, Out.str());
  
  const ProgramState *state = N->getState().getPtr();
  if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
    if (report.isInteresting(R))
      event->setPrunable(false);
    else {
      SVal V = state->getSVal(R);
      if (report.isInteresting(V))
        event->setPrunable(false);
    }
  }
  return event;
}
// Based on QualType::isTrivial.
bool isTriviallyDefaultConstructible(QualType Type, const ASTContext &Context) {
  if (Type.isNull())
    return false;

  if (Type->isArrayType())
    return isTriviallyDefaultConstructible(Context.getBaseElementType(Type),
                                           Context);

  // Return false for incomplete types after skipping any incomplete array
  // types which are expressly allowed by the standard and thus our API.
  if (Type->isIncompleteType())
    return false;

  if (Context.getLangOpts().ObjCAutoRefCount) {
    switch (Type.getObjCLifetime()) {
    case Qualifiers::OCL_ExplicitNone:
      return true;

    case Qualifiers::OCL_Strong:
    case Qualifiers::OCL_Weak:
    case Qualifiers::OCL_Autoreleasing:
      return false;

    case Qualifiers::OCL_None:
      if (Type->isObjCLifetimeType())
        return false;
      break;
    }
  }

  QualType CanonicalType = Type.getCanonicalType();
  if (CanonicalType->isDependentType())
    return false;

  // As an extension, Clang treats vector types as Scalar types.
  if (CanonicalType->isScalarType() || CanonicalType->isVectorType())
    return true;

  if (const auto *RT = CanonicalType->getAs<RecordType>()) {
    return recordIsTriviallyDefaultConstructible(*RT->getDecl(), Context);
  }

  // No other types can match.
  return false;
}
SVal BasicStoreManager::LazyRetrieve(Store store, const TypedRegion *R) {
    const VarRegion *VR = dyn_cast<VarRegion>(R);
    if (!VR)
        return UnknownVal();

    const VarDecl *VD = VR->getDecl();
    QualType T = VD->getType();

    // Only handle simple types that we can symbolicate.
    if (!SymbolManager::canSymbolicate(T) || !T->isScalarType())
        return UnknownVal();

    // Globals and parameters start with symbolic values.
    // Local variables initially are undefined.
    if (VR->hasGlobalsOrParametersStorage())
        return ValMgr.getRegionValueSymbolVal(R);
    return UndefinedVal();
}
Exemple #9
0
SVal ValueManager::getConjuredSymbolVal(const Expr* E, unsigned Count) {
  QualType T = E->getType();
  SymbolRef sym = SymMgr.getConjuredSymbol(E, Count);

  // If T is of function pointer type, create a CodeTextRegion wrapping a
  // symbol.
  if (T->isFunctionPointerType()) {
    return Loc::MakeVal(MemMgr.getCodeTextRegion(sym, T));
  }

  if (Loc::IsLocType(T))
    return Loc::MakeVal(MemMgr.getSymbolicRegion(sym));

  if (T->isIntegerType() && T->isScalarType())
    return makeNonLoc(sym);

  return UnknownVal();
}
Exemple #10
0
SVal ValueManager::getRegionValueSymbolVal(const MemRegion* R) {
  SymbolRef sym = SymMgr.getRegionValueSymbol(R);
                                
  if (const TypedRegion* TR = dyn_cast<TypedRegion>(R)) {
    QualType T = TR->getValueType(SymMgr.getContext());

    // If T is of function pointer type, create a CodeTextRegion wrapping a
    // symbol.
    if (T->isFunctionPointerType()) {
      return Loc::MakeVal(MemMgr.getCodeTextRegion(sym, T));
    }
    
    if (Loc::IsLocType(T))
      return Loc::MakeVal(MemMgr.getSymbolicRegion(sym));
  
    // Only handle integers for now.
    if (T->isIntegerType() && T->isScalarType())
      return makeNonLoc(sym);
  }

  return UnknownVal();
}
Exemple #11
0
static void SuggestInitializationFixit(Sema &S, const VarDecl *VD) {
  // Don't issue a fixit if there is already an initializer.
  if (VD->getInit())
    return;

  // Suggest possible initialization (if any).
  const char *initialization = 0;
  QualType VariableTy = VD->getType().getCanonicalType();

  if (VariableTy->isObjCObjectPointerType() ||
      VariableTy->isBlockPointerType()) {
    // Check if 'nil' is defined.
    if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("nil")))
      initialization = " = nil";
    else
      initialization = " = 0";
  }
  else if (VariableTy->isRealFloatingType())
    initialization = " = 0.0";
  else if (VariableTy->isBooleanType() && S.Context.getLangOptions().CPlusPlus)
    initialization = " = false";
  else if (VariableTy->isEnumeralType())
    return;
  else if (VariableTy->isPointerType() || VariableTy->isMemberPointerType()) {
    // Check if 'NULL' is defined.
    if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("NULL")))
      initialization = " = NULL";
    else
      initialization = " = 0";
  }
  else if (VariableTy->isScalarType())
    initialization = " = 0";

  if (initialization) {
    SourceLocation loc = S.PP.getLocForEndOfToken(VD->getLocEnd());
    S.Diag(loc, diag::note_var_fixit_add_initialization)
      << FixItHint::CreateInsertion(loc, initialization);
  }
}
void GRSimpleVals::EvalCall(ExplodedNodeSet<GRState>& Dst,
                            GRExprEngine& Eng,
                            GRStmtNodeBuilder<GRState>& Builder,
                            CallExpr* CE, SVal L,
                            ExplodedNode<GRState>* Pred) {
  
  GRStateManager& StateMgr = Eng.getStateManager();
  const GRState* St = Builder.GetState(Pred);
  
  // Invalidate all arguments passed in by reference (Locs).

  for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
        I != E; ++I) {

    SVal V = StateMgr.GetSVal(St, *I);
    
    if (isa<loc::MemRegionVal>(V))
      St = StateMgr.BindLoc(St, cast<Loc>(V), UnknownVal());
    else if (isa<nonloc::LocAsInteger>(V))
      St = StateMgr.BindLoc(St, cast<nonloc::LocAsInteger>(V).getLoc(),
                            UnknownVal());
    
  }
  
  // Make up a symbol for the return value of this function.  
  // FIXME: We eventually should handle structs and other compound types
  // that are returned by value.
  QualType T = CE->getType();  
  if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())) {    
    unsigned Count = Builder.getCurrentBlockCount();
    SVal X = Eng.getValueManager().getConjuredSymbolVal(CE, Count);
    St = StateMgr.BindExpr(St, CE, X, Eng.getCFG().isBlkExpr(CE), false);
  }  
    
  Builder.MakeNode(Dst, CE, Pred, St);
}
Exemple #13
0
bool SymbolManager::canSymbolicate(QualType T) {
  return Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType());
}