]> granicus.if.org Git - clang/commitdiff
[analyzer] Unwrap the pointers when ignoring the const cast.
authorAnna Zaks <ganna@apple.com>
Fri, 13 Jan 2012 00:56:55 +0000 (00:56 +0000)
committerAnna Zaks <ganna@apple.com>
Fri, 13 Jan 2012 00:56:55 +0000 (00:56 +0000)
radar://10686991

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148081 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Core/SValBuilder.cpp
test/Analysis/taint-generic.c

index 7fc947828f3f0c589636f53b4fe04183f0cb77f4..62867973fcbc7118bf40d7576f8b1a7f203c277d 100644 (file)
@@ -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.
index fd9884d3fa8e8a8ebc740966414a31184893f277..5423d05e0cb9919c3c12740825049550774ac939 100644 (file)
@@ -79,6 +79,9 @@ void testUncontrolledFormatString(char **p) {
   strcpy(scpy, s);
   sprintf(buf,scpy); // expected-warning {{Uncontrolled Format String}}
 
+  stpcpy(*(++p), s); // this generates __inline.
+  setproctitle(*(p), 3); // expected-warning {{Uncontrolled Format String}}
+
   char spcpy[80];
   stpcpy(spcpy, s);
   setproctitle(spcpy, 3); // expected-warning {{Uncontrolled Format String}}