[clang] [clang] Ignore GCC 11 `[[malloc(x)]]` attribute (PR #68059)
Alois Klink via cfe-commits
cfe-commits at lists.llvm.org
Sat Oct 7 11:45:38 PDT 2023
https://github.com/aloisklink updated https://github.com/llvm/llvm-project/pull/68059
>From a76561f522f628b0882572f8dabee6f7e4abd5f5 Mon Sep 17 00:00:00 2001
From: Alois Klink <alois at aloisklink.com>
Date: Mon, 2 Oct 2023 19:59:06 +0100
Subject: [PATCH] [clang] Ignore GCC 11 [[malloc(x)]] attribute
Ignore the `[[malloc(x)]]` or `[[malloc(x, 1)]]` function attribute
syntax added in [GCC 11][1] and print a warning instead of an error.
Unlike `[[malloc]]` with no arguments (which is supported by Clang),
GCC uses the one or two argument form to specify a deallocator for
GCC's static analyzer.
Code currently compiled with `[[malloc(x)]]` or
`__attribute((malloc(x)))` fails with the following error:
`'malloc' attribute takes no arguments`.
[1]: https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;f=gcc/doc/extend.texi;h=dce6c58db87ebf7f4477bd3126228e73e4eeee97#patch6
Fixes: https://github.com/llvm/llvm-project/issues/51607
Partial-Bug: https://github.com/llvm/llvm-project/issues/53152
---
clang/docs/ReleaseNotes.rst | 5 +++++
clang/include/clang/Basic/Attr.td | 2 ++
clang/include/clang/Basic/AttrDocs.td | 3 +++
.../clang/Basic/DiagnosticCommonKinds.td | 4 ++++
clang/lib/Sema/SemaDeclAttr.cpp | 20 ++++++++++++++++---
clang/test/Sema/attr-args.c | 6 ++++--
clang/test/SemaCXX/attr-print.cpp | 8 ++++++++
7 files changed, 43 insertions(+), 5 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6be824771c583be..3cbeed044ada396 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -289,6 +289,11 @@ Bug Fixes to Compiler Builtins
Bug Fixes to Attribute Support
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+- Clang now emits a warning instead of an error when using the one or two
+ argument form of GCC 11's ``__attribute__((malloc(deallocator)))``
+ or ``__attribute__((malloc(deallocator, ptr-index)))``
+ (`#51607 <https://github.com/llvm/llvm-project/issues/51607>`).
+
Bug Fixes to C++ Support
^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 7a6ec77ae84b15a..db1f332efdb7653 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1629,6 +1629,8 @@ def IFunc : Attr, TargetSpecificAttr<TargetELF> {
def Restrict : InheritableAttr {
let Spellings = [Declspec<"restrict">, GCC<"malloc">];
+ let Args = [IdentifierArgument<"Deallocator", /*opt*/ 1>,
+ ParamIdxArgument<"DeallocatorPtrArgIndex", /*opt*/ 1>];
let Subjects = SubjectList<[Function]>;
let Documentation = [RestrictDocs];
}
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 8d928dcc146b254..1e498aeea6b7832 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -4122,6 +4122,9 @@ def RestrictDocs : Documentation {
The ``malloc`` attribute indicates that the function acts like a system memory
allocation function, returning a pointer to allocated storage disjoint from the
storage for any other object accessible to the caller.
+
+The form of ``malloc`` with one or two arguments (supported by GCC 11) is
+currently ignored by Clang.
}];
}
diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index f2df283c74829f6..35472b92e460850 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -177,6 +177,10 @@ def warn_unknown_attribute_ignored : Warning<
"unknown attribute %0 ignored">, InGroup<UnknownAttributes>;
def warn_attribute_ignored : Warning<"%0 attribute ignored">,
InGroup<IgnoredAttributes>;
+def warn_multiarg_malloc_attribute_ignored: Warning<
+ "'malloc' attribute ignored because"
+ " Clang does not support the one/two argument form">,
+ InGroup<IgnoredAttributes>;
def err_keyword_not_supported_on_target : Error<
"%0 is not supported on this target">;
def err_use_of_tag_name_without_tag : Error<
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index ed0b4d29b056397..9fe190b74db58fe 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -2064,13 +2064,27 @@ static void handleTLSModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
static void handleRestrictAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
QualType ResultType = getFunctionOrMethodResultType(D);
- if (ResultType->isAnyPointerType() || ResultType->isBlockPointerType()) {
+ if (!ResultType->isAnyPointerType() && !ResultType->isBlockPointerType()) {
+ S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only)
+ << AL << getFunctionOrMethodResultSourceRange(D);
+ return;
+ }
+
+ if (getNumAttributeArgs(AL) == 0) {
D->addAttr(::new (S.Context) RestrictAttr(S.Context, AL));
return;
}
- S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only)
- << AL << getFunctionOrMethodResultSourceRange(D);
+ if (AL.getAttributeSpellingListIndex() == RestrictAttr::Declspec_restrict) {
+ // __declspec(restrict) accepts no arguments
+ S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 0;
+ return;
+ }
+
+ // FIXME: GCC uses [[malloc(my_func)]] to specify a deallocator for the
+ // returned pointer, but this isn't currently supported in LLVM
+ // see https://github.com/llvm/llvm-project/issues/51607
+ S.Diag(AL.getLoc(), diag::warn_multiarg_malloc_attribute_ignored);
}
static void handleCPUSpecificAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
diff --git a/clang/test/Sema/attr-args.c b/clang/test/Sema/attr-args.c
index e275c90be1f9dca..26b642d0363ea71 100644
--- a/clang/test/Sema/attr-args.c
+++ b/clang/test/Sema/attr-args.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -fsyntax-only %s
+// RUN: %clang_cc1 -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -fsyntax-only -fdeclspec %s
int a;
inline __attribute__((noreturn(a))) void *f1(void); // expected-error {{'noreturn' attribute takes no arguments}}
@@ -6,7 +6,9 @@ inline __attribute__((always_inline(a))) void *f2(void); // expected-error {{'a
inline __attribute__((cdecl(a))) void *f3(void); // expected-error {{'cdecl' attribute takes no arguments}}
inline __attribute__((const(a))) void *f4(void); // expected-error {{'const' attribute takes no arguments}}
inline __attribute__((fastcall(a))) void *f5(void); // expected-error {{'fastcall' attribute takes no arguments}}
-inline __attribute__((malloc(a))) void *f5(void); // expected-error {{'malloc' attribute takes no arguments}}
+inline __declspec(restrict(a)) void *f6_a(void); // expected-error {{'restrict' attribute takes no arguments}}
+inline __attribute__((malloc(a, 1, a))) void *f6_b(void); // expected-error {{'malloc' attribute takes no more than 2 arguments}}
+inline __attribute__((malloc(a, 1))) void *f6_c(void); // expected-warning {{'malloc' attribute ignored because Clang does not support the one/two argument form}}
inline __attribute__((nothrow(a))) void *f7(void); // expected-error {{'nothrow' attribute takes no arguments}}
inline __attribute__((stdcall(a))) void *f8(void); // expected-error {{'stdcall' attribute takes no arguments}}
inline __attribute__((used(a))) void *f9(void); // expected-error {{'used' attribute takes no arguments}}
diff --git a/clang/test/SemaCXX/attr-print.cpp b/clang/test/SemaCXX/attr-print.cpp
index dff290be696be24..17e4d3d823cfd8e 100644
--- a/clang/test/SemaCXX/attr-print.cpp
+++ b/clang/test/SemaCXX/attr-print.cpp
@@ -28,6 +28,14 @@ int v __attribute__((visibility("hidden")));
// CHECK: char *PR24565() __attribute__((malloc))
char *PR24565() __attribute__((__malloc__));
+void my_cleanup_func(char *);
+
+// using __attribute__(malloc()) with args is currently ignored by Clang
+// CHECK: char *PR52265_a()
+__attribute__((malloc(my_cleanup_func))) char *PR52265_a();
+// CHECK: char *PR52265_b()
+__attribute__((malloc(my_cleanup_func, 1))) char *PR52265_b();
+
// CHECK: class __attribute__((consumable("unknown"))) AttrTester1
class __attribute__((consumable(unknown))) AttrTester1 {
// CHECK: void callableWhen() __attribute__((callable_when("unconsumed", "consumed")));
More information about the cfe-commits
mailing list