https://github.com/el-ev created 
https://github.com/llvm/llvm-project/pull/200117

Resolves #197206

During template instantiation, check that the return type is a valid pointer 
type before adding a `ReturnsNonNullAttr`.

>From a9908518b9c45f86f6e9c0c4f12911b179714777 Mon Sep 17 00:00:00 2001
From: Iris Shi <[email protected]>
Date: Thu, 28 May 2026 14:23:36 +0800
Subject: [PATCH] [clang] Validate return type when instantiating
 `returns_nonnull` attribute

---
 clang/docs/ReleaseNotes.rst                   |  1 +
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  | 11 ++++++++++
 .../returns-nonnull-nonptr-crash.cpp          | 21 +++++++++++++++++++
 3 files changed, 33 insertions(+)
 create mode 100644 clang/test/CodeGenCXX/returns-nonnull-nonptr-crash.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f3865672120e0..5ede3047a7e59 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -655,6 +655,7 @@ Bug Fixes to Attribute Support
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 - Fixed a behavioral discrepancy between deleted functions and private members 
when checking the ``enable_if`` attribute. (#GH175895)
 - Fixed ``init_priority`` attribute by delaying type checks until after the 
type is deduced.
+- Fixed a crash in optimized builds when ``returns_nonnull`` was applied to a 
non-pointer return type. (#GH197206)
 
 Bug Fixes to C++ Support
 ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index c9bc613a7c4ea..0b20cc44e9f19 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1013,6 +1013,17 @@ void Sema::InstantiateAttrs(const 
MultiLevelTemplateArgumentList &TemplateArgs,
       continue;
     }
 
+    if (auto *A = dyn_cast<ReturnsNonNullAttr>(TmplAttr)) {
+      auto *FD = cast<FunctionDecl>(New);
+      QualType ResultType = getFunctionOrMethodResultType(FD);
+      if (!isValidPointerAttrType(ResultType))
+        Diag(A->getLocation(), diag::warn_attribute_return_pointers_only)
+            << A << SourceRange() << getFunctionOrMethodResultSourceRange(FD);
+      else if (!New->hasAttr<ReturnsNonNullAttr>())
+        New->addAttr(A->clone(Context));
+      continue;
+    }
+
     if (auto *A = dyn_cast<OwnerAttr>(TmplAttr)) {
       if (!New->hasAttr<OwnerAttr>())
         New->addAttr(A->clone(Context));
diff --git a/clang/test/CodeGenCXX/returns-nonnull-nonptr-crash.cpp 
b/clang/test/CodeGenCXX/returns-nonnull-nonptr-crash.cpp
new file mode 100644
index 0000000000000..06659746a6cb9
--- /dev/null
+++ b/clang/test/CodeGenCXX/returns-nonnull-nonptr-crash.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=c++17 -O1 -emit-obj -Wno-ignored-attributes -o 
/dev/null %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
+
+// Regression test for issue #197206
+
+class A {};
+
+template <typename B> class C {
+  // expected-warning@+1 {{'returns_nonnull' attribute only applies to return 
values that are pointers}}
+  friend B D(C) __attribute__((returns_nonnull)) {
+    B E;
+    return E;
+  }
+};
+
+template <typename>
+C<A> F();
+
+C<A> H = F<int>(); // expected-note {{in instantiation of template class 
'C<A>' requested here}}
+
+void G() { D(H); }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to