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'.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@194916 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 0527e49..3cdb727 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -6872,15 +6872,6 @@
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 @@
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) {