[PATCH] D142733: Add _Optional as fast qualifier
chrisbazley created this revision. Herald added subscribers: Moerafaat, zero9178, bzcheeseman, sdasgup3, wenzhicui, wrengr, cota, teijeong, rdzhabarov, tatianashp, jdoerfert, msifontes, jurahul, Kayjukh, grosul1, Joonsoo, liufengdb, aartbik, mgester, arpith-jacob, antiagainst, shauheen, rriddle, mehdi_amini, thopre, martong, hiraditya. Herald added a reviewer: shafik. Herald added a reviewer: shafik. Herald added a reviewer: rriddle. Herald added a project: All. chrisbazley requested review of this revision. Herald added subscribers: llvm-commits, lldb-commits, cfe-commits, stephenneuendorffer, nicolasvasilache. Herald added projects: clang, LLDB, MLIR, LLVM. A new pointee type qualifier for the purpose of adding pointer nullability information to C programs. Its goal is to provide value not only for static analysis and documentation, but also for compilers which report errors based only on existing type-compatibility rules. The syntax and semantics are designed to be as familiar (to C programmers) and ergonomic as possible. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D142733 Files: clang/include/clang/AST/APValue.h clang/include/clang/AST/CanonicalType.h clang/include/clang/AST/Type.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Basic/TokenKinds.def clang/include/clang/Sema/DeclSpec.h clang/include/clang/Sema/Sema.h clang/lib/AST/ASTImporter.cpp clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/TypePrinter.cpp clang/lib/CodeGen/CGDebugInfo.cpp clang/lib/Format/FormatToken.h clang/lib/Format/QualifierAlignmentFixer.cpp clang/lib/Format/TokenAnnotator.cpp clang/lib/Format/UnwrappedLineParser.cpp clang/lib/Parse/ParseDecl.cpp clang/lib/Parse/ParseDeclCXX.cpp clang/lib/Parse/ParseObjc.cpp clang/lib/Parse/ParseTentative.cpp clang/lib/Sema/DeclSpec.cpp clang/lib/Sema/SemaCodeComplete.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaDeclObjC.cpp clang/lib/Sema/SemaOverload.cpp clang/lib/Sema/SemaType.cpp lldb/include/lldb/Symbol/Type.h lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp lldb/source/Symbol/Type.cpp llvm/docs/LangRef.rst llvm/docs/SourceLevelDebugging.rst llvm/include/llvm/BinaryFormat/Dwarf.def llvm/include/llvm/DebugInfo/CodeView/CodeView.h llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h llvm/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h llvm/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h llvm/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h llvm/include/llvm/DebugInfo/PDB/Native/NativeSymbolEnumerator.h llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeArray.h llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeEnum.h llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h llvm/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeUDT.h llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h llvm/include/llvm/DebugInfo/PDB/PDBSymbolData.h llvm/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h llvm/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp llvm/lib/DWARFLinker/DWARFLinker.cpp llvm/lib/DebugInfo/DWARF/DWARFDie.cpp llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp llvm/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp llvm/lib/DebugInfo/PDB/Native/NativeTypeArray.cpp llvm/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp llvm/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp llvm/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp llvm/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp llvm/lib/DebugInfo/PDB/Native/NativeTypeVTShape.cpp llvm/lib/IR/Verifier.cpp llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp llvm/lib/Target/BPF/BPFPreserveDIType.cpp llvm/lib/Target/BPF/BTF.def llvm/lib/Target/BPF/BTFDebug.cpp llvm/tools/llvm-pdb
[PATCH] D142734: Updated CheckAddressOfOperand
chrisbazley created this revision. Herald added a project: All. chrisbazley requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. The semantics of the unary & operator are modified so that if its operand has type "type" then its result has type "pointer to type", with the omission of any _Optional qualifier of the pointed-to type. Also added a new helper method, ASTContext::getNonOptionalType. Rationale: A new idiom &* is proposed to allow removal of the _Optional qualifier from a pointee whilst allowing static analyzers to check the validity of such conversions. This is merely the simplest expression that incorporates a semantic dereference without actually accessing the pointed-to object. There is only one way to get the address of an object (excepting arithmetic), whereas there are many ways to dereference a pointer. This is why the semantics of & are modified rather than modifying *, [] and ->. The operand of & is already treated specially, being exempt from implicit conversion of an array type into a pointer, for example. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D142734 Files: clang/include/clang/AST/ASTContext.h clang/lib/Sema/SemaExpr.cpp Index: clang/lib/Sema/SemaExpr.cpp === --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -14585,10 +14585,18 @@ if (getLangOpts().C99) { // Implement C99-only parts of addressof rules. if (UnaryOperator* uOp = dyn_cast(op)) { - if (uOp->getOpcode() == UO_Deref) + if (uOp->getOpcode() == UO_Deref) { // Per C99 6.5.3.2, the address of a deref always returns a valid result // (assuming the deref expression is valid). -return uOp->getSubExpr()->getType(); +auto Result = uOp->getSubExpr()->getType(); +if (const PointerType *PT = Result->getAs()) { + // A dereferenced pointer is not a null pointer (by definition). + auto PointeeType = PT->getPointeeType(); + Result = + Context.getPointerType(Context.getNonOptionalType(PointeeType)); +} +return Result; + } } // Technically, there should be a check for array subscript // expressions here, but the result of one is always an lvalue anyway. @@ -14602,6 +14610,7 @@ Expr::LValueClassification lval = op->ClassifyLValue(Context); unsigned AddressOfError = AO_No_Error; + QualType Ty = Context.getNonOptionalType(op->getType()); if (lval == Expr::LV_ClassTemporary || lval == Expr::LV_ArrayTemporary) { bool sfinae = (bool)isSFINAEContext(); @@ -14611,10 +14620,9 @@ if (sfinae) return QualType(); // Materialize the temporary as an lvalue so that we can take its address. -OrigOp = op = -CreateMaterializeTemporaryExpr(op->getType(), OrigOp.get(), true); +OrigOp = op = CreateMaterializeTemporaryExpr(Ty, OrigOp.get(), true); } else if (isa(op)) { -return Context.getPointerType(op->getType()); +return Context.getPointerType(Ty); } else if (lval == Expr::LV_MemberFunction) { // If it's an instance method, make a member pointer. // The expression must have exactly the form &A::foo. @@ -14652,7 +14660,7 @@ Diag(OpLoc, diag::err_typecheck_addrof_dtor) << op->getSourceRange(); QualType MPTy = Context.getMemberPointerType( -op->getType(), Context.getTypeDeclType(MD->getParent()).getTypePtr()); +Ty, Context.getTypeDeclType(MD->getParent()).getTypePtr()); // Under the MS ABI, lock down the inheritance model now. if (Context.getTargetInfo().getCXXABI().isMicrosoft()) (void)isCompleteType(OpLoc, MPTy); @@ -14660,7 +14668,7 @@ } else if (lval != Expr::LV_Valid && lval != Expr::LV_IncompleteVoidType) { // C99 6.5.3.2p1 // The operand must be either an l-value or a function designator -if (!op->getType()->isFunctionType()) { +if (!Ty->isFunctionType()) { // Use a special diagnostic for loads from property references. if (isa(op)) { AddressOfError = AO_Property_Expansion; @@ -14711,8 +14719,7 @@ Ctx = Ctx->getParent(); QualType MPTy = Context.getMemberPointerType( - op->getType(), - Context.getTypeDeclType(cast(Ctx)).getTypePtr()); + Ty, Context.getTypeDeclType(cast(Ctx)).getTypePtr()); // Under the MS ABI, lock down the inheritance model now. if (Context.getTargetInfo().getCXXABI().isMicrosoft()) (void)isCompleteType(OpLoc, MPTy); @@ -14737,12 +14744,12 @@ } // If the operand has type "type", the result has type "pointer to type". - if (op->getType()->isObjCObjectType()) -return Context.getObjCObjectPointerType(op->getType()); + if (Ty->isObjCObjectType()) +return Context.getObjCObjectPointerType(Ty); CheckAddressOfPackedMember(op); - return Context.getPointe
[PATCH] D142736: Add QualType::getNullability for _Optional
chrisbazley created this revision. Herald added subscribers: kadircet, arphaman. Herald added a project: All. chrisbazley requested review of this revision. Herald added projects: clang, clang-tools-extra. Herald added a subscriber: cfe-commits. The purpose of this change is to ensure that a qualified declaration such as '_Optional int *' is treated as equivalent to the annotated declaration 'int *_Nullable' in all situations where type qualifiers are available. The new method falls back to Type::getNullability() if called for a QualType which is not a pointer to an _Optional-qualified type. Updated all of the callers which previously invoked Type::getNullability() via QualType::operator->() so that they call the new method directly on the QualType instead. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D142736 Files: clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp clang/include/clang/AST/ASTContext.h clang/include/clang/AST/Type.h clang/lib/AST/ASTContext.cpp clang/lib/AST/Type.cpp clang/lib/CodeGen/CGCall.cpp clang/lib/CodeGen/CGDecl.cpp clang/lib/CodeGen/CodeGenFunction.cpp clang/lib/Sema/Sema.cpp clang/lib/Sema/SemaChecking.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaDeclObjC.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaExprObjC.cpp clang/lib/Sema/SemaLambda.cpp clang/lib/Sema/SemaObjCProperty.cpp clang/lib/Sema/SemaType.cpp clang/tools/libclang/CXType.cpp Index: clang/tools/libclang/CXType.cpp === --- clang/tools/libclang/CXType.cpp +++ clang/tools/libclang/CXType.cpp @@ -1332,7 +1332,7 @@ if (T.isNull()) return CXTypeNullability_Invalid; - if (auto nullability = T->getNullability()) { + if (auto nullability = T.getNullability()) { switch (*nullability) { case NullabilityKind::NonNull: return CXTypeNullability_NonNull; Index: clang/lib/Sema/SemaType.cpp === --- clang/lib/Sema/SemaType.cpp +++ clang/lib/Sema/SemaType.cpp @@ -4713,7 +4713,7 @@ complainAboutMissingNullability = CAMN_InnerPointers; if (T->canHaveNullability(/*ResultIfUnknown*/ false) && -!T->getNullability()) { +!T.getNullability()) { // Note that we allow but don't require nullability on dependent types. ++NumPointersRemaining; } @@ -4935,7 +4935,7 @@ // nullability and perform consistency checking. if (S.CodeSynthesisContexts.empty()) { if (T->canHaveNullability(/*ResultIfUnknown*/ false) && -!T->getNullability()) { +!T.getNullability()) { if (isVaList(T)) { // Record that we've seen a pointer, but do nothing else. if (NumPointersRemaining > 0) @@ -4959,7 +4959,7 @@ } if (complainAboutMissingNullability == CAMN_Yes && T->isArrayType() && -!T->getNullability() && !isVaList(T) && D.isPrototypeContext() && +!T.getNullability() && !isVaList(T) && D.isPrototypeContext() && !hasOuterPointerLikeChunk(D, D.getNumTypeObjects())) { checkNullabilityConsistency(S, SimplePointerKind::Array, D.getDeclSpec().getTypeSpecTypeLoc()); @@ -7415,7 +7415,7 @@ // This (unlike the code above) looks through typedefs that might // have nullability specifiers on them, which means we cannot // provide a useful Fix-It. - if (auto existingNullability = desugared->getNullability()) { + if (auto existingNullability = desugared.getNullability()) { if (nullability != *existingNullability) { S.Diag(nullabilityLoc, diag::err_nullability_conflicting) << DiagNullabilityKind(nullability, isContextSensitive) @@ -7514,7 +7514,7 @@ // If we started with an object pointer type, rebuild it. if (ptrType) { equivType = S.Context.getObjCObjectPointerType(equivType); -if (auto nullability = type->getNullability()) { +if (auto nullability = type.getNullability()) { // We create a nullability attribute from the __kindof attribute. // Make sure that will make sense. assert(attr.getAttributeSpellingListIndex() == 0 && Index: clang/lib/Sema/SemaObjCProperty.cpp === --- clang/lib/Sema/SemaObjCProperty.cpp +++ clang/lib/Sema/SemaObjCProperty.cpp @@ -2754,7 +2754,7 @@ if (Attributes & ObjCPropertyAttribute::kind_weak) { // 'weak' and 'nonnull' are mutually exclusive. -if (auto nullability = PropertyTy->getNullability()) { +if (auto nullability = PropertyTy.getNullability()) { if (*nullability == NullabilityKind::NonNull) Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) << "nonnull" << "weak"; Index: clang/lib/Sema/SemaLambda.cpp === --- clang/lib/Sema/SemaLambda.cpp +++ clang/lib/Sema/SemaLambda.cpp @@ -777,8 +777,8 @@ if (C
[PATCH] D142737: Updated getNullabilityAnnotation for checkers
chrisbazley created this revision. Herald added subscribers: steakhal, martong, JDevlieghere. Herald added a reviewer: NoQ. Herald added a project: All. chrisbazley requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. NullabilityChecker and TrustNonnullChecker use a pre-existing helper function, getNullabilityAnnotation() to get a Nullability value from a QualType. That function is now updated to return Nullability::Nullable if the given type is a pointer to an _Optional-qualified type. The purpose is to allow declarations such as _Optional int *x; to be treated (for static analysis purposes) as equivalent to int *_Nullable x; thereby removing one barrier to adoption of the _Optional type qualifier. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D142737 Files: clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp Index: clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp === --- clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp +++ clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp @@ -100,7 +100,21 @@ return std::make_pair(VD, RHS); } +bool pointeeIsOptional(QualType Type) { + if (const PointerType *PT = Type->getAs()) { +auto PointeeType = PT->getPointeeType(); +if (PointeeType.isOptionalQualified()) { + return true; +} + } + return false; +} + Nullability getNullabilityAnnotation(QualType Type) { + if (pointeeIsOptional(Type)) { +return Nullability::Nullable; + } + const auto *AttrType = Type->getAs(); if (!AttrType) return Nullability::Unspecified; Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h === --- clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h +++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h @@ -62,6 +62,10 @@ Nonnull }; +/// Find out whether the given type is a pointer to an optional value. +/// If true then the pointer value should be treated as nullable. +bool pointeeIsOptional(QualType Type); + /// Get nullability annotation for a given type. Nullability getNullabilityAnnotation(QualType Type); Index: clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp === --- clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp +++ clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp @@ -100,7 +100,21 @@ return std::make_pair(VD, RHS); } +bool pointeeIsOptional(QualType Type) { + if (const PointerType *PT = Type->getAs()) { +auto PointeeType = PT->getPointeeType(); +if (PointeeType.isOptionalQualified()) { + return true; +} + } + return false; +} + Nullability getNullabilityAnnotation(QualType Type) { + if (pointeeIsOptional(Type)) { +return Nullability::Nullable; + } + const auto *AttrType = Type->getAs(); if (!AttrType) return Nullability::Unspecified; Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h === --- clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h +++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h @@ -62,6 +62,10 @@ Nonnull }; +/// Find out whether the given type is a pointer to an optional value. +/// If true then the pointer value should be treated as nullable. +bool pointeeIsOptional(QualType Type); + /// Get nullability annotation for a given type. Nullability getNullabilityAnnotation(QualType Type); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D142738: Warn if _Optional used at top-level of decl
chrisbazley created this revision. Herald added a project: All. chrisbazley requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. Parameter declarations using [] syntax can be written more naturally using an _Optional qualifier than using Clang's _Nullable annotation, e.g. void myfunc(_Optional const char s[]); // s may be a null pointer With the above exception, it isn't useful to declare a non-pointed-to object as _Optional (although so-qualified types exist during expression evaluation). Such declarations are therefore disallowed, like equivalent abuse of the restrict qualifier, to avoid confusion. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D142738 Files: clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaType.cpp Index: clang/lib/Sema/SemaType.cpp === --- clang/lib/Sema/SemaType.cpp +++ clang/lib/Sema/SemaType.cpp @@ -5807,6 +5807,16 @@ } } + // Types other than those of a pointed-to object or pointed-to incomplete type + // shall not be _Optional-qualified in a declaration. + if (T.isOptionalQualified() && !IsTypedefName && + (!T->isArrayType() || !D.isPrototypeContext())) { +S.Diag(D.getDeclSpec().getOptionalSpecLoc(), + diag::err_typecheck_invalid_optional_not_pointee) +<< T; +Context.getNonOptionalType(T); + } + // Apply any undistributed attributes from the declaration or declarator. ParsedAttributesView NonSlidingAttrs; for (ParsedAttr &AL : D.getDeclarationAttributes()) { Index: clang/lib/Sema/SemaDecl.cpp === --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -5088,6 +5088,13 @@ Diag(DS.getRestrictSpecLoc(), diag::err_typecheck_invalid_restrict_not_pointer_noarg) << DS.getSourceRange(); + +// Types other than those of a pointed-to object or pointed-to incomplete +// type shall not be _Optional-qualified in a declaration. +if (TypeQuals & DeclSpec::TQ_optional) + Diag(DS.getOptionalSpecLoc(), + diag::err_typecheck_invalid_optional_not_pointee_noarg) + << DS.getSourceRange(); } if (DS.isInlineSpecified()) Index: clang/include/clang/Basic/DiagnosticSemaKinds.td === --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5930,6 +5930,10 @@ "restrict requires a pointer or reference">; def err_typecheck_invalid_restrict_invalid_pointee : Error< "pointer to function type %0 may not be 'restrict' qualified">; +def err_typecheck_invalid_optional_not_pointee : Error< + "_Optional is only valid on a pointed-to object or incomplete type (%0 is invalid)">; +def err_typecheck_invalid_optional_not_pointee_noarg : Error< + "_Optional is only valid on a pointed-to object or incomplete type">; def ext_typecheck_zero_array_size : Extension< "zero size arrays are an extension">, InGroup; def err_typecheck_zero_array_size : Error< Index: clang/lib/Sema/SemaType.cpp === --- clang/lib/Sema/SemaType.cpp +++ clang/lib/Sema/SemaType.cpp @@ -5807,6 +5807,16 @@ } } + // Types other than those of a pointed-to object or pointed-to incomplete type + // shall not be _Optional-qualified in a declaration. + if (T.isOptionalQualified() && !IsTypedefName && + (!T->isArrayType() || !D.isPrototypeContext())) { +S.Diag(D.getDeclSpec().getOptionalSpecLoc(), + diag::err_typecheck_invalid_optional_not_pointee) +<< T; +Context.getNonOptionalType(T); + } + // Apply any undistributed attributes from the declaration or declarator. ParsedAttributesView NonSlidingAttrs; for (ParsedAttr &AL : D.getDeclarationAttributes()) { Index: clang/lib/Sema/SemaDecl.cpp === --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -5088,6 +5088,13 @@ Diag(DS.getRestrictSpecLoc(), diag::err_typecheck_invalid_restrict_not_pointer_noarg) << DS.getSourceRange(); + +// Types other than those of a pointed-to object or pointed-to incomplete +// type shall not be _Optional-qualified in a declaration. +if (TypeQuals & DeclSpec::TQ_optional) + Diag(DS.getOptionalSpecLoc(), + diag::err_typecheck_invalid_optional_not_pointee_noarg) + << DS.getSourceRange(); } if (DS.isInlineSpecified()) Index: clang/include/clang/Basic/DiagnosticSemaKinds.td === --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5930,6 +5930,10 @@ "restrict requires a pointer or refer
[PATCH] D142739: Standalone checker for use of _Optional qualifier
chrisbazley created this revision. Herald added subscribers: steakhal, martong. Herald added a reviewer: NoQ. Herald added a project: All. chrisbazley requested review of this revision. Herald added projects: clang, LLVM. Herald added subscribers: llvm-commits, cfe-commits. This checker tries to find violations in use of pointers to _Optional objects which cannot be detected by the type system alone. This requires detection of null pointer dereferences at the expression level, rather than at the level of simulated memory accesses (which is already implemented by other checkers). Such expressions include those which implicitly remove the _Optional qualifier from pointer targets without actually accessing the pointed-to object. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D142739 Files: clang/docs/analyzer/checkers.rst clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt clang/lib/StaticAnalyzer/Checkers/OptionalityChecker.cpp llvm/utils/gn/secondary/clang/lib/StaticAnalyzer/Checkers/BUILD.gn Index: llvm/utils/gn/secondary/clang/lib/StaticAnalyzer/Checkers/BUILD.gn === --- llvm/utils/gn/secondary/clang/lib/StaticAnalyzer/Checkers/BUILD.gn +++ llvm/utils/gn/secondary/clang/lib/StaticAnalyzer/Checkers/BUILD.gn @@ -97,6 +97,7 @@ "ObjCSelfInitChecker.cpp", "ObjCSuperDeallocChecker.cpp", "ObjCUnusedIVarsChecker.cpp", +"OptionalityChecker.cpp", "PaddingChecker.cpp", "PointerArithChecker.cpp", "PointerIterationChecker.cpp", Index: clang/lib/StaticAnalyzer/Checkers/OptionalityChecker.cpp === --- /dev/null +++ clang/lib/StaticAnalyzer/Checkers/OptionalityChecker.cpp @@ -0,0 +1,138 @@ +//===-- OptionalityChecker.cpp - Optionality checker --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This checker tries to find violations in use of pointers to _Optional +// objects which cannot be detected by the type system alone. This requires +// detection of null pointer dereferences at the expression level, rather than +// at the level of simulated memory accesses (which is already implemented by +// other checkers). +// +// Such expressions include those which implicitly remove the _Optional +// qualifier from pointer targets without actually accessing the pointed-to +// object. +// +//===--===// + +#include "Iterator.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" + +#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h" + +#include "llvm/ADT/StringExtras.h" +#include "llvm/Support/Path.h" + +using namespace clang; +using namespace ento; + +namespace { + +class OptionalityChecker +: public Checker< + check::PreStmt, check::PreStmt, + check::PreStmt, check::PreStmt> { + + void verifyAccess(CheckerContext &C, const Expr *E) const; + +public: + void checkPreStmt(const UnaryOperator *UO, CheckerContext &C) const; + void checkPreStmt(const BinaryOperator *BO, CheckerContext &C) const; + void checkPreStmt(const ArraySubscriptExpr *ASE, CheckerContext &C) const; + void checkPreStmt(const MemberExpr *ME, CheckerContext &C) const; + + CheckerNameRef CheckName; + mutable std::unique_ptr BT; + + const std::unique_ptr &getBugType() const { +if (!BT) + BT.reset(new BugType(CheckName, "Optionality", categories::MemoryError)); +return BT; + } + +private: + void reportBug(StringRef Msg, ExplodedNode *N, BugReporter &BR) const { +const std::unique_ptr &BT = getBugType(); +auto R = std::make_unique(*BT, Msg, N); +BR.emitReport(std::move(R)); + } +}; + +} // end anonymous namespace + +void OptionalityChecker::checkPreStmt(const UnaryOperator *UO, + CheckerContext &C) const { + if (isa(UO->getSubExpr())) +return; + + UnaryOperatorKind OK = UO->getOpcode(); + + if (clang::ento::iterator::isAccessOperator(OK)) { +verifyAccess(C, UO->getSubExpr()); + } +} + +void OptionalityChecker::checkPreStmt(const BinaryOperator *BO, + CheckerContext &C) const { + BinaryOperatorKind OK = BO->getOpcode(); + + if (clang::ento::iterator::isAccessOperator(OK)) { +verifyAccess(C, BO->getLHS()); + } +} + +void OptionalityChecker::checkPreStmt(const ArraySubscriptExpr
[PATCH] D142741: Fix ProgramState::isNull for non-region symbols
chrisbazley created this revision. Herald added subscribers: steakhal, martong. Herald added a reviewer: NoQ. Herald added a project: All. chrisbazley requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. This method was good at telling that a pointer definitely is null, but bad at telling that it definitely isn't null. For example, it returned 'not sure' in the following trivial case: int main(void) { int p; int _Optional *q = &p; if (q) { *q = 0; // spurious warning } return 0; } When analyzing the above program, the statement if (q) does not create a constraint such as range [1, 18446744073709551615] for use in future inferences about the value of q. The reason is that SimpleConstraintManager::assumeInternal replaces the condition specified by its caller with 1 if invoked on a symbol (such as q) that lacks an associated memory region. Constraints are not recorded for integer constants. Added fallback in ProgramState::isNull to do the same conversion and check for a zero result if invoked on an expression which is not a constant and does not wrap a symbol (or wraps a symbol that lacks a memory region). Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D142741 Files: clang/lib/StaticAnalyzer/Core/ProgramState.cpp Index: clang/lib/StaticAnalyzer/Core/ProgramState.cpp === --- clang/lib/StaticAnalyzer/Core/ProgramState.cpp +++ clang/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -386,8 +386,24 @@ return false; SymbolRef Sym = V.getAsSymbol(/* IncludeBaseRegion */ true); - if (!Sym) + if (!Sym) { +if (Optional LV = V.getAs()) { + SValBuilder &SVB = stateMgr->getSValBuilder(); + QualType T; + const MemRegion *MR = LV->getAsRegion(); + if (const TypedRegion *TR = dyn_cast_or_null(MR)) +T = TR->getLocationType(); + else +T = SVB.getContext().VoidPtrTy; + + V = SVB.evalCast(*LV, SVB.getContext().BoolTy, T); + auto const integer = V.getAsInteger(); + if (integer) { +return integer->isZero(); + } +} return ConditionTruthVal(); + } return getStateManager().ConstraintMgr->isNull(this, Sym); } Index: clang/lib/StaticAnalyzer/Core/ProgramState.cpp === --- clang/lib/StaticAnalyzer/Core/ProgramState.cpp +++ clang/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -386,8 +386,24 @@ return false; SymbolRef Sym = V.getAsSymbol(/* IncludeBaseRegion */ true); - if (!Sym) + if (!Sym) { +if (Optional LV = V.getAs()) { + SValBuilder &SVB = stateMgr->getSValBuilder(); + QualType T; + const MemRegion *MR = LV->getAsRegion(); + if (const TypedRegion *TR = dyn_cast_or_null(MR)) +T = TR->getLocationType(); + else +T = SVB.getContext().VoidPtrTy; + + V = SVB.evalCast(*LV, SVB.getContext().BoolTy, T); + auto const integer = V.getAsInteger(); + if (integer) { +return integer->isZero(); + } +} return ConditionTruthVal(); + } return getStateManager().ConstraintMgr->isNull(this, Sym); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D142742: Generate ImplicitNullDerefEvent from CallAndMessageChecker
chrisbazley created this revision. Herald added subscribers: steakhal, martong. Herald added a reviewer: NoQ. Herald added a project: All. chrisbazley requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. Without this change, the following code does not generate "warning: Nullable pointer is dereferenced": void test(void (*_Nullable fn)(void)) { fn(); } Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D142742 Files: clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp Index: clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp === --- clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp @@ -32,7 +32,7 @@ class CallAndMessageChecker : public Checker { + check::PreCall, EventDispatcher> { mutable std::unique_ptr BT_call_null; mutable std::unique_ptr BT_call_undef; mutable std::unique_ptr BT_cxx_call_null; @@ -389,16 +389,30 @@ ProgramStateRef StNonNull, StNull; std::tie(StNonNull, StNull) = State->assume(L.castAs()); - if (StNull && !StNonNull) { -if (!ChecksEnabled[CK_FunctionPointer]) { - C.addSink(StNull); + if (StNull) { +if (!StNonNull) { + if (!ChecksEnabled[CK_FunctionPointer]) { +C.addSink(StNull); +return nullptr; + } + if (!BT_call_null) +BT_call_null.reset(new BuiltinBug( +OriginalName, +"Called function pointer is null (null dereference)")); + emitBadCall(BT_call_null.get(), C, Callee); return nullptr; } -if (!BT_call_null) - BT_call_null.reset(new BuiltinBug( - OriginalName, "Called function pointer is null (null dereference)")); -emitBadCall(BT_call_null.get(), C, Callee); -return nullptr; + +// Otherwise, we have the case where the location could either be +// null or not-null. Record the error node as an "implicit" null +// dereference. +if (ExplodedNode *N = C.generateSink(StNull, C.getPredecessor())) { + printf("\nimplicit null dereference\n"); + ImplicitNullDerefEvent event = {L, /*isLoad=*/true, N, + &C.getBugReporter(), + /*IsDirectDereference=*/true}; + dispatchEvent(event); +} } return StNonNull; Index: clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp === --- clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp @@ -32,7 +32,7 @@ class CallAndMessageChecker : public Checker { + check::PreCall, EventDispatcher> { mutable std::unique_ptr BT_call_null; mutable std::unique_ptr BT_call_undef; mutable std::unique_ptr BT_cxx_call_null; @@ -389,16 +389,30 @@ ProgramStateRef StNonNull, StNull; std::tie(StNonNull, StNull) = State->assume(L.castAs()); - if (StNull && !StNonNull) { -if (!ChecksEnabled[CK_FunctionPointer]) { - C.addSink(StNull); + if (StNull) { +if (!StNonNull) { + if (!ChecksEnabled[CK_FunctionPointer]) { +C.addSink(StNull); +return nullptr; + } + if (!BT_call_null) +BT_call_null.reset(new BuiltinBug( +OriginalName, +"Called function pointer is null (null dereference)")); + emitBadCall(BT_call_null.get(), C, Callee); return nullptr; } -if (!BT_call_null) - BT_call_null.reset(new BuiltinBug( - OriginalName, "Called function pointer is null (null dereference)")); -emitBadCall(BT_call_null.get(), C, Callee); -return nullptr; + +// Otherwise, we have the case where the location could either be +// null or not-null. Record the error node as an "implicit" null +// dereference. +if (ExplodedNode *N = C.generateSink(StNull, C.getPredecessor())) { + printf("\nimplicit null dereference\n"); + ImplicitNullDerefEvent event = {L, /*isLoad=*/true, N, + &C.getBugReporter(), + /*IsDirectDereference=*/true}; + dispatchEvent(event); +} } return StNonNull; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D142743: Fix nullability checking of top-level functions
chrisbazley created this revision. Herald added subscribers: steakhal, martong. Herald added a reviewer: NoQ. Herald added a project: All. chrisbazley requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. The existing nullability checker is so limited when applied to top-level functions that a casual observer might assume it doesn't work at all: void test1(int *_Nullable x) { *x = 5; // no warning! } Added a NullabilityChecker::checkBeginFunction method to honour any _Nullable annotation of parameters in a top-level call. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D142743 Files: clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp Index: clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp === --- clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp @@ -26,12 +26,13 @@ #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" +#include "clang/Analysis/AnyCall.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Path.h" @@ -78,10 +79,11 @@ }; class NullabilityChecker -: public Checker, - check::PostCall, check::PostStmt, - check::PostObjCMessage, check::DeadSymbols, eval::Assume, - check::Location, check::Event> { +: public Checker, check::PostCall, + check::PostStmt, check::PostObjCMessage, + check::DeadSymbols, eval::Assume, check::Location, + check::Event> { public: // If true, the checker will not diagnose nullabilility issues for calls @@ -104,6 +106,7 @@ CheckerContext &C) const; ProgramStateRef evalAssume(ProgramStateRef State, SVal Cond, bool Assumption) const; + void checkBeginFunction(CheckerContext &C) const; void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep) const override; @@ -1344,6 +1347,59 @@ } } +/// We want to trust developer annotations and consider all 'nullable' +/// parameters as potentially null. Each marked parameter will get a +/// corresponding constraint. +/// +/// \code +/// void foo(int *_Nullable x) { +/// // . . . +/// *x = 42;// we want to consider this as an error... +/// // . . . +/// } +/// \endcode +void NullabilityChecker::checkBeginFunction(CheckerContext &Context) const { + // Planned assumption makes sense only for top-level functions. + if (!Context.inTopFrame()) +return; + + const LocationContext *LocContext = Context.getLocationContext(); + + const Decl *FD = LocContext->getDecl(); + // AnyCall helps us here to avoid checking for FunctionDecl and ObjCMethodDecl + // separately and aggregates interfaces of these classes. + auto AbstractCall = AnyCall::forDecl(FD); + if (!AbstractCall) +return; + + ProgramStateRef State = Context.getState(); + + for (const ParmVarDecl *Parameter : AbstractCall->parameters()) { +Nullability RequiredNullability = +getNullabilityAnnotation(Parameter->getType()); + +if (RequiredNullability != Nullability::Nullable) + continue; + +Loc ParameterLoc = State->getLValue(Parameter, LocContext); +// We never consider top-level function parameters undefined. +auto StoredVal = +State->getSVal(ParameterLoc).castAs(); + +const MemRegion *Region = getTrackRegion(StoredVal); +if (!Region) + continue; + +const Stmt *NullabilitySource = Parameter->getBody(); +if (ProgramStateRef NewState = State->set( +Region, NullabilityState(RequiredNullability, NullabilitySource))) { + State = NewState; +} + } + + Context.addTransition(State); +} + void ento::registerNullabilityBase(CheckerManager &mgr) { mgr.registerChecker(); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D142744: Re-analyze functions as top-level
chrisbazley created this revision. Herald added subscribers: steakhal, martong. Herald added a reviewer: NoQ. Herald added a project: All. chrisbazley requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. If a function with a _Nullable parameter has at least one caller, the checker behaves as though no other parameter value is possible. This is because the static analyzer doesn't re-analyse functions as top level (with the exception of C++ copy and move operators, and ObjC methods). Fixed by modifying shouldSkipFunction to return false. After this change, Clang-tidy even emits different warnings for the same line of code, if appropriate: "Nullable pointer is dereferenced" for a (simulated) top-level call and "Dereference of null pointer" for a call to the same function with a known null value. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D142744 Files: clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Index: clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp === --- clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -408,6 +408,12 @@ // Count naming convention errors more aggressively. if (isa(D)) return false; + + // If a function with a _Nullable parameter has at least one caller, the + // checker behaves as though no other parameter value is possible. This is + // because the static analyzer doesn't re-analyse functions as top level. + return false; + // We also want to reanalyze all C++ copy and move assignment operators to // separately check the two cases where 'this' aliases with the parameter and // where it may not. (cplusplus.SelfAssignmentChecker) Index: clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp === --- clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -408,6 +408,12 @@ // Count naming convention errors more aggressively. if (isa(D)) return false; + + // If a function with a _Nullable parameter has at least one caller, the + // checker behaves as though no other parameter value is possible. This is + // because the static analyzer doesn't re-analyse functions as top level. + return false; + // We also want to reanalyze all C++ copy and move assignment operators to // separately check the two cases where 'this' aliases with the parameter and // where it may not. (cplusplus.SelfAssignmentChecker) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D142744: Re-analyze functions as top-level
chrisbazley added a comment. This change is admittedly a hack. It might be better to check the function parameter types, or maybe the list of exceptions in this function is now so long that it no longer serves any purpose. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D142744/new/ https://reviews.llvm.org/D142744 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D142739: Standalone checker for use of _Optional qualifier
chrisbazley added a comment. Please refer to https://discourse.llvm.org/t/rfc-optional-a-type-qualifier-to-indicate-pointer-nullability/ and https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3089.pdf for the wider context of this commit. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D142739/new/ https://reviews.llvm.org/D142739 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D142741: Fix ProgramState::isNull for non-region symbols
chrisbazley added a comment. Please refer to https://discourse.llvm.org/t/rfc-optional-a-type-qualifier-to-indicate-pointer-nullability/ and https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3089.pdf for the wider context of this commit. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D142741/new/ https://reviews.llvm.org/D142741 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D142742: Generate ImplicitNullDerefEvent from CallAndMessageChecker
chrisbazley added a comment. Please refer to https://discourse.llvm.org/t/rfc-optional-a-type-qualifier-to-indicate-pointer-nullability/ and https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3089.pdf for the wider context of this commit. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D142742/new/ https://reviews.llvm.org/D142742 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D142743: Fix nullability checking of top-level functions
chrisbazley added a comment. Please refer to https://discourse.llvm.org/t/rfc-optional-a-type-qualifier-to-indicate-pointer-nullability/ and https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3089.pdf for the wider context of this commit. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D142743/new/ https://reviews.llvm.org/D142743 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D142744: Re-analyze functions as top-level
chrisbazley added a comment. Please refer to https://discourse.llvm.org/t/rfc-optional-a-type-qualifier-to-indicate-pointer-nullability/ and https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3089.pdf for the wider context of this commit. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D142744/new/ https://reviews.llvm.org/D142744 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D142733: Add _Optional as fast qualifier
chrisbazley added a comment. Please refer to https://discourse.llvm.org/t/rfc-optional-a-type-qualifier-to-indicate-pointer-nullability/ and https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3089.pdf for the wider context of this commit. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D142733/new/ https://reviews.llvm.org/D142733 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D142734: Updated CheckAddressOfOperand
chrisbazley added a comment. Please refer to https://discourse.llvm.org/t/rfc-optional-a-type-qualifier-to-indicate-pointer-nullability/ and https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3089.pdf for the wider context of this commit. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D142734/new/ https://reviews.llvm.org/D142734 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D142736: Add QualType::getNullability for _Optional
chrisbazley added a comment. Please refer to https://discourse.llvm.org/t/rfc-optional-a-type-qualifier-to-indicate-pointer-nullability/ and https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3089.pdf for the wider context of this commit. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D142736/new/ https://reviews.llvm.org/D142736 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D142737: Updated getNullabilityAnnotation for checkers
chrisbazley added a comment. Please refer to https://discourse.llvm.org/t/rfc-optional-a-type-qualifier-to-indicate-pointer-nullability/ and https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3089.pdf for the wider context of this commit. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D142737/new/ https://reviews.llvm.org/D142737 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D142738: Warn if _Optional used at top-level of decl
chrisbazley added a comment. Please refer to https://discourse.llvm.org/t/rfc-optional-a-type-qualifier-to-indicate-pointer-nullability/ and https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3089.pdf for the wider context of this commit. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D142738/new/ https://reviews.llvm.org/D142738 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D142733: Add _Optional as fast qualifier
chrisbazley added a comment. Hi, thanks very much for looking at my patch. I added the link that you proposed to all of the patches in the stack. > Assuming that we want to go in this direction, it seems quite expensive to > model this as a fast qualifier rather than an extended qualifier. True, and I'm not at all wedded to the idea of _Optional being a fast qualifier. I added it in the simplest way I knew how, having no prior experience of the codebase. What would be really useful would be if you could show/explain how to add it in a less risky way. If not, I can look into it myself. > Are these annotations expected to be so common that it's better to increase > the alignment of all types than perform extra allocations and indirections > for _Optional qualifiers? Given time, I hope so, but realistically not in the near future. > Have you measured the memory impact of increasing the alignment of Type? No, because I didn't think it necessary for the purpose of prototyping. If there's any prospect of getting my patches merged then I'd be delighted to invest the time... but only if increasing the alignment is a necessary thing to do. > I think that should be a prerequisite to adding any new kind of fast > qualifier, and if we do add such a qualifier, we should select carefully > which qualifier gets this precious bit in QualType. I believe that over time, _Optional would be a much more appropriate use of the precious bit currently occupied by volatile because I expect it to be used more heavily, but I can't make that argument yet. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D142733/new/ https://reviews.llvm.org/D142733 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits