diff options
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index aef66619f6b..a58752cb42a 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -70,12 +70,13 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) { } // See if this is a deleted function. - if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { if (FD->isDeleted()) { Diag(Loc, diag::err_deleted_function_use); Diag(D->getLocation(), diag::note_unavailable_here) << true; return true; } + } // See if the decl is unavailable if (D->getAttr<UnavailableAttr>()) { @@ -83,6 +84,28 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) { Diag(D->getLocation(), diag::note_unavailable_here) << 0; } + if (D->getDeclContext()->isFunctionOrMethod() && + !D->getDeclContext()->Encloses(CurContext)) { + // We've found the name of a function or variable that was + // declared with external linkage within another function (and, + // therefore, a scope where we wouldn't normally see the + // declaration). Once we've made sure that no previous declaration + // was properly made visible, produce a warning. + bool HasGlobalScopedDeclaration = false; + for (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); FD; + FD = FD->getPreviousDeclaration()) { + if (FD->getDeclContext()->isFileContext()) { + HasGlobalScopedDeclaration = true; + break; + } + } + // FIXME: do the same thing for variable declarations + + if (!HasGlobalScopedDeclaration) { + Diag(Loc, diag::warn_use_out_of_scope_declaration) << D; + Diag(D->getLocation(), diag::note_previous_declaration); + } + } return false; } |