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

1

2

3

4

5

6

7

8

9

10

11

12

13

28#include "llvm/Support/Casting.h"

29#include "llvm/Support/Compiler.h"

30#include "llvm/Support/ErrorHandling.h"

31#include "llvm/Support/raw_ostream.h"

32#include

33#include

34

35using namespace clang;

36using namespace ento;

37

38

39

40

41

42

43

44

45

47 if (std::optionalloc::MemRegionVal X = getAsloc::MemRegionVal()) {

50 if (const auto *FD = dyn_cast(CTR->getDecl()))

51 return FD;

52 }

53

54 if (auto X = getAsnonloc::PointerToMember()) {

55 if (const auto *MD = dyn_cast_or_null(X->getDecl()))

56 return MD;

57 }

58 return nullptr;

59}

60

61

62

63

64

65

66

67

69

73 : dyn_cast(R->StripCasts()))

74 return SymR->getSymbol();

75

76 return nullptr;

77}

78

79

81 std::optionalloc::MemRegionVal X = getAsloc::MemRegionVal();

82

83 if (X)

84 return nullptr;

85

87

88 while (const auto *SR = dyn_cast(R)) {

89 if (const auto *SymR = dyn_cast(SR))

90 return SymR->getSymbol();

91 else

92 R = SR->getSuperRegion();

93 }

94

95 return nullptr;

96}

97

98

99

100

101

102

103

105

106 if (std::optionalnonloc::SymbolVal X = getAsnonloc::SymbolVal())

107 return X->getSymbol();

108

110}

111

113 if (auto CI = getAsnonloc::ConcreteInt())

114 return CI->getValue().get();

115 if (auto CI = getAsloc::ConcreteInt())

116 return CI->getValue().get();

117 return nullptr;

118}

119

121 if (std::optionalloc::MemRegionVal X = getAsloc::MemRegionVal())

122 return X->getRegion();

123

124 if (std::optionalnonloc::LocAsInteger X = getAsnonloc::LocAsInteger())

125 return X->getLoc().getAsRegion();

126

127 return nullptr;

128}

129

130namespace {

131class TypeRetrievingVisitor

132 : public FullSValVisitor<TypeRetrievingVisitor, QualType> {

133private:

135

136public:

137 TypeRetrievingVisitor(const ASTContext &Context) : Context(Context) {}

138

141 }

144 }

145 template QualType VisitConcreteInt(ConcreteInt CI) {

146 const llvm::APSInt &Value = CI.getValue();

147 if (1 == Value.getBitWidth())

148 return Context.BoolTy;

150 }

153 if (NestedType.isNull())

154 return NestedType;

155

158 }

161 }

164 }

167 }

170 }

173 }

176 }

178};

179}

180

182 TypeRetrievingVisitor TRV{Context};

183 return TRV.Visit(*this);

184}

185

188}

189

192}

193

196}

197

199 return getPTMData().isNull();

200}

201

203 const auto PTMD = this->getPTMData();

204 if (PTMD.isNull())

205 return nullptr;

206

208 if (const auto *NDP = dyn_cast<const NamedDecl *>(PTMD))

209 ND = NDP;

210 else

211 ND = cast<const PointerToMemberData *>(PTMD)->getDeclaratorDecl();

212

213 return ND;

214}

215

216

217

218

219

221 return getValue()->begin();

222}

223

225 return getValue()->end();

226}

227

230 if (isa<const NamedDecl *>(PTMD))

231 return {};

232 return cast<const PointerToMemberData *>(PTMD)->begin();

233}

234

237 if (isa<const NamedDecl *>(PTMD))

238 return {};

239 return cast<const PointerToMemberData *>(PTMD)->end();

240}

241

242

243

244

245

247 return getAsnonloc::ConcreteInt() || getAsloc::ConcreteInt();

248}

249

251 if (std::optionalloc::ConcreteInt LV = getAsloc::ConcreteInt())

252 return *LV->getValue().get() == I;

253 if (std::optionalnonloc::ConcreteInt NV = getAsnonloc::ConcreteInt())

254 return *NV->getValue().get() == I;

255 return false;

256}

257

259 return isConstant(0);

260}

261

262

263

264

265

268#define BASIC_SVAL(Id, Parent) \

269 case Id##Kind: \

270 return #Id;

271#define LOC_SVAL(Id, Parent) \

272 case Loc##Id##Kind: \

273 return #Id;

274#define NONLOC_SVAL(Id, Parent) \

275 case NonLoc##Id##Kind: \

276 return #Id;

277#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"

278#undef REGION

279 }

280 llvm_unreachable("Unkown kind!");

281}

282

283LLVM_DUMP_METHOD void SVal::dump() const { dumpToStream(llvm::errs()); }

284

286 std::string Buf;

287 llvm::raw_string_ostream TempOut(Buf);

288

289 dumpToStream(TempOut);

290

292}

293

295 if (isUndef()) {

296 os << "Undefined";

297 return;

298 }

299 if (isUnknown()) {

300 os << "Unknown";

301 return;

302 }

304 castAs().dumpToStream(os);

305 return;

306 }

308 castAs().dumpToStream(os);

309 return;

310 }

311 llvm_unreachable("Unhandled SVal kind!");

312}

313

316 case nonloc::ConcreteIntKind: {

317 APSIntPtr Value = castAsnonloc::ConcreteInt().getValue();

318 os << Value << ' ' << (Value->isSigned() ? 'S' : 'U')

319 << Value->getBitWidth() << 'b';

320 break;

321 }

