TrustNonnullChecker.cpp (344779) | TrustNonnullChecker.cpp (353358) |
---|---|
1//== TrustNonnullChecker.cpp --------- API nullability modeling -*- C++ -*--==// 2// | 1//== TrustNonnullChecker.cpp --------- API nullability modeling -*- C++ -*--==// 2// |
3// The LLVM Compiler Infrastructure | 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 |
4// | 6// |
5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// | |
8//===----------------------------------------------------------------------===// 9// 10// This checker adds nullability-related assumptions: 11// 12// 1. Methods annotated with _Nonnull 13// which come from system headers actually return a non-null pointer. 14// 15// 2. NSDictionary key is non-null after the keyword subscript operation --- 67 unchanged lines hidden (view full) --- 83 // Only trust annotations for system headers for non-protocols. 84 if (!Call.isInSystemHeader()) 85 return; 86 87 ProgramStateRef State = C.getState(); 88 89 if (isNonNullPtr(Call, C)) 90 if (auto L = Call.getReturnValue().getAs<Loc>()) | 7//===----------------------------------------------------------------------===// 8// 9// This checker adds nullability-related assumptions: 10// 11// 1. Methods annotated with _Nonnull 12// which come from system headers actually return a non-null pointer. 13// 14// 2. NSDictionary key is non-null after the keyword subscript operation --- 67 unchanged lines hidden (view full) --- 82 // Only trust annotations for system headers for non-protocols. 83 if (!Call.isInSystemHeader()) 84 return; 85 86 ProgramStateRef State = C.getState(); 87 88 if (isNonNullPtr(Call, C)) 89 if (auto L = Call.getReturnValue().getAs<Loc>()) |
91 State = State->assume(*L, /*Assumption=*/true); | 90 State = State->assume(*L, /*assumption=*/true); |
92 93 C.addTransition(State); 94 } 95 96 void checkPostObjCMessage(const ObjCMethodCall &Msg, 97 CheckerContext &C) const { 98 const ObjCInterfaceDecl *ID = Msg.getReceiverInterface(); 99 if (!ID) 100 return; 101 102 ProgramStateRef State = C.getState(); 103 104 // Index to setter for NSMutableDictionary is assumed to be non-null, 105 // as an exception is thrown otherwise. 106 if (interfaceHasSuperclass(ID, "NSMutableDictionary") && 107 (Msg.getSelector() == SetObjectForKeyedSubscriptSel || 108 Msg.getSelector() == SetObjectForKeySel)) { 109 if (auto L = Msg.getArgSVal(1).getAs<Loc>()) | 91 92 C.addTransition(State); 93 } 94 95 void checkPostObjCMessage(const ObjCMethodCall &Msg, 96 CheckerContext &C) const { 97 const ObjCInterfaceDecl *ID = Msg.getReceiverInterface(); 98 if (!ID) 99 return; 100 101 ProgramStateRef State = C.getState(); 102 103 // Index to setter for NSMutableDictionary is assumed to be non-null, 104 // as an exception is thrown otherwise. 105 if (interfaceHasSuperclass(ID, "NSMutableDictionary") && 106 (Msg.getSelector() == SetObjectForKeyedSubscriptSel || 107 Msg.getSelector() == SetObjectForKeySel)) { 108 if (auto L = Msg.getArgSVal(1).getAs<Loc>()) |
110 State = State->assume(*L, /*Assumption=*/true); | 109 State = State->assume(*L, /*assumption=*/true); |
111 } 112 113 // Record an implication: index is non-null if the output is non-null. 114 if (interfaceHasSuperclass(ID, "NSDictionary") && 115 (Msg.getSelector() == ObjectForKeyedSubscriptSel || 116 Msg.getSelector() == ObjectForKeySel)) { 117 SymbolRef ArgS = Msg.getArgSVal(0).getAsSymbol(); 118 SymbolRef RetS = Msg.getReturnValue().getAsSymbol(); --- 125 unchanged lines hidden (view full) --- 244 } 245 246 return State; 247 } 248}; 249 250} // end empty namespace 251 | 110 } 111 112 // Record an implication: index is non-null if the output is non-null. 113 if (interfaceHasSuperclass(ID, "NSDictionary") && 114 (Msg.getSelector() == ObjectForKeyedSubscriptSel || 115 Msg.getSelector() == ObjectForKeySel)) { 116 SymbolRef ArgS = Msg.getArgSVal(0).getAsSymbol(); 117 SymbolRef RetS = Msg.getReturnValue().getAsSymbol(); --- 125 unchanged lines hidden (view full) --- 243 } 244 245 return State; 246 } 247}; 248 249} // end empty namespace 250 |
252 | |
253void ento::registerTrustNonnullChecker(CheckerManager &Mgr) { 254 Mgr.registerChecker<TrustNonnullChecker>(Mgr.getASTContext()); 255} | 251void ento::registerTrustNonnullChecker(CheckerManager &Mgr) { 252 Mgr.registerChecker<TrustNonnullChecker>(Mgr.getASTContext()); 253} |
254 255bool ento::shouldRegisterTrustNonnullChecker(const LangOptions &LO) { 256 return true; 257} |
|