Add a new -Wundefined-inline warning for inline functions which are used but not
defined. Fixes PR14993!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174158 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 4404c6f..0d549fc 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2215,6 +2215,23 @@
New->setType(QualType(NewType, 0));
NewQType = Context.getCanonicalType(New->getType());
}
+
+ // If this redeclaration makes the function inline, we may need to add it to
+ // UndefinedButUsed.
+ if (!Old->isInlined() && New->isInlined() &&
+ !New->hasAttr<GNUInlineAttr>() &&
+ (getLangOpts().CPlusPlus || !getLangOpts().GNUInline) &&
+ Old->isUsed(false) &&
+ !Old->isDefined() && !New->isThisDeclarationADefinition())
+ UndefinedButUsed.insert(std::make_pair(Old->getCanonicalDecl(),
+ SourceLocation()));
+
+ // If this redeclaration makes it newly gnu_inline, we don't want to warn
+ // about it.
+ if (New->hasAttr<GNUInlineAttr>() &&
+ Old->isInlined() && !Old->hasAttr<GNUInlineAttr>()) {
+ UndefinedButUsed.erase(Old->getCanonicalDecl());
+ }
if (getLangOpts().CPlusPlus) {
// (C++98 13.1p2):
@@ -8431,12 +8448,17 @@
if (FD) {
FD->setBody(Body);
- // The only way to be included in UndefinedInternals is if there is an
- // ODR-use before the definition. Avoid the expensive map lookup if this
+ // The only way to be included in UndefinedButUsed is if there is an
+ // ODR use before the definition. Avoid the expensive map lookup if this
// is the first declaration.
- if (FD->getPreviousDecl() != 0 && FD->getPreviousDecl()->isUsed() &&
- FD->getLinkage() != ExternalLinkage)
- UndefinedInternals.erase(FD);
+ if (FD->getPreviousDecl() != 0 && FD->getPreviousDecl()->isUsed()) {
+ if (FD->getLinkage() != ExternalLinkage)
+ UndefinedButUsed.erase(FD);
+ else if (FD->isInlined() &&
+ (LangOpts.CPlusPlus || !LangOpts.GNUInline) &&
+ (!FD->getPreviousDecl()->hasAttr<GNUInlineAttr>()))
+ UndefinedButUsed.erase(FD);
+ }
// If the function implicitly returns zero (like 'main') or is naked,
// don't complain about missing return statements.