[clang] [clang] assume_aligned incorrectly diagnoses a dependent return type (PR #111573)

Amr Hesham via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 9 13:41:48 PDT 2024


https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/111573

>From 0f1405efdbb6a9bc24c878346d96ae6720771a44 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <amr96 at programmer.net>
Date: Tue, 8 Oct 2024 20:12:45 +0200
Subject: [PATCH] [clang] assume_aligned incorrectly diagnoses a dependent
 return type

---
 clang/include/clang/Sema/Sema.h                    | 7 ++++---
 clang/lib/Sema/SemaDeclAttr.cpp                    | 7 ++++---
 clang/test/SemaCXX/alloc-align-attr.cpp            | 3 +++
 clang/test/SemaCXX/builtin-assume-aligned-tmpl.cpp | 6 ++++++
 clang/test/SemaCXX/noescape-attr.cpp               | 7 +++++++
 clang/test/SemaObjCXX/noescape.mm                  | 7 +++----
 6 files changed, 27 insertions(+), 10 deletions(-)
 create mode 100644 clang/test/SemaCXX/noescape-attr.cpp

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 7ff9c2754a6fe0..6931f50202162c 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4453,9 +4453,10 @@ class Sema final : public SemaBase {
                                       SourceLocation *ArgLocation = nullptr);
 
   /// Determine if type T is a valid subject for a nonnull and similar
-  /// attributes. By default, we look through references (the behavior used by
-  /// nonnull), but if the second parameter is true, then we treat a reference
-  /// type as valid.
+  /// attributes. Dependent types are considered valid so they can be checked
+  /// during instantiation time. By default, we look through references (the
+  /// behavior used by nonnull), but if the second parameter is true, then we
+  /// treat a reference type as valid.
   bool isValidPointerAttrType(QualType T, bool RefOkay = false);
 
   /// AddAssumeAlignedAttr - Adds an assume_aligned attribute to a particular
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index af983349a89b58..e2174ba926f17f 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1216,6 +1216,8 @@ static void handlePreferredName(Sema &S, Decl *D, const ParsedAttr &AL) {
 }
 
 bool Sema::isValidPointerAttrType(QualType T, bool RefOkay) {
+  if (T->isDependentType())
+    return true;
   if (RefOkay) {
     if (T->isReferenceType())
       return true;
@@ -1284,7 +1286,7 @@ static void handleNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
     for (unsigned I = 0, E = getFunctionOrMethodNumParams(D);
          I != E && !AnyPointers; ++I) {
       QualType T = getFunctionOrMethodParamType(D, I);
-      if (T->isDependentType() || S.isValidPointerAttrType(T))
+      if (S.isValidPointerAttrType(T))
         AnyPointers = true;
     }
 
@@ -1409,8 +1411,7 @@ void Sema::AddAllocAlignAttr(Decl *D, const AttributeCommonInfo &CI,
   AllocAlignAttr TmpAttr(Context, CI, ParamIdx());
   SourceLocation AttrLoc = CI.getLoc();
 
-  if (!ResultType->isDependentType() &&
-      !isValidPointerAttrType(ResultType, /* RefOkay */ true)) {
+  if (!isValidPointerAttrType(ResultType, /* RefOkay */ true)) {
     Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)
         << &TmpAttr << CI.getRange() << getFunctionOrMethodResultSourceRange(D);
     return;
diff --git a/clang/test/SemaCXX/alloc-align-attr.cpp b/clang/test/SemaCXX/alloc-align-attr.cpp
index 79095f8d985147..5a40e8d8fb6b56 100644
--- a/clang/test/SemaCXX/alloc-align-attr.cpp
+++ b/clang/test/SemaCXX/alloc-align-attr.cpp
@@ -23,6 +23,9 @@ void* dependent_param_func(T param) __attribute__((alloc_align(1)));// expected-
 template <int T>
 void* illegal_align_param(int p) __attribute__((alloc_align(T))); // expected-error {{'alloc_align' attribute requires parameter 1 to be an integer constant}}
 
+template <typename T>
+T dependent_return_type(int p) __attribute__((alloc_align(1)));
+
 void dependent_impl(int align) {
   dependent_ret<int> a; // expected-note {{in instantiation of template class 'dependent_ret<int>' requested here}}
   a.Foo(1);
diff --git a/clang/test/SemaCXX/builtin-assume-aligned-tmpl.cpp b/clang/test/SemaCXX/builtin-assume-aligned-tmpl.cpp
index 61b85557d6b294..e709c936735c74 100644
--- a/clang/test/SemaCXX/builtin-assume-aligned-tmpl.cpp
+++ b/clang/test/SemaCXX/builtin-assume-aligned-tmpl.cpp
@@ -52,6 +52,12 @@ T *atest3() __attribute__((assume_aligned(31, o))); // expected-error {{requeste
 template <typename T, int o>
 T *atest4() __attribute__((assume_aligned(32, o)));
 
+template<typename T>
+T atest5(int) __attribute__((assume_aligned(2)));
+
+// expected-warning at +1 {{'assume_aligned' attribute only applies to return values that are pointers or references}}
+int atest6(int) __attribute__((assume_aligned(2)));
+
 void test22() {
   atest3<int, 5>();
   atest4<int, 5>();
diff --git a/clang/test/SemaCXX/noescape-attr.cpp b/clang/test/SemaCXX/noescape-attr.cpp
new file mode 100644
index 00000000000000..78dc4f07ffef87
--- /dev/null
+++ b/clang/test/SemaCXX/noescape-attr.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+void test1(T __attribute__((noescape)) arr, int size);
+
+// expected-warning at +1 {{'noescape' attribute only applies to pointer arguments}}
+void test2(int __attribute__((noescape)) arr, int size);
\ No newline at end of file
diff --git a/clang/test/SemaObjCXX/noescape.mm b/clang/test/SemaObjCXX/noescape.mm
index 4b52164dffd3da..999a91b87300b7 100644
--- a/clang/test/SemaObjCXX/noescape.mm
+++ b/clang/test/SemaObjCXX/noescape.mm
@@ -17,7 +17,7 @@
 void noescapeFunc2(int *); // expected-error {{conflicting types for 'noescapeFunc2'}}
 
 template <class T>
-void noescapeFunc5(__attribute__((noescape)) T); // expected-warning {{'noescape' attribute only applies to pointer arguments}}
+void noescapeFunc5(__attribute__((noescape)) T);
 template <class T>
 void noescapeFunc6(__attribute__((noescape)) const T &);
 template <class T>
@@ -144,7 +144,7 @@ -(void) m1:(int*) p {
 
 struct S6 {
   S6();
-  S6(const S6 &) = delete; // expected-note 12 {{'S6' has been explicitly marked deleted here}}
+  S6(const S6 &) = delete; // expected-note 11 {{'S6' has been explicitly marked deleted here}}
   int f;
 };
 
@@ -161,7 +161,7 @@ void test1(C0 *c0) {
   __block S6 b6; // expected-error {{call to deleted constructor of 'S6'}}
   __block S6 b7; // expected-error {{call to deleted constructor of 'S6'}}
   __block S6 b8; // expected-error {{call to deleted constructor of 'S6'}}
-  __block S6 b9; // expected-error {{call to deleted constructor of 'S6'}}
+  __block S6 b9;
   __block S6 b10; // expected-error {{call to deleted constructor of 'S6'}}
   __block S6 b11; // expected-error {{call to deleted constructor of 'S6'}}
   __block S6 b12;
@@ -199,7 +199,6 @@ void test1(C0 *c0) {
     (void)b8;
   });
 
-  // FIXME: clang shouldn't reject this.
   noescapeFunc5(^{
     (void)b9;
   });



More information about the cfe-commits mailing list