From d2b0cf38be1e6bd9b35353ae3da49eda5dc4e1e5 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Sun, 20 Oct 2013 05:40:29 +0000 Subject: [PATCH] Sema: Diagnose global replacement functions declared as inline This fixes PR17591. N.B. This actually goes beyond what the standard mandates by requiring the restriction to hold for declarations instead of definitions. This is believed to be a defect in the standard and an LWG issue has been submitted. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@193044 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ lib/Sema/SemaDecl.cpp | 7 +++++++ test/SemaCXX/new-delete.cpp | 2 ++ 3 files changed, 11 insertions(+) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index d8fef68d48..55c4e9d57b 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -5900,6 +5900,8 @@ def err_operator_new_delete_declared_in_namespace : Error< "%0 cannot be declared inside a namespace">; def err_operator_new_delete_declared_static : Error< "%0 cannot be declared static in global scope">; +def err_operator_new_delete_declared_inline : Error< + "%0 cannot be declared 'inline'">; def err_operator_new_delete_invalid_result_type : Error< "%0 must return type %1">; def err_operator_new_delete_dependent_result_type : Error< diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index d7c4f7834f..176fe8a1cf 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -6804,6 +6804,13 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewFD->setType(Context.getFunctionType(FPT->getResultType(), FPT->getArgTypes(), EPI)); } + + // C++11 [replacement.functions]p3: + // The program's definitions shall not be specified as inline. + if (isInline && NewFD->isReplaceableGlobalAllocationFunction()) + Diag(D.getDeclSpec().getInlineSpecLoc(), + diag::err_operator_new_delete_declared_inline) + << NewFD->getDeclName(); } // Filter out previous declarations that don't match the scope. diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp index 898c6e0879..de26cad62e 100644 --- a/test/SemaCXX/new-delete.cpp +++ b/test/SemaCXX/new-delete.cpp @@ -24,6 +24,8 @@ void* operator new(size_t, int*); // expected-note 3 {{candidate}} void* operator new(size_t, float*); // expected-note 3 {{candidate}} void* operator new(size_t, S); // expected-note 2 {{candidate}} +inline void operator delete(void *); // expected-error {{'operator delete' cannot be declared 'inline'}} + struct foo { }; void good_news() -- 2.40.0