Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -1973,6 +1973,8 @@ "function concept declaration must be a definition">; def err_var_concept_not_initialized : Error< "variable concept declaration must be initialized">; +def err_function_concept_exception_spec : Error< + "function concept can not have exception specifiers">; // C++11 char16_t/char32_t def warn_cxx98_compat_unicode_type : Warning< Index: include/clang/Sema/DeclSpec.h =================================================================== --- include/clang/Sema/DeclSpec.h +++ include/clang/Sema/DeclSpec.h @@ -1255,8 +1255,12 @@ /// any. unsigned MutableLoc; - /// \brief The location of the keyword introducing the spec, if any. - unsigned ExceptionSpecLoc; + /// \brief The beginning location of the keyword introducing the spec, if + /// any. + unsigned ExceptionSpecLocBeg; + + /// \brief The end location of the keyword introducing the spec, if any. + unsigned ExceptionSpecLocEnd; /// Params - This is a pointer to a new[]'d array of ParamInfo objects that /// describe the parameters specified by this function declarator. null if @@ -1323,8 +1327,12 @@ return SourceLocation::getFromRawEncoding(RParenLoc); } - SourceLocation getExceptionSpecLoc() const { - return SourceLocation::getFromRawEncoding(ExceptionSpecLoc); + SourceLocation getExceptionSpecLocBeg() const { + return SourceLocation::getFromRawEncoding(ExceptionSpecLocBeg); + } + + SourceLocation getExceptionSpecLocEnd() const { + return SourceLocation::getFromRawEncoding(ExceptionSpecLocEnd); } /// \brief Retrieve the location of the ref-qualifier, if any. @@ -1496,7 +1504,7 @@ SourceLocation RestrictQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, - SourceLocation ESpecLoc, + SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, Index: lib/Parse/ParseDecl.cpp =================================================================== --- lib/Parse/ParseDecl.cpp +++ lib/Parse/ParseDecl.cpp @@ -5612,7 +5612,7 @@ VolatileQualifierLoc, RestrictQualifierLoc, /*MutableLoc=*/SourceLocation(), - ESpecType, ESpecRange.getBegin(), + ESpecType, ESpecRange, DynamicExceptions.data(), DynamicExceptionRanges.data(), DynamicExceptions.size(), Index: lib/Parse/ParseExpr.cpp =================================================================== --- lib/Parse/ParseExpr.cpp +++ lib/Parse/ParseExpr.cpp @@ -2747,7 +2747,7 @@ /*RestrictQualifierLoc=*/NoLoc, /*MutableLoc=*/NoLoc, EST_None, - /*ESpecLoc=*/NoLoc, + /*ESpecRange=*/SourceRange(), /*Exceptions=*/nullptr, /*ExceptionRanges=*/nullptr, /*NumExceptions=*/0, Index: lib/Parse/ParseExprCXX.cpp =================================================================== --- lib/Parse/ParseExprCXX.cpp +++ lib/Parse/ParseExprCXX.cpp @@ -1149,7 +1149,7 @@ /*VolatileQualifierLoc=*/NoLoc, /*RestrictQualifierLoc=*/NoLoc, MutableLoc, - ESpecType, ESpecRange.getBegin(), + ESpecType, ESpecRange, DynamicExceptions.data(), DynamicExceptionRanges.data(), DynamicExceptions.size(), @@ -1217,7 +1217,7 @@ /*RestrictQualifierLoc=*/NoLoc, MutableLoc, EST_None, - /*ESpecLoc=*/NoLoc, + /*ESpecRange=*/SourceRange(), /*Exceptions=*/nullptr, /*ExceptionRanges=*/nullptr, /*NumExceptions=*/0, Index: lib/Sema/DeclSpec.cpp =================================================================== --- lib/Sema/DeclSpec.cpp +++ lib/Sema/DeclSpec.cpp @@ -177,7 +177,7 @@ SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, - SourceLocation ESpecLoc, + SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, @@ -212,7 +212,8 @@ I.Fun.RestrictQualifierLoc = RestrictQualifierLoc.getRawEncoding(); I.Fun.MutableLoc = MutableLoc.getRawEncoding(); I.Fun.ExceptionSpecType = ESpecType; - I.Fun.ExceptionSpecLoc = ESpecLoc.getRawEncoding(); + I.Fun.ExceptionSpecLocBeg = ESpecRange.getBegin().getRawEncoding(); + I.Fun.ExceptionSpecLocEnd = ESpecRange.getEnd().getRawEncoding(); I.Fun.NumExceptions = 0; I.Fun.Exceptions = nullptr; I.Fun.NoexceptExpr = nullptr; Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -7444,6 +7444,21 @@ NewFD->setInvalidDecl(); } + if (const FunctionProtoType *FPT = R->getAs()) { + if (FPT->hasExceptionSpec()) { + auto LocBeg = D.getFunctionTypeInfo().getExceptionSpecLocBeg(); + auto LocEnd = D.getFunctionTypeInfo().getExceptionSpecLocEnd(); + Diag(LocBeg, diag::err_function_concept_exception_spec) + << FixItHint::CreateRemoval(SourceRange(LocBeg, LocEnd)); + NewFD->setInvalidDecl(); + } + else { + NewFD->setType(Context.getFunctionType( + FPT->getReturnType(), FPT->getParamTypes(), + FPT->getExtProtoInfo().withExceptionSpec(EST_BasicNoexcept))); + } + } + // C++ Concepts TS [dcl.spec.concept]p2: Every concept definition is // implicity defined to be a constexpr declaration (implicitly inline) NewFD->setImplicitlyInline(); @@ -11077,7 +11092,7 @@ /*RestrictQualifierLoc=*/NoLoc, /*MutableLoc=*/NoLoc, EST_None, - /*ESpecLoc=*/NoLoc, + /*ESpecRange=*/SourceRange(), /*Exceptions=*/nullptr, /*ExceptionRanges=*/nullptr, /*NumExceptions=*/0, Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -700,7 +700,7 @@ /*VolatileQualifierLoc=*/NoLoc, /*RestrictQualifierLoc=*/NoLoc, /*MutableLoc=*/NoLoc, EST_None, - /*ESpecLoc=*/NoLoc, + /*ESpecRange=*/SourceRange(), /*Exceptions=*/nullptr, /*ExceptionRanges=*/nullptr, /*NumExceptions=*/0, @@ -3833,7 +3833,7 @@ // Exception specs are not allowed in typedefs. Complain, but add it // anyway. if (IsTypedefName && FTI.getExceptionSpecType()) - S.Diag(FTI.getExceptionSpecLoc(), diag::err_exception_spec_in_typedef) + S.Diag(FTI.getExceptionSpecLocBeg(), diag::err_exception_spec_in_typedef) << (D.getContext() == Declarator::AliasDeclContext || D.getContext() == Declarator::AliasTemplateContext); Index: test/SemaCXX/cxx-concept-declaration.cpp =================================================================== --- test/SemaCXX/cxx-concept-declaration.cpp +++ test/SemaCXX/cxx-concept-declaration.cpp @@ -23,3 +23,5 @@ template concept bool D6; // expected-error {{variable concept declaration must be initialized}} +template +concept bool D7() throw(int) { return true; } // expected-error {{function concept can not have exception specifiers}}