void VisitArraySubscriptExpr(clang::ArraySubscriptExpr *AS) { // find array name and size clang::DeclRefExpr *DR; if (!(DR = clang::dyn_cast<clang::DeclRefExpr>( AS->getBase()->IgnoreImpCasts()))) { printf("Can't handle complex array expressions:\n\t%s\n", toString(AS)); exit(1); } const char *arr = DR->getDecl()->getNameAsString().c_str(); int size = variables.arraySize(arr); clang::Expr *ind = AS->getIdx(); // Both size and index are literals. No need for abstraction: if (clang::IntegerLiteral *IL = clang::dyn_cast<clang::IntegerLiteral>(ind)) { int val = (int)*IL->getValue().getRawData(); if (val < 0 || val >= size) { printf("** Index out of bounds error: Array %s, size %d, index " "%d\n", arr, size, val); printf("\t%s\n", toString(AS)); error = true; } // Size is a literal but the index is an abstract value: } else if (clang::DeclRefExpr *DR = clang::dyn_cast<clang::DeclRefExpr>(ind->IgnoreImpCasts())) { char *varInd = variables.find( DR->getDecl()->getNameAsString().c_str()); if (!blkApronCtx->isIndexInBound(varInd, size)) { printf("** Index out of bounds error: Index %s, Array %s, size " "%d\n", toString(DR), arr, size); error = true; } } else { printf("Can't handle compound expressions as array indexes:\n\t%s\n", toString(AS)); exit(1); } // else if (clang::ImplicitCastExpr *CE = // clang::dyn_cast<clang::ImplicitCastExpr>(ind)) { // Visit(CE); // char *indVar = variables.getLastVar(); // analysisCtx->addArrayIndex(indVar, size); // } // variables.toggleCollectingVars(false); }