clang 23.0.0git
ExprEngineC.cpp
Go to the documentation of this file.
1//=-- ExprEngineC.cpp - ExprEngine support for C expressions ----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines ExprEngine's support for C expressions.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/DeclCXX.h"
14#include "clang/AST/ExprCXX.h"
17#include <optional>
18
19using namespace clang;
20using namespace ento;
21using llvm::APSInt;
22
23/// Optionally conjure and return a symbol for offset when processing
24/// \p Elem.
25/// If \p Other is a location, conjure a symbol for \p Symbol
26/// (offset) if it is unknown so that memory arithmetic always
27/// results in an ElementRegion.
28/// \p Count The number of times the current basic block was visited.
31 SValBuilder &svalBuilder,
32 unsigned Count,
33 const StackFrame *SF) {
35 Symbol.isUnknown()) {
36 return svalBuilder.conjureSymbolVal(Elem, SF, Ty, Count);
37 }
38 return Symbol;
39}
40
42 ExplodedNode *Pred,
43 ExplodedNodeSet &Dst) {
44
45 Expr *LHS = B->getLHS()->IgnoreParens();
46 Expr *RHS = B->getRHS()->IgnoreParens();
47
48 // FIXME: Prechecks eventually go in ::Visit().
49 ExplodedNodeSet CheckedSet;
50 ExplodedNodeSet Tmp2;
51 getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, B, *this);
52
53 // With both the LHS and RHS evaluated, process the operation itself.
54 for (ExplodedNodeSet::iterator it=CheckedSet.begin(), ei=CheckedSet.end();
55 it != ei; ++it) {
56
57 ProgramStateRef state = (*it)->getState();
58 const StackFrame *SF = (*it)->getStackFrame();
59 SVal LeftV = state->getSVal(LHS, SF);
60 SVal RightV = state->getSVal(RHS, SF);
61
63
64 if (Op == BO_Assign) {
65 // EXPERIMENTAL: "Conjured" symbols.
66 // FIXME: Handle structs.
67 if (RightV.isUnknown()) {
68 unsigned Count = getNumVisitedCurrent();
69 RightV = svalBuilder.conjureSymbolVal(nullptr, getCFGElementRef(), SF,
70 Count);
71 }
72 // Simulate the effects of a "store": bind the value of the RHS
73 // to the L-Value represented by the LHS.
74 SVal ExprVal = B->isGLValue() ? LeftV : RightV;
75 evalStore(Tmp2, B, LHS, *it, state->BindExpr(B, SF, ExprVal), LeftV,
76 RightV);
77 continue;
78 }
79
80 if (!B->isAssignmentOp()) {
81 NodeBuilder Bldr(*it, Tmp2, *currBldrCtx);
82
83 if (B->isAdditiveOp()) {
84 // TODO: This can be removed after we enable history tracking with
85 // SymSymExpr.
86 unsigned Count = getNumVisitedCurrent();
88 RightV, LeftV, getCFGElementRef(), RHS->getType(), svalBuilder,
89 Count, SF);
90 LeftV = conjureOffsetSymbolOnLocation(LeftV, RightV, getCFGElementRef(),
91 LHS->getType(), svalBuilder,
92 Count, SF);
93 }
94
95 // Although we don't yet model pointers-to-members, we do need to make
96 // sure that the members of temporaries have a valid 'this' pointer for
97 // other checks.
98 if (B->getOpcode() == BO_PtrMemD)
99 state = createTemporaryRegionIfNeeded(state, SF, LHS);
100
101 // Process non-assignments except commas or short-circuited
102 // logical expressions (LAnd and LOr).
103 SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType());
104 if (!Result.isUnknown()) {
105 state = state->BindExpr(B, SF, Result);
106 } else {
107 // If we cannot evaluate the operation escape the operands.
108 state = escapeValues(state, LeftV, PSK_EscapeOther);
109 state = escapeValues(state, RightV, PSK_EscapeOther);
110 }
111
112 Bldr.generateNode(B, *it, state);
113 continue;
114 }
115
116 assert (B->isCompoundAssignmentOp());
117
118 switch (Op) {
119 default:
120 llvm_unreachable("Invalid opcode for compound assignment.");
121 case BO_MulAssign: Op = BO_Mul; break;
122 case BO_DivAssign: Op = BO_Div; break;
123 case BO_RemAssign: Op = BO_Rem; break;
124 case BO_AddAssign: Op = BO_Add; break;
125 case BO_SubAssign: Op = BO_Sub; break;
126 case BO_ShlAssign: Op = BO_Shl; break;
127 case BO_ShrAssign: Op = BO_Shr; break;
128 case BO_AndAssign: Op = BO_And; break;
129 case BO_XorAssign: Op = BO_Xor; break;
130 case BO_OrAssign: Op = BO_Or; break;
131 }
132
133 // Perform a load (the LHS). This performs the checks for
134 // null dereferences, and so on.
135 ExplodedNodeSet Tmp;
136 SVal location = LeftV;
137 evalLoad(Tmp, B, LHS, *it, state, location);
138
139 for (ExplodedNode *N : Tmp) {
140 state = N->getState();
141 const StackFrame *SF = N->getStackFrame();
142 SVal V = state->getSVal(LHS, SF);
143
144 // Get the computation type.
145 QualType CTy =
146 cast<CompoundAssignOperator>(B)->getComputationResultType();
147 CTy = getContext().getCanonicalType(CTy);
148
149 QualType CLHSTy =
150 cast<CompoundAssignOperator>(B)->getComputationLHSType();
151 CLHSTy = getContext().getCanonicalType(CLHSTy);
152
154
155 // Promote LHS.
156 V = svalBuilder.evalCast(V, CLHSTy, LTy);
157
158 // Compute the result of the operation.
159 SVal Result = svalBuilder.evalCast(evalBinOp(state, Op, V, RightV, CTy),
160 B->getType(), CTy);
161
162 // EXPERIMENTAL: "Conjured" symbols.
163 // FIXME: Handle structs.
164
165 SVal LHSVal;
166
167 if (Result.isUnknown()) {
168 // The symbolic value is actually for the type of the left-hand side
169 // expression, not the computation type, as this is the value the
170 // LValue on the LHS will bind to.
171 LHSVal = svalBuilder.conjureSymbolVal(/*symbolTag=*/nullptr,
172 getCFGElementRef(), SF, LTy,
174 // However, we need to convert the symbol to the computation type.
175 Result = svalBuilder.evalCast(LHSVal, CTy, LTy);
176 } else {
177 // The left-hand side may bind to a different value then the
178 // computation type.
179 LHSVal = svalBuilder.evalCast(Result, LTy, CTy);
180 }
181
182 // In C++, assignment and compound assignment operators return an
183 // lvalue.
184 if (B->isGLValue())
185 state = state->BindExpr(B, SF, location);
186 else
187 state = state->BindExpr(B, SF, Result);
188
189 evalStore(Tmp2, B, LHS, N, state, location, LHSVal);
190 }
191 }
192
193 // FIXME: postvisits eventually go in ::Visit()
194 getCheckerManager().runCheckersForPostStmt(Dst, Tmp2, B, *this);
195}
196
198 ExplodedNodeSet &Dst) {
199
201
202 const BlockDecl *BD = BE->getBlockDecl();
203 // Get the value of the block itself.
204 SVal V = svalBuilder.getBlockPointer(BD, T, Pred->getStackFrame(),
206
207 ProgramStateRef State = Pred->getState();
208
209 // If we created a new MemRegion for the block, we should explicitly bind
210 // the captured variables.
211 if (const BlockDataRegion *BDR =
212 dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) {
213
214 auto ReferencedVars = BDR->referenced_vars();
215 auto CI = BD->capture_begin();
216 auto CE = BD->capture_end();
217 for (auto Var : ReferencedVars) {
218 const VarRegion *capturedR = Var.getCapturedRegion();
219 const TypedValueRegion *originalR = Var.getOriginalRegion();
220
221 // If the capture had a copy expression, use the result of evaluating
222 // that expression, otherwise use the original value.
223 // We rely on the invariant that the block declaration's capture variables
224 // are a prefix of the BlockDataRegion's referenced vars (which may include
225 // referenced globals, etc.) to enable fast lookup of the capture for a
226 // given referenced var.
227 const Expr *copyExpr = nullptr;
228 if (CI != CE) {
229 assert(CI->getVariable() == capturedR->getDecl());
230 copyExpr = CI->getCopyExpr();
231 CI++;
232 }
233
234 if (capturedR != originalR) {
235 SVal originalV;
236 const StackFrame *SF = Pred->getStackFrame();
237 if (copyExpr) {
238 originalV = State->getSVal(copyExpr, SF);
239 } else {
240 originalV = State->getSVal(loc::MemRegionVal(originalR));
241 }
242 State = State->bindLoc(loc::MemRegionVal(capturedR), originalV, SF);
243 }
244 }
245 }
246
247 ExplodedNodeSet Tmp;
248 NodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
249 Bldr.generateNode(BE, Pred, State->BindExpr(BE, Pred->getStackFrame(), V),
251
252 // FIXME: Move all post/pre visits to ::Visit().
253 getCheckerManager().runCheckersForPostStmt(Dst, Tmp, BE, *this);
254}
255
258 const StackFrame *SF, QualType T, QualType ExTy,
259 const CastExpr *CastE, NodeBuilder &Bldr,
260 ExplodedNode *Pred) {
261 if (T->isLValueReferenceType()) {
262 assert(!CastE->getType()->isLValueReferenceType());
263 ExTy = getContext().getLValueReferenceType(ExTy);
264 } else if (T->isRValueReferenceType()) {
265 assert(!CastE->getType()->isRValueReferenceType());
266 ExTy = getContext().getRValueReferenceType(ExTy);
267 }
268 // Delegate to SValBuilder to process.
269 SVal OrigV = state->getSVal(Ex, SF);
270 SVal SimplifiedOrigV = svalBuilder.simplifySVal(state, OrigV);
271 SVal V = svalBuilder.evalCast(SimplifiedOrigV, T, ExTy);
272 // Negate the result if we're treating the boolean as a signed i1
273 if (CastE->getCastKind() == CK_BooleanToSignedIntegral && V.isValid())
274 V = svalBuilder.evalMinus(V.castAs<NonLoc>());
275
276 state = state->BindExpr(CastE, SF, V);
277 if (V.isUnknown() && !OrigV.isUnknown()) {
278 state = escapeValues(state, OrigV, PSK_EscapeOther);
279 }
280 Bldr.generateNode(CastE, Pred, state);
281
282 return state;
283}
284
285void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
286 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
287
288 ExplodedNodeSet DstPreStmt;
289 getCheckerManager().runCheckersForPreStmt(DstPreStmt, Pred, CastE, *this);
290
291 if (CastE->getCastKind() == CK_LValueToRValue) {
292 for (ExplodedNode *Node : DstPreStmt) {
293 ProgramStateRef State = Node->getState();
294 const StackFrame *SF = Node->getStackFrame();
295 evalLoad(Dst, CastE, CastE, Node, State, State->getSVal(Ex, SF));
296 }
297 return;
298 }
299 if (CastE->getCastKind() == CK_LValueToRValueBitCast) {
300 // Handle `__builtin_bit_cast`:
301 ExplodedNodeSet DstEvalLoc;
302
303 // Simulate the lvalue-to-rvalue conversion on `Ex`:
304 for (ExplodedNode *Node : DstPreStmt) {
305 ProgramStateRef State = Node->getState();
306 const StackFrame *SF = Node->getStackFrame();
307 evalLocation(DstEvalLoc, CastE, Ex, Node, State, State->getSVal(Ex, SF),
308 true);
309 }
310 // Simulate the operation that actually casts the original value to a new
311 // value of the destination type :
312 NodeBuilder Bldr(DstEvalLoc, Dst, *currBldrCtx);
313
314 for (ExplodedNode *Node : DstEvalLoc) {
315 ProgramStateRef State = Node->getState();
316 const StackFrame *SF = Node->getStackFrame();
317 // Although `Ex` is an lvalue, it could have `Loc::ConcreteInt` kind
318 // (e.g., `(int *)123456`). In such cases, there is no MemRegion
319 // available and we can't get the value to be casted.
320 SVal CastedV = UnknownVal();
321
322 if (const MemRegion *MR = State->getSVal(Ex, SF).getAsRegion()) {
323 SVal OrigV = State->getSVal(MR);
324 CastedV = svalBuilder.evalCast(svalBuilder.simplifySVal(State, OrigV),
325 CastE->getType(), Ex->getType());
326 }
327 State = State->BindExpr(CastE, SF, CastedV);
328 Bldr.generateNode(CastE, Node, State);
329 }
330 return;
331 }
332
333 // All other casts.
334 QualType T = CastE->getType();
335 QualType ExTy = Ex->getType();
336
337 if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE))
338 T = ExCast->getTypeAsWritten();
339
340 NodeBuilder Bldr(DstPreStmt, Dst, *currBldrCtx);
341 for (ExplodedNode *Pred : DstPreStmt) {
342 ProgramStateRef state = Pred->getState();
343 const StackFrame *SF = Pred->getStackFrame();
344
345 switch (CastE->getCastKind()) {
346 case CK_LValueToRValue:
347 case CK_LValueToRValueBitCast:
348 llvm_unreachable("LValueToRValue casts handled earlier.");
349 case CK_ToVoid:
350 continue;
351 // The analyzer doesn't do anything special with these casts,
352 // since it understands retain/release semantics already.
353 case CK_ARCProduceObject:
354 case CK_ARCConsumeObject:
355 case CK_ARCReclaimReturnedObject:
356 case CK_ARCExtendBlockObject: // Fall-through.
357 case CK_CopyAndAutoreleaseBlockObject:
358 // The analyser can ignore atomic casts for now, although some future
359 // checkers may want to make certain that you're not modifying the same
360 // value through atomic and nonatomic pointers.
361 case CK_AtomicToNonAtomic:
362 case CK_NonAtomicToAtomic:
363 // True no-ops.
364 case CK_NoOp:
365 case CK_ConstructorConversion:
366 case CK_UserDefinedConversion:
367 case CK_FunctionToPointerDecay:
368 case CK_BuiltinFnToFnPtr:
369 case CK_HLSLArrayRValue: {
370 // Copy the SVal of Ex to CastE.
371 ProgramStateRef state = Pred->getState();
372 const StackFrame *SF = Pred->getStackFrame();
373 SVal V = state->getSVal(Ex, SF);
374 state = state->BindExpr(CastE, SF, V);
375 Bldr.generateNode(CastE, Pred, state);
376 continue;
377 }
378 case CK_MemberPointerToBoolean:
379 case CK_PointerToBoolean: {
380 SVal V = state->getSVal(Ex, SF);
381 auto PTMSV = V.getAs<nonloc::PointerToMember>();
382 if (PTMSV)
383 V = svalBuilder.makeTruthVal(!PTMSV->isNullMemberPointer(), ExTy);
384 if (V.isUndef() || PTMSV) {
385 state = state->BindExpr(CastE, SF, V);
386 Bldr.generateNode(CastE, Pred, state);
387 continue;
388 }
389 // Explicitly proceed with default handler for this case cascade.
390 state = handleLValueBitCast(state, Ex, SF, T, ExTy, CastE, Bldr, Pred);
391 continue;
392 }
393 case CK_Dependent:
394 case CK_ArrayToPointerDecay:
395 case CK_BitCast:
396 case CK_AddressSpaceConversion:
397 case CK_BooleanToSignedIntegral:
398 case CK_IntegralToPointer:
399 case CK_PointerToIntegral: {
400 SVal V = state->getSVal(Ex, SF);
402 state = state->BindExpr(CastE, SF, UnknownVal());
403 Bldr.generateNode(CastE, Pred, state);
404 continue;
405 }
406 // Explicitly proceed with default handler for this case cascade.
407 state = handleLValueBitCast(state, Ex, SF, T, ExTy, CastE, Bldr, Pred);
408 continue;
409 }
410 case CK_IntegralToBoolean:
411 case CK_IntegralToFloating:
412 case CK_FloatingToIntegral:
413 case CK_FloatingToBoolean:
414 case CK_FloatingCast:
415 case CK_FloatingRealToComplex:
416 case CK_FloatingComplexToReal:
417 case CK_FloatingComplexToBoolean:
418 case CK_FloatingComplexCast:
419 case CK_FloatingComplexToIntegralComplex:
420 case CK_IntegralRealToComplex:
421 case CK_IntegralComplexToReal:
422 case CK_IntegralComplexToBoolean:
423 case CK_IntegralComplexCast:
424 case CK_IntegralComplexToFloatingComplex:
425 case CK_CPointerToObjCPointerCast:
426 case CK_BlockPointerToObjCPointerCast:
427 case CK_AnyPointerToBlockPointerCast:
428 case CK_ObjCObjectLValueCast:
429 case CK_ZeroToOCLOpaqueType:
430 case CK_IntToOCLSampler:
431 case CK_LValueBitCast:
432 case CK_FloatingToFixedPoint:
433 case CK_FixedPointToFloating:
434 case CK_FixedPointCast:
435 case CK_FixedPointToBoolean:
436 case CK_FixedPointToIntegral:
437 case CK_IntegralToFixedPoint: {
438 state = handleLValueBitCast(state, Ex, SF, T, ExTy, CastE, Bldr, Pred);
439 continue;
440 }
441 case CK_IntegralCast: {
442 // Delegate to SValBuilder to process.
443 SVal V = state->getSVal(Ex, SF);
444 if (AMgr.options.ShouldSupportSymbolicIntegerCasts)
445 V = svalBuilder.evalCast(V, T, ExTy);
446 else
447 V = svalBuilder.evalIntegralCast(state, V, T, ExTy);
448 state = state->BindExpr(CastE, SF, V);
449 Bldr.generateNode(CastE, Pred, state);
450 continue;
451 }
452 case CK_DerivedToBase:
453 case CK_UncheckedDerivedToBase: {
454 // For DerivedToBase cast, delegate to the store manager.
455 SVal val = state->getSVal(Ex, SF);
456 val = getStoreManager().evalDerivedToBase(val, CastE);
457 state = state->BindExpr(CastE, SF, val);
458 Bldr.generateNode(CastE, Pred, state);
459 continue;
460 }
461 // Handle C++ dyn_cast.
462 case CK_Dynamic: {
463 SVal val = state->getSVal(Ex, SF);
464
465 // Compute the type of the result.
466 QualType resultType = CastE->getType();
467 if (CastE->isGLValue())
468 resultType = getContext().getPointerType(resultType);
469
470 bool Failed = true;
471
472 // Check if the value being cast does not evaluates to 0.
473 if (!val.isZeroConstant())
474 if (std::optional<SVal> V =
475 StateMgr.getStoreManager().evalBaseToDerived(val, T)) {
476 val = *V;
477 Failed = false;
478 }
479
480 if (Failed) {
481 if (T->isReferenceType()) {
482 // A bad_cast exception is thrown if input value is a reference.
483 // Currently, we model this, by generating a sink.
484 Bldr.generateSink(CastE, Pred, state);
485 continue;
486 } else {
487 // If the cast fails on a pointer, bind to 0.
488 state = state->BindExpr(CastE, SF,
489 svalBuilder.makeNullWithType(resultType));
490 }
491 } else {
492 // If we don't know if the cast succeeded, conjure a new symbol.
493 if (val.isUnknown()) {
494 DefinedOrUnknownSVal NewSym = svalBuilder.conjureSymbolVal(
495 /*symbolTag=*/nullptr, getCFGElementRef(), SF, resultType,
497 state = state->BindExpr(CastE, SF, NewSym);
498 } else
499 // Else, bind to the derived region value.
500 state = state->BindExpr(CastE, SF, val);
501 }
502 Bldr.generateNode(CastE, Pred, state);
503 continue;
504 }
505 case CK_BaseToDerived: {
506 SVal val = state->getSVal(Ex, SF);
507 QualType resultType = CastE->getType();
508 if (CastE->isGLValue())
509 resultType = getContext().getPointerType(resultType);
510
511 if (!val.isConstant()) {
512 std::optional<SVal> V = getStoreManager().evalBaseToDerived(val, T);
513 val = V ? *V : UnknownVal();
514 }
515
516 // Failed to cast or the result is unknown, fall back to conservative.
517 if (val.isUnknown()) {
518 val = svalBuilder.conjureSymbolVal(
519 /*symbolTag=*/nullptr, getCFGElementRef(), SF, resultType,
521 }
522 state = state->BindExpr(CastE, SF, val);
523 Bldr.generateNode(CastE, Pred, state);
524 continue;
525 }
526 case CK_NullToPointer: {
527 SVal V = svalBuilder.makeNullWithType(CastE->getType());
528 state = state->BindExpr(CastE, SF, V);
529 Bldr.generateNode(CastE, Pred, state);
530 continue;
531 }
532 case CK_NullToMemberPointer: {
533 SVal V = svalBuilder.getMemberPointer(nullptr);
534 state = state->BindExpr(CastE, SF, V);
535 Bldr.generateNode(CastE, Pred, state);
536 continue;
537 }
538 case CK_DerivedToBaseMemberPointer:
539 case CK_BaseToDerivedMemberPointer:
540 case CK_ReinterpretMemberPointer: {
541 SVal V = state->getSVal(Ex, SF);
542 if (auto PTMSV = V.getAs<nonloc::PointerToMember>()) {
543 SVal CastedPTMSV =
544 svalBuilder.makePointerToMember(getBasicVals().accumCXXBase(
545 CastE->path(), *PTMSV, CastE->getCastKind()));
546 state = state->BindExpr(CastE, SF, CastedPTMSV);
547 Bldr.generateNode(CastE, Pred, state);
548 continue;
549 }
550 // Explicitly proceed with default handler for this case cascade.
551 }
552 [[fallthrough]];
553 // Various C++ casts that are not handled yet.
554 case CK_ToUnion:
555 case CK_MatrixCast:
556 case CK_VectorSplat:
557 case CK_HLSLElementwiseCast:
558 case CK_HLSLAggregateSplatCast:
559 case CK_HLSLMatrixTruncation:
560 case CK_HLSLVectorTruncation: {
561 QualType resultType = CastE->getType();
562 if (CastE->isGLValue())
563 resultType = getContext().getPointerType(resultType);
564 SVal result = svalBuilder.conjureSymbolVal(
565 /*symbolTag=*/nullptr, getCFGElementRef(), SF, resultType,
567 state = state->BindExpr(CastE, SF, result);
568 Bldr.generateNode(CastE, Pred, state);
569 continue;
570 }
571 }
572 }
573}
574
576 ExplodedNode *Pred,
577 ExplodedNodeSet &Dst) {
578 NodeBuilder B(Pred, Dst, *currBldrCtx);
579
580 ProgramStateRef State = Pred->getState();
581 const StackFrame *SF = Pred->getStackFrame();
582
583 const Expr *Init = CL->getInitializer();
584 SVal V = State->getSVal(CL->getInitializer(), SF);
585
587 // No work needed. Just pass the value up to this expression.
588 } else {
589 assert(isa<InitListExpr>(Init));
590 Loc CLLoc = State->getLValue(CL, SF);
591 State = State->bindLoc(CLLoc, V, SF);
592
593 if (CL->isGLValue())
594 V = CLLoc;
595 }
596
597 B.generateNode(CL, Pred, State->BindExpr(CL, SF, V));
598}
599
601 ExplodedNodeSet &Dst) {
602 if (isa<TypedefNameDecl>(*DS->decl_begin())) {
603 // C99 6.7.7 "Any array size expressions associated with variable length
604 // array declarators are evaluated each time the declaration of the typedef
605 // name is reached in the order of execution."
606 // The checkers should know about typedef to be able to handle VLA size
607 // expressions.
608 ExplodedNodeSet DstPre;
609 getCheckerManager().runCheckersForPreStmt(DstPre, Pred, DS, *this);
610 getCheckerManager().runCheckersForPostStmt(Dst, DstPre, DS, *this);
611 return;
612 }
613
614 // Assumption: The CFG has one DeclStmt per Decl.
615 const VarDecl *VD = dyn_cast_or_null<VarDecl>(*DS->decl_begin());
616
617 if (!VD) {
618 //TODO:AZ: remove explicit insertion after refactoring is done.
619 Dst.insert(Pred);
620 return;
621 }
622
623 // FIXME: all pre/post visits should eventually be handled by ::Visit().
624 ExplodedNodeSet dstPreVisit;
625 getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this);
626
627 ExplodedNodeSet dstEvaluated;
628 NodeBuilder B(dstPreVisit, dstEvaluated, *currBldrCtx);
629 for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
630 I!=E; ++I) {
631 ExplodedNode *N = *I;
632 ProgramStateRef state = N->getState();
633 const StackFrame *SF = N->getStackFrame();
634
635 // Decls without InitExpr are not initialized explicitly.
636 if (const Expr *InitEx = VD->getInit()) {
637
638 // Note in the state that the initialization has occurred.
639 ExplodedNode *UpdatedN = N;
640 SVal InitVal = state->getSVal(InitEx, SF);
641
642 assert(DS->isSingleDecl());
643 if (getObjectUnderConstruction(state, DS, SF)) {
644 state = finishObjectConstruction(state, DS, SF);
645 // We constructed the object directly in the variable.
646 // No need to bind anything.
647 B.generateNode(DS, UpdatedN, state);
648 } else {
649 // Recover some path-sensitivity if a scalar value evaluated to
650 // UnknownVal.
651 if (InitVal.isUnknown()) {
652 QualType Ty = InitEx->getType();
653 if (InitEx->isGLValue()) {
654 Ty = getContext().getPointerType(Ty);
655 }
656
657 InitVal = svalBuilder.conjureSymbolVal(
658 /*symbolTag=*/nullptr, getCFGElementRef(), SF, Ty,
660 }
661
662
663 B.takeNodes(UpdatedN);
664 ExplodedNodeSet Dst2;
665 evalBind(Dst2, DS, UpdatedN, state->getLValue(VD, SF), InitVal, true);
666 B.addNodes(Dst2);
667 }
668 }
669 else {
670 B.generateNode(DS, N, state);
671 }
672 }
673
675}
676
678 ExplodedNodeSet &Dst) {
679 // This method acts upon CFG elements for logical operators && and ||
680 // and attaches the value (true or false) to them as expressions.
681 // It doesn't produce any state splits.
682 // If we made it that far, we're past the point when we modeled the short
683 // circuit. It means that we should have precise knowledge about whether
684 // we've short-circuited. If we did, we already know the value we need to
685 // bind. If we didn't, the value of the RHS (casted to the boolean type)
686 // is the answer.
687 // Currently this method tries to figure out whether we've short-circuited
688 // by looking at the ExplodedGraph. This method is imperfect because there
689 // could inevitably have been merges that would have resulted in multiple
690 // potential path traversal histories. We bail out when we fail.
691 // Due to this ambiguity, a more reliable solution would have been to
692 // track the short circuit operation history path-sensitively until
693 // we evaluate the respective logical operator.
694 assert(B->getOpcode() == BO_LAnd ||
695 B->getOpcode() == BO_LOr);
696
697 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
698 ProgramStateRef state = Pred->getState();
699
700 if (B->getType()->isVectorType()) {
701 // FIXME: We do not model vector arithmetic yet. When adding support for
702 // that, note that the CFG-based reasoning below does not apply, because
703 // logical operators on vectors are not short-circuit. Currently they are
704 // modeled as short-circuit in Clang CFG but this is incorrect.
705 // Do not set the value for the expression. It'd be UnknownVal by default.
706 Bldr.generateNode(B, Pred, state);
707 return;
708 }
709
710 ExplodedNode *N = Pred;
711 while (!N->getLocation().getAs<BlockEdge>()) {
712 ProgramPoint P = N->getLocation();
713 assert(P.getAs<PreStmt>() || P.getAs<PreStmtPurgeDeadSymbols>() ||
714 P.getAs<BlockEntrance>());
715 (void) P;
716 if (N->pred_size() != 1) {
717 // We failed to track back where we came from.
718 Bldr.generateNode(B, Pred, state);
719 return;
720 }
721 N = *N->pred_begin();
722 }
723
724 if (N->pred_size() != 1) {
725 // We failed to track back where we came from.
726 Bldr.generateNode(B, Pred, state);
727 return;
728 }
729
731 SVal X;
732
733 // Determine the value of the expression by introspecting how we
734 // got this location in the CFG. This requires looking at the previous
735 // block we were in and what kind of control-flow transfer was involved.
736 const CFGBlock *SrcBlock = BE.getSrc();
737 // The only terminator (if there is one) that makes sense is a logical op.
738 CFGTerminator T = SrcBlock->getTerminator();
739 if (const BinaryOperator *Term = cast_or_null<BinaryOperator>(T.getStmt())) {
740 (void) Term;
741 assert(Term->isLogicalOp());
742 assert(SrcBlock->succ_size() == 2);
743 // Did we take the true or false branch?
744 unsigned constant = (*SrcBlock->succ_begin() == BE.getDst()) ? 1 : 0;
745 X = svalBuilder.makeIntVal(constant, B->getType());
746 }
747 else {
748 // If there is no terminator, by construction the last statement
749 // in SrcBlock is the value of the enclosing expression.
750 // However, we still need to constrain that value to be 0 or 1.
751 assert(!SrcBlock->empty());
752 CFGStmt Elem = SrcBlock->rbegin()->castAs<CFGStmt>();
753 const Expr *RHS = cast<Expr>(Elem.getStmt());
754 SVal RHSVal = N->getState()->getSVal(RHS, Pred->getStackFrame());
755
756 if (RHSVal.isUndef()) {
757 X = RHSVal;
758 } else {
759 // We evaluate "RHSVal != 0" expression which result in 0 if the value is
760 // known to be false, 1 if the value is known to be true and a new symbol
761 // when the assumption is unknown.
762 nonloc::ConcreteInt Zero(getBasicVals().getValue(0, B->getType()));
763 X = evalBinOp(N->getState(), BO_NE,
764 svalBuilder.evalCast(RHSVal, B->getType(), RHS->getType()),
765 Zero, B->getType());
766 }
767 }
768 Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getStackFrame(), X));
769}
770
772 const Expr *L,
773 const Expr *R,
774 ExplodedNode *Pred,
775 ExplodedNodeSet &Dst) {
776 assert(L && R);
777
778 NodeBuilder B(Pred, Dst, *currBldrCtx);
779 ProgramStateRef state = Pred->getState();
780 const StackFrame *SF = Pred->getStackFrame();
781 const CFGBlock *SrcBlock = nullptr;
782
783 // Find the predecessor block.
784 ProgramStateRef SrcState = state;
785 for (const ExplodedNode *N = Pred ; N ; N = *N->pred_begin()) {
786 auto Edge = N->getLocationAs<BlockEdge>();
787 if (!Edge.has_value()) {
788 // If the state N has multiple predecessors P, it means that successors
789 // of P are all equivalent.
790 // In turn, that means that all nodes at P are equivalent in terms
791 // of observable behavior at N, and we can follow any of them.
792 // FIXME: a more robust solution which does not walk up the tree.
793 continue;
794 }
795 SrcBlock = Edge->getSrc();
796 SrcState = N->getState();
797 break;
798 }
799
800 assert(SrcBlock && "missing function entry");
801
802 // Find the last expression in the predecessor block. That is the
803 // expression that is used for the value of the ternary expression.
804 bool hasValue = false;
805 SVal V;
806
807 for (CFGElement CE : llvm::reverse(*SrcBlock)) {
808 if (std::optional<CFGStmt> CS = CE.getAs<CFGStmt>()) {
809 const Expr *ValEx = cast<Expr>(CS->getStmt());
810 ValEx = ValEx->IgnoreParens();
811
812 // For GNU extension '?:' operator, the left hand side will be an
813 // OpaqueValueExpr, so get the underlying expression.
814 if (const OpaqueValueExpr *OpaqueEx = dyn_cast<OpaqueValueExpr>(L))
815 L = OpaqueEx->getSourceExpr();
816
817 // If the last expression in the predecessor block matches true or false
818 // subexpression, get its the value.
819 if (ValEx == L->IgnoreParens() || ValEx == R->IgnoreParens()) {
820 hasValue = true;
821 V = SrcState->getSVal(ValEx, SF);
822 }
823 break;
824 }
825 }
826
827 if (!hasValue)
828 V = svalBuilder.conjureSymbolVal(nullptr, getCFGElementRef(), SF,
830
831 // Generate a new node with the binding from the appropriate path.
832 B.generateNode(Ex, Pred, state->BindExpr(Ex, SF, V, true));
833}
834
837 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
838 NodeBuilder B(Pred, Dst, *currBldrCtx);
840 if (OOE->EvaluateAsInt(Result, getContext())) {
841 APSInt IV = Result.Val.getInt();
842 assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType()));
843 assert(OOE->getType()->castAs<BuiltinType>()->isInteger());
844 assert(IV.isSigned() == OOE->getType()->isSignedIntegerType());
845 SVal X = svalBuilder.makeIntVal(IV);
846 B.generateNode(OOE, Pred,
847 Pred->getState()->BindExpr(OOE, Pred->getStackFrame(), X));
848 }
849 // FIXME: Handle the case where __builtin_offsetof is not a constant.
850}
851
852
855 ExplodedNode *Pred,
856 ExplodedNodeSet &Dst) {
857 // FIXME: Prechecks eventually go in ::Visit().
858 ExplodedNodeSet CheckedSet;
859 getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, Ex, *this);
860
861 ExplodedNodeSet EvalSet;
862 NodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
863
864 QualType T = Ex->getTypeOfArgument();
865
866 for (ExplodedNode *N : CheckedSet) {
867 if (Ex->getKind() == UETT_SizeOf || Ex->getKind() == UETT_DataSizeOf ||
868 Ex->getKind() == UETT_CountOf) {
869 if (!T->isIncompleteType() && !T->isConstantSizeType()) {
870 assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");
871
872 // FIXME: Add support for VLA type arguments and VLA expressions.
873 // When that happens, we should probably refactor VLASizeChecker's code.
874 continue;
875 } else if (T->getAs<ObjCObjectType>()) {
876 // Some code tries to take the sizeof an ObjCObjectType, relying that
877 // the compiler has laid out its representation. Just report Unknown
878 // for these.
879 continue;
880 }
881 }
882
883 APSInt Value = Ex->EvaluateKnownConstInt(getContext());
884 CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue());
885
886 ProgramStateRef state = N->getState();
887 state = state->BindExpr(
888 Ex, N->getStackFrame(),
889 svalBuilder.makeIntVal(amt.getQuantity(), Ex->getType()));
890 Bldr.generateNode(Ex, N, state);
891 }
892
893 getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, Ex, *this);
894}
895
897 NodeBuilder &Bldr) {
898 // FIXME: We can probably just have some magic in Environment::getSVal()
899 // that propagates values, instead of creating a new node here.
900 //
901 // Unary "+" is a no-op, similar to a parentheses. We still have places
902 // where it may be a block-level expression, so we need to
903 // generate an extra node that just propagates the value of the
904 // subexpression.
905 const Expr *Ex = U->getSubExpr()->IgnoreParens();
906 ProgramStateRef state = N->getState();
907 const StackFrame *SF = N->getStackFrame();
908 Bldr.generateNode(U, N, state->BindExpr(U, SF, state->getSVal(Ex, SF)));
909}
910
912 ExplodedNodeSet &Dst) {
913 // FIXME: Prechecks eventually go in ::Visit().
914 ExplodedNodeSet CheckedSet;
915 getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, U, *this);
916
917 ExplodedNodeSet EvalSet;
918 NodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
919
920 for (ExplodedNode *N : CheckedSet) {
921 switch (U->getOpcode()) {
922 default: {
923 Bldr.takeNodes(N);
924 ExplodedNodeSet Tmp;
926 Bldr.addNodes(Tmp);
927 break;
928 }
929 case UO_Real: {
930 const Expr *Ex = U->getSubExpr()->IgnoreParens();
931
932 // FIXME: We don't have complex SValues yet.
933 if (Ex->getType()->isAnyComplexType()) {
934 // Just report "Unknown."
935 break;
936 }
937
938 // For all other types, UO_Real is an identity operation.
939 assert (U->getType() == Ex->getType());
940 ProgramStateRef state = N->getState();
941 const StackFrame *SF = N->getStackFrame();
942 Bldr.generateNode(U, N, state->BindExpr(U, SF, state->getSVal(Ex, SF)));
943 break;
944 }
945
946 case UO_Imag: {
947 const Expr *Ex = U->getSubExpr()->IgnoreParens();
948 // FIXME: We don't have complex SValues yet.
949 if (Ex->getType()->isAnyComplexType()) {
950 // Just report "Unknown."
951 break;
952 }
953 // For all other types, UO_Imag returns 0.
954 ProgramStateRef state = N->getState();
955 const StackFrame *SF = N->getStackFrame();
956 SVal X = svalBuilder.makeZeroVal(Ex->getType());
957 Bldr.generateNode(U, N, state->BindExpr(U, SF, X));
958 break;
959 }
960
961 case UO_AddrOf: {
962 // Process pointer-to-member address operation.
963 const Expr *Ex = U->getSubExpr()->IgnoreParens();
964 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Ex)) {
965 const ValueDecl *VD = DRE->getDecl();
966
968 ProgramStateRef State = N->getState();
969 const StackFrame *SF = N->getStackFrame();
970 SVal SV = svalBuilder.getMemberPointer(cast<NamedDecl>(VD));
971 Bldr.generateNode(U, N, State->BindExpr(U, SF, SV));
972 break;
973 }
974 }
975 // Explicitly proceed with default handler for this case cascade.
976 handleUOExtension(N, U, Bldr);
977 break;
978 }
979 case UO_Plus:
980 assert(!U->isGLValue());
981 [[fallthrough]];
982 case UO_Deref:
983 case UO_Extension: {
984 handleUOExtension(N, U, Bldr);
985 break;
986 }
987
988 case UO_LNot:
989 case UO_Minus:
990 case UO_Not: {
991 assert (!U->isGLValue());
992 const Expr *Ex = U->getSubExpr()->IgnoreParens();
993 ProgramStateRef state = N->getState();
994 const StackFrame *SF = N->getStackFrame();
995
996 // Get the value of the subexpression.
997 SVal V = state->getSVal(Ex, SF);
998
999 if (V.isUnknownOrUndef()) {
1000 Bldr.generateNode(U, N, state->BindExpr(U, SF, V));
1001 break;
1002 }
1003
1004 switch (U->getOpcode()) {
1005 default:
1006 llvm_unreachable("Invalid Opcode.");
1007 case UO_Not:
1008 // FIXME: Do we need to handle promotions?
1009 state = state->BindExpr(
1010 U, SF, svalBuilder.evalComplement(V.castAs<NonLoc>()));
1011 break;
1012 case UO_Minus:
1013 // FIXME: Do we need to handle promotions?
1014 state =
1015 state->BindExpr(U, SF, svalBuilder.evalMinus(V.castAs<NonLoc>()));
1016 break;
1017 case UO_LNot:
1018 // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
1019 //
1020 // Note: technically we do "E == 0", but this is the same in the
1021 // transfer functions as "0 == E".
1022 SVal Result;
1023 if (std::optional<Loc> LV = V.getAs<Loc>()) {
1024 Loc X = svalBuilder.makeNullWithType(Ex->getType());
1025 Result = evalBinOp(state, BO_EQ, *LV, X, U->getType());
1026 } else if (Ex->getType()->isFloatingType()) {
1027 // FIXME: handle floating point types.
1028 Result = UnknownVal();
1029 } else {
1030 nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
1031 Result = evalBinOp(state, BO_EQ, V.castAs<NonLoc>(), X, U->getType());
1032 }
1033
1034 state = state->BindExpr(U, SF, Result);
1035 break;
1036 }
1037 Bldr.generateNode(U, N, state);
1038 break;
1039 }
1040 }
1041 }
1042
1043 getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, U, *this);
1044}
1045
1047 ExplodedNode *Pred,
1048 ExplodedNodeSet &Dst) {
1049 // Handle ++ and -- (both pre- and post-increment).
1050 assert (U->isIncrementDecrementOp());
1051 const Expr *Ex = U->getSubExpr()->IgnoreParens();
1052
1053 const StackFrame *SF = Pred->getStackFrame();
1054 ProgramStateRef state = Pred->getState();
1055 SVal loc = state->getSVal(Ex, SF);
1056
1057 // Perform a load.
1058 ExplodedNodeSet Tmp;
1059 evalLoad(Tmp, U, Ex, Pred, state, loc);
1060
1061 ExplodedNodeSet Dst2;
1062 NodeBuilder Bldr(Tmp, Dst2, *currBldrCtx);
1063 for (ExplodedNode *N : Tmp) {
1064 state = N->getState();
1065 assert(SF == N->getStackFrame());
1066 SVal V2_untested = state->getSVal(Ex, SF);
1067
1068 // Propagate unknown and undefined values.
1069 if (V2_untested.isUnknownOrUndef()) {
1070 state = state->BindExpr(U, SF, V2_untested);
1071
1072 // Perform the store, so that the uninitialized value detection happens.
1073 Bldr.takeNodes(N);
1074 ExplodedNodeSet Dst3;
1075 evalStore(Dst3, U, Ex, N, state, loc, V2_untested);
1076 Bldr.addNodes(Dst3);
1077
1078 continue;
1079 }
1080 DefinedSVal V2 = V2_untested.castAs<DefinedSVal>();
1081
1082 // Handle all other values.
1083 BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add : BO_Sub;
1084
1085 // If the UnaryOperator has non-location type, use its type to create the
1086 // constant value. If the UnaryOperator has location type, create the
1087 // constant with int type and pointer width.
1088 SVal RHS;
1089 SVal Result;
1090
1091 if (U->getType()->isAnyPointerType())
1092 RHS = svalBuilder.makeArrayIndex(1);
1093 else if (U->getType()->isIntegralOrEnumerationType())
1094 RHS = svalBuilder.makeIntVal(1, U->getType());
1095 else
1096 RHS = UnknownVal();
1097
1098 // The use of an operand of type bool with the ++ operators is deprecated
1099 // but valid until C++17. And if the operand of the ++ operator is of type
1100 // bool, it is set to true until C++17. Note that for '_Bool', it is also
1101 // set to true when it encounters ++ operator.
1102 if (U->getType()->isBooleanType() && U->isIncrementOp())
1103 Result = svalBuilder.makeTruthVal(true, U->getType());
1104 else
1105 Result = evalBinOp(state, Op, V2, RHS, U->getType());
1106
1107 // Conjure a new symbol if necessary to recover precision.
1108 if (Result.isUnknown()){
1109 DefinedOrUnknownSVal SymVal = svalBuilder.conjureSymbolVal(
1110 /*symbolTag=*/nullptr, getCFGElementRef(), SF,
1112 Result = SymVal;
1113
1114 // If the value is a location, ++/-- should always preserve
1115 // non-nullness. Check if the original value was non-null, and if so
1116 // propagate that constraint.
1117 if (Loc::isLocType(U->getType())) {
1118 DefinedOrUnknownSVal Constraint =
1119 svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType()));
1120
1121 if (!state->assume(Constraint, true)) {
1122 // It isn't feasible for the original value to be null.
1123 // Propagate this constraint.
1124 Constraint = svalBuilder.evalEQ(state, SymVal,
1125 svalBuilder.makeZeroVal(U->getType()));
1126
1127 state = state->assume(Constraint, false);
1128 assert(state);
1129 }
1130 }
1131 }
1132
1133 // Since the lvalue-to-rvalue conversion is explicit in the AST,
1134 // we bind an l-value if the operator is prefix and an lvalue (in C++).
1135 if (U->isGLValue())
1136 state = state->BindExpr(U, SF, loc);
1137 else
1138 state = state->BindExpr(U, SF, U->isPostfix() ? V2 : Result);
1139
1140 // Perform the store.
1141 Bldr.takeNodes(N);
1142 ExplodedNodeSet Dst3;
1143 evalStore(Dst3, U, Ex, N, state, loc, Result);
1144 Bldr.addNodes(Dst3);
1145 }
1146 Dst.insert(Dst2);
1147}
#define V(N, I)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
static SVal conjureOffsetSymbolOnLocation(SVal Symbol, SVal Other, ConstCFGElementRef Elem, QualType Ty, SValBuilder &svalBuilder, unsigned Count, const StackFrame *SF)
Optionally conjure and return a symbol for offset when processing Elem.
#define X(type, name)
Definition Value.h:97
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
A builtin binary operation expression such as "x + y" or "x <= y".
Definition Expr.h:4041
Expr * getLHS() const
Definition Expr.h:4091
Expr * getRHS() const
Definition Expr.h:4093
static bool isAdditiveOp(Opcode Opc)
Definition Expr.h:4127
static bool isAssignmentOp(Opcode Opc)
Definition Expr.h:4177
static bool isCompoundAssignmentOp(Opcode Opc)
Definition Expr.h:4182
Opcode getOpcode() const
Definition Expr.h:4086
BinaryOperatorKind Opcode
Definition Expr.h:4046
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition Decl.h:4678
capture_const_iterator capture_begin() const
Definition Decl.h:4807
capture_const_iterator capture_end() const
Definition Decl.h:4808
const CFGBlock * getSrc() const
const CFGBlock * getDst() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition Expr.h:6672
const BlockDecl * getBlockDecl() const
Definition Expr.h:6684
This class is used for builtin types like 'int'.
Definition TypeBase.h:3226
bool isInteger() const
Definition TypeBase.h:3287
Represents a single basic block in a source-level CFG.
Definition CFG.h:639
reverse_iterator rbegin()
Definition CFG.h:949
bool empty() const
Definition CFG.h:987
CFGTerminator getTerminator() const
Definition CFG.h:1119
succ_iterator succ_begin()
Definition CFG.h:1024
unsigned succ_size() const
Definition CFG.h:1042
Represents a top-level expression in a basic block.
Definition CFG.h:55
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type.
Definition CFG.h:100
const Stmt * getStmt() const
Definition CFG.h:140
Represents CFGBlock terminator statement.
Definition CFG.h:566
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition Expr.h:3679
CastKind getCastKind() const
Definition Expr.h:3723
llvm::iterator_range< path_iterator > path()
Path through the class hierarchy taken by casts between base and derived classes (see implementation ...
Definition Expr.h:3766
CharUnits - This is an opaque type for sizes expressed in character units.
Definition CharUnits.h:38
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition CharUnits.h:185
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition CharUnits.h:63
CompoundLiteralExpr - [C99 6.5.2.5].
Definition Expr.h:3608
A reference to a declared variable, function, enum, etc.
Definition Expr.h:1273
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition Stmt.h:1641
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.
Definition Stmt.h:1654
decl_iterator decl_begin()
Definition Stmt.h:1695
ExplicitCastExpr - An explicit cast written in the source code.
Definition Expr.h:3931
This represents one expression.
Definition Expr.h:112
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
bool isGLValue() const
Definition Expr.h:287
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3093
QualType getType() const
Definition Expr.h:144
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition Expr.h:2530
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition Expr.h:1181
Represents a point after we ran remove dead bindings BEFORE processing the given statement.
T castAs() const
Convert to the specified ProgramPoint type, asserting that this ProgramPoint is of the desired type.
std::optional< T > getAs() const
Convert to the specified ProgramPoint type, returning std::nullopt if this ProgramPoint is not of the...
A (possibly-)qualified type.
Definition TypeBase.h:937
It represents a stack frame of the call stack.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
Definition Type.cpp:2267
bool isRValueReferenceType() const
Definition TypeBase.h:8709
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9337
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition TypeBase.h:9165
bool isLValueReferenceType() const
Definition TypeBase.h:8705
bool isAnyComplexType() const
Definition TypeBase.h:8812
bool isVectorType() const
Definition TypeBase.h:8816
bool isFloatingType() const
Definition Type.cpp:2390
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition Expr.h:2628
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
Definition Expr.h:2697
UnaryExprOrTypeTrait getKind() const
Definition Expr.h:2660
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition Expr.h:2247
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
Represents a variable declaration or definition.
Definition Decl.h:924
const Expr * getInit() const
Definition Decl.h:1381
BlockDataRegion - A region that represents a block instance.
Definition MemRegion.h:705
void runCheckersForPostStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting Stmts.
void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng)
Run checkers for pre-visiting Stmts.
ExplodedNodeSet is a set of ExplodedNode * elements with the invariant that its elements cannot be nu...
void insert(ExplodedNode *N)
const ProgramStateRef & getState() const
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
unsigned pred_size() const
const StackFrame * getStackFrame() const
void VisitBinaryOperator(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBinaryOperator - Transfer function logic for binary operators.
void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGuardedExpr - Transfer function logic for ?, __builtin_choose.
void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCast - Transfer function logic for all casts (implicit and explicit).
BasicValueFactory & getBasicVals()
Definition ExprEngine.h:491
void VisitLogicalExpr(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLogicalExpr - Transfer function logic for '&&', '||'.
SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op, SVal LHS, SVal RHS, QualType T)
Definition ExprEngine.h:679
void VisitUnaryOperator(const UnaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryOperator - Transfer function logic for unary operators.
void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitDeclStmt - Transfer function logic for DeclStmts.
ProgramStateRef handleLValueBitCast(ProgramStateRef state, const Expr *Ex, const StackFrame *SF, QualType T, QualType ExTy, const CastExpr *CastE, NodeBuilder &Bldr, ExplodedNode *Pred)
void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBlockExpr - Transfer function logic for BlockExprs.
void VisitIncrementDecrementOperator(const UnaryOperator *U, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Handle ++ and – (both pre- and post-increment).
ASTContext & getContext() const
getContext - Return the ASTContext associated with this analysis.
Definition ExprEngine.h:214
StoreManager & getStoreManager()
Definition ExprEngine.h:478
ConstCFGElementRef getCFGElementRef() const
Definition ExprEngine.h:290
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
ProgramStateRef escapeValues(ProgramStateRef State, ArrayRef< SVal > Vs, PointerEscapeKind K, const CallEvent *Call=nullptr) const
A simple wrapper when you only need to notify checkers of pointer-escape of some values.
CheckerManager & getCheckerManager() const
Definition ExprEngine.h:223
static std::optional< SVal > getObjectUnderConstruction(ProgramStateRef State, const ConstructionContextItem &Item, const StackFrame *SF)
By looking at a certain item that may be potentially part of an object's ConstructionContext,...
unsigned getNumVisitedCurrent() const
Definition ExprEngine.h:299
void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitOffsetOfExpr - Transfer function for offsetof.
void evalLoad(ExplodedNodeSet &Dst, const Expr *NodeEx, const Expr *BoundExpr, ExplodedNode *Pred, ProgramStateRef St, SVal location, const ProgramPointTag *tag=nullptr, QualType LoadTy=QualType())
Simulate a read of the result of Ex.
void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCompoundLiteralExpr - Transfer function logic for compound literals.
void handleUOExtension(ExplodedNode *N, const UnaryOperator *U, NodeBuilder &Bldr)
void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE, ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val, const ProgramPointTag *tag=nullptr)
evalStore - Handle the semantics of a store via an assignment.
static bool isLocType(QualType T)
Definition SVals.h:262
MemRegion - The root abstract class for all memory regions.
Definition MemRegion.h:97
This is the simplest builder which generates nodes in the ExplodedGraph.
Definition CoreEngine.h:265
void takeNodes(const ExplodedNodeSet &S)
Definition CoreEngine.h:330
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred, bool MarkAsSink=false)
Generates a node in the ExplodedGraph.
ExplodedNode * generateSink(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a sink in the ExplodedGraph.
Definition CoreEngine.h:300
void addNodes(const ExplodedNodeSet &S)
Definition CoreEngine.h:336
const ExplodedNodeSet & getResults() const
Definition CoreEngine.h:326
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, ConstCFGElementRef elem, const StackFrame *SF, unsigned count)
Create a new symbol with a unique 'name'.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition SVals.h:56
bool isUndef() const
Definition SVals.h:107
bool isZeroConstant() const
Definition SVals.cpp:257
bool isUnknownOrUndef() const
Definition SVals.h:109
bool isConstant() const
Definition SVals.cpp:245
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
Definition SVals.h:83
bool isUnknown() const
Definition SVals.h:105
SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast)
Evaluates a chain of derived-to-base casts through the path specified in Cast.
Definition Store.cpp:254
std::optional< SVal > evalBaseToDerived(SVal Base, QualType DerivedPtrType)
Attempts to do a down cast.
Definition Store.cpp:318
TypedValueRegion - An abstract class representing regions having a typed value.
Definition MemRegion.h:562
const VarDecl * getDecl() const override=0
Value representing integer constant.
Definition SVals.h:300
Value representing pointer-to-member.
Definition SVals.h:434
Definition SPIR.cpp:35
@ PSK_EscapeOther
The reason for pointer escape is unknown.
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
Definition Address.h:330
CFGBlock::ConstCFGElementRef ConstCFGElementRef
Definition CFG.h:1235
@ Result
The result type of a method or function.
Definition TypeBase.h:905
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Other
Other implicit parameter.
Definition Decl.h:1763
EvalResult is a struct with detailed info about an evaluated expression.
Definition Expr.h:648