From: Aaron Ballman Date: Tue, 17 Oct 2017 20:33:35 +0000 (+0000) Subject: Enable support for the [[nodiscard]] attribute from WG14 N2050 when enabling double... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6a20f1df9306b119ab68a4507fce68cf543cca96;p=clang Enable support for the [[nodiscard]] attribute from WG14 N2050 when enabling double square bracket attributes in C code. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@316026 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 4ee2a9845c..5ff08dd700 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -2004,10 +2004,10 @@ def WarnUnused : InheritableAttr { } def WarnUnusedResult : InheritableAttr { - let Spellings = [CXX11<"", "nodiscard", 201603>, + let Spellings = [CXX11<"", "nodiscard", 201603>, C2x<"", "nodiscard">, CXX11<"clang", "warn_unused_result">, GCC<"warn_unused_result">]; - let Subjects = SubjectList<[ObjCMethod, Enum, CXXRecord, FunctionLike], + let Subjects = SubjectList<[ObjCMethod, Enum, Record, FunctionLike], WarnDiag, "ExpectedFunctionMethodEnumOrClass">; let Documentation = [WarnUnusedResultsDocs]; } diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 9b0d976ebb..f27df1de81 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -3056,7 +3056,8 @@ SourceRange FunctionDecl::getExceptionSpecSourceRange() const { const Attr *FunctionDecl::getUnusedResultAttr() const { QualType RetType = getReturnType(); if (RetType->isRecordType()) { - if (const CXXRecordDecl *Ret = RetType->getAsCXXRecordDecl()) { + if (const auto *Ret = + dyn_cast_or_null(RetType->getAsTagDecl())) { if (const auto *R = Ret->getAttr()) return R; } diff --git a/test/Sema/c2x-nodiscard.c b/test/Sema/c2x-nodiscard.c new file mode 100644 index 0000000000..f128d3bb57 --- /dev/null +++ b/test/Sema/c2x-nodiscard.c @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes -verify %s + +struct [[nodiscard]] S1 { // ok + int i; +}; +struct [[nodiscard nodiscard]] S2 { // expected-error {{attribute 'nodiscard' cannot appear multiple times in an attribute specifier}} + int i; +}; +struct [[nodiscard("Wrong")]] S3 { // expected-error {{'nodiscard' cannot have an argument list}} + int i; +}; + +[[nodiscard]] int f1(void); +enum [[nodiscard]] E1 { One }; + +[[nodiscard]] int i; // expected-warning {{'nodiscard' attribute only applies to functions, methods, enums, and classes}} + +struct [[nodiscard]] S4 { + int i; +}; +struct S4 get_s(void); + +enum [[nodiscard]] E2 { Two }; +enum E2 get_e(void); + +[[nodiscard]] int get_i(); + +void f2(void) { + get_s(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + get_i(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + get_e(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + // Okay, warnings are not encouraged + (void)get_s(); + (void)get_i(); + (void)get_e(); +} + +struct [[nodiscard]] error_info{ + int i; +}; + +struct error_info enable_missile_safety_mode(void); +void launch_missiles(void); +void test_missiles(void) { + enable_missile_safety_mode(); // expected-warning {{ignoring return value of function declared with 'nodiscard'}} + launch_missiles(); +} +