/* Implementation of custom_edge_info::update_model vfunc
for dynamic_call_info_t.
- Update state for the dynamically discorverd calls */
+ Update state for a dynamically discovered call (or return), by pushing
+ or popping the a frame for the appropriate function. */
bool
dynamic_call_info_t::update_model (region_model *model,
const exploded_edge *eedge,
- region_model_context *) const
+ region_model_context *ctxt) const
{
gcc_assert (eedge);
- const program_state &dest_state = eedge->m_dest->get_state ();
- *model = *dest_state.m_region_model;
+ if (m_is_returning_call)
+ model->update_for_return_gcall (m_dynamic_call, ctxt);
+ else
+ {
+ function *callee = eedge->m_dest->get_function ();
+ model->update_for_gcall (m_dynamic_call, ctxt, callee);
+ }
return true;
}
--- /dev/null
+#include "analyzer-decls.h"
+
+extern int rand (void);
+
+void test_1 (void)
+{
+ int ret = 0;
+ while (ret != 42)
+ ret = rand() % 1000;
+
+ if (ret != 42)
+ __analyzer_dump_path (); /* { dg-bogus "path" } */
+}
+
+static void empty_local_fn (void) {}
+extern void external_fn (void);
+
+void test_2 (void)
+{
+ void (*callback) () = empty_local_fn;
+ int ret = 0;
+ while (ret != 42)
+ ret = rand() % 1000;
+
+ (*callback) ();
+
+ if (ret != 42)
+ __analyzer_dump_path (); /* { dg-bogus "path" } */
+}
+
+void test_3 (void)
+{
+ void (*callback) () = external_fn;
+ int ret = 0;
+ while (ret != 42)
+ ret = rand() % 1000;
+
+ (*callback) ();
+
+ if (ret != 42)
+ __analyzer_dump_path (); /* { dg-bogus "path" } */
+}
--- /dev/null
+/* { dg-require-effective-target pthread } */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "analyzer-decls.h"
+
+int z;
+
+static void func(void * o)
+{
+ (void) o;
+}
+
+int main(int argc,
+ int ** argv)
+{
+ struct timespec now;
+
+ int * x;
+ int ret = 0;
+
+ pthread_cleanup_push(func, NULL);
+
+ while (ret != ETIMEDOUT)
+ ret = rand() % 1000;
+
+ if (ret != ETIMEDOUT)
+ x = &z;
+
+ pthread_cleanup_pop(1);
+
+ if (ret == ETIMEDOUT)
+ return 0;
+
+ __analyzer_dump_path (); /* { dg-bogus "path" } */
+ printf("x = %d\n", *x); /* { dg-bogus "use of uninitialized value 'x'" } */
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "analyzer-decls.h"
+
+int z;
+
+static void func(void)
+{
+}
+
+int main(int argc,
+ int ** argv)
+{
+ int * x;
+ int ret = 0;
+ void (*callback) () = func;
+
+ while (ret != 110)
+ ret = rand() % 1000;
+
+ if (ret != 110)
+ x = &z;
+
+ (*callback) ();
+
+ if (ret == 110)
+ return 0;
+
+ __analyzer_dump_path (); /* { dg-bogus "path" } */
+ printf("x = %d\n", *x); /* { dg-bogus "use of uninitialized value 'x'" } */
+
+ return 0;
+}