From: Douglas Gregor Date: Tue, 10 Apr 2012 20:43:46 +0000 (+0000) Subject: When we determine that an initialization sequence failed due to an X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=69a30b838c723cb1850de55cfa48a402cfeeb6e0;p=clang When we determine that an initialization sequence failed due to an incomplete type, keep track of the actual type that was incomplete. Otherwise, we might fail to produce a diagnostic. Fixes PR12498. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154432 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h index 23cc4455db..4433843ff8 100644 --- a/include/clang/Sema/Initialization.h +++ b/include/clang/Sema/Initialization.h @@ -734,6 +734,9 @@ private: /// \brief The candidate set created when initialization failed. OverloadCandidateSet FailedCandidateSet; + /// \brief The incomplete type that caused a failure. + QualType FailedIncompleteType; + /// \brief Prints a follow-up note that highlights the location of /// the initialized entity, if it's remote. void PrintInitLocationNote(Sema &S, const InitializedEntity &Entity); @@ -949,6 +952,8 @@ public: void SetFailed(FailureKind Failure) { SequenceKind = FailedSequence; this->Failure = Failure; + assert((Failure != FK_Incomplete || !FailedIncompleteType.isNull()) && + "Incomplete type failure requires a type!"); } /// \brief Note that this initialization sequence failed due to failed @@ -967,6 +972,13 @@ public: return FailedOverloadResult; } + /// \brief Note that this initialization sequence failed due to an + /// incomplete type. + void setIncompleteTypeFailure(QualType IncompleteType) { + FailedIncompleteType = IncompleteType; + SetFailed(FK_Incomplete); + } + /// \brief Determine why initialization failed. FailureKind getFailureKind() const { assert(Failed() && "Not an initialization failure!"); diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index ee051428da..a65b41fd1c 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -2877,7 +2877,7 @@ static void TryConstructorInitialization(Sema &S, // The type we're constructing needs to be complete. if (S.RequireCompleteType(Kind.getLocation(), DestType, 0)) { - Sequence.SetFailed(InitializationSequence::FK_Incomplete); + Sequence.setIncompleteTypeFailure(DestType); return; } @@ -3109,7 +3109,7 @@ static void TryListInitialization(Sema &S, } if (DestType->isRecordType()) { if (S.RequireCompleteType(InitList->getLocStart(), DestType, S.PDiag())) { - Sequence.SetFailed(InitializationSequence::FK_Incomplete); + Sequence.setIncompleteTypeFailure(DestType); return; } @@ -5687,7 +5687,7 @@ bool InitializationSequence::Diagnose(Sema &S, break; case FK_Incomplete: - S.RequireCompleteType(Kind.getLocation(), DestType, + S.RequireCompleteType(Kind.getLocation(), FailedIncompleteType, diag::err_init_incomplete_type); break; diff --git a/test/SemaCXX/cxx0x-initializer-constructor.cpp b/test/SemaCXX/cxx0x-initializer-constructor.cpp index 68c149218a..09aca24b70 100644 --- a/test/SemaCXX/cxx0x-initializer-constructor.cpp +++ b/test/SemaCXX/cxx0x-initializer-constructor.cpp @@ -267,3 +267,17 @@ namespace PR12120 { struct B { explicit B(short); B(long); }; // expected-note 2 {{candidate}} B b = { 0 }; // expected-error {{ambiguous}} } + +namespace PR12498 { + class ArrayRef; // expected-note{{forward declaration}} + + struct C { + void foo(const ArrayRef&); // expected-note{{passing argument to parameter here}} + }; + + static void bar(C* c) + { + c->foo({ nullptr, 1 }); // expected-error{{initialization of incomplete type 'const PR12498::ArrayRef'}} + } + +}