Static Value-Flow Analysis
Loading...
Searching...
No Matches
AbsExtAPI.cpp
Go to the documentation of this file.
1//===- AbsExtAPI.cpp -- Abstract Interpretation External API handler-----//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-> <Yulei Sui>
6//
7
8// This program is free software: you can redistribute it and/or modify
9// it under the terms of the GNU Affero General Public License as published by
10// the Free Software Foundation, either version 3 of the License, or
11// (at your option) any later version.
12
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU Affero General Public License for more details.
17
18// You should have received a copy of the GNU Affero General Public License
19// along with this program. If not, see <http://www.gnu.org/licenses/>.
20//
21//===----------------------------------------------------------------------===//
22
23
24//
25// Created on: Sep 9, 2024
26// Author: Xiao Cheng, Jiawei Wang
27//
28//
29#include "AE/Svfexe/AbsExtAPI.h"
31#include "SVFIR/SVFIR.h"
32#include "Util/Options.h"
33
34using namespace SVF;
41
43{
44#define SSE_FUNC_PROCESS(LLVM_NAME ,FUNC_NAME) \
45 auto sse_##FUNC_NAME = [this](const CallICFGNode *callNode) { \
46 /* run real ext function */ \
47 assert(callNode->arg_size() >= 1 && "external function expects one argument"); \
48 const SVFVar* argVar = callNode->getArgument(0); \
49 const AbstractValue& argVal = ae->getAbsValue(argVar, callNode); \
50 IntervalValue result = IntervalValue::top(); \
51 if (argVal.isInterval() && argVal.getInterval().is_numeral()) { \
52 u32_t rhs = argVal.getInterval().lb().getIntNumeral(); \
53 result = IntervalValue(FUNC_NAME(rhs)); \
54 } \
55 const SVFVar* retVar = callNode->getRetICFGNode()->getActualRet(); \
56 ae->updateAbsValue(retVar, result, callNode); \
57 }; \
58 func_map[#FUNC_NAME] = sse_##FUNC_NAME;
59
71 SSE_FUNC_PROCESS(llvm.sin.f64, sin);
72 SSE_FUNC_PROCESS(llvm.cos.f64, cos);
73 SSE_FUNC_PROCESS(llvm.tan.f64, tan);
74 SSE_FUNC_PROCESS(llvm.log.f64, log);
78
79 auto sse_svf_assert = [this](const CallICFGNode* callNode)
80 {
81 checkpoints.erase(callNode);
82 const AbstractValue& arg0Val = ae->getAbsValue(callNode->getArgument(0), callNode);
83 if (arg0Val.getInterval().equals(IntervalValue(1, 1)))
84 {
85 SVFUtil::errs() << SVFUtil::sucMsg("The assertion is successfully verified!!\n");
86 }
87 else
88 {
89 SVFUtil::errs() << SVFUtil::errMsg("Assertion failure, this svf_assert cannot be verified!!\n") << callNode->toString() << "\n";
90 assert(false);
91 }
92 return;
93 };
94 func_map["svf_assert"] = sse_svf_assert;
95
96 auto svf_assert_eq = [this](const CallICFGNode* callNode)
97 {
98 const AbstractValue& arg0Val = ae->getAbsValue(callNode->getArgument(0), callNode);
99 const AbstractValue& arg1Val = ae->getAbsValue(callNode->getArgument(1), callNode);
100 if (arg0Val.getInterval().equals(arg1Val.getInterval()))
101 {
102 SVFUtil::errs() << SVFUtil::sucMsg("The assertion is successfully verified!!\n");
103 }
104 else
105 {
106 SVFUtil::errs() <<"svf_assert_eq Fail. " << callNode->toString() << "\n";
107 assert(false);
108 }
109 return;
110 };
111 func_map["svf_assert_eq"] = svf_assert_eq;
112
113 auto svf_print = [&](const CallICFGNode* callNode)
114 {
115 assert(callNode->arg_size() >= 2 && "svf_print expects two arguments");
116 std::string text = strRead(callNode->getArgument(1), callNode);
118 std::cout << "Text: " << text <<", Value: " << callNode->getArgument(0)->toString()
119 << ", PrintVal: " << itv.toString() << ", Loc:" << callNode->getSourceLoc() << std::endl;
120 return;
121 };
122 func_map["svf_print"] = svf_print;
123
124 auto svf_set_value = [&](const CallICFGNode* callNode)
125 {
126 assert(callNode->arg_size() >= 3 && "set_value expects three arguments");
128 const AbstractValue& lbVal = ae->getAbsValue(callNode->getArgument(1), callNode);
129 const AbstractValue& ubVal = ae->getAbsValue(callNode->getArgument(2), callNode);
130 assert(lbVal.getInterval().is_numeral() && ubVal.getInterval().is_numeral());
133 num.getInterval().meet_with(IntervalValue(lbVal.getInterval().lb(), ubVal.getInterval().ub()));
134 ae->updateAbsValue(callNode->getArgument(0), num, callNode);
135 const ICFGNode* node = SVFUtil::cast<ValVar>(callNode->getArgument(0))->getICFGNode();
136 for (const SVFStmt* stmt: node->getSVFStmts())
137 {
138 if (SVFUtil::isa<LoadStmt>(stmt))
139 {
140 const LoadStmt* load = SVFUtil::cast<LoadStmt>(stmt);
142 for (auto addr : ptrVal.getAddrs())
143 as.store(addr, num);
144 }
145 }
146 return;
147 };
148 func_map["set_value"] = svf_set_value;
149
150 auto sse_fread = [&](const CallICFGNode *callNode)
151 {
152 assert(callNode->arg_size() >= 3 && "fread expects at least three arguments");
156 (void)block_byte;
157 };
158 func_map["fread"] = sse_fread;
159
160 auto sse_sprintf = [&](const CallICFGNode *callNode)
161 {
162 // printf is difficult to predict since it has no byte size arguments
163 };
164
165 auto sse_snprintf = [&](const CallICFGNode *callNode)
166 {
167 assert(callNode->arg_size() >= 2 &&
168 "formatted-output function expects at least two arguments");
169 u32_t elemSize = 1;
170 if (callNode->arg_size() > 2 &&
171 callNode->getArgument(2)->getType()->isArrayTy())
172 {
173 elemSize = SVFUtil::cast<SVFArrayType>(
174 callNode->getArgument(2)->getType())
175 ->getTypeOfElement()->getByteSize();
176 }
177 IntervalValue size = ae->getAbsValue(callNode->getArgument(1), callNode).getInterval()
179 (void)size;
180 };
181 func_map["__snprintf_chk"] = sse_snprintf;
182 func_map["__vsprintf_chk"] = sse_sprintf;
183 func_map["__sprintf_chk"] = sse_sprintf;
184 func_map["snprintf"] = sse_snprintf;
185 func_map["sprintf"] = sse_sprintf;
186 func_map["vsprintf"] = sse_sprintf;
187 func_map["vsnprintf"] = sse_snprintf;
188 func_map["__vsnprintf_chk"] = sse_snprintf;
189 func_map["swprintf"] = sse_snprintf;
190 func_map["_snwprintf"] = sse_snprintf;
191
192
193 auto sse_itoa = [&](const CallICFGNode* callNode)
194 {
195 assert(callNode->arg_size() >= 3 && "itoa expects three arguments");
196 u32_t num = (u32_t) ae->getAbsValue(callNode->getArgument(0), callNode).getInterval().getNumeral();
197 std::string snum = std::to_string(num);
198 (void)snum;
199 };
200 func_map["itoa"] = sse_itoa;
201
202
203 auto sse_strlen = [&](const CallICFGNode *callNode)
204 {
205 assert(callNode->arg_size() >= 1 && "strlen expects one argument");
206 const SVFVar* retVar = callNode->getRetICFGNode()->getActualRet();
207 IntervalValue byteLen = getStrlen(callNode->getArgument(0), callNode);
208 u32_t elemSize = getElementSize(callNode->getArgument(0));
209 if (byteLen.is_numeral() && elemSize > 1)
211 else
213 };
214 func_map["strlen"] = sse_strlen;
215 func_map["wcslen"] = sse_strlen;
216
217 auto sse_recv = [&](const CallICFGNode *callNode)
218 {
219 assert(callNode->arg_size() >= 4 && "recv expects four arguments");
221 const SVFVar* retVar = callNode->getRetICFGNode()->getActualRet();
223 };
224 func_map["recv"] = sse_recv;
225 func_map["__recv"] = sse_recv;
226
227 auto sse_free = [&](const CallICFGNode *callNode)
228 {
229 assert(callNode->arg_size() >= 1 && "free expects one argument");
231 const AbstractValue& ptrVal = ae->getAbsValue(callNode->getArgument(0), callNode);
232 for (auto addr: ptrVal.getAddrs())
233 {
235 as.addToFreedAddrs(addr);
236 }
237 };
238 // Add all free-related functions to func_map
239 std::vector<std::string> freeFunctions =
240 {
241 "VOS_MemFree", "cfree", "free", "free_all_mem", "freeaddrinfo",
242 "gcry_mpi_release", "gcry_sexp_release", "globfree", "nhfree",
243 "obstack_free", "safe_cfree", "safe_free", "safefree", "safexfree",
244 "sm_free", "vim_free", "xfree", "SSL_CTX_free", "SSL_free", "XFree"
245 };
246
247 for (const auto& name : freeFunctions)
248 {
250 }
251};
252
254{
255 return ae->getAbsState(node);
256}
257
259{
260 // traverse every ICFGNode
261 Set<std::string> ae_checkpoint_names = {"svf_assert"};
262 Set<std::string> buf_checkpoint_names = {"UNSAFE_BUFACCESS", "SAFE_BUFACCESS"};
263 Set<std::string> nullptr_checkpoint_names = {"UNSAFE_LOAD", "SAFE_LOAD"};
264
265 for (auto it = svfir->getICFG()->begin(); it != svfir->getICFG()->end(); ++it)
266 {
267 const ICFGNode* node = it->second;
268 if (const CallICFGNode *call = SVFUtil::dyn_cast<CallICFGNode>(node))
269 {
270 if (const FunObjVar *fun = call->getCalledFunction())
271 {
272 if (ae_checkpoint_names.find(fun->getName()) !=
274 {
275 checkpoints.insert(call);
276 }
278 {
279 if (buf_checkpoint_names.find(fun->getName()) !=
281 {
282 checkpoints.insert(call);
283 }
284 }
286 {
287 if (nullptr_checkpoint_names.find(fun->getName()) !=
289 {
290 checkpoints.insert(call);
291 }
292 }
293 }
294 }
295 }
296}
297
299{
300 if (!checkpoints.empty())
301 {
302 SVFUtil::errs() << SVFUtil::errMsg("At least one svf_assert has not been checked!!") << "\n";
303 for (const CallICFGNode* call: checkpoints)
304 SVFUtil::errs() << call->toString() + "\n";
305 assert(false);
306 }
307}
308
309std::string AbsExtAPI::strRead(const ValVar* rhs, const ICFGNode* node)
310{
312 std::string str0;
313
315 {
318
320 for (const auto &addr: expr0.getAddrs())
321 {
322 val.join_with(as.load(addr));
323 }
324 if (!val.getInterval().is_numeral())
325 {
326 break;
327 }
328 if ((char) val.getInterval().getIntNumeral() == '\0')
329 {
330 break;
331 }
332 str0.push_back((char) val.getInterval().getIntNumeral());
333 }
334 return str0;
335}
336
338{
339 const FunObjVar *fun = call->getCalledFunction();
340 assert(fun && "FunObjVar* is nullptr");
342 // get type of mem api
343 for (const std::string &annotation: ExtAPI::getExtAPI()->getExtFuncAnnotations(fun))
344 {
345 if (annotation.find("MEMCPY") != std::string::npos)
346 extType = MEMCPY;
347 if (annotation.find("MEMSET") != std::string::npos)
348 extType = MEMSET;
349 if (annotation.find("STRCPY") != std::string::npos)
350 extType = STRCPY;
351 if (annotation.find("STRCAT") != std::string::npos)
352 extType = STRCAT;
353 }
354 if (extType == UNCLASSIFIED)
355 {
356 if (func_map.find(fun->getName()) != func_map.end())
357 {
358 func_map[fun->getName()](call);
359 }
360 else
361 {
362 const SVFVar* ret = call->getRetICFGNode()->getActualRet();
363 if (ret && !ret->getType()->isPointerTy())
364 {
365 ae->updateAbsValue(ret, IntervalValue(), call);
366 }
367 }
368 }
369 // 1. memcpy functions like memcpy_chk, strncpy, annotate("MEMCPY"), annotate("BUF_CHECK:Arg0, Arg2"), annotate("BUF_CHECK:Arg1, Arg2")
370 else if (extType == MEMCPY)
371 {
372 IntervalValue len = ae->getAbsValue(call->getArgument(2), call).getInterval();
373 handleMemcpy(call->getArgument(0), call->getArgument(1), len, 0, call);
374 }
375 else if (extType == MEMSET)
376 {
379 handleMemset(call->getArgument(0), elem, len, call);
380 }
381 else if (extType == STRCPY)
382 {
383 handleStrcpy(call);
384 }
385 else if (extType == STRCAT)
386 {
387 // Both strcat and strncat are annotated as STRCAT.
388 // Distinguish by name: strncat/wcsncat contain "ncat".
389 const std::string& name = fun->getName();
390 if (name.find("ncat") != std::string::npos)
391 handleStrncat(call);
392 else
393 handleStrcat(call);
394 }
395 else
396 {
397
398 }
399 return;
400}
401
402// ===----------------------------------------------------------------------===//
403// Shared primitives for string/memory handlers
404// ===----------------------------------------------------------------------===//
405
409{
410 if (var->getType()->isArrayTy())
411 {
412 return SVFUtil::dyn_cast<SVFArrayType>(var->getType())
413 ->getTypeOfElement()->getByteSize();
414 }
415 if (var->getType()->isPointerTy())
416 return 1;
417 assert(false && "unsupported type for element size");
418 return 1;
419}
420
425{
426 return !len.isBottom() && !len.lb().is_minus_infinity();
427}
428
430{
431 u32_t byteCount = 0;
432 if (isValidLength(len) && len.lb().getIntNumeral() > 0)
433 {
435 (u32_t)len.lb().getIntNumeral());
436 }
437 return byteCount;
438}
439
444{
446 // Step 1: determine the buffer size (in bytes) backing this pointer
447 u32_t dst_size = 0;
448 const AbstractValue& ptrVal = ae->getAbsValue(strValue, node);
449 for (const auto& addr : ptrVal.getAddrs())
450 {
451 // Unknown and null pointers have no concrete backing buffer to inspect.
453 continue;
454 NodeID objId = as.getIDFromAddr(addr);
456 {
458 }
459 else
460 {
461 const ICFGNode* icfgNode = svfir->getBaseObject(objId)->getICFGNode();
462 for (const SVFStmt* stmt2: icfgNode->getSVFStmts())
463 {
464 if (const AddrStmt* addrStmt = SVFUtil::dyn_cast<AddrStmt>(stmt2))
465 {
467 }
468 }
469 }
470 }
471
472 // Step 2: scan for '\0' terminator
473 u32_t len = 0;
474 for (u32_t index = 0; index < dst_size; index++)
475 {
479 for (const auto &addr: expr0.getAddrs())
480 {
481 val.join_with(as.load(addr));
482 }
483 if (val.getInterval().is_numeral() &&
484 (char) val.getInterval().getIntNumeral() == '\0')
485 {
486 break;
487 }
488 ++len;
489 }
490
491 // Step 3: scale by element size and return
493 if (len == 0)
495 return IntervalValue(len * elemSize);
496}
497
498// ===----------------------------------------------------------------------===//
499// String/memory operation handlers
500// ===----------------------------------------------------------------------===//
501
505{
506 const ValVar* dst = call->getArgument(0);
507 const ValVar* src = call->getArgument(1);
508 IntervalValue srcLen = getStrlen(src, call);
509 assert(isValidLength(srcLen) && "getStrlen must return a bounded length");
510 handleMemcpy(dst, src, srcLen, 0, call);
511}
512
516{
517 const ValVar* dst = call->getArgument(0);
518 const ValVar* src = call->getArgument(1);
519 IntervalValue dstLen = getStrlen(dst, call);
520 IntervalValue srcLen = getStrlen(src, call);
521 assert(isValidLength(dstLen) && "getStrlen must return a bounded length");
522 handleMemcpy(dst, src, srcLen, dstLen.lb().getIntNumeral(), call);
523}
524
528{
529 const ValVar* dst = call->getArgument(0);
530 const ValVar* src = call->getArgument(1);
532 IntervalValue dstLen = getStrlen(dst, call);
533 assert(isValidLength(dstLen) && "getStrlen must return a bounded length");
534 handleMemcpy(dst, src, n, dstLen.lb().getIntNumeral(), call);
535}
536
539 const ValVar *src, const IntervalValue& len,
540 u32_t start_idx, const ICFGNode* node)
541{
543
546 u32_t range_val = size / elemSize;
547
548 for (u32_t index = 0; index < range_val; index++)
549 {
554 for (const auto &dstAddr: expr_dst.getAddrs())
555 {
556 for (const auto &srcAddr: expr_src.getAddrs())
557 {
558 u32_t objId = as.getIDFromAddr(srcAddr);
559 if (as.inAddrToValTable(objId) || as.inAddrToAddrsTable(objId))
560 {
561 as.store(dstAddr, as.load(srcAddr));
562 }
563 }
564 }
565 }
566}
567
574 const IntervalValue& elem, const IntervalValue& len, const ICFGNode* node)
575{
577
578 u32_t elemSize = 1;
579 if (dst->getType()->isArrayTy())
580 {
581 elemSize = SVFUtil::dyn_cast<SVFArrayType>(dst->getType())
582 ->getTypeOfElement()->getByteSize();
583 }
584 else if (dst->getType()->isPointerTy())
585 {
586 elemSize = 1;
587 }
588 else
589 {
590 assert(false && "unsupported type for element size");
591 }
593 u32_t range_val = size / elemSize;
594
595 for (u32_t index = 0; index < range_val; index++)
596 {
598 for (const auto &addr: lhs_gep.getAddrs())
599 {
600 u32_t objId = as.getIDFromAddr(addr);
601 if (as.inAddrToValTable(objId))
602 {
603 AbstractValue tmp = as.load(addr);
605 as.store(addr, tmp);
606 }
607 else
608 {
609 as.store(addr, elem);
610 }
611 }
612 }
613}
614
627{
628 if (const SVFIntegerType* intType = SVFUtil::dyn_cast<SVFIntegerType>(type))
629 {
630 u32_t bits = type->getByteSize() * 8;
631 s64_t ub = 0;
632 s64_t lb = 0;
633 if (bits >= 32)
634 {
635 if (intType->isSigned())
636 {
637 ub = static_cast<s64_t>(std::numeric_limits<s32_t>::max());
638 lb = static_cast<s64_t>(std::numeric_limits<s32_t>::min());
639 }
640 else
641 {
642 ub = static_cast<s64_t>(std::numeric_limits<u32_t>::max());
643 lb = static_cast<s64_t>(std::numeric_limits<u32_t>::min());
644 }
645 }
646 else if (bits == 16)
647 {
648 if (intType->isSigned())
649 {
650 ub = static_cast<s64_t>(std::numeric_limits<s16_t>::max());
651 lb = static_cast<s64_t>(std::numeric_limits<s16_t>::min());
652 }
653 else
654 {
655 ub = static_cast<s64_t>(std::numeric_limits<u16_t>::max());
656 lb = static_cast<s64_t>(std::numeric_limits<u16_t>::min());
657 }
658 }
659 else if (bits == 8)
660 {
661 if (intType->isSigned())
662 {
663 ub = static_cast<s64_t>(std::numeric_limits<int8_t>::max());
664 lb = static_cast<s64_t>(std::numeric_limits<int8_t>::min());
665 }
666 else
667 {
668 ub = static_cast<s64_t>(std::numeric_limits<uint8_t>::max());
669 lb = static_cast<s64_t>(std::numeric_limits<uint8_t>::min());
670 }
671 }
672 return IntervalValue(lb, ub);
673 }
674 else if (SVFUtil::isa<SVFOtherType>(type))
675 {
676 // handle other type like float double, set s32_t as the range
677 s64_t ub = static_cast<s64_t>(std::numeric_limits<s32_t>::max());
678 s64_t lb = static_cast<s64_t>(std::numeric_limits<s32_t>::min());
679 return IntervalValue(lb, ub);
680 }
681 else
682 {
683 return IntervalValue::top();
684 // other types, return top interval
685 }
686}
#define SSE_FUNC_PROCESS(LLVM_NAME,FUNC_NAME)
newitem type
Definition cJSON.cpp:2739
cJSON * n
Definition cJSON.cpp:2558
const char *const name
Definition cJSON.h:264
int index
Definition cJSON.h:170
AbstractInterpretation * ae
Owning AbstractInterpretation; provides state access.
Definition AbsExtAPI.h:132
AbstractState & getAbsState(const ICFGNode *node)
Retrieves the abstract state from the trace for a given ICFG node.
void collectCheckPoint()
void initExtFunMap()
Initializes the external function map.
Definition AbsExtAPI.cpp:42
IntervalValue getStrlen(const ValVar *strValue, const ICFGNode *node)
Calculate the length of a null-terminated string in abstract state.
void handleMemcpy(const ValVar *dst, const ValVar *src, const IntervalValue &len, u32_t start_idx, const ICFGNode *node)
Core memcpy: copy len bytes from src to dst starting at dst[start_idx].
void handleExtAPI(const CallICFGNode *call)
Handles an external API call.
void handleStrncat(const CallICFGNode *call)
static bool isValidLength(const IntervalValue &len)
Check if an interval length is usable (not bottom, not unbounded).
Set< const CallICFGNode * > checkpoints
Definition AbsExtAPI.h:129
void checkPointAllSet()
std::string strRead(const ValVar *rhs, const ICFGNode *node)
Reads a string from the abstract state.
u32_t getElementSize(const ValVar *var)
Get the byte size of each element for a pointer/array variable.
void handleMemset(const ValVar *dst, const IntervalValue &elem, const IntervalValue &len, const ICFGNode *node)
AbsExtAPI(AbstractInterpretation *ae)
Constructor for AbsExtAPI.
Definition AbsExtAPI.cpp:35
SVFIR * svfir
Pointer to the SVF intermediate representation.
Definition AbsExtAPI.h:133
ExtAPIType
Enumeration of external API types.
Definition AbsExtAPI.h:55
static u32_t getBoundedMinimumByteCount(const IntervalValue &len)
Return the lower bound of len, capped by the field limit.
IntervalValue getRangeLimitFromType(const SVFType *type)
Gets the range limit from a type.
ICFG * icfg
Pointer to the interprocedural control flow graph.
Definition AbsExtAPI.h:134
void handleStrcat(const CallICFGNode *call)
void handleStrcpy(const CallICFGNode *call)
Map< std::string, std::function< void(const CallICFGNode *)> > func_map
Map of function names to handlers.
Definition AbsExtAPI.h:135
AbstractState & getAbsState(const ICFGNode *node)
u32_t getAllocaInstByteSize(const AddrStmt *addr)
AddressValue getGepObjAddrs(const ValVar *pointer, IntervalValue offset)
virtual const AbstractValue & getAbsValue(const ValVar *var, const ICFGNode *node)
virtual void updateAbsValue(const ValVar *var, const AbstractValue &val, const ICFGNode *node)
static bool isNullOrBlackHoleAddr(u32_t addr)
Whether addr has no concrete backing memory object.
void join_with(const AbstractValue &other)
IntervalValue & getInterval()
const ICFGNode * getICFGNode() const
Get the ICFGNode related to the creation of this object.
bool isConstantByteSize() const
Check if byte size is a const value.
u32_t getByteSizeOfObj() const
Get the byte size of this object.
const ValVar * getArgument(u32_t ArgNo) const
Parameter operations.
Definition ICFGNode.h:483
const FunObjVar * getCalledFunction() const
Definition ICFGNode.h:501
const RetICFGNode * getRetICFGNode() const
Return callsite.
Definition ICFGNode.h:440
static ExtAPI * getExtAPI()
Definition ExtAPI.cpp:43
const std::vector< std::string > & getExtFuncAnnotations(const FunObjVar *fun)
Definition ExtAPI.cpp:232
iterator begin()
Iterators.
virtual const std::string toString() const
Definition ICFG.cpp:50
const SVFStmtList & getSVFStmts() const
Definition ICFGNode.h:116
const std::string toString() const
void set_to_top()
Set current IntervalValue as top.
static IntervalValue top()
Create the IntervalValue [-inf, +inf].
const ValVar * getRHSVar() const
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition Options.h:34
static const Option< bool > NullDerefCheck
nullptr dereference checker, Default: false
Definition Options.h:248
static const Option< bool > BufferOverflowCheck
buffer overflow checker, Default: false
Definition Options.h:246
const SVFVar * getActualRet() const
Return actual return parameter.
Definition ICFGNode.h:625
const BaseObjVar * getBaseObject(NodeID id) const
Definition SVFIR.h:498
ICFG * getICFG() const
Definition SVFIR.h:231
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:120
bool isArrayTy() const
Definition SVFType.h:297
bool isPointerTy() const
Definition SVFType.h:292
virtual const SVFType * getType() const
Definition SVFValue.h:169
virtual const std::string & getName() const
Definition SVFValue.h:184
int iscntrl(int c)
Definition extapi.c:1011
int isdigit(int c)
Definition extapi.c:1016
int isgraph(int c)
Definition extapi.c:1021
int isspace(char c)
Definition extapi.c:1041
int isprint(int c)
Definition extapi.c:1031
int ispunct(int argument)
Definition extapi.c:1036
int isblank(int character)
Definition extapi.c:1006
int isalnum(int character)
Definition extapi.c:996
int isupper(int c)
Definition extapi.c:1046
int isxdigit(int c)
Definition extapi.c:1051
int isalpha(int character)
Definition extapi.c:1001
std::string sucMsg(const std::string &msg)
Returns successful message by converting a string into green string output.
Definition SVFUtil.cpp:75
std::string errMsg(const std::string &msg)
Print error message by converting a string into red string output.
Definition SVFUtil.cpp:98
std::ostream & errs()
Overwrite llvm::errs()
Definition SVFUtil.h:64
for isBitcode
Definition BasicTypes.h:70
u32_t NodeID
Definition GeneralType.h:76
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
unsigned u32_t
Definition GeneralType.h:67
signed long long s64_t
Definition GeneralType.h:70