[cfe-commits] r172243 - in /cfe/trunk: lib/Sema/SemaDecl.cpp test/Sema/function-redecl.c test/SemaCXX/function-redecl.cpp
Rafael Espindola
rafael.espindola at gmail.com
Fri Jan 11 11:34:23 PST 2013
Author: rafael
Date: Fri Jan 11 13:34:23 2013
New Revision: 172243
URL: http://llvm.org/viewvc/llvm-project?rev=172243&view=rev
Log:
Reject incompatible redeclarations of extern C symbols.
Before we were only checking if the new declaration itself was marked extern
C. Fixes prpr14766.
Modified:
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/Sema/function-redecl.c
cfe/trunk/test/SemaCXX/function-redecl.cpp
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=172243&r1=172242&r2=172243&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Jan 11 13:34:23 2013
@@ -4691,6 +4691,14 @@
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 @@
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 @@
&& "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())
Modified: cfe/trunk/test/Sema/function-redecl.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/function-redecl.c?rev=172243&r1=172242&r2=172243&view=diff
==============================================================================
--- cfe/trunk/test/Sema/function-redecl.c (original)
+++ cfe/trunk/test/Sema/function-redecl.c Fri Jan 11 13:34:23 2013
@@ -92,8 +92,6 @@
int *(*fp)(int) = outer8; // expected-error{{use of undeclared identifier 'outer8'}}
}
-static float outer8(float); // okay
-
enum e { e1, e2 };
// GNU extension: prototypes and K&R function definitions
Modified: cfe/trunk/test/SemaCXX/function-redecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/function-redecl.cpp?rev=172243&r1=172242&r2=172243&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/function-redecl.cpp (original)
+++ cfe/trunk/test/SemaCXX/function-redecl.cpp Fri Jan 11 13:34:23 2013
@@ -116,3 +116,21 @@
}
void Foo::beEvil() {} // expected-error {{out-of-line definition of 'beEvil' does not match any declaration in namespace 'redecl_typo::Foo'; did you mean 'BeEvil'?}}
}
+
+namespace test2 {
+ extern "C" {
+ void f() {
+ void test2_g(int); // expected-note {{previous declaration is here}}
+ }
+ }
+}
+int test2_g(int); // expected-error {{functions that differ only in their return type cannot be overloaded}}
+
+namespace test3 {
+ extern "C" {
+ void f() {
+ extern int test3_x; // expected-note {{previous definition is here}}
+ }
+ }
+}
+float test3_x; // expected-error {{redefinition of 'test3_x' with a different type: 'float' vs 'int'}}
More information about the cfe-commits
mailing list