diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index bfb209a074f8b4ce3a1188bb7266e92c87a27793..e4e9b147683eeb9f28bacf4fdbea31de4ebbddca 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -121,31 +121,26 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc, bool AlreadySearched = false; bool LookAtPrefix = true; - // C++ [basic.lookup.qual]p6: + // C++11 [basic.lookup.qual]p6: // If a pseudo-destructor-name (5.2.4) contains a nested-name-specifier, // the type-names are looked up as types in the scope designated by the - // nested-name-specifier. In a qualified-id of the form: + // nested-name-specifier. Similarly, in a qualified-id of the form: // - // ::[opt] nested-name-specifier ~ class-name + // nested-name-specifier[opt] class-name :: ~ class-name // - // where the nested-name-specifier designates a namespace scope, and in - // a qualified-id of the form: + // the second class-name is looked up in the same scope as the first. // - // ::opt nested-name-specifier class-name :: ~ class-name - // - // the class-names are looked up as types in the scope designated by - // the nested-name-specifier. - // - // Here, we check the first case (completely) and determine whether the - // code below is permitted to look at the prefix of the - // nested-name-specifier. + // Here, we determine whether the code below is permitted to look at the + // prefix of the nested-name-specifier. DeclContext *DC = computeDeclContext(SS, EnteringContext); if (DC && DC->isFileContext()) { AlreadySearched = true; LookupCtx = DC; isDependent = false; - } else if (DC && isa<CXXRecordDecl>(DC)) + } else if (DC && isa<CXXRecordDecl>(DC)) { LookAtPrefix = false; + LookInScope = true; + } // The second case from the C++03 rules quoted further above. NestedNameSpecifier *Prefix = 0; @@ -163,8 +158,6 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc, LookupCtx = computeDeclContext(SS, EnteringContext); isDependent = LookupCtx && LookupCtx->isDependentContext(); } - - LookInScope = false; } else if (ObjectTypePtr) { // C++ [basic.lookup.classref]p3: // If the unqualified-id is ~type-name, the type-name is looked up diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp index 0956de3c2a8893c02465e5708a54730f9346f4f3..83c8dd8fc22dff9e0ad3f9a69845dc6d126e09e5 100644 --- a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp +++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s +// expected-no-diagnostics struct C { typedef int I; @@ -20,5 +21,5 @@ struct A { typedef A AB; int main() { AB *p; - p->AB::~AB(); // expected-error{{expected the class name after '~' to name a destructor}} + p->AB::~AB(); } diff --git a/test/CXX/drs/dr2xx.cpp b/test/CXX/drs/dr2xx.cpp index 692ed1d1afde41f14e555c1d5591dfc4335d4358..bb9af9fd9337e7d975a80f591bd568da7993065d 100644 --- a/test/CXX/drs/dr2xx.cpp +++ b/test/CXX/drs/dr2xx.cpp @@ -466,7 +466,7 @@ namespace dr243 { // dr243: yes A a2 = b; // expected-error {{ambiguous}} } -namespace dr244 { // dr244: no +namespace dr244 { // dr244: 3.5 struct B {}; struct D : B {}; // expected-note {{here}} D D_object; @@ -480,7 +480,7 @@ namespace dr244 { // dr244: no B_ptr->~B_alias(); B_ptr->B_alias::~B(); // This is valid under DR244. - B_ptr->B_alias::~B_alias(); // FIXME: expected-error {{expected the class name after '~' to name a destructor}} + B_ptr->B_alias::~B_alias(); B_ptr->dr244::~B(); // expected-error {{refers to a member in namespace}} B_ptr->dr244::~B_alias(); // expected-error {{refers to a member in namespace}} } @@ -1013,11 +1013,16 @@ namespace dr298 { // dr298: yes B::B() {} // expected-error {{requires a type specifier}} B::A() {} // ok - C::~C() {} // expected-error {{expected the class name}} - C::~A() {} // ok + C::~C() {} // expected-error {{destructor cannot be declared using a typedef 'C' (aka 'const dr298::A') of the class name}} typedef struct D E; // expected-note {{here}} struct E {}; // expected-error {{conflicts with typedef}} + + struct F { + ~F(); + }; + typedef const F G; + G::~F() {} // ok } namespace dr299 { // dr299: yes c++11 diff --git a/www/cxx_dr_status.html b/www/cxx_dr_status.html index 35e72313676caeb3af490e9f65488b0fb63537d2..79790131c22dc4777eadd1a43202d2a9df1e03b0 100644 --- a/www/cxx_dr_status.html +++ b/www/cxx_dr_status.html @@ -1504,7 +1504,7 @@ accessible?</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#244">244</a></td> <td>CD1</td> <td>Destructor lookup</td> - <td class="none" align="center">No</td> + <td class="svn" align="center">SVN</td> </tr> <tr id="245"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#245">245</a></td>