• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

daisytuner / sdfglib / 16796354623

07 Aug 2025 05:56AM UTC coverage: 64.3%. Remained the same
16796354623

push

github

web-flow
Merge pull request #175 from daisytuner/pointee-type-fix

handles opaque pointer in peel_to_innermost_element

3 of 4 new or added lines in 1 file covered. (75.0%)

8867 of 13790 relevant lines covered (64.3%)

116.71 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.11
/src/types/utils.cpp
1
#include "sdfg/types/utils.h"
2

3
#include "sdfg/codegen/utils.h"
4
#include "sdfg/symbolic/symbolic.h"
5

6
#include "sdfg/codegen/language_extensions/c_language_extension.h"
7

8
namespace sdfg {
9
namespace types {
10

11
const types::IType&
12
infer_type_internal(const sdfg::Function& function, const types::IType& type, const data_flow::Subset& subset) {
962✔
13
    if (subset.empty()) {
962✔
14
        return type;
463✔
15
    }
16

17
    if (type.type_id() == TypeID::Scalar) {
499✔
18
        if (!subset.empty()) {
×
19
            throw InvalidSDFGException("Scalar type must have no subset");
×
20
        }
21

22
        return type;
×
23
    } else if (type.type_id() == TypeID::Array) {
499✔
24
        auto& array_type = static_cast<const types::Array&>(type);
498✔
25

26
        data_flow::Subset element_subset(subset.begin() + 1, subset.end());
498✔
27
        return infer_type_internal(function, array_type.element_type(), element_subset);
498✔
28
    } else if (type.type_id() == TypeID::Structure) {
499✔
29
        auto& structure_type = static_cast<const types::Structure&>(type);
1✔
30

31
        auto& definition = function.structure(structure_type.name());
1✔
32

33
        data_flow::Subset element_subset(subset.begin() + 1, subset.end());
1✔
34
        auto member = SymEngine::rcp_dynamic_cast<const SymEngine::Integer>(subset.at(0));
1✔
35
        return infer_type_internal(function, definition.member_type(member), element_subset);
1✔
36
    } else if (type.type_id() == TypeID::Pointer) {
1✔
37
        throw InvalidSDFGException("Subset references non-contiguous memory");
×
38
    }
39

40
    throw InvalidSDFGException("Type inference failed because of unknown type");
×
41
};
962✔
42

43
const types::IType& infer_type(const sdfg::Function& function, const types::IType& type, const data_flow::Subset& subset) {
1,338✔
44
    if (subset.empty()) {
1,338✔
45
        return type;
875✔
46
    }
47

48
    if (type.type_id() == TypeID::Pointer) {
463✔
49
        auto& pointer_type = static_cast<const types::Pointer&>(type);
218✔
50
        if (!pointer_type.has_pointee_type()) {
218✔
51
            throw InvalidSDFGException("Non-empty subset for pointer type without pointee type");
×
52
        }
53

54
        auto& pointee_type = pointer_type.pointee_type();
218✔
55

56
        data_flow::Subset element_subset(subset.begin() + 1, subset.end());
218✔
57
        return infer_type_internal(function, pointee_type, element_subset);
218✔
58
    } else {
218✔
59
        return infer_type_internal(function, type, subset);
245✔
60
    }
61
};
1,338✔
62

63
std::unique_ptr<types::IType> recombine_array_type(const types::IType& type, uint depth, const types::IType& inner_type) {
21✔
64
    if (depth == 0) {
21✔
65
        return inner_type.clone();
9✔
66
    } else {
67
        if (auto atype = dynamic_cast<const types::Array*>(&type)) {
12✔
68
            return std::make_unique<types::Array>(
12✔
69
                atype->storage_type(),
12✔
70
                atype->alignment(),
12✔
71
                atype->initializer(),
12✔
72
                *recombine_array_type(atype->element_type(), depth - 1, inner_type).get(),
12✔
73
                atype->num_elements()
12✔
74
            );
75
        } else {
76
            throw std::runtime_error("construct_type: Non array types are not supported yet!");
×
77
        }
78
    }
79
};
21✔
80

81
const IType& peel_to_innermost_element(const IType& type, int follow_ptr) {
13✔
82
    int next_follow = follow_ptr;
13✔
83
    if (follow_ptr == PEEL_TO_INNERMOST_ELEMENT_FOLLOW_ONLY_OUTER_PTR) {
13✔
84
        next_follow = 0; // only follow an outermost pointer
5✔
85
    }
5✔
86

87
    switch (type.type_id()) {
13✔
88
        case TypeID::Array:
89
            return peel_to_innermost_element(dynamic_cast<const types::Array&>(type).element_type(), next_follow);
3✔
90
        case TypeID::Reference:
91
            return peel_to_innermost_element(dynamic_cast<const codegen::Reference&>(type).reference_type(), next_follow);
×
92
        case TypeID::Pointer:
93
            if (follow_ptr != 0) {
6✔
94
                if (follow_ptr != PEEL_TO_INNERMOST_ELEMENT_FOLLOW_ONLY_OUTER_PTR) {
5✔
95
                    next_follow = follow_ptr - 1; // follow one less pointer
×
96
                }
×
97

98
                auto& pointer_type = dynamic_cast<const types::Pointer&>(type);
5✔
99
                if (pointer_type.has_pointee_type()) {
5✔
100
                    return peel_to_innermost_element(pointer_type.pointee_type(), next_follow);
5✔
101
                } else {
NEW
102
                    return type;
×
103
                }
104
            }
105
            // fall back to cut-off if we did not follow the pointer
106
        default:
107
            return type;
5✔
108
    }
109
}
13✔
110

111
symbolic::Expression get_contiguous_element_size(const types::IType& type, bool allow_comp_time_eval) {
5✔
112
    // need to peel explicitly, primitive_type() would follow ALL pointers, even ***, even though this is not contiguous
113
    auto& innermost = peel_to_innermost_element(type, PEEL_TO_INNERMOST_ELEMENT_FOLLOW_ONLY_OUTER_PTR);
5✔
114

115
    return get_type_size(innermost, allow_comp_time_eval);
5✔
116
}
117

118
symbolic::Expression get_type_size(const types::IType& type, bool allow_comp_time_eval) {
13✔
119
    bool only_symbolic = false;
13✔
120

121
    auto id = type.type_id();
13✔
122
    if (id == TypeID::Pointer || id == TypeID::Reference || id == TypeID::Function) {
13✔
123
        // TODO NEED target info to know pointer size (4 or 8 bytes?) !!
124
        only_symbolic = true;
4✔
125
    } else if (id == TypeID::Structure) {
13✔
126
        // TODO if we have the target definition, we could evaluate the StructureDefinition to a size
127
        only_symbolic = true;
5✔
128
    } else if (id == TypeID::Array) {
9✔
129
        auto& arr = dynamic_cast<const types::Array&>(type);
1✔
130
        auto inner_element_size = get_type_size(arr.element_type(), allow_comp_time_eval);
1✔
131
        if (!inner_element_size.is_null()) {
1✔
132
            return symbolic::mul(inner_element_size, arr.num_elements());
1✔
133
        } else {
134
            return {};
×
135
        }
136
    }
1✔
137

138
    if (only_symbolic) {
12✔
139
        // Could not statically figure out the size
140
        // Could be struct we could evaluate by its definition or sth. we do not understand here
141
        if (allow_comp_time_eval) {
9✔
142
            return symbolic::size_of_type(type);
5✔
143
        } else { // size unknown
144
            return {};
4✔
145
        }
146
    } else { // should just be a primitive type
147
        auto prim_type = type.primitive_type();
3✔
148

149
        long size_of_type = static_cast<long>(types::bit_width(prim_type)) / 8;
3✔
150
        if (size_of_type != 0) {
3✔
151
            return symbolic::integer(size_of_type);
3✔
152
        } else {
153
            codegen::CLanguageExtension lang;
×
154
            std::cerr << "Unexpected primitive_type " << primitive_type_to_string(prim_type) << " of "
×
155
                      << lang.declaration("", type) << ", unknown size";
×
156
            return {};
×
157
        }
×
158
    }
159
}
13✔
160

161
} // namespace types
162
} // namespace sdfg
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc