summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2013-04-14 08:50:55 +0000
committerJohn McCall <rjmccall@apple.com>2013-04-14 08:50:55 +0000
commitad327cd214e835b9b7c88bf696e2e20e012cf2b6 (patch)
treefd458fa78f05c0896d0c6b50c2597fb81aa04df2 /clang/lib
parent512dc38f817ccc3aaea3d642584b3ca2c4d734d3 (diff)
downloadbcm5719-llvm-ad327cd214e835b9b7c88bf696e2e20e012cf2b6.tar.gz
bcm5719-llvm-ad327cd214e835b9b7c88bf696e2e20e012cf2b6.zip
Handle incompatible redeclarations of library builtins better.
Invalid redeclarations of valid explicit declarations shouldn't take the same path as redeclarations of implicit declarations, and invalid local extern declarations shouldn't foul things up for everybody else. llvm-svn: 179482
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp32
1 files changed, 21 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index b3cbbf203e2..52d39d323fe 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2697,21 +2697,31 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) {
// Fall through to diagnose conflicting types.
}
- // A function that has already been declared has been redeclared or defined
- // with a different type- show appropriate diagnostic
- if (unsigned BuiltinID = Old->getBuiltinID()) {
- // The user has declared a builtin function with an incompatible
- // signature.
+ // A function that has already been declared has been redeclared or
+ // defined with a different type; show an appropriate diagnostic.
+
+ // If the previous declaration was an implicitly-generated builtin
+ // declaration, then at the very least we should use a specialized note.
+ unsigned BuiltinID;
+ if (Old->isImplicit() && (BuiltinID = Old->getBuiltinID())) {
+ // If it's actually a library-defined builtin function like 'malloc'
+ // or 'printf', just warn about the incompatible redeclaration.
if (Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) {
- // The function the user is redeclaring is a library-defined
- // function like 'malloc' or 'printf'. Warn about the
- // redeclaration, then pretend that we don't know about this
- // library built-in.
Diag(New->getLocation(), diag::warn_redecl_library_builtin) << New;
Diag(Old->getLocation(), diag::note_previous_builtin_declaration)
<< Old << Old->getType();
- New->getIdentifier()->setBuiltinID(Builtin::NotBuiltin);
- Old->setInvalidDecl();
+
+ // If this is a global redeclaration, just forget hereafter
+ // about the "builtin-ness" of the function.
+ //
+ // Doing this for local extern declarations is problematic. If
+ // the builtin declaration remains visible, a second invalid
+ // local declaration will produce a hard error; if it doesn't
+ // remain visible, a single bogus local redeclaration (which is
+ // actually only a warning) could break all the downstream code.
+ if (!New->getDeclContext()->isFunctionOrMethod())
+ New->getIdentifier()->setBuiltinID(Builtin::NotBuiltin);
+
return false;
}
OpenPOWER on IntegriCloud