[clang] [clang] Validate return type when instantiating `returns_nonnull` atttribute (PR #200117)
via cfe-commits
cfe-commits at lists.llvm.org
Wed May 27 23:28:52 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Iris Shi (el-ev)
<details>
<summary>Changes</summary>
Resolves #<!-- -->197206
During template instantiation, check that the return type is a valid pointer type before adding a `ReturnsNonNullAttr`.
---
Full diff: https://github.com/llvm/llvm-project/pull/200117.diff
3 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+1)
- (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+11)
- (added) clang/test/CodeGenCXX/returns-nonnull-nonptr-crash.cpp (+21)
``````````diff
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 at +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); }
``````````
</details>
https://github.com/llvm/llvm-project/pull/200117
More information about the cfe-commits
mailing list