From 323660ae742aecb524898f956590d599e8869f7f Mon Sep 17 00:00:00 2001 From: Shafik Yaghmour Date: Fri, 2 Feb 2024 20:26:54 -0800 Subject: [PATCH] [Clang][Sema] Fix crash with const qualified member operator new (#80327) We should diagnose a const qualified member operator new but we fail to do so and this leads to crash during debug info generation. The fix is to diagnose this as ill-formed in the front-end. Fixes: https://github.com/llvm/llvm-project/issues/79748 --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/Sema/SemaType.cpp | 13 +++++++++++-- clang/test/SemaCXX/function-type-qual.cpp | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index cd8a82f281f52..7ed1dff17f397 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -192,6 +192,8 @@ Bug Fixes to C++ Support and (`#79745 `_) - Fix incorrect code generation caused by the object argument of ``static operator()`` and ``static operator[]`` calls not being evaluated. Fixes (`#67976 `_) +- Fix crash and diagnostic with const qualified member operator new. + Fixes (`#79748 `_) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 7cee73d5d6bae..aee2c9c4a7ded 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -5907,6 +5907,11 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, // - the type-id in the default argument of a type-parameter, or // - the type-id of a template-argument for a type-parameter // + // C++23 [dcl.fct]p6 (P0847R7) + // ... A member-declarator with an explicit-object-parameter-declaration + // shall not include a ref-qualifier or a cv-qualifier-seq and shall not be + // declared static or virtual ... + // // FIXME: Checking this here is insufficient. We accept-invalid on: // // template struct S { void f(T); }; @@ -5914,8 +5919,12 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, // // ... for instance. if (IsQualifiedFunction && - !(Kind == Member && !D.isExplicitObjectMemberFunction() && - D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static) && + // Check for non-static member function and not and + // explicit-object-parameter-declaration + (Kind != Member || D.isExplicitObjectMemberFunction() || + D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static || + (D.getContext() == clang::DeclaratorContext::Member && + D.isStaticMember())) && !IsTypedefName && D.getContext() != DeclaratorContext::TemplateArg && D.getContext() != DeclaratorContext::TemplateTypeArg) { SourceLocation Loc = D.getBeginLoc(); diff --git a/clang/test/SemaCXX/function-type-qual.cpp b/clang/test/SemaCXX/function-type-qual.cpp index bb25c17e83bdf..f4906f58abbae 100644 --- a/clang/test/SemaCXX/function-type-qual.cpp +++ b/clang/test/SemaCXX/function-type-qual.cpp @@ -37,3 +37,21 @@ void instantiateArrayDecay() { int a[1]; arrayDecay(a); } + +namespace GH79748 { +typedef decltype(sizeof(0)) size_t; +struct A { + void* operator new(size_t bytes) const; //expected-error {{static member function cannot have 'const' qualifier}} + void* operator new[](size_t bytes) const; //expected-error {{static member function cannot have 'const' qualifier}} + + void operator delete(void*) const; //expected-error {{static member function cannot have 'const' qualifier}} + void operator delete[](void*) const; //expected-error {{static member function cannot have 'const' qualifier}} +}; +struct B { + void* operator new(size_t bytes) volatile; //expected-error {{static member function cannot have 'volatile' qualifier}} + void* operator new[](size_t bytes) volatile; //expected-error {{static member function cannot have 'volatile' qualifier}} + + void operator delete(void*) volatile; //expected-error {{static member function cannot have 'volatile' qualifier}} + void operator delete[](void*) volatile; //expected-error {{static member function cannot have 'volatile' qualifier}} +}; +}