aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-01-11 19:34:23 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-01-11 19:34:23 +0000
commit294ddc63398f2c9435fcfbdb4da4ac3a23c1cbba (patch)
treef37144238f30c6ee03a65b6102ecd492ee9ce008 /lib/Sema/SemaDecl.cpp
parent4d8efb48b9de9feee79c948ef9d05febd6d0c20b (diff)
Reject incompatible redeclarations of extern C symbols.
Before we were only checking if the new declaration itself was marked extern C. Fixes prpr14766. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172243 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp22
1 files changed, 14 insertions, 8 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 59343f6670..0cf1238220 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -4691,6 +4691,14 @@ void Sema::CheckShadow(Scope *S, VarDecl *D) {
CheckShadow(S, D, R);
}
+template<typename T>
+static bool mayConflictWithNonVisibleExternC(const T *ND) {
+ VarDecl::StorageClass SC = ND->getStorageClass();
+ if (ND->hasCLanguageLinkage() && (SC == SC_Extern || SC == SC_PrivateExtern))
+ return true;
+ return ND->getDeclContext()->isTranslationUnit();
+}
+
/// \brief Perform semantic checking on a newly-created variable
/// declaration.
///
@@ -4793,10 +4801,9 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD,
NewVD->setTypeSourceInfo(FixedTInfo);
}
- if (Previous.empty() && NewVD->isExternC()) {
- // Since we did not find anything by this name and we're declaring
- // an extern "C" variable, look for a non-visible extern "C"
- // declaration with the same name.
+ if (Previous.empty() && mayConflictWithNonVisibleExternC(NewVD)) {
+ // Since we did not find anything by this name, look for a non-visible
+ // extern "C" declaration with the same name.
llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos
= findLocallyScopedExternCDecl(NewVD->getDeclName());
if (Pos != LocallyScopedExternCDecls.end())
@@ -6146,10 +6153,9 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
&& "Variably modified return types are not handled here");
// Check for a previous declaration of this name.
- if (Previous.empty() && NewFD->isExternC()) {
- // Since we did not find anything by this name and we're declaring
- // an extern "C" function, look for a non-visible extern "C"
- // declaration with the same name.
+ if (Previous.empty() && mayConflictWithNonVisibleExternC(NewFD)) {
+ // Since we did not find anything by this name, look for a non-visible
+ // extern "C" declaration with the same name.
llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos
= findLocallyScopedExternCDecl(NewFD->getDeclName());
if (Pos != LocallyScopedExternCDecls.end())