diff --git a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp index b198b1c2ff4d1..1a4eb88fb6ab2 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp @@ -22,6 +22,11 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h" +#include +#include +#include +#include +#include using namespace clang; using namespace ento; @@ -77,6 +82,26 @@ bool BuiltinFunctionChecker::evalCall(const CallEvent &Call, const LocationContext *LCtx = C.getLocationContext(); const Expr *CE = Call.getOriginExpr(); + if (const auto *AttrStmt = dyn_cast(CE)) { + for (const Attr *I : AttrStmt->getAttrs()) { + if (const auto *AssumeAttr = dyn_cast(I)) { + const Expr *AssumeExpr = AssumeAttr->getAssumption(); + SVal Arg = C.getSVal(AssumeExpr); + if (Arg.isUndef()) + return true; + + state = state->assume(Arg.castAs(), true); + if (!state) { + C.generateSink(C.getState(), C.getPredecessor()); + return true; + } + + C.addTransition(state); + return true; + } + } + } + if (isBuiltinLikeFunction(Call)) { C.addTransition(state->BindExpr(CE, LCtx, Call.getArgSVal(0))); return true;