diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-11-16 01:57:09 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-11-16 01:57:09 +0000 |
commit | fa27bc4c7b8f0d8a7f30818344af69d354177743 (patch) | |
tree | 22fad6a2216d5ca2f317dbb9d373ae2e1cbc3d32 /clang | |
parent | f07183ce9402cb11de96bdb253806b15b0c6295a (diff) | |
download | bcm5719-llvm-fa27bc4c7b8f0d8a7f30818344af69d354177743.tar.gz bcm5719-llvm-fa27bc4c7b8f0d8a7f30818344af69d354177743.zip |
If a replaceable global operator new/delete is marked inline, don't warn if
it's also __attribute__((used)), since that undoes the problematic part of
'inline'.
llvm-svn: 194916
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 23 | ||||
-rw-r--r-- | clang/test/SemaCXX/new-delete.cpp | 9 |
2 files changed, 21 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 0527e495791..3cdb72714f4 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6872,15 +6872,6 @@ 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. - // - // N.B. We diagnose declarations instead of definitions per LWG issue 2340. - if (isInline && NewFD->isReplaceableGlobalAllocationFunction()) - Diag(D.getDeclSpec().getInlineSpecLoc(), - diag::ext_operator_new_delete_declared_inline) - << NewFD->getDeclName(); } // Filter out previous declarations that don't match the scope. @@ -7015,6 +7006,20 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, Previous.getResultKind() != LookupResult::FoundOverloaded) && "previous declaration set still overloaded"); } else { + // C++11 [replacement.functions]p3: + // The program's definitions shall not be specified as inline. + // + // N.B. We diagnose declarations instead of definitions per LWG issue 2340. + // + // Suppress the diagnostic if the function is __attribute__((used)), since + // that forces an external definition to be emitted. + if (D.getDeclSpec().isInlineSpecified() && + NewFD->isReplaceableGlobalAllocationFunction() && + !NewFD->hasAttr<UsedAttr>()) + Diag(D.getDeclSpec().getInlineSpecLoc(), + diag::ext_operator_new_delete_declared_inline) + << NewFD->getDeclName(); + // If the declarator is a template-id, translate the parser's template // argument list into our AST format. if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) { diff --git a/clang/test/SemaCXX/new-delete.cpp b/clang/test/SemaCXX/new-delete.cpp index 2f408525ea3..7facd10ca5f 100644 --- a/clang/test/SemaCXX/new-delete.cpp +++ b/clang/test/SemaCXX/new-delete.cpp @@ -18,14 +18,19 @@ struct V : U { }; +inline void operator delete(void *); // expected-warning {{replacement function 'operator delete' cannot be declared 'inline'}} + +__attribute__((used)) +inline void *operator new(size_t) { // no warning, due to __attribute__((used)) + return 0; +} + // PR5823 void* operator new(const size_t); // expected-note 2 {{candidate}} 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-warning {{replacement function 'operator delete' cannot be declared 'inline'}} - struct foo { }; void good_news() |