Enable support for the [[maybe_unused]] attribute from WG14 N2053 when enabling double square bracket attributes in C code.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@316096 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Aaron Ballman 2017-10-18 16:59:27 +00:00
parent 58199aaa59
commit f53794cdab
4 changed files with 51 additions and 2 deletions

View File

@ -1936,7 +1936,8 @@ def ObjCRequiresPropertyDefs : InheritableAttr {
}
def Unused : InheritableAttr {
let Spellings = [CXX11<"", "maybe_unused", 201603>, GCC<"unused">];
let Spellings = [CXX11<"", "maybe_unused", 201603>, GCC<"unused">,
C2x<"", "maybe_unused">];
let Subjects = SubjectList<[Var, ObjCIvar, Type, Enum, EnumConstant, Label,
Field, ObjCMethod, FunctionLike], WarnDiag,
"ExpectedForMaybeUnused">;

View File

@ -79,7 +79,8 @@ static void DiagnoseUnusedOfDecl(Sema &S, NamedDecl *D, SourceLocation Loc) {
if (const auto *A = D->getAttr<UnusedAttr>()) {
// [[maybe_unused]] should not diagnose uses, but __attribute__((unused))
// should diagnose them.
if (A->getSemanticSpelling() != UnusedAttr::CXX11_maybe_unused) {
if (A->getSemanticSpelling() != UnusedAttr::CXX11_maybe_unused &&
A->getSemanticSpelling() != UnusedAttr::C2x_maybe_unused) {
const Decl *DC = cast_or_null<Decl>(S.getCurObjCLexicalContext());
if (DC && !DC->hasAttr<UnusedAttr>())
S.Diag(Loc, diag::warn_used_but_marked_unused) << D->getDeclName();

View File

@ -0,0 +1,12 @@
// RUN: %clang_cc1 -fsyntax-only -Wunused -fdouble-square-bracket-attributes -verify %s
struct [[maybe_unused]] S1 { // ok
int a [[maybe_unused]];
};
struct [[maybe_unused maybe_unused]] S2 { // expected-error {{attribute 'maybe_unused' cannot appear multiple times in an attribute specifier}}
int a;
};
struct [[maybe_unused("Wrong")]] S3 { // expected-error {{'maybe_unused' cannot have an argument list}}
int a;
};

View File

@ -0,0 +1,35 @@
// RUN: %clang_cc1 -fsyntax-only -Wunused -fdouble-square-bracket-attributes -verify %s
struct [[maybe_unused]] S1 { // ok
int a [[maybe_unused]];
};
enum [[maybe_unused]] E1 {
EnumVal [[maybe_unused]]
};
[[maybe_unused]] void unused_func([[maybe_unused]] int parm) {
typedef int maybe_unused_int [[maybe_unused]];
[[maybe_unused]] int I;
}
void f1(void) {
int x; // expected-warning {{unused variable}}
typedef int I; // expected-warning {{unused typedef 'I'}}
// Should not warn about these due to not being used.
[[maybe_unused]] int y;
typedef int maybe_unused_int [[maybe_unused]];
// Should not warn about these uses.
struct S1 s;
maybe_unused_int test;
y = 12;
}
void f2(void);
[[maybe_unused]] void f2(void);
void f2(void) {
}