summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-11-16 01:57:09 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-11-16 01:57:09 +0000
commitfa27bc4c7b8f0d8a7f30818344af69d354177743 (patch)
tree22fad6a2216d5ca2f317dbb9d373ae2e1cbc3d32 /clang
parentf07183ce9402cb11de96bdb253806b15b0c6295a (diff)
downloadbcm5719-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.cpp23
-rw-r--r--clang/test/SemaCXX/new-delete.cpp9
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()
OpenPOWER on IntegriCloud