@@ -113,6 +113,10 @@ bool CheckThis(InterpState &S, CodePtr OpPC, const Pointer &This);
113113// / Checks if a method is pure virtual.
114114bool CheckPure (InterpState &S, CodePtr OpPC, const CXXMethodDecl *MD);
115115
116+ // / Checks if all the arguments annotated as 'nonnull' are in fact not null.
117+ bool CheckNonNullArgs (InterpState &S, CodePtr OpPC, const Function *F,
118+ const CallExpr *CE, unsigned ArgSize);
119+
116120// / Sets the given integral value to the pointer, which is of
117121// / a std::{weak,partial,strong}_ordering type.
118122bool SetThreeWayComparisonField (InterpState &S, CodePtr OpPC,
@@ -1980,6 +1984,7 @@ inline bool CallVar(InterpState &S, CodePtr OpPC, const Function *Func,
19801984
19811985 return false ;
19821986}
1987+
19831988inline bool Call (InterpState &S, CodePtr OpPC, const Function *Func,
19841989 uint32_t VarArgSize) {
19851990 if (Func->hasThisPointer ()) {
@@ -2083,7 +2088,8 @@ inline bool CallBI(InterpState &S, CodePtr &PC, const Function *Func,
20832088 return false ;
20842089}
20852090
2086- inline bool CallPtr (InterpState &S, CodePtr OpPC, uint32_t ArgSize) {
2091+ inline bool CallPtr (InterpState &S, CodePtr OpPC, uint32_t ArgSize,
2092+ const CallExpr *CE) {
20872093 const FunctionPointer &FuncPtr = S.Stk .pop <FunctionPointer>();
20882094
20892095 const Function *F = FuncPtr.getFunction ();
@@ -2095,6 +2101,12 @@ inline bool CallPtr(InterpState &S, CodePtr OpPC, uint32_t ArgSize) {
20952101 }
20962102 assert (F);
20972103
2104+ // Check argument nullability state.
2105+ if (F->hasNonNullAttr ()) {
2106+ if (!CheckNonNullArgs (S, OpPC, F, CE, ArgSize))
2107+ return false ;
2108+ }
2109+
20982110 assert (ArgSize >= F->getWrittenArgSize ());
20992111 uint32_t VarArgSize = ArgSize - F->getWrittenArgSize ();
21002112
@@ -2151,6 +2163,18 @@ inline bool OffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E) {
21512163 return true ;
21522164}
21532165
2166+ template <PrimType Name, class T = typename PrimConv<Name>::T>
2167+ inline bool CheckNonNullArg (InterpState &S, CodePtr OpPC) {
2168+ const T &Arg = S.Stk .peek <T>();
2169+ if (!Arg.isZero ())
2170+ return true ;
2171+
2172+ const SourceLocation &Loc = S.Current ->getLocation (OpPC);
2173+ S.CCEDiag (Loc, diag::note_non_null_attribute_failed);
2174+
2175+ return false ;
2176+ }
2177+
21542178// ===----------------------------------------------------------------------===//
21552179// Read opcode arguments
21562180// ===----------------------------------------------------------------------===//
0 commit comments