| mgehre updated this revision to Diff 72981. mgehre added a comment. | View Revision
Add additional gsl::suppress spelling, add test, add documentation
Files:
include/clang/Basic/Attr.td
include/clang/Basic/AttrDocs.td
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaStmtAttr.cpp
test/SemaCXX/suppress.cpp
include/clang/Basic/AttrDocs.td
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaStmtAttr.cpp
test/SemaCXX/suppress.cpp
Index: test/SemaCXX/suppress.cpp
===================================================================
--- /dev/null
+++ test/SemaCXX/suppress.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only %s -verify
+
+[[clang::suppress("globally")]];
+
+namespace N {
+ [[clang::suppress("in-a-namespace")]];
+}
+
+[[clang::suppress("readability-identifier-naming")]]
+void f_() {
+ int *aVar_Name;
+ [[gsl::suppress("type", "bounds")]] {
+ aVar_Name = reinterpret_cast<int*>(7);
+ }
+
+ [[clang::suppress]] int x; // expected-error {{'suppress' attribute takes at least 1 argument}}
+ [[clang::suppress()]] int y; // expected-error {{'suppress' attribute takes at least 1 argument}}
+ int [[clang::suppress("r")]] z; // expected-error {{'suppress' attribute cannot be applied to types}}
+ [[clang::suppress(f_)]] float f; // expected-error {{'suppress' attribute requires a string}}
+}
+
+union [[gsl::suppress("type.1")]] U {
+ int i;
+ float f;
+};
Index: lib/Sema/SemaStmtAttr.cpp
===================================================================
--- lib/Sema/SemaStmtAttr.cpp
+++ lib/Sema/SemaStmtAttr.cpp
@@ -53,6 +53,28 @@
return ::new (S.Context) auto(Attr);
}
+static Attr *handleSuppressAttr(Sema &S, Stmt *St, const AttributeList &A,
+ SourceRange Range) {
+ if (A.getNumArgs() < 1) {
+ S.Diag(A.getLoc(), diag::err_attribute_too_few_arguments) << A.getName() << 1;
+ return nullptr;
+ }
+
+ std::vector<StringRef> Rules;
+ for (unsigned I = 0, E = A.getNumArgs(); I != E; ++I) {
+ StringRef RuleName;
+ SourceLocation LiteralLoc;
+
+ if (!S.checkStringLiteralArgumentAttr(A, I, RuleName, &LiteralLoc))
+ return nullptr;
+
+ Rules.push_back(RuleName);
+ }
+
+ return ::new (S.Context) SuppressAttr(A.getRange(), S.Context, Rules.data(), Rules.size(),
+ A.getAttributeSpellingListIndex());
+}
+
static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A,
SourceRange) {
IdentifierLoc *PragmaNameLoc = A.getArgAsIdent(0);
@@ -283,6 +305,8 @@
return handleLoopHintAttr(S, St, A, Range);
case AttributeList::AT_OpenCLUnrollHint:
return handleOpenCLUnrollHint(S, St, A, Range);
+ case AttributeList::AT_Suppress:
+ return handleSuppressAttr(S, St, A, Range);
default:
// if we're here, then we parsed a known attribute, but didn't recognize
// it as a statement attribute => it is declaration attribute
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -3838,6 +3838,26 @@
}
}
+static void handleSuppressAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+ if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
+ return;
+
+ std::vector<StringRef> Rules;
+ for (unsigned I = 0, E = Attr.getNumArgs(); I != E; ++I) {
+ StringRef RuleName;
+ SourceLocation LiteralLoc;
+
+ if (!S.checkStringLiteralArgumentAttr(Attr, I, RuleName, &LiteralLoc))
+ return;
+
+ Rules.push_back(RuleName);
+ }
+ D->addAttr(::new (S.Context) SuppressAttr(
+ Attr.getRange(), S.Context, Rules.data(), Rules.size(),
+ Attr.getAttributeSpellingListIndex()));
+}
+
+
bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
const FunctionDecl *FD) {
if (attr.isInvalid())
@@ -5830,6 +5850,9 @@
case AttributeList::AT_PreserveAll:
handleCallConvAttr(S, D, Attr);
break;
+ case AttributeList::AT_Suppress:
+ handleSuppressAttr(S, D, Attr);
+ break;
case AttributeList::AT_OpenCLKernel:
handleSimpleAttribute<OpenCLKernelAttr>(S, D, Attr);
break;
Index: include/clang/Basic/AttrDocs.td
===================================================================
--- include/clang/Basic/AttrDocs.td
+++ include/clang/Basic/AttrDocs.td
@@ -2501,6 +2501,33 @@
}];
}
+def SuppressDocs : Documentation {
+ let Category = DocCatStmt;
+ let Content = [{
+The ``[[clang::suppress]]`` and ``[[gsl::suppress]]`` attributes can be used
+to suppress specific clang-tidy warnings. They can be attached to a scope,
+statement or type. The ``[[gsl::suppress]]`` is an alias of ``[[clang::suppress]]``
+which is intended to be used for suppressing rules of the C++ Core Guidelines_
+in a portable way. The attribute can be attached to declarations, statements,
+and on namespace scope.
+
+.. code-block: c++
+ [[clang::suppress("readability-identifier-naming")]]
+ void f_() {
+ int *aVar_Name;
+ [[gsl::suppress("type")]] {
+ aVar_Name = reinterpret-cast<int*>(7);
+ }
+ }
+ namespace N {
+ [[clang::suppress("type", "bounds")]];
+ ...
+ }
+
+.. Guidelines_: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#inforce-enforcement
+ }];
+}
+
def AbiTagsDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Index: include/clang/Basic/Attr.td
===================================================================
--- include/clang/Basic/Attr.td
+++ include/clang/Basic/Attr.td
@@ -1464,6 +1464,12 @@
let Documentation = [SwiftIndirectResultDocs];
}
+def Suppress : StmtAttr {
+ let Spellings = [CXX11<"clang", "suppress">, CXX11<"gsl", "suppress">];
+ let Args = [VariadicStringArgument<"Rules">];
+ let Documentation = [SuppressDocs];
+}
+
def SysVABI : InheritableAttr {
let Spellings = [GCC<"sysv_abi">];
// let Subjects = [Function, ObjCMethod];
_______________________________________________ cfe-commits mailing list [email protected] http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
