From: Douglas Gregor Date: Wed, 28 Apr 2010 07:04:26 +0000 (+0000) Subject: When the qualifier of a id-expression is non-dependent but not X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e6ec5c42047c717014f7490bb9697945ae7a9d5b;p=clang When the qualifier of a id-expression is non-dependent but not complete, return an error rather than falling back to building a dependent declaration reference, since we might not be in a dependent context. Fixes a fiendish crash-on-invalid in Boost.FunctionTypes that I wasn't able to reduce to anything useful. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102491 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 89a329140f..bdd1cfb66b 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1232,11 +1232,12 @@ Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS, DeclarationName Name, SourceLocation NameLoc) { DeclContext *DC; - if (!(DC = computeDeclContext(SS, false)) || - DC->isDependentContext() || - RequireCompleteDeclContext(SS)) + if (!(DC = computeDeclContext(SS, false)) || DC->isDependentContext()) return BuildDependentDeclRefExpr(SS, Name, NameLoc, 0); + if (RequireCompleteDeclContext(SS)) + return ExprError(); + LookupResult R(*this, Name, NameLoc, LookupOrdinaryName); LookupQualifiedName(R, DC); diff --git a/test/SemaTemplate/instantiate-function-params.cpp b/test/SemaTemplate/instantiate-function-params.cpp index cfca020aad..eb16cf7651 100644 --- a/test/SemaTemplate/instantiate-function-params.cpp +++ b/test/SemaTemplate/instantiate-function-params.cpp @@ -3,13 +3,13 @@ // PR6619 template struct if_c { }; template struct if_ { - typedef if_c< static_cast(T1::value)> almost_type_; // expected-note 7{{in instantiation}} + typedef if_c< static_cast(T1::value)> almost_type_; // expected-note 5{{in instantiation}} }; template struct wrap_constraints { }; template -inline char has_constraints_(Model* , // expected-note 4{{while substituting deduced template arguments into function template 'has_constraints_' [with }} \ +inline char has_constraints_(Model* , // expected-note 2{{while substituting deduced template arguments into function template 'has_constraints_' [with }} \ // expected-note 3{{candidate template ignored}} - wrap_constraints* = 0); // expected-note 4{{in instantiation}} + wrap_constraints* = 0); // expected-note 2{{in instantiation}} template struct not_satisfied { static const bool value = sizeof( has_constraints_((Model*)0) == 1); // expected-error 3{{no matching function}} @@ -17,19 +17,18 @@ template struct not_satisfied { template struct requirement_; template struct instantiate { }; -template struct requirement_ : if_< not_satisfied >::type { // expected-error 3{{no type named}} \ - // expected-note 7{{in instantiation}} +template struct requirement_ : if_< not_satisfied >::type { // expected-note 5{{in instantiation}} }; template struct usage_requirements { }; template < typename TT > struct InputIterator { - typedef instantiate< & requirement_ x)>::failed> boost_concept_check1; // expected-note 2{{in instantiation}} + typedef instantiate< & requirement_ x)>::failed> boost_concept_check1; // expected-note {{in instantiation}} }; -template < typename TT > struct ForwardIterator : InputIterator { // expected-note 2{{in instantiation}} - typedef instantiate< & requirement_ x)>::failed> boost_concept_check2; // expected-note 2 {{in instantiation}} +template < typename TT > struct ForwardIterator : InputIterator { // expected-note {{in instantiation}} + typedef instantiate< & requirement_ x)>::failed> boost_concept_check2; // expected-note {{in instantiation}} }; -typedef instantiate< &requirement_ x)>::failed> boost_concept_checkX;// expected-note 6{{in instantiation}} +typedef instantiate< &requirement_ x)>::failed> boost_concept_checkX;// expected-note 3{{in instantiation}} template struct X0 { }; template struct X0 { };