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
