Merge pull request #5986 from MathiasVP/side-effects-for-nonconst-smart-pointers

C++: Fix `hasDefaultSideEffect` for non-const smart pointers
This commit is contained in:
Dave Bartolomeo
2021-06-04 13:57:44 -04:00
committed by GitHub
4 changed files with 326 additions and 1 deletions

View File

@@ -10,6 +10,64 @@ private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.models.interfaces.PointerWrapper
private import semmle.code.cpp.models.interfaces.SideEffect
private predicate isDeeplyConst(Type t) {
t.isConst() and
isDeeplyConstBelow(t)
or
isDeeplyConst(t.(Decltype).getBaseType())
or
isDeeplyConst(t.(ReferenceType).getBaseType())
or
exists(SpecifiedType specType | specType = t |
specType.getASpecifier().getName() = "const" and
isDeeplyConstBelow(specType.getBaseType())
)
or
isDeeplyConst(t.(ArrayType).getBaseType())
}
private predicate isDeeplyConstBelow(Type t) {
t instanceof BuiltInType
or
not t instanceof PointerWrapper and
t instanceof Class
or
t instanceof Enum
or
isDeeplyConstBelow(t.(Decltype).getBaseType())
or
isDeeplyConst(t.(PointerType).getBaseType())
or
isDeeplyConst(t.(ReferenceType).getBaseType())
or
isDeeplyConstBelow(t.(SpecifiedType).getBaseType())
or
isDeeplyConst(t.(ArrayType).getBaseType())
or
isDeeplyConst(t.(GNUVectorType).getBaseType())
or
isDeeplyConst(t.(FunctionPointerIshType).getBaseType())
or
isDeeplyConst(t.(PointerWrapper).getTemplateArgument(0))
or
isDeeplyConst(t.(PointerToMemberType).getBaseType())
or
isDeeplyConstBelow(t.(TypedefType).getBaseType())
}
private predicate isConstPointerLike(Type t) {
(
t instanceof PointerWrapper
or
t instanceof PointerType
or
t instanceof ArrayType
or
t instanceof ReferenceType
) and
isDeeplyConstBelow(t)
}
/**
* Holds if the specified call has a side effect that does not come from a `SideEffectFunction`
* model.
@@ -45,7 +103,7 @@ private predicate hasDefaultSideEffect(Call call, ParameterIndex i, boolean buff
) and
(
isWrite = true and
not call.getTarget().getParameter(i).getType().isDeeplyConstBelow()
not isConstPointerLike(call.getTarget().getParameter(i).getUnderlyingType())
or
isWrite = false
)