Index: cfe/trunk/lib/Sema/SemaDeclAttr.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp @@ -1898,7 +1898,16 @@ } } - // FIXME: check if target symbol exists in current file + // Mark target used to prevent unneeded-internal-declaration warnings. + if (!S.LangOpts.CPlusPlus) { + // FIXME: demangle Str for C++, as the attribute refers to the mangled + // linkage name, not the pre-mangled identifier. + const DeclarationNameInfo target(&S.Context.Idents.get(Str), AL.getLoc()); + LookupResult LR(S, target, Sema::LookupOrdinaryName); + if (S.LookupQualifiedName(LR, S.getCurLexicalContext())) + for (NamedDecl *ND : LR) + ND->markUsed(S.Context); + } D->addAttr(::new (S.Context) AliasAttr(AL.getRange(), S.Context, Str, AL.getAttributeSpellingListIndex())); Index: cfe/trunk/test/Sema/alias-unused.c =================================================================== --- cfe/trunk/test/Sema/alias-unused.c +++ cfe/trunk/test/Sema/alias-unused.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -Wunneeded-internal-declaration -x c -verify %s +// expected-no-diagnostics +static int f() { return 42; } +int g() __attribute__((alias("f"))); + +static int foo [] = { 42, 0xDEAD }; +extern typeof(foo) bar __attribute__((unused, alias("foo")));