@@ -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