dblaikie updated this revision to Diff 432804.
dblaikie added a comment.
Use a single attribute, with a filter in the sema parsing code
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D102122/new/
https://reviews.llvm.org/D102122
Files:
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttributeCommonInfo.h
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/AST/Expr.cpp
clang/lib/Basic/Attributes.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p1.cpp
clang/test/Misc/pragma-attribute-supported-attributes-list.test
clang/test/Sema/c2x-nodiscard.c
clang/test/Sema/unused-expr.c
clang/test/SemaCXX/warn-unused-result.cpp
Index: clang/test/SemaCXX/warn-unused-result.cpp
===================================================================
--- clang/test/SemaCXX/warn-unused-result.cpp
+++ clang/test/SemaCXX/warn-unused-result.cpp
@@ -254,3 +254,29 @@
void i([[nodiscard]] bool (*fp)()); // expected-warning {{'nodiscard' attribute only applies to functions, classes, or enumerations}}
}
+
+namespace unused_typedef_result {
+[[clang::warn_unused_result]] typedef void *a;
+a af1();
+void af2() {
+ af1(); // expected-warning {{ignoring return value}}
+ void *(*a1)();
+ a1(); // no warning
+ a (*a2)();
+ a2(); // expected-warning {{ignoring return value}}
+}
+[[nodiscard]] typedef void *b; // expected-warning {{warn_unused_result on typedefs only supported with gnu or clang scoped standard spelling}}
+b bf1();
+void bf2() {
+ bf1(); // no warning
+}
+__attribute__((warn_unused_result)) typedef void *c;
+c cf1();
+void cf2() {
+ cf1(); // expected-warning {{ignoring return value}}
+ void *(*c1)();
+ c1();
+ c (*c2)();
+ c2(); // expected-warning {{ignoring return value}}
+}
+}
Index: clang/test/Sema/unused-expr.c
===================================================================
--- clang/test/Sema/unused-expr.c
+++ clang/test/Sema/unused-expr.c
@@ -96,7 +96,7 @@
return 0;
}
-int t7 __attribute__ ((warn_unused_result)); // expected-warning {{'warn_unused_result' attribute only applies to Objective-C methods, enums, structs, unions, classes, functions, and function pointers}}
+int t7 __attribute__ ((warn_unused_result)); // expected-warning {{'warn_unused_result' attribute only applies to Objective-C methods, enums, structs, unions, classes, functions, function pointers, and typedefs}}
// PR4010
int (*fn4)(void) __attribute__ ((warn_unused_result));
Index: clang/test/Sema/c2x-nodiscard.c
===================================================================
--- clang/test/Sema/c2x-nodiscard.c
+++ clang/test/Sema/c2x-nodiscard.c
@@ -15,7 +15,7 @@
[[nodiscard]] int f1(void);
enum [[nodiscard]] E1 { One };
-[[nodiscard]] int i; // expected-warning {{'nodiscard' attribute only applies to Objective-C methods, enums, structs, unions, classes, functions, and function pointers}}
+[[nodiscard]] int i; // expected-warning {{'nodiscard' attribute only applies to Objective-C methods, enums, structs, unions, classes, functions, function pointers, and typedefs}}
struct [[nodiscard]] S4 {
int i;
Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test
===================================================================
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -185,7 +185,7 @@
// CHECK-NEXT: VecReturn (SubjectMatchRule_record)
// CHECK-NEXT: VecTypeHint (SubjectMatchRule_function)
// CHECK-NEXT: WarnUnused (SubjectMatchRule_record)
-// CHECK-NEXT: WarnUnusedResult (SubjectMatchRule_objc_method, SubjectMatchRule_enum, SubjectMatchRule_record, SubjectMatchRule_hasType_functionType)
+// CHECK-NEXT: WarnUnusedResult (SubjectMatchRule_objc_method, SubjectMatchRule_enum, SubjectMatchRule_record, SubjectMatchRule_hasType_functionType, SubjectMatchRule_type_alias)
// CHECK-NEXT: Weak (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record)
// CHECK-NEXT: WeakRef (SubjectMatchRule_variable, SubjectMatchRule_function)
// CHECK-NEXT: WebAssemblyExportName (SubjectMatchRule_function)
Index: clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p1.cpp
===================================================================
--- clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p1.cpp
+++ clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p1.cpp
@@ -7,4 +7,4 @@
[[nodiscard]] int f();
enum [[nodiscard]] E {};
-namespace [[nodiscard]] N {} // expected-warning {{'nodiscard' attribute only applies to Objective-C methods, enums, structs, unions, classes, functions, and function pointers}}
+namespace [[nodiscard]] N {} // expected-warning {{'nodiscard' attribute only applies to Objective-C methods, enums, structs, unions, classes, functions, function pointers, and typedefs}}
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -3156,6 +3156,11 @@
S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
}
+ if ((!AL.isGNUAttribute() && !(AL.isStandardAttributeSyntax() && AL.isClangScope())) && isa<TypedefNameDecl>(D)) {
+ S.Diag(AL.getLoc(), diag::warn_unused_result_typedef_unsupported_spelling);
+ return;
+ }
+
D->addAttr(::new (S.Context) WarnUnusedResultAttr(S.Context, AL, Str));
}
Index: clang/lib/Basic/Attributes.cpp
===================================================================
--- clang/lib/Basic/Attributes.cpp
+++ clang/lib/Basic/Attributes.cpp
@@ -85,6 +85,10 @@
return ScopeName && (ScopeName->isStr("gnu") || ScopeName->isStr("__gnu__"));
}
+bool AttributeCommonInfo::isClangScope() const {
+ return ScopeName && (ScopeName->isStr("clang") || ScopeName->isStr("_Clang"));
+}
+
#include "clang/Sema/AttrParsedAttrKinds.inc"
static SmallString<64> normalizeName(const IdentifierInfo *Name,
Index: clang/lib/AST/Expr.cpp
===================================================================
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -1522,6 +1522,10 @@
if (const auto *A = TD->getAttr<WarnUnusedResultAttr>())
return A;
+ if (const auto *TD = getCallReturnType(Ctx)->getAs<TypedefType>())
+ if (const auto *A = TD->getDecl()->getAttr<WarnUnusedResultAttr>())
+ return A;
+
// Otherwise, see if the callee is marked nodiscard and return that attribute
// instead.
const Decl *D = getCalleeDecl();
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8729,6 +8729,9 @@
def warn_unused_result_msg : Warning<
"ignoring return value of function declared with %0 attribute: %1">,
InGroup<UnusedResult>;
+def warn_unused_result_typedef_unsupported_spelling : Warning<
+ "warn_unused_result on typedefs only supported with gnu or clang scoped "
+ "standard spelling">, InGroup<UnusedResult>;
def warn_unused_volatile : Warning<
"expression result unused; assign into a variable to force a volatile load">,
InGroup<DiagGroup<"unused-volatile-lvalue">>;
Index: clang/include/clang/Basic/AttributeCommonInfo.h
===================================================================
--- clang/include/clang/Basic/AttributeCommonInfo.h
+++ clang/include/clang/Basic/AttributeCommonInfo.h
@@ -146,6 +146,7 @@
bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
bool isGNUScope() const;
+ bool isClangScope() const;
bool isAlignasAttribute() const {
// FIXME: Use a better mechanism to determine this.
@@ -164,6 +165,8 @@
return isCXX11Attribute() || isC2xAttribute();
}
+ bool isGNUAttribute() const { return SyntaxUsed == AS_GNU; }
+
bool isKeywordAttribute() const {
return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
}
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -2944,7 +2944,7 @@
C2x<"", "nodiscard", 201904>,
CXX11<"clang", "warn_unused_result">,
GCC<"warn_unused_result">];
- let Subjects = SubjectList<[ObjCMethod, Enum, Record, FunctionLike]>;
+ let Subjects = SubjectList<[ObjCMethod, Enum, Record, FunctionLike, TypedefName]>;
let Args = [StringArgument<"Message", 1>];
let Documentation = [WarnUnusedResultsDocs];
let AdditionalMembers = [{
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits