NoQ updated this revision to Diff 127548. NoQ added a comment. - Fix comments as suggested by Devin. - Point out that arithmetic on void pointers is a GNU extension.
https://reviews.llvm.org/D40939 Files: include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h lib/StaticAnalyzer/Core/ExprEngine.cpp lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp Index: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp =================================================================== --- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -988,6 +988,12 @@ elementType = resultTy->getPointeeType(); } + // Represent arithmetic on void pointers as arithmetic on char pointers. + // It is fine when a TypedValueRegion of char value type represents + // a void pointer. Note that arithmetic on void pointers is a GCC extension. + if (elementType->isVoidType()) + elementType = getContext().CharTy; + if (Optional<NonLoc> indexV = index.getAs<NonLoc>()) { return loc::MemRegionVal(MemMgr.getElementRegion(elementType, *indexV, superR, getContext())); Index: lib/StaticAnalyzer/Core/ExprEngine.cpp =================================================================== --- lib/StaticAnalyzer/Core/ExprEngine.cpp +++ lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -2178,9 +2178,17 @@ ProgramStateRef state = Node->getState(); if (IsGLValueLike) { - SVal V = state->getLValue(A->getType(), - state->getSVal(Idx, LCtx), - state->getSVal(Base, LCtx)); + QualType T = A->getType(); + + // One of the forbidden LValue types! We still need to have sensible + // symbolic locations to represent this stuff. Note that arithmetic on + // void pointers is a GCC extension. + if (T->isVoidType()) + T = getContext().CharTy; + + SVal V = state->getLValue(T, + state->getSVal(Idx, LCtx), + state->getSVal(Base, LCtx)); Bldr.generateNode(A, Node, state->BindExpr(A, LCtx, V), nullptr, ProgramPoint::PostLValueKind); } else if (IsVectorType) { Index: include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -961,7 +961,10 @@ CXXThisRegion(const PointerType *thisPointerTy, const StackArgumentsSpaceRegion *sReg) : TypedValueRegion(sReg, CXXThisRegionKind), - ThisPointerTy(thisPointerTy) {} + ThisPointerTy(thisPointerTy) { + assert(ThisPointerTy->getPointeeType()->getAsCXXRecordDecl() && + "Invalid region type!"); + } static void ProfileRegion(llvm::FoldingSetNodeID &ID, const PointerType *PT, @@ -1075,6 +1078,8 @@ assert((!Idx.getAs<nonloc::ConcreteInt>() || Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) && "The index must be signed"); + assert(!elementType.isNull() && !elementType->isVoidType() && + "Invalid region type!"); } static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
Index: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp =================================================================== --- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -988,6 +988,12 @@ elementType = resultTy->getPointeeType(); } + // Represent arithmetic on void pointers as arithmetic on char pointers. + // It is fine when a TypedValueRegion of char value type represents + // a void pointer. Note that arithmetic on void pointers is a GCC extension. + if (elementType->isVoidType()) + elementType = getContext().CharTy; + if (Optional<NonLoc> indexV = index.getAs<NonLoc>()) { return loc::MemRegionVal(MemMgr.getElementRegion(elementType, *indexV, superR, getContext())); Index: lib/StaticAnalyzer/Core/ExprEngine.cpp =================================================================== --- lib/StaticAnalyzer/Core/ExprEngine.cpp +++ lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -2178,9 +2178,17 @@ ProgramStateRef state = Node->getState(); if (IsGLValueLike) { - SVal V = state->getLValue(A->getType(), - state->getSVal(Idx, LCtx), - state->getSVal(Base, LCtx)); + QualType T = A->getType(); + + // One of the forbidden LValue types! We still need to have sensible + // symbolic locations to represent this stuff. Note that arithmetic on + // void pointers is a GCC extension. + if (T->isVoidType()) + T = getContext().CharTy; + + SVal V = state->getLValue(T, + state->getSVal(Idx, LCtx), + state->getSVal(Base, LCtx)); Bldr.generateNode(A, Node, state->BindExpr(A, LCtx, V), nullptr, ProgramPoint::PostLValueKind); } else if (IsVectorType) { Index: include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -961,7 +961,10 @@ CXXThisRegion(const PointerType *thisPointerTy, const StackArgumentsSpaceRegion *sReg) : TypedValueRegion(sReg, CXXThisRegionKind), - ThisPointerTy(thisPointerTy) {} + ThisPointerTy(thisPointerTy) { + assert(ThisPointerTy->getPointeeType()->getAsCXXRecordDecl() && + "Invalid region type!"); + } static void ProfileRegion(llvm::FoldingSetNodeID &ID, const PointerType *PT, @@ -1075,6 +1078,8 @@ assert((!Idx.getAs<nonloc::ConcreteInt>() || Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) && "The index must be signed"); + assert(!elementType.isNull() && !elementType->isVoidType() && + "Invalid region type!"); } static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits