Index: clang/include/clang/Basic/Attr.td =================================================================== --- clang/include/clang/Basic/Attr.td +++ clang/include/clang/Basic/Attr.td @@ -3561,3 +3561,33 @@ let SemaHandler = 0; let Documentation = [Undocumented]; } + +def NoRefCntblBaseVirtualDtor : InheritableAttr { + let Spellings = [Clang<"NoRefCntblBaseVirtualDtor">]; + let Subjects = SubjectList<[CXXRecord]>; + let Documentation = [Undocumented]; +} + +def NoUncountedLambdaCaptures : InheritableAttr { + let Spellings = [Clang<"NoUncountedLambdaCaptures">]; + let Subjects = SubjectList<[Var]>; + let Documentation = [Undocumented]; +} + +def NoNoUncountedMember : InheritableAttr { + let Spellings = [Clang<"NoNoUncountedMember">]; + let Subjects = SubjectList<[Field]>; + let Documentation = [Undocumented]; +} + +def NoUncountedLocalVars : InheritableAttr { + let Spellings = [Clang<"NoUncountedLocalVars">]; + let Subjects = SubjectList<[Var]>; + let Documentation = [Undocumented]; +} + +def NoUncountedCallArgs : InheritableAttr { + let Spellings = [Clang<"NoUncountedCallArgs">]; + let Subjects = SubjectList<[ParmVar]>; + let Documentation = [Undocumented]; +} Index: clang/lib/Sema/SemaDeclAttr.cpp =================================================================== --- clang/lib/Sema/SemaDeclAttr.cpp +++ clang/lib/Sema/SemaDeclAttr.cpp @@ -7963,6 +7963,26 @@ case ParsedAttr::AT_UseHandle: handleHandleAttr(S, D, AL); break; + + case ParsedAttr::AT_NoRefCntblBaseVirtualDtor: + handleSimpleAttribute(S, D, AL); + break; + + case ParsedAttr::AT_NoUncountedLambdaCaptures: + handleSimpleAttribute(S, D, AL); + break; + + case ParsedAttr::AT_NoNoUncountedMember: + handleSimpleAttribute(S, D, AL); + break; + + case ParsedAttr::AT_NoUncountedLocalVars: + handleSimpleAttribute(S, D, AL); + break; + + case ParsedAttr::AT_NoUncountedCallArgs: + handleSimpleAttribute(S, D, AL); + break; } } Index: clang/lib/StaticAnalyzer/Checkers/WebKit/NoUncountedMembersChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/WebKit/NoUncountedMembersChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/WebKit/NoUncountedMembersChecker.cpp @@ -74,6 +74,9 @@ if (!MemberType) continue; + if (Member->hasAttr()) + continue; + if (auto *MemberCXXRD = MemberType->getPointeeCXXRecordDecl()) { // If we don't see the definition we just don't know. if (MemberCXXRD->hasDefinition()) { Index: clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp @@ -122,6 +122,9 @@ SrcMgr::C_User) return true; + if (RD->hasAttr()) + return true; + return false; } Index: clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp @@ -81,6 +81,9 @@ // if ((*P)->hasAttr()) // continue; + if ((*P)->hasAttr()) + continue; + const auto *ArgType = (*P)->getType().getTypePtrOrNull(); if (!ArgType) continue; // FIXME? Should we bail? Index: clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp @@ -58,6 +58,11 @@ for (const LambdaCapture &C : L->captures()) { if (C.capturesVariable()) { VarDecl *CapturedVar = C.getCapturedVar(); + if (!CapturedVar) + continue; + if (CapturedVar->hasAttr()) + continue; + if (auto *CapturedVarType = CapturedVar->getType().getTypePtrOrNull()) { Optional IsUncountedPtr = isUncountedPtr(CapturedVarType); if (IsUncountedPtr && *IsUncountedPtr) { Index: clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLocalVarsChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLocalVarsChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLocalVarsChecker.cpp @@ -222,6 +222,9 @@ if (isDeclaredInForOrIf(V)) return true; + if (V->hasAttr()) + return true; + return false; } Index: clang/test/Analysis/Checkers/WebKit/call-args.cpp =================================================================== --- clang/test/Analysis/Checkers/WebKit/call-args.cpp +++ clang/test/Analysis/Checkers/WebKit/call-args.cpp @@ -342,3 +342,10 @@ // expected-warning@-1{{Call argument for parameter 'bad' is uncounted and unsafe}} } } + +namespace suppression { + void consume_refcntbl_unsafe([[clang::NoUncountedCallArgs]] RefCountable*) {} + void foo() { + consume_refcntbl_unsafe(provide()); + } +} Index: clang/test/Analysis/Checkers/WebKit/ref-cntbl-base-virtual-dtor.cpp =================================================================== --- clang/test/Analysis/Checkers/WebKit/ref-cntbl-base-virtual-dtor.cpp +++ clang/test/Analysis/Checkers/WebKit/ref-cntbl-base-virtual-dtor.cpp @@ -13,7 +13,7 @@ virtual ~DerivedWithVirtualDtor() {} }; - +struct [[clang::NoRefCntblBaseVirtualDtor]] Derived2 : RefCntblBase { }; template struct DerivedClassTmpl : T { }; Index: clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp =================================================================== --- clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp +++ clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp @@ -42,3 +42,10 @@ auto foo4 = [=]() {}; RefCountable *ref_countable = nullptr; } + +void suppressed() { + RefCountable patatino; + RefCountable& ref_countable_ref [[clang::NoUncountedLambdaCaptures]] = patatino; + + auto foo1 = [ref_countable_ref](){}; +} \ No newline at end of file Index: clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp =================================================================== --- clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp +++ clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp @@ -97,3 +97,10 @@ for (RefCountable *a : array) { } } } // namespace ignore_for_if + +namespace suppression { +void foo_ref() { + RefCountable automatic; + RefCountable &bar [[clang::NoUncountedLocalVars]] = automatic; +} +} Index: clang/test/Analysis/Checkers/WebKit/uncounted-members.cpp =================================================================== --- clang/test/Analysis/Checkers/WebKit/uncounted-members.cpp +++ clang/test/Analysis/Checkers/WebKit/uncounted-members.cpp @@ -41,3 +41,9 @@ void forceTmplToInstantiate(RefPtr) {} } + +namespace suppression { + struct Foo { + RefCountable* a [[clang::NoNoUncountedMember]] = nullptr; + }; +}