On Jan 29, 2009, at 9:15 PM, Zhongxing Xu wrote:
Added: cfe/trunk/test/Analysis/rdar-6541136.c
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/rdar-6541136.c?rev=63347&view=auto
=
=
=
=
=
=
=
=
======================================================================
--- cfe/trunk/test/Analysis/rdar-6541136.c (added)
+++ cfe/trunk/test/Analysis/rdar-6541136.c Thu Jan 29 18:08:43 2009
@@ -0,0 +1,20 @@
+// clang -verify -analyze -checker-cfref -analyzer-store-basic %s
+
+struct tea_cheese { unsigned magic; };
+typedef struct tea_cheese kernel_tea_cheese_t;
+extern kernel_tea_cheese_t _wonky_gesticulate_cheese;
+
+// This test case exercises the ElementRegion::getRValueType() logic.
+// All it tests is that it does not crash or do anything weird.
+// The out-of-bounds-access on line 19 is caught using the region
store variant.
+
+void foo( void )
+{
+ kernel_tea_cheese_t *wonky = &_wonky_gesticulate_cheese;
+ struct load_wine *cmd = (void*) &wonky[1];
This is like an ill use of the type system. What do you think we
emit a warning instead of following it.
That is, we emit a warning when the array region does not have array
type or pointer type.
Yes this is really gross code. It actually contains more stuff than
the original test case I looked at just to see if the analyzer would
crash. The original test case was basically:
kernel_tea_cheese_t *wonky = &_wonky_gesticulate_cheese;
struct load_wine *cmd = (void*) &wonky[1];
Let's just consider this for a moment. While the out-of-bounds access
looks wrong in all cases, aside from the out-of-bounds access it may
be "okay." Consider the following possible definition of struct
load_wine:
struct load_wine {
struct tea_cheese x;
...
};
In this case, it is okay to cast a 'struct tea_cheese*' to a 'struct
load_wine*'. This kind of pattern appears a lot in the Gtk+ code (and
other C libraries) to simulate object-oriented programming and
inheritance.
The problem here is that we don't have the definition of 'struct
load_wine'. If we did, we could do some extra type checking (as you
suggest). In this case, we don't, so what do we do?
As for:
char *p = (void*) &wonky[1];
*p = 1;
Yes that is really gross. What should we do here? This is
technically an out-of-bounds memory write (which we don't flag because
of the abuse of the type system), but as you said it is an abuse of
the type system. With our path-sensitive type information in the
RegionStore objects perhaps we can flag a more lucid warning? On the
other hand, assuming that &wonky[1] is valid (say wonky was an array),
we're just writing '1' to the first byte of the 'magic' field. The
rabbit hole goes arbitrary deep._______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits