clang: lib/Sema/SemaBoundsSafety.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
15
17
20 if (CountInBytes)
25}
26
29
30
31
32
33 while (RD && (RD->isAnonymousStructOrUnion() ||
34 (!RD->isCompleteDefinition() && RD->getName().empty()))) {
35 const auto *Parent = dyn_cast(RD->getParent());
37 break;
39 }
40 return RD;
41}
42
49};
50
52 bool OrNull) {
53
54
56
60 return true;
61 }
62
63 const auto FieldTy = FD->getType();
64 if (FieldTy->isArrayType() && (CountInBytes || OrNull)) {
66 diag::err_count_attr_not_on_ptr_or_flexible_array_member)
67 << Kind << FD->getLocation() << 1;
68 return true;
69 }
70 if (!FieldTy->isArrayType() && !FieldTy->isPointerType()) {
72 diag::err_count_attr_not_on_ptr_or_flexible_array_member)
73 << Kind << FD->getLocation() << 0;
74 return true;
75 }
76
79 if (FieldTy->isArrayType() &&
81 StrictFlexArraysLevel, true)) {
83 diag::err_counted_by_attr_on_array_not_flexible_array_member)
85 return true;
86 }
87
91 int SelectPtrOrArr = 0;
92 if (FieldTy->isPointerType()) {
94 SelectPtrOrArr = 0;
95 } else {
96 assert(FieldTy->isArrayType());
99 SelectPtrOrArr = 1;
100 }
101
102
103
104 bool ShouldWarn = false;
112 if (FieldTy->isArrayType() && ().BoundsSafety) {
113
114
115
116
117
118
119 ShouldWarn = true;
120 }
122 }
123
125 unsigned DiagID = ShouldWarn
126 ? diag::warn_counted_by_attr_elt_type_unknown_size
127 : diag::err_counted_by_attr_pointee_unknown_size;
129 << SelectPtrOrArr << PointeeTy << (int)InvalidTypeKind
131 return true;
132 }
133
134
135
136 if (->getType()->isIntegerType() || E->getType()->isBooleanType()) {
137 Diag(E->getBeginLoc(), diag::err_count_attr_argument_not_integer)
138 << Kind << E->getSourceRange();
139 return true;
140 }
141
142 auto *DRE = dyn_cast(E);
143 if (!DRE) {
145 diag::err_count_attr_only_support_simple_decl_reference)
146 << Kind << E->getSourceRange();
147 return true;
148 }
149
150 auto *CountDecl = DRE->getDecl();
151 FieldDecl *CountFD = dyn_cast(CountDecl);
152 if (auto *IFD = dyn_cast(CountDecl)) {
153 CountFD = IFD->getAnonField();
154 }
155 if (!CountFD) {
156 Diag(E->getBeginLoc(), diag::err_count_attr_must_be_in_structure)
157 << CountDecl << Kind << E->getSourceRange();
158
159 Diag(CountDecl->getBeginLoc(),
160 diag::note_flexible_array_counted_by_attr_field)
161 << CountDecl << CountDecl->getSourceRange();
162 return true;
163 }
164
167 Diag(CountFD->getBeginLoc(), diag::err_count_attr_refer_to_union)
169 return true;
170 }
171
172
173
176
177 if (RD != CountRD) {
178 Diag(E->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct)
179 << CountFD << Kind << FieldTy->isArrayType() << E->getSourceRange();
181 diag::note_flexible_array_counted_by_attr_field)
183 return true;
184 }
185 }
186 return false;
187}
188
189}
enum clang::sema::@1725::IndirectLocalPathEntry::EntryKind Kind
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
SourceLocation getLocation() const
static bool isFlexibleArrayMemberLike(ASTContext &Context, const Decl *D, QualType Ty, LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel, bool IgnoreTemplateOrMacroSubstitution)
Whether it resembles a flexible array member.
SourceLocation getBeginLoc() const LLVM_READONLY
This represents one expression.
Represents a member of a struct/union/class.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
StrictFlexArraysLevelKind
@ IncompleteOnly
Any trailing array member of undefined size is a FAM.
A (possibly-)qualified type.
Represents a struct/union/class.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
bool CheckCountedByAttrOnField(FieldDecl *FD, Expr *E, bool CountInBytes, bool OrNull)
Check if applying the specified attribute variant from the "counted by" family of attributes to Field...
bool isSizelessType() const
As an extension, we classify types as one of "sized" or "sizeless"; every type is one or the other.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isStructureTypeWithFlexibleArrayMember() const
The JSON file list parser is used to communicate input to InstallAPI.
static CountAttributedType::DynamicCountPointerKind getCountAttrKind(bool CountInBytes, bool OrNull)
CountedByInvalidPointeeTypeKind
static const RecordDecl * GetEnclosingNamedOrTopAnonRecord(const FieldDecl *FD)