[PATCH] D30489: [analyzer] catch out of bounds for VLA

Daniel Marjamäki via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 3 03:28:24 PST 2017


danielmarjamaki added a comment.

To me it seems that the extent is calculated properly in ArrayBoundsV2.

Existing code:

  DefinedOrUnknownSVal extentVal =
    rawOffset.getRegion()->getExtent(svalBuilder);

This ugly little debug code will extract the needed VLA information from the extentVal...

  if (extentVal.getSubKind() == nonloc::SymbolValKind) {
    SymbolRef SR = extentVal.castAs<nonloc::SymbolVal>().getSymbol();
    const SymbolExtent *SE = dyn_cast<SymbolExtent>(SR);
    const MemRegion *SEMR = SE->getRegion();
    if (SEMR->getKind() == MemRegion::VarRegionKind) {
      const VarRegion *VR = cast<VarRegion>(SEMR);
      QualType T = VR->getDecl()->getType();
      ASTContext &Ctx = checkerContext.getASTContext();
      const VariableArrayType *VLA = Ctx.getAsVariableArrayType(T);

A VLA->dump() after that will output:

  VariableArrayType 0x87f6a80 'char [sz]' variably_modified 
  |-BuiltinType 0x87f6480 'char'
  `-ImplicitCastExpr 0x87f6a70 'int' <LValueToRValue>
    `-DeclRefExpr 0x87f6a58 'int' lvalue ParmVar 0x87f6948 'sz' 'int'

which is exactly what the corresponding VLA->dump() in the checkPreStmt() outputs.

As far as I see the problem is that the ProgramState does not keep the symbolic value for sz.

In checkPreStmt the state is:

  Expressions:
   (0xe4acb0,0xe04790) sz : reg_$0<int sz>
   (0xe4acb0,0xe04828) array : &array
   (0xe4acb0,0xe04840) sz : &sz
   (0xe4acb0,0xe04858) array : &element{array,0 S64b,char}
   (0xe4acb0,0xe04868) sz : reg_$0<int sz>
   (0xe4acb0,0xe048b0) 1 : 1 S8b

in checkLocation() the state is:

  Expressions:
   (0xe4acb0,0xe04878) array[sz] : &element{array,reg_$0<int sz>,char}
   (0xe4acb0,0xe048b0) 1 : 1 S8b
   (0xe4acb0,0xe048c0) array[sz] = 1 : 1 S8b
  Ranges of symbol values:
   reg_$0<int sz> : { [0, 2147483647] }

This little code works in checkPreStmt() but not in checkLocation():

  SVal sizeV = State->getSVal(VLA->getSizeExpr(), C.getLocationContext());

In checkPreStmt that returns "reg_$0<int sz>" and in checkLocation() that returns "Unknown".

Do you agree that this is the problem? Would it be a good idea to try to keep the sz in the ProgramState?


Repository:
  rL LLVM

https://reviews.llvm.org/D30489





More information about the cfe-commits mailing list