dblaikie created this revision. dblaikie added a reviewer: aaron.ballman. dblaikie requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
While it's not as robust as using the attribute on enums/classes (the type information may be lost through a function pointer, a declaration or use of the underlying type without using the typedef, etc) but I think there's still value in being able to attribute a typedef and have all return types written with that typedef pick up the warn_unused_result behavior. Specifically I'd like to be able to annotate LLVMErrorRef (a wrapper for llvm::Error used in the C API - the underlying type is a raw pointer, so it can't be attributed itself) to reduce the chance of unhandled errors. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D102122 Files: clang/include/clang/Basic/Attr.td clang/lib/AST/Expr.cpp 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,15 @@ 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 *p; +p f1(); +void f2() { + f1(); // expected-warning {{ignoring return value}} + void *(*p1)(); + p1(); // no warning + p (*p2)(); + p2(); // expected-warning {{ignoring return value}} +} +} Index: clang/lib/AST/Expr.cpp =================================================================== --- clang/lib/AST/Expr.cpp +++ clang/lib/AST/Expr.cpp @@ -1413,6 +1413,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/Attr.td =================================================================== --- clang/include/clang/Basic/Attr.td +++ clang/include/clang/Basic/Attr.td @@ -2812,7 +2812,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 = [{
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,15 @@ 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 *p; +p f1(); +void f2() { + f1(); // expected-warning {{ignoring return value}} + void *(*p1)(); + p1(); // no warning + p (*p2)(); + p2(); // expected-warning {{ignoring return value}} +} +} Index: clang/lib/AST/Expr.cpp =================================================================== --- clang/lib/AST/Expr.cpp +++ clang/lib/AST/Expr.cpp @@ -1413,6 +1413,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/Attr.td =================================================================== --- clang/include/clang/Basic/Attr.td +++ clang/include/clang/Basic/Attr.td @@ -2812,7 +2812,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 cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits