[cfe-commits] r171585 - in /cfe/trunk: lib/AST/Decl.cpp test/SemaCXX/linkage2.cpp
Rafael Espindola
rafael.espindola at gmail.com
Fri Jan 4 17:28:37 PST 2013
Author: rafael
Date: Fri Jan 4 19:28:37 2013
New Revision: 171585
URL: http://llvm.org/viewvc/llvm-project?rev=171585&view=rev
Log:
Assert that redeclarations have the same linkage.
It is somewhat hard to test linkage, so I decided to try to add an assert. This
already found some interesting cases where there were different.
Modified:
cfe/trunk/lib/AST/Decl.cpp
cfe/trunk/test/SemaCXX/linkage2.cpp
Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=171585&r1=171584&r2=171585&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Fri Jan 4 19:28:37 2013
@@ -268,8 +268,8 @@
if (D->isInAnonymousNamespace()) {
const VarDecl *Var = dyn_cast<VarDecl>(D);
const FunctionDecl *Func = dyn_cast<FunctionDecl>(D);
- if ((!Var || !Var->getDeclContext()->isExternCContext()) &&
- (!Func || !Func->getDeclContext()->isExternCContext()))
+ if ((!Var || !Var->hasCLanguageLinkage()) &&
+ (!Func || !Func->hasCLanguageLinkage()))
return LinkageInfo::uniqueExternal();
}
@@ -634,6 +634,31 @@
CachedLinkage = LV.linkage();
CacheValidAndVisibility = LV.visibility() + 1;
CachedVisibilityExplicit = LV.visibilityExplicit();
+
+#ifndef NDEBUG
+ // In C (because of gnu inline) and in c++ with microsoft extensions an
+ // static can follow an extern, so we can have two decls with different
+ // linkages.
+ const LangOptions &Opts = getASTContext().getLangOpts();
+ if (!Opts.CPlusPlus || Opts.MicrosoftExt)
+ return LV;
+
+ // We have just computed the linkage for this decl. By induction we know
+ // that all other computed linkages match, check that the one we just computed
+ // also does.
+ NamedDecl *D = NULL;
+ for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
+ NamedDecl *T = cast<NamedDecl>(*I);
+ if (T == this)
+ continue;
+ if (T->CacheValidAndVisibility != 0) {
+ D = T;
+ break;
+ }
+ }
+ assert(!D || D->CachedLinkage == CachedLinkage);
+#endif
+
return LV;
}
@@ -772,7 +797,7 @@
// one such matching entity, the program is ill-formed. Otherwise,
// if no matching entity is found, the block scope entity receives
// external linkage.
- if (D->getLexicalDeclContext()->isFunctionOrMethod()) {
+ if (D->getDeclContext()->isFunctionOrMethod()) {
if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
if (Function->isInAnonymousNamespace() &&
!Function->getDeclContext()->isExternCContext())
Modified: cfe/trunk/test/SemaCXX/linkage2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/linkage2.cpp?rev=171585&r1=171584&r2=171585&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/linkage2.cpp (original)
+++ cfe/trunk/test/SemaCXX/linkage2.cpp Fri Jan 4 19:28:37 2013
@@ -18,3 +18,25 @@
static void test2_f(int x) { // expected-error {{conflicting types for 'test2_f'}}
}
}
+
+namespace test3 {
+ extern "C" {
+ namespace {
+ extern int x2;
+ void f2();
+ }
+ }
+ namespace {
+ int x2;
+ void f2() {}
+ }
+}
+
+namespace test4 {
+ void dummy() {
+ void Bar();
+ class A {
+ friend void Bar();
+ };
+ }
+}
More information about the cfe-commits
mailing list