From 7eb5d377d7bc0c3a786563bcdb22e2edbd8565ed Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Wed, 14 Oct 2009 14:59:48 +0000 Subject: [PATCH] Use partial diagnostics properly in call to RequireCompleteType. Among other things, this means we get a note on the declaration of the incomplete type when it is used in an exception specification. llvm-svn: 84099 --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +- clang/lib/Sema/SemaExceptionSpec.cpp | 14 ++++++-------- clang/test/SemaCXX/exception-spec.cpp | 7 ++++++- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5efab50ae38a..fc840a2d58bb 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -356,7 +356,7 @@ def err_distant_exception_spec : Error< "exception specifications are not allowed beyond a single level " "of indirection">; def err_incomplete_in_exception_spec : Error< - "%select{|pointer to |reference to }1incomplete type %0 is not allowed " + "%select{|pointer to |reference to }0incomplete type %1 is not allowed " "in exception specification">; def err_mismatched_exception_spec : Error< "exception specification in declaration does not match previous declaration">; diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index 261bebf9553c..12d06b4905b3 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -41,11 +41,9 @@ bool Sema::CheckSpecifiedExceptionType(QualType T, const SourceRange &Range) { // C++ 15.4p2: A type denoted in an exception-specification shall not denote // an incomplete type. - // FIXME: This isn't right. This will supress diagnostics from template - // instantiation and then simply emit the invalid type diagnostic. - if (RequireCompleteType(Range.getBegin(), T, 0)) - return Diag(Range.getBegin(), diag::err_incomplete_in_exception_spec) - << Range << T << /*direct*/0; + if (RequireCompleteType(Range.getBegin(), T, + PDiag(diag::err_incomplete_in_exception_spec) << /*direct*/0 << Range)) + return true; // C++ 15.4p2: A type denoted in an exception-specification shall not denote // an incomplete type a pointer or reference to an incomplete type, other @@ -60,9 +58,9 @@ bool Sema::CheckSpecifiedExceptionType(QualType T, const SourceRange &Range) { } else return false; - if (!T->isVoidType() && RequireCompleteType(Range.getBegin(), T, 0)) - return Diag(Range.getBegin(), diag::err_incomplete_in_exception_spec) - << Range << T << /*indirect*/kind; + if (!T->isVoidType() && RequireCompleteType(Range.getBegin(), T, + PDiag(diag::err_incomplete_in_exception_spec) << /*direct*/kind << Range)) + return true; return false; } diff --git a/clang/test/SemaCXX/exception-spec.cpp b/clang/test/SemaCXX/exception-spec.cpp index f55a4494ea4d..9b2a07d79654 100644 --- a/clang/test/SemaCXX/exception-spec.cpp +++ b/clang/test/SemaCXX/exception-spec.cpp @@ -24,7 +24,7 @@ void (**j)() throw(int); // expected-error {{not allowed beyond a single}} // Pointer to function returning pointer to pointer to function with spec void (**(*h())())() throw(int); // expected-error {{not allowed beyond a single}} -struct Incomplete; +struct Incomplete; // expected-note 3 {{forward declaration}} // Exception spec must not have incomplete types, or pointers to them, except // void. @@ -180,3 +180,8 @@ void mfnptr() void (Str1::*pfn2)() = &Str1::f; // valid void (Str1::*pfn3)() throw() = &Str1::f; // expected-error {{not superset}} expected-error {{incompatible type}} } + +// Don't suppress errors in template instantiation. +template struct TEx; // expected-note {{template is declared here}} + +void tf() throw(TEx); // expected-error {{implicit instantiation of undefined template}}