clang: lib/StaticAnalyzer/Core/BugSuppression.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

12#include "llvm/Support/FormatVariadic.h"

13#include "llvm/Support/TimeProfiler.h"

14

15using namespace clang;

16using namespace ento;

17

18namespace {

19

21

22inline bool hasSuppression(const Decl *D) {

23

24

25 if (const auto *Suppression = D->getAttr())

26 return !Suppression->isGSL() &&

27 (Suppression->diagnosticIdentifiers().empty());

28 return false;

29}

31

32

33 return llvm::any_of(S->getAttrs(), [](const Attr *A) {

34 const auto *Suppression = dyn_cast(A);

35 return Suppression && !Suppression->isGSL() &&

36 (Suppression->diagnosticIdentifiers().empty());

37 });

38}

39

40template inline SourceRange getRange(const NodeType *Node) {

41 return Node->getSourceRange();

42}

44

45

46

47

48

49

50

51

53}

54

57

58

59

60

61

62

63

64 return SM.isBeforeInTranslationUnit(RHS, LHS);

65}

66

69

70

71

72

73

74

75

76

79}

80

82public:

83 static void initialize(const Decl *D, Ranges &ToInit) {

84 CacheInitializer(ToInit).TraverseDecl(const_cast<Decl *>(D));

85 }

86

87 bool VisitDecl(Decl *D) override {

88

89

90

91

92 return VisitAttributedNode(D);

93 }

94

95 bool VisitAttributedStmt(AttributedStmt *AS) override {

96

97

98

99 return VisitAttributedNode(AS);

100 }

101

102private:

103 template bool VisitAttributedNode(NodeType *Node) {

104 if (hasSuppression(Node)) {

105

106

107

109 }

110

111 return true;

112 }

113

114 void addRange(SourceRange R) {

116 Result.push_back(R);

117 }

118 }

119

120 CacheInitializer(Ranges &R) : Result(R) {

121 ShouldVisitTemplateInstantiations = true;

122 ShouldWalkTypesOfTypeLocs = false;

123 ShouldVisitImplicitCode = false;

124 ShouldVisitLambdaBody = true;

125 }

126 Ranges &Result;

127};

128

129std::string timeScopeName(const Decl *DeclWithIssue) {

130 if (!llvm::timeTraceProfilerEnabled())

131 return "";

132 return llvm::formatv(

133 "BugSuppression::isSuppressed init suppressions cache for {0}",

135 .str();

136}

137

138llvm::TimeTraceMetadata getDeclTimeTraceMetadata(const Decl *DeclWithIssue) {

139 assert(DeclWithIssue);

140 assert(llvm::timeTraceProfilerEnabled());

141 std::string Name = "";

142 if (const auto *ND = dyn_cast(DeclWithIssue)) {

143 Name = ND->getNameAsString();

144 }

146 auto Line = SM.getPresumedLineNumber(DeclWithIssue->getBeginLoc());

147 auto Fname = SM.getFilename(DeclWithIssue->getBeginLoc());

148 return llvm::TimeTraceMetadata{std::move(Name), Fname.str(),

149 static_cast<int>(Line)};

150}

151

152}

153

154

155

156

157

158

163

164 return isSuppressed(Location, DeclWithIssue, {}) ||

165 isSuppressed(UniqueingLocation, DeclWithIssue, {});

166}

167

169 const Decl *DeclWithIssue,

171 if (!Location.isValid())

172 return false;

173

174 if (!DeclWithIssue) {

175

176

177

178

180 } else {

181

182

183

184 while (true) {

185

186

187 const Decl *Parent =

190 break;

191

192 DeclWithIssue = Parent;

193 }

194 }

195

196

197

198

199

200

201

202

203

204

205

206 auto InsertionResult = CachedSuppressionLocations.insert(

207 std::make_pair(DeclWithIssue, CachedRanges{}));

208 Ranges &SuppressionRanges = InsertionResult.first->second;

209 if (InsertionResult.second) {

210 llvm::TimeTraceScope TimeScope(

211 timeScopeName(DeclWithIssue),

212 [DeclWithIssue]() { return getDeclTimeTraceMetadata(DeclWithIssue); });

213

214 CacheInitializer::initialize(DeclWithIssue, SuppressionRanges);

215 }

216

217 SourceRange BugRange = Location.asRange();

219

220 return llvm::any_of(SuppressionRanges,

222 return fullyContains(Suppression, BugRange, SM);

223 });

224}

static CharSourceRange getRange(const CharSourceRange &EditRange, const SourceManager &SM, const LangOptions &LangOpts, bool IncludeMacroExpansion)

SourceManager & getSourceManager()

Attr - This represents one attribute.

Represents an attribute applied to a statement.

ArrayRef< const Attr * > getAttrs() const

Decl - This represents one declaration (or definition), e.g.

ASTContext & getASTContext() const LLVM_READONLY

const char * getDeclKindName() const

SourceLocation getBeginLoc() const LLVM_READONLY

TranslationUnitDecl * getTranslationUnitDecl()

DeclContext * getLexicalDeclContext()

getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).

Encodes a location in the source.

This class handles loading and caching of source files into memory.

A trivial tuple used to represent a source range.

SourceLocation getEnd() const

SourceLocation getBegin() const

This class provides an interface through which checkers can create individual bug reports.

virtual PathDiagnosticLocation getUniqueingLocation() const =0

Get the location on which the report should be uniqued.

virtual PathDiagnosticLocation getLocation() const =0

The primary location of the bug report that points at the undesirable behavior in the code.

virtual const Decl * getDeclWithIssue() const =0

The smallest declaration that contains the bug location.

llvm::ArrayRef< llvm::StringRef > DiagnosticIdentifierList

bool isSuppressed(const BugReport &)

Return true if the given bug report was explicitly suppressed by the user.

Definition BugSuppression.cpp:159

std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl

All declarations that can appear in a module declaration.

The JSON file list parser is used to communicate input to InstallAPI.

bool isa(CodeGen::Address addr)

void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)

DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor