[cfe-commits] r171139 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/SemaCXX/linkage2.cpp
Rafael Espindola
rafael.espindola at gmail.com
Wed Dec 26 19:56:20 PST 2012
Author: rafael
Date: Wed Dec 26 21:56:20 2012
New Revision: 171139
URL: http://llvm.org/viewvc/llvm-project?rev=171139&view=rev
Log:
Implement dcl.link paragraph 5.
The language linkage of redeclarations must match. GCC was already reporting
an error for this.
Added:
cfe/trunk/test/SemaCXX/linkage2.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaDecl.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=171139&r1=171138&r2=171139&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Dec 26 21:56:20 2012
@@ -3257,6 +3257,8 @@
"inline declaration of %0 not allowed in block scope">;
def err_static_non_static : Error<
"static declaration of %0 follows non-static declaration">;
+def err_different_language_linkage : Error<
+ "declaration of %0 has a different language linkage">;
def warn_weak_import : Warning <
"an already-declared variable is made a weak_import declaration %0">;
def warn_static_non_static : ExtWarn<
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=171139&r1=171138&r2=171139&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Dec 26 21:56:20 2012
@@ -1969,6 +1969,32 @@
return ABIDefaultCC == CC;
}
+/// Check if the given decl has C language linkage. Note that this is not
+/// the same as D.isExternC() since decls with non external linkage can have C
+/// language linkage. They can also have C language linkage when they are
+/// not declared in an extern C context, but a previous decl is.
+template<typename T>
+bool hasCLanguageLinkage(const T &D) {
+ // Language linkage is a C++ concept, but saying that everything in C has
+ // C language linkage fits the implementation nicelly.
+ ASTContext &Context = D.getASTContext();
+ if (!Context.getLangOpts().CPlusPlus)
+ return true;
+
+ // dcl.link 4: A C language linkage is ignored in determining the language
+ // linkage of the names of class members and the function type of class member
+ // functions.
+ const DeclContext *DC = D.getDeclContext();
+ if (DC->isRecord())
+ return false;
+
+ // If the first decl is in an extern "C" context, any other redeclaration
+ // will have C language linkage. If the first one is not in an extern "C"
+ // context, we would have reported an error for any other decl being in one.
+ const T *First = D.getFirstDeclaration();
+ return First->getDeclContext()->isExternCContext();
+}
+
/// MergeFunctionDecl - We just parsed a function 'New' from
/// declarator D which has the same name and scope as a previous
/// declaration 'Old'. Figure out how to resolve this situation,
@@ -2229,6 +2255,12 @@
assert(OldQTypeForComparison.isCanonical());
}
+ if (!hasCLanguageLinkage(*Old) && hasCLanguageLinkage(*New)) {
+ Diag(New->getLocation(), diag::err_different_language_linkage) << New;
+ Diag(Old->getLocation(), PrevDiag);
+ return true;
+ }
+
if (OldQTypeForComparison == NewQType)
return MergeCompatibleFunctionDecls(New, Old, S);
@@ -2612,6 +2644,14 @@
New->setInvalidDecl();
return;
}
+
+ if (!hasCLanguageLinkage(*Old) && hasCLanguageLinkage(*New)) {
+ Diag(New->getLocation(), diag::err_different_language_linkage) << New;
+ Diag(Old->getLocation(), diag::note_previous_definition);
+ New->setInvalidDecl();
+ return;
+ }
+
// c99 6.2.2 P4.
// For an identifier declared with the storage-class specifier extern in a
// scope in which a prior declaration of that identifier is visible, if
Added: cfe/trunk/test/SemaCXX/linkage2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/linkage2.cpp?rev=171139&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/linkage2.cpp (added)
+++ cfe/trunk/test/SemaCXX/linkage2.cpp Wed Dec 26 21:56:20 2012
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace test1 {
+ int x; // expected-note {{previous definition is here}}
+ static int y; // expected-note {{previous definition is here}}
+ void f() {} // expected-note {{previous definition is here}}
+
+ extern "C" {
+ extern int x; // expected-error {{declaration of 'x' has a different language linkage}}
+ extern int y; // expected-error {{declaration of 'y' has a different language linkage}}
+ void f(); // expected-error {{declaration of 'f' has a different language linkage}}
+ }
+}
More information about the cfe-commits
mailing list