diff options
author | John McCall <rjmccall@apple.com> | 2011-02-19 02:53:41 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-02-19 02:53:41 +0000 |
commit | 15e310a3b970b64a84cb30f0005bc396b4d978cb (patch) | |
tree | a07be31cb50547b6d1a6f71a6397f500a58e300d /lib/Sema/SemaExpr.cpp | |
parent | 370e6e984cc32167228b66eaf9610c010da0d794 (diff) |
Warn about code that uses variables and functions with internal linkage
without defining them. This should be an error, but I'm paranoid about
"uses" that end up not actually requiring a definition. I'll revisit later.
Also, teach IR generation to not set internal linkage on variable
declarations, just for safety's sake. Doing so produces an invalid module
if the variable is not ultimately defined.
Also, fix several places in the test suite where we were using internal
functions without definitions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126016 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 792eb8af98..df49ad5c9a 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -9284,6 +9284,9 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) { MarkVTableUsed(Loc, MethodDecl->getParent()); } if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { + // Recursive functions should be marked when used from another function. + if (CurContext == Function) return; + // Implicit instantiation of function templates and member functions of // class templates. if (Function->isImplicitlyInstantiable()) { @@ -9312,19 +9315,23 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) { else PendingInstantiations.push_back(std::make_pair(Function, Loc)); } - } else // Walk redefinitions, as some of them may be instantiable. + } else { + // Walk redefinitions, as some of them may be instantiable. for (FunctionDecl::redecl_iterator i(Function->redecls_begin()), e(Function->redecls_end()); i != e; ++i) { if (!i->isUsed(false) && i->isImplicitlyInstantiable()) MarkDeclarationReferenced(Loc, *i); } + } - // FIXME: keep track of references to static functions - - // Recursive functions should be marked when used from another function. - if (CurContext != Function) - Function->setUsed(true); + // Keep track of used but undefined functions. + if (!Function->isPure() && !Function->hasBody() && + Function->getLinkage() != ExternalLinkage) { + SourceLocation &old = UndefinedInternals[Function->getCanonicalDecl()]; + if (old.isInvalid()) old = Loc; + } + Function->setUsed(true); return; } @@ -9341,7 +9348,12 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) { } } - // FIXME: keep track of references to static data? + // Keep track of used but undefined variables. + if (Var->hasDefinition() == VarDecl::DeclarationOnly + && Var->getLinkage() != ExternalLinkage) { + SourceLocation &old = UndefinedInternals[Var->getCanonicalDecl()]; + if (old.isInvalid()) old = Loc; + } D->setUsed(true); return; |