https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/209836
>From c4778ace872f13c2dd1068dd0295c286833f2104 Mon Sep 17 00:00:00 2001 From: AZero13 <[email protected]> Date: Wed, 15 Jul 2026 13:15:11 -0400 Subject: [PATCH] [clang][Sema] Allow abstract declarators to specify cv-qualified function types Exempted DeclaratorContext::TypeName from the check. Abstract declarator contexts (used by typeof, sizeof, C-style casts) now properly bypass this restricted rule, matching how TemplateArg was already correctly exempted. --- clang/lib/Sema/SemaType.cpp | 3 +- clang/test/CXX/drs/cwg14xx.cpp | 11 +++++ .../SemaCXX/qualified-function-typeof.cpp | 46 +++++++++++++++++++ clang/www/cxx_dr_status.html | 2 +- 4 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 clang/test/SemaCXX/qualified-function-typeof.cpp diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 5161db6ac1a99..b49a0a80e41d4 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -5601,7 +5601,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, (D.getContext() == clang::DeclaratorContext::Member && D.isStaticMember())) && !IsTypedefName && D.getContext() != DeclaratorContext::TemplateArg && - D.getContext() != DeclaratorContext::TemplateTypeArg) { + D.getContext() != DeclaratorContext::TemplateTypeArg && + D.getContext() != DeclaratorContext::TypeName) { SourceLocation Loc = D.getBeginLoc(); SourceRange RemovalRange; unsigned I; diff --git a/clang/test/CXX/drs/cwg14xx.cpp b/clang/test/CXX/drs/cwg14xx.cpp index afa4bc9d8179a..d6ef90429d267 100644 --- a/clang/test/CXX/drs/cwg14xx.cpp +++ b/clang/test/CXX/drs/cwg14xx.cpp @@ -50,6 +50,17 @@ namespace cwg1413 { // cwg1413: 12 }; } // namespace cwg1413 +namespace cwg1417 { // cwg1417: 24 + template<typename T> struct S { + typedef T F; + typedef T *P; + // expected-error@-1 {{pointer to function type 'void () const' cannot have 'const' qualifier}} + // expected-note@#cwg1417-s {{in instantiation of template class 'cwg1417::S<void () const>' requested here}} + typedef T &R; + // expected-error@-1 {{reference to function type 'void () const' cannot have 'const' qualifier}} + }; + S<void() const> s; // #cwg1417-s +} namespace cwg1423 { // cwg1423: 11 #if __cplusplus >= 201103L bool b1 = nullptr; diff --git a/clang/test/SemaCXX/qualified-function-typeof.cpp b/clang/test/SemaCXX/qualified-function-typeof.cpp new file mode 100644 index 0000000000000..d9aea33e40ea4 --- /dev/null +++ b/clang/test/SemaCXX/qualified-function-typeof.cpp @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++23 %s + +using F = void() const; + +struct S { + using F = void() const; +}; + +void testTypeOf() { + using T1 = __typeof__(F); + using T2 = __typeof__(S::F); + using T3 = __typeof_unqual__(F); + using T4 = __typeof_unqual__(S::F); +} + +template <typename T> +struct TypeIdentity { + using type = T; +}; + +void testTemplateArg() { + using U1 = TypeIdentity<F>::type; + using U2 = TypeIdentity<S::F>::type; +} + +namespace std { class type_info; } + +namespace test_other_contexts { + void test() { + auto &a = typeid(F); // expected-error {{type operand 'F' (aka 'void () const') of 'typeid' cannot have 'const' qualifier}} + auto &b = typeid(void() const); // expected-error {{type operand 'void () const' of 'typeid' cannot have 'const' qualifier}} + + unsigned s1 = sizeof(F); // expected-error {{invalid application of 'sizeof' to a function type}} + unsigned s2 = sizeof(void() const); // expected-error {{invalid application of 'sizeof' to a function type}} + unsigned a1 = alignof(F); // expected-error {{invalid application of 'alignof' to a function type}} + unsigned a2 = alignof(void() const); // expected-error {{invalid application of 'alignof' to a function type}} + + auto c1 = (F)nullptr; // expected-error {{C-style cast from 'std::nullptr_t' to 'F' (aka 'void () const') is not allowed}} + auto c2 = (void() const)nullptr; // expected-error {{C-style cast from 'std::nullptr_t' to 'void () const' is not allowed}} + + auto n1 = new F; // expected-error {{non-member function of type 'F' (aka 'void () const') cannot have 'const' qualifier}} \ + // expected-error {{cannot allocate function type 'void ()' with new}} + auto n2 = new (void() const); // expected-error {{non-member function cannot have 'const' qualifier}} \ + // expected-error {{cannot allocate function type 'void ()' with new}} + } +} diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html index af91ac559d274..7367f6443a3ae 100755 --- a/clang/www/cxx_dr_status.html +++ b/clang/www/cxx_dr_status.html @@ -9696,7 +9696,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td>[<a href="https://wg21.link/dcl.fct">dcl.fct</a>]</td> <td>C++14</td> <td>Pointers/references to functions with cv-qualifiers or <I>ref-qualifier</I></td> - <td class="unknown" align="center">Unknown</td> + <td class="unreleased" align="center">Clang 24</td> </tr> <tr id="1418"> <td><a href="https://cplusplus.github.io/CWG/issues/1418.html">1418</a></td> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
