Merge pull request #15132 from MathiasVP/fix-joins-in-isModifiableAtImpl

C++: Fix joins in `isModifiableAtImpl`
This commit is contained in:
Mathias Vorreiter Pedersen
2023-12-18 15:01:36 +01:00
committed by GitHub
3 changed files with 23 additions and 6 deletions

View File

@@ -997,7 +997,8 @@ private Type getTypeImpl0(Type t, int indirectionIndex) {
* *
* If `indirectionIndex` cannot be stripped off `t`, an `UnknownType` is returned. * If `indirectionIndex` cannot be stripped off `t`, an `UnknownType` is returned.
*/ */
bindingset[indirectionIndex] bindingset[t, indirectionIndex]
pragma[inline_late]
Type getTypeImpl(Type t, int indirectionIndex) { Type getTypeImpl(Type t, int indirectionIndex) {
result = getTypeImpl0(t, indirectionIndex) result = getTypeImpl0(t, indirectionIndex)
or or

View File

@@ -418,6 +418,11 @@ class BaseCallVariable extends AbstractBaseSourceVariable, TBaseCallVariable {
} }
private module IsModifiableAtImpl { private module IsModifiableAtImpl {
pragma[nomagic]
private predicate isUnderlyingIndirectionType(Type t) {
t = any(Indirection ind).getUnderlyingType()
}
/** /**
* Holds if the `indirectionIndex`'th dereference of a value of type * Holds if the `indirectionIndex`'th dereference of a value of type
* `cppType` is a type that can be modified (either by modifying the value * `cppType` is a type that can be modified (either by modifying the value
@@ -445,10 +450,9 @@ private module IsModifiableAtImpl {
bindingset[cppType, indirectionIndex] bindingset[cppType, indirectionIndex]
pragma[inline_late] pragma[inline_late]
private predicate impl(CppType cppType, int indirectionIndex) { private predicate impl(CppType cppType, int indirectionIndex) {
exists(Type pointerType, Type base, Type t | exists(Type pointerType, Type base |
pointerType = t.getUnderlyingType() and isUnderlyingIndirectionType(pointerType) and
pointerType = any(Indirection ind).getUnderlyingType() and cppType.hasUnderlyingType(pointerType, _) and
cppType.hasType(t, _) and
base = getTypeImpl(pointerType, indirectionIndex) base = getTypeImpl(pointerType, indirectionIndex)
| |
// The value cannot be modified if it has a const specifier, // The value cannot be modified if it has a const specifier,

View File

@@ -227,7 +227,7 @@ class CppType extends TCppType {
predicate hasType(Type type, boolean isGLValue) { none() } predicate hasType(Type type, boolean isGLValue) { none() }
/** /**
* Holds if this type represents the C++ type `type`. If `isGLValue` is `true`, then this type * Holds if this type represents the C++ unspecified type `type`. If `isGLValue` is `true`, then this type
* represents a glvalue of type `type`. Otherwise, it represents a prvalue of type `type`. * represents a glvalue of type `type`. Otherwise, it represents a prvalue of type `type`.
*/ */
final predicate hasUnspecifiedType(Type type, boolean isGLValue) { final predicate hasUnspecifiedType(Type type, boolean isGLValue) {
@@ -236,6 +236,18 @@ class CppType extends TCppType {
type = specifiedType.getUnspecifiedType() type = specifiedType.getUnspecifiedType()
) )
} }
/**
* Holds if this type represents the C++ type `type` (after resolving
* typedefs). If `isGLValue` is `true`, then this type represents a glvalue
* of type `type`. Otherwise, it represents a prvalue of type `type`.
*/
final predicate hasUnderlyingType(Type type, boolean isGLValue) {
exists(Type typedefType |
this.hasType(typedefType, isGLValue) and
type = typedefType.getUnderlyingType()
)
}
} }
/** /**