return reg;
}
+/* Return the region for an unknown access of type REGION_TYPE,
+ creating it if necessary.
+ This is a symbolic_region, where the pointer is an unknown_svalue
+ of type ®ION_TYPE. */
+
+const region *
+region_model_manager::get_unknown_symbolic_region (tree region_type)
+{
+ tree ptr_type = region_type ? build_pointer_type (region_type) : NULL_TREE;
+ const svalue *unknown_ptr = get_or_create_unknown_svalue (ptr_type);
+ return get_symbolic_region (unknown_ptr);
+}
+
/* Return the region that describes accessing field FIELD of PARENT,
creating it if necessary. */
/* (*UNKNOWN_PTR).field is (*UNKNOWN_PTR_OF_&FIELD_TYPE). */
if (parent->symbolic_for_unknown_ptr_p ())
- {
- tree ptr_to_field_type = build_pointer_type (TREE_TYPE (field));
- const svalue *unknown_ptr_to_field
- = get_or_create_unknown_svalue (ptr_to_field_type);
- return get_symbolic_region (unknown_ptr_to_field);
- }
+ return get_unknown_symbolic_region (TREE_TYPE (field));
field_region::key_t key (parent, field);
if (field_region *reg = m_field_regions.get (key))
tree element_type,
const svalue *index)
{
+ /* (UNKNOWN_PTR[IDX]) is (UNKNOWN_PTR). */
+ if (parent->symbolic_for_unknown_ptr_p ())
+ return get_unknown_symbolic_region (element_type);
+
element_region::key_t key (parent, element_type, index);
if (element_region *reg = m_element_regions.get (key))
return reg;
tree type,
const svalue *byte_offset)
{
+ /* (UNKNOWN_PTR + OFFSET) is (UNKNOWN_PTR). */
+ if (parent->symbolic_for_unknown_ptr_p ())
+ return get_unknown_symbolic_region (type);
+
/* If BYTE_OFFSET is zero, return PARENT. */
if (tree cst_offset = byte_offset->maybe_get_constant ())
if (zerop (cst_offset))
tree type,
const svalue *byte_size_sval)
{
+ if (parent->symbolic_for_unknown_ptr_p ())
+ return get_unknown_symbolic_region (type);
+
if (byte_size_sval->get_type () != size_type_node)
byte_size_sval = get_or_create_cast (size_type_node, byte_size_sval);
if (type == original_region->get_type ())
return original_region;
+ if (original_region->symbolic_for_unknown_ptr_p ())
+ return get_unknown_symbolic_region (type);
+
cast_region::key_t key (original_region, type);
if (cast_region *reg = m_cast_regions.get (key))
return reg;
{
gcc_assert (parent);
+ if (parent->symbolic_for_unknown_ptr_p ())
+ return get_unknown_symbolic_region (type);
+
bit_range_region::key_t key (parent, type, bits);
if (bit_range_region *reg = m_bit_range_regions.get (key))
return reg;
symbolic_region::symbolic_region (unsigned id, region *parent,
const svalue *sval_ptr)
: region (complexity::from_pair (parent, sval_ptr), id, parent,
- TREE_TYPE (sval_ptr->get_type ())),
+ (sval_ptr->get_type ()
+ ? TREE_TYPE (sval_ptr->get_type ())
+ : NULL_TREE)),
m_sval_ptr (sval_ptr)
{
}
{
pp_string (pp, "symbolic_region(");
get_parent_region ()->dump_to_pp (pp, simple);
- pp_string (pp, ", ");
- print_quoted_type (pp, get_type ());
+ if (get_type ())
+ {
+ pp_string (pp, ", ");
+ print_quoted_type (pp, get_type ());
+ }
pp_string (pp, ", ");
m_sval_ptr->dump_to_pp (pp, simple);
pp_string (pp, ")");
--- /dev/null
+/* { dg-additional-options "-O2" } */
+
+extern void free (void *__ptr) __attribute__ ((__nothrow__ , __leaf__));
+
+enum pipecmd_tag
+{
+ PIPECMD_PROCESS,
+ PIPECMD_SEQUENCE
+};
+
+struct pipecmd {
+ enum pipecmd_tag tag;
+ union {
+ struct pipecmd_process {
+ int argc;
+ int argv_max;
+ char **argv;
+ } process;
+ struct pipecmd_sequence {
+ int ncommands;
+ int commands_max;
+ struct pipecmd **commands;
+ } sequence;
+ } u;
+};
+
+static char *argstr_get_word (const char **argstr)
+{
+ while (**argstr) {
+ switch (**argstr) {
+ case ' ':
+ case '\t':
+ return (void *) 0;
+ }
+ }
+ return (void *) 0;
+}
+
+struct pipecmd *pipecmd_new_argstr (const char *argstr)
+{
+ argstr_get_word (&argstr);
+ return (void *) 0;
+}
+
+void pipecmd_free (struct pipecmd *cmd)
+{
+ int i;
+
+ if (!cmd)
+ return;
+
+ switch (cmd->tag) {
+ case PIPECMD_PROCESS: {
+ struct pipecmd_process *cmdp = &cmd->u.process;
+
+ for (i = 0; i < cmdp->argc; ++i)
+ free (cmdp->argv[i]);
+ free (cmdp->argv);
+
+ break;
+ }
+
+ case PIPECMD_SEQUENCE: {
+ struct pipecmd_sequence *cmds = &cmd->u.sequence;
+
+ for (i = 0; i < cmds->ncommands; ++i)
+ pipecmd_free (cmds->commands[i]);
+ free (cmds->commands);
+
+ break;
+ }
+ }
+
+ free (cmd);
+}