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() && getLangOpts().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 (E->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) {

144 Diag(E->getBeginLoc(),

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)