@@ -6,7 +6,6 @@ Author: Daniel Kroening, kroening@kroening.com
66
77\*******************************************************************/  
88
9- 
109#include  " type.h" 
1110#include  " std_types.h" 
1211#include  " namespace.h" 
@@ -48,26 +47,24 @@ bool is_number(const typet &type)
4847bool  is_constant_or_has_constant_components (
4948  const  typet &type, const  namespacet &ns)
5049{
51-   //  Helper function to avoid the code duplication
52-   //  in the branches  below.
50+   //  Helper function to avoid the code duplication in the branches 
51+   //  below.
5352  const  auto  has_constant_components =
54-   [](const  typet &subtype) -> bool 
55-   {
56-     if (subtype.id () == ID_struct || subtype.id () == ID_union)
53+     [&ns](const  typet &subtype) -> bool 
5754    {
58-       const  auto  &struct_union_type = to_struct_union_type (subtype);
59-       for (const  auto  &component : struct_union_type.components ())
55+       if (subtype.id () == ID_struct || subtype.id () == ID_union)
6056      {
61-         if (component.type ().id () == ID_pointer)
62-           return  component.type ().get_bool (ID_C_constant);
63-         if (component.type ().get_bool (ID_C_constant))
64-           return  true ;
57+         const  auto  &struct_union_type = to_struct_union_type (subtype);
58+         for (const  auto  &component : struct_union_type.components ())
59+         {
60+           if (is_constant_or_has_constant_components (component.type (), ns))
61+             return  true ;
62+         }
6563      }
66-     }
67-     return  false ;
68-   };
64+       return  false ;
65+     };
6966
70-   //  There are 3  possibilities the code below is handling.
67+   //  There are 4  possibilities the code below is handling.
7168  //  The possibilities are enumerated as comments, to show
7269  //  what each code is supposed to be handling. For more
7370  //  comprehensive test case for this, take a look at
@@ -77,30 +74,34 @@ bool is_constant_or_has_constant_components(
7774  if (type.get_bool (ID_C_constant))
7875    return  true ;
7976
77+   //  This is a termination condition to break the recursion
78+   //  for recursive types such as the following:
79+   //  struct list { const int datum; struct list * next; };
80+   //  NOTE: the difference between this condition and the previous
81+   //  one is that this one always returns.
82+   if (type.id ()==ID_pointer)
83+     return  type.get_bool (ID_C_constant);
84+ 
8085  //  When we have a case like the following, we don't immediately
8186  //  see the struct t. Instead, we only get to see symbol t1, which
8287  //  we have to use the namespace to resolve to its definition:
8388  //  struct t { const int a; };
8489  //  struct t t1;
8590  if (type.id () == ID_symbol)
8691  {
87-     const  auto  &subtype  = ns.follow (type);
88-     return  has_constant_components (subtype );
92+     const  auto  &resolved_type  = ns.follow (type);
93+     return  has_constant_components (resolved_type );
8994  }
9095
91-   //  In a case like this, were  we see an array (b[3] here), we know that
96+   //  In a case like this, where  we see an array (b[3] here), we know that
9297  //  the array contains subtypes. We get the first one, and
9398  //  then resolve it to its  definition through the usage of the namespace.
9499  //  struct contains_constant_pointer { int x; int * const p; };
95100  //  struct contains_constant_pointer b[3] = { {23, &y}, {23, &y}, {23, &y} };
96101  if (type.has_subtype ())
97102  {
98103    const  auto  &subtype = type.subtype ();
99-     if (subtype.id () == ID_symbol)
100-     {
101-       const  auto  &new_subtype = ns.follow (to_symbol_type (subtype));
102-       return  has_constant_components (new_subtype);
103-     }
104+     return  is_constant_or_has_constant_components (subtype, ns);
104105  }
105106
106107  return  false ;
0 commit comments