r200897 - DR101, PR12770: If a function is declared in the same context as a
Richard Smith
richard-llvm at metafoo.co.uk
Wed Feb 5 17:31:34 PST 2014
Author: rsmith
Date: Wed Feb 5 19:31:33 2014
New Revision: 200897
URL: http://llvm.org/viewvc/llvm-project?rev=200897&view=rev
Log:
DR101, PR12770: If a function is declared in the same context as a
using-declaration, and they declare the same function (either because
the using-declaration is in the same namespace as the declaration it
imports, or because they're both extern "C"), they do not conflict.
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp
cfe/trunk/test/CXX/drs/dr1xx.cpp
cfe/trunk/test/Modules/linkage-merge.cpp
cfe/trunk/www/cxx_dr_status.html
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=200897&r1=200896&r2=200897&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Feb 5 19:31:33 2014
@@ -1889,7 +1889,7 @@ public:
void mergeDeclAttributes(NamedDecl *New, Decl *Old,
AvailabilityMergeKind AMK = AMK_Redeclaration);
void MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls);
- bool MergeFunctionDecl(FunctionDecl *New, Decl *Old, Scope *S,
+ bool MergeFunctionDecl(FunctionDecl *New, NamedDecl *&Old, Scope *S,
bool MergeTypeWithOld);
bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old,
Scope *S, bool MergeTypeWithOld);
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=200897&r1=200896&r2=200897&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Feb 5 19:31:33 2014
@@ -2268,8 +2268,8 @@ static bool haveIncompatibleLanguageLink
/// merged with.
///
/// Returns true if there was an error, false otherwise.
-bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S,
- bool MergeTypeWithOld) {
+bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
+ Scope *S, bool MergeTypeWithOld) {
// Verify the old decl was also a function.
FunctionDecl *Old = OldD->getAsFunction();
if (!Old) {
@@ -2283,18 +2283,34 @@ bool Sema::MergeFunctionDecl(FunctionDec
return true;
}
- Diag(New->getLocation(), diag::err_using_decl_conflict_reverse);
- Diag(Shadow->getTargetDecl()->getLocation(),
- diag::note_using_decl_target);
- Diag(Shadow->getUsingDecl()->getLocation(),
- diag::note_using_decl) << 0;
+ // C++11 [namespace.udecl]p14:
+ // If a function declaration in namespace scope or block scope has the
+ // same name and the same parameter-type-list as a function introduced
+ // by a using-declaration, and the declarations do not declare the same
+ // function, the program is ill-formed.
+
+ // Check whether the two declarations might declare the same function.
+ Old = dyn_cast<FunctionDecl>(Shadow->getTargetDecl());
+ if (Old &&
+ !Old->getDeclContext()->getRedeclContext()->Equals(
+ New->getDeclContext()->getRedeclContext()) &&
+ !(Old->isExternC() && New->isExternC()))
+ Old = 0;
+
+ if (!Old) {
+ Diag(New->getLocation(), diag::err_using_decl_conflict_reverse);
+ Diag(Shadow->getTargetDecl()->getLocation(),
+ diag::note_using_decl_target);
+ Diag(Shadow->getUsingDecl()->getLocation(), diag::note_using_decl) << 0;
+ return true;
+ }
+ OldD = Old;
+ } else {
+ Diag(New->getLocation(), diag::err_redefinition_different_kind)
+ << New->getDeclName();
+ Diag(OldD->getLocation(), diag::note_previous_definition);
return true;
}
-
- Diag(New->getLocation(), diag::err_redefinition_different_kind)
- << New->getDeclName();
- Diag(OldD->getLocation(), diag::note_previous_definition);
- return true;
}
// If the old declaration is invalid, just give up here.
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=200897&r1=200896&r2=200897&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Feb 5 19:31:33 2014
@@ -7252,7 +7252,7 @@ bool Sema::CheckUsingShadowDecl(UsingDec
case Ovl_NonFunction:
Diag(Using->getLocation(), diag::err_using_decl_conflict);
break;
-
+
// We found a decl with the exact signature.
case Ovl_Match:
// If we're in a record, we want to hide the target, so we
Modified: cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp?rev=200897&r1=200896&r2=200897&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp Wed Feb 5 19:31:33 2014
@@ -1,14 +1,16 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-// C++03 [namespace.udecl]p11:
+// C++03 [namespace.udecl]p11: (per DR101)
// If a function declaration in namespace scope or block scope has
// the same name and the same parameter types as a function
-// introduced by a using-declaration, the program is
-// ill-formed. [Note: two using-declarations may introduce functions
-// with the same name and the same parameter types. If, for a call
-// to an unqualified function name, function overload resolution
-// selects the functions introduced by such using-declarations, the
-// function call is ill-formed.
+// introduced by a using-declaration, and the declarations do not declare the
+// same function, the program is ill-formed. [Note: two using-declarations may
+// introduce functions with the same name and the same parameter types. If,
+// for a call to an unqualified function name, function overload resolution
+// selects the functions introduced by such using-declarations, the function
+// call is ill-formed.]
+//
+// FIXME: DR565 introduces parallel wording here for function templates.
namespace test0 {
namespace ns { void foo(); } // expected-note {{target of using declaration}}
@@ -89,3 +91,13 @@ namespace test5 {
template class Test0<int>;
template class Test1<int>;
}
+
+namespace test6 {
+ namespace ns { void foo(); } // expected-note {{target of using declaration}}
+ using ns::foo; // expected-note {{using declaration}}
+ namespace ns {
+ using test6::foo;
+ void foo() {}
+ }
+ void foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+}
Modified: cfe/trunk/test/CXX/drs/dr1xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr1xx.cpp?rev=200897&r1=200896&r2=200897&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr1xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr1xx.cpp Wed Feb 5 19:31:33 2014
@@ -9,7 +9,7 @@ namespace dr100 { // dr100: yes
B<"bar"> b; // expected-error {{does not refer to any declaration}}
}
-namespace dr101 { // dr101: yes
+namespace dr101 { // dr101: 3.5
extern "C" void dr101_f();
typedef unsigned size_t;
namespace X {
@@ -18,6 +18,8 @@ namespace dr101 { // dr101: yes
}
using X::dr101_f;
using X::size_t;
+ extern "C" void dr101_f();
+ typedef unsigned size_t;
}
namespace dr102 { // dr102: yes
Modified: cfe/trunk/test/Modules/linkage-merge.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/linkage-merge.cpp?rev=200897&r1=200896&r2=200897&view=diff
==============================================================================
--- cfe/trunk/test/Modules/linkage-merge.cpp (original)
+++ cfe/trunk/test/Modules/linkage-merge.cpp Wed Feb 5 19:31:33 2014
@@ -7,6 +7,5 @@ static int f(int);
int f(int);
static void g(int);
-// expected-error at -1 {{declaration conflicts with target of using declaration already in scope}}
-// expected-note at Inputs/linkage-merge-foo.h:2 {{target of using declaration}}
-// expected-note at Inputs/linkage-merge-bar.h:3 {{using declaration}}
+// expected-error at -1 {{functions that differ only in their return type cannot be overloaded}}
+// expected-note at Inputs/linkage-merge-foo.h:2 {{previous declaration is here}}
Modified: cfe/trunk/www/cxx_dr_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=200897&r1=200896&r2=200897&view=diff
==============================================================================
--- cfe/trunk/www/cxx_dr_status.html (original)
+++ cfe/trunk/www/cxx_dr_status.html Wed Feb 5 19:31:33 2014
@@ -645,7 +645,7 @@
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#101">101</a></td>
<td>TC1</td>
<td>Redeclaration of extern "C" names via using-declarations</td>
- <td class="full" align="center">Yes</td>
+ <td class="svn" align="center">SVN</td>
</tr>
<tr>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#102">102</a></td>
More information about the cfe-commits
mailing list