diff options
Diffstat (limited to 'lib/StaticAnalyzer/Core/SValBuilder.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/SValBuilder.cpp | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/lib/StaticAnalyzer/Core/SValBuilder.cpp b/lib/StaticAnalyzer/Core/SValBuilder.cpp index 7fc947828f..62867973fc 100644 --- a/lib/StaticAnalyzer/Core/SValBuilder.cpp +++ b/lib/StaticAnalyzer/Core/SValBuilder.cpp @@ -231,14 +231,41 @@ DefinedOrUnknownSVal SValBuilder::evalEQ(const ProgramState *state, Context.IntTy)); } +/// Recursively check if the pointer types are equal modulo const, volatile, +/// and restrict qualifiers. Assumes the input types are canonical. +/// TODO: This is based off of code in SemaCast; can we reuse it. +static bool haveSimilarTypes(ASTContext &Context, QualType T1, + QualType T2) { + while (Context.UnwrapSimilarPointerTypes(T1, T2)) { + Qualifiers Quals1, Quals2; + T1 = Context.getUnqualifiedArrayType(T1, Quals1); + T2 = Context.getUnqualifiedArrayType(T2, Quals2); + + // Make sure that non cvr-qualifiers the other qualifiers (e.g., address + // spaces) are identical. + Quals1.removeCVRQualifiers(); + Quals2.removeCVRQualifiers(); + if (Quals1 != Quals2) + return false; + } + + if (T1 != T2) + return false; + + return true; +} + // FIXME: should rewrite according to the cast kind. SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) { + castTy = Context.getCanonicalType(castTy); + originalTy = Context.getCanonicalType(originalTy); if (val.isUnknownOrUndef() || castTy == originalTy) return val; // For const casts, just propagate the value. if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType()) - if (Context.hasSameUnqualifiedType(castTy, originalTy)) + if (haveSimilarTypes(Context, Context.getPointerType(castTy), + Context.getPointerType(originalTy))) return val; // Check for casts from pointers to integers. |