322 case nonloc::SymbolValKind:

323 os << castAsnonloc::SymbolVal().getSymbol();

324 break;

325

326 case nonloc::LocAsIntegerKind: {

328 os << C.getLoc() << " [as " << C.getNumBits() << " bit integer]";

329 break;

330 }

331 case nonloc::CompoundValKind: {

333 os << "compoundVal{";

334 bool first = true;

335 for (const auto &I : C) {

336 if (first) {

337 os << ' '; first = false;

338 }

339 else

340 os << ", ";

341

342 I.dumpToStream(os);

343 }

344 os << "}";

345 break;

346 }

347 case nonloc::LazyCompoundValKind: {

349 os << "lazyCompoundVal{" << const_cast<void *>(C.getStore())

350 << ',' << C.getRegion()

351 << '}';

352 break;

353 }

354 case nonloc::PointerToMemberKind: {

355 os << "pointerToMember{";

357 castAsnonloc::PointerToMember();

360 bool first = true;

361 for (const auto &I : CastRes) {

362 if (first) {

363 os << ' '; first = false;

364 }

365 else

366 os << ", ";

367

368 os << I->getType();

369 }

370

371 os << '}';

372 break;

373 }

374 default:

375 assert(false && "Pretty-printed not implemented for this NonLoc.");

376 break;

377 }

378}

379

382 case loc::ConcreteIntKind:

383 os << castAsloc::ConcreteInt().getValue()->getZExtValue() << " (Loc)";

384 break;

385 case loc::GotoLabelKind:

386 os << "&&" << castAsloc::GotoLabel().getLabel()->getName();

387 break;

388 case loc::MemRegionValKind:

389 os << '&' << castAsloc::MemRegionVal().getRegion()->getString();

390 break;

391 default:

392 llvm_unreachable("Pretty-printing not implemented for this Loc.");

393 }

394}

Defines the clang::ASTContext interface.

static const MemRegion * getRegion(const CallEvent &Call, const MutexDescriptor &Descriptor, bool IsLock)

static Decl::Kind getKind(const Decl *D)

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.

C Language Family Type Representation.

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const

getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...

Represents a function declaration or definition.

This represents a decl that may have a name.

std::string getQualifiedNameAsString() const

A (possibly-)qualified type.

bool isNull() const

Return true if this QualType doesn't point to a type yet.

bool isSignedIntegerType() const

Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...

A safe wrapper around APSInt objects allocated and owned by BasicValueFactory.

AllocaRegion - A region that represents an untyped blob of bytes created by a call to 'alloca'.

FullSValVisitor - a convenient mixed visitor for all three: SVal, SymExpr and MemRegion subclasses.

FunctionCodeRegion - A region that represents code texts of function.

void dumpToStream(raw_ostream &Out) const

static bool classof(SVal V)

MemRegion - The root abstract class for all memory regions.

LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const

const SymbolicRegion * getSymbolicBase() const

If this is a symbolic region, returns the region.

const RegionTy * getAs() const

static bool classof(SVal V)

void dumpToStream(raw_ostream &Out) const

bool isZeroConstant() const

void dumpToStream(raw_ostream &OS) const

SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const

If this SVal wraps a symbol return that SymbolRef.

const FunctionDecl * getAsFunctionDecl() const

getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a CodeTextRegion wrapping a FunctionDecl...

void printJson(raw_ostream &Out, bool AddQuotes) const

printJson - Pretty-prints in JSON format.

StringRef getKindStr() const

QualType getType(const ASTContext &) const

Try to get a reasonable type for the given value.

const llvm::APSInt * getAsInteger() const

If this SVal is loc::ConcreteInt or nonloc::ConcreteInt, return a pointer to APSInt which is held in ...

SymbolRef getAsLocSymbol(bool IncludeBaseRegions=false) const

If this SVal is a location and wraps a symbol, return that SymbolRef.

const MemRegion * getAsRegion() const

SymbolRef getLocSymbolInBase() const

Get the symbol in the SVal or its base region.

virtual QualType getType() const =0

SymbolicRegion - A special, "non-concrete" region.

SymbolRef getSymbol() const

It might return null.

TypedRegion - An abstract class representing regions that are typed.

virtual QualType getLocationType() const =0

TypedValueRegion - An abstract class representing regions having a typed value.

virtual QualType getValueType() const =0

LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * stripCasts(bool StripBaseCasts=true) const

Get the underlining region and strip casts.

LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getRegion() const

Get the underlining region.

The simplest example of a concrete compound value is nonloc::CompoundVal, which represents a concrete...

LLVM_ATTRIBUTE_RETURNS_NONNULL const CompoundValData * getValue() const

llvm::ImmutableList< SVal >::iterator iterator

While nonloc::CompoundVal covers a few simple use cases, nonloc::LazyCompoundVal is a more performant...

LLVM_ATTRIBUTE_RETURNS_NONNULL const TypedValueRegion * getRegion() const

This function itself is immaterial.

const void * getStore() const

It might return null.

unsigned getNumBits() const

Value representing pointer-to-member.

bool isNullMemberPointer() const

llvm::PointerUnion< const NamedDecl *, const PointerToMemberData * > PTMDataType

llvm::ImmutableList< const CXXBaseSpecifier * >::iterator iterator

const NamedDecl * getDecl() const

Represents symbolic expression that isn't a location.

LLVM_ATTRIBUTE_RETURNS_NONNULL SymbolRef getSymbol() const

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

std::string JsonFormat(StringRef RawSR, bool AddQuotes)