From d7421384ecab5271594595cf3ebda3580a6f366a Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Wed, 10 Jun 2015 19:06:59 +0000 Subject: [PATCH] Do not parse members of incomplete class. If definition of a class is unknown and out-of-line definition of its member is encountered, do not parse the member declaration. This change fixes PR18542. Differential Revision: http://reviews.llvm.org/D8010 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@239483 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 6 ++++-- test/SemaCXX/incomplete-call.cpp | 12 ++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 047958e2fc..1c0eea72dd 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -4663,12 +4663,14 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, RequireCompleteDeclContext(D.getCXXScopeSpec(), DC)) return nullptr; + // If a class is incomplete, do not parse entities inside it. if (isa(DC) && !cast(DC)->hasDefinition()) { Diag(D.getIdentifierLoc(), diag::err_member_def_undefined_record) << Name << DC << D.getCXXScopeSpec().getRange(); - D.setInvalidType(); - } else if (!D.getDeclSpec().isFriendSpecified()) { + return nullptr; + } + if (!D.getDeclSpec().isFriendSpecified()) { if (diagnoseQualifiedDeclaration(D.getCXXScopeSpec(), DC, Name, D.getIdentifierLoc())) { if (DC->isRecord()) diff --git a/test/SemaCXX/incomplete-call.cpp b/test/SemaCXX/incomplete-call.cpp index 69eb03a3ed..6f5169ee8a 100644 --- a/test/SemaCXX/incomplete-call.cpp +++ b/test/SemaCXX/incomplete-call.cpp @@ -47,3 +47,15 @@ struct C; // expected-note{{forward declaration}} void test_incomplete_object_call(C& c) { c(); // expected-error{{incomplete type in call to object of type}} } + +namespace pr18542 { + struct X { + int count; + template class basic_istream; + template + void basic_istream::read() { // expected-error{{out-of-line definition of 'read' from class 'basic_istream' without definition}} + count = 0; + } + }; +} + -- 2.40.0