Index: include/clang/AST/Decl.h =================================================================== --- include/clang/AST/Decl.h +++ include/clang/AST/Decl.h @@ -1574,6 +1574,7 @@ bool HasImplicitReturnZero : 1; bool IsLateTemplateParsed : 1; bool IsConstexpr : 1; + bool IsConcept : 1; /// \brief Indicates if the function uses __try. bool UsesSEHTry : 1; @@ -1847,6 +1848,10 @@ bool isConstexpr() const { return IsConstexpr; } void setConstexpr(bool IC) { IsConstexpr = IC; } + /// Whether this is a (C++ Concepts TS) function concept. + bool isConcept() const { return IsConcept; } + void setConcept(bool IC) { IsConcept = IC; } + /// \brief Indicates the function uses __try. bool usesSEHTry() const { return UsesSEHTry; } void setUsesSEHTry(bool UST) { UsesSEHTry = UST; } Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -1990,6 +1990,9 @@ def err_concept_decl_invalid_specifiers : Error< "%select{variable|function}0 concept cannot be declared " "'%select{thread_local|inline|friend|constexpr}1'">; +def err_concept_specified_specialization : Error< + "%'concept' cannot be applied on an " + "%select{explicit instantiation|explicit specialization|partial specialization}0">; // C++11 char16_t/char32_t def warn_cxx98_compat_unicode_type : Warning< Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -5898,6 +5898,17 @@ << 0 << 3; NewVD->setInvalidDecl(true); } + + // C++ Concepts TS [dcl.spec.concept]p1: The concept specifier shall be + // applied only to the definition of a [...] variable template, declared + // in namespace scope. [...] A concept definition refers to [...] a + // variable concept and its initializer. + if (IsVariableTemplateSpecialization) { + Diag(D.getDeclSpec().getConceptSpecLoc(), + diag::err_concept_specified_specialization) + << (IsPartialSpecialization ? 2 : 1); + NewVD->setInvalidDecl(true); + } } } @@ -7544,6 +7555,9 @@ } if (isConcept) { + // This is a function concept. + NewFD->setConcept(true); + // C++ Concepts TS [dcl.spec.concept]p1: The concept specifier shall be // applied only to the definition of a function template [...] if (!D.isFunctionDefinition()) { @@ -7595,6 +7609,15 @@ << 1 << 3; NewFD->setInvalidDecl(true); } + + // C++ Concepts TS [dcl.spec.concept]p1: The concept specifier shall be + // applied only to the definition of a function template [...], declared + // in namespace scope. [...] A concept definition refers to either a + // function concept and its definition [...]. + if (isFunctionTemplateSpecialization) { + Diag(D.getDeclSpec().getConceptSpecLoc(), + diag::err_concept_specified_specialization) << 1; + } } // If __module_private__ was specified, mark the function accordingly. @@ -7858,7 +7881,7 @@ TemplateArgs); HasExplicitTemplateArgs = true; - + if (NewFD->isInvalidDecl()) { HasExplicitTemplateArgs = false; } else if (FunctionTemplate) { Index: lib/Sema/SemaTemplate.cpp =================================================================== --- lib/Sema/SemaTemplate.cpp +++ lib/Sema/SemaTemplate.cpp @@ -7597,6 +7597,17 @@ Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_explicit_instantiation_constexpr); + // C++ Concepts TS [dcl.spec.concept]p1: The concept specifier shall be + // applied only to the definition of a function template or variable template, + // declared in namespace scope. A concept definition refers to either a + // function concept and its definition or a variable concept and its + // initializer. + if (D.getDeclSpec().isConceptSpecified()) { + Diag(D.getDeclSpec().getConceptSpecLoc(), + diag:: err_concept_specified_specialization) << 0; + return true; + } + // C++0x [temp.explicit]p2: // There are two forms of explicit instantiation: an explicit instantiation // definition and an explicit instantiation declaration. An explicit Index: test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p1.cpp =================================================================== --- test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p1.cpp +++ test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p1.cpp @@ -39,3 +39,20 @@ template concept union TCU1 {}; // expected-error {{'concept' can only appear on the definition of a function template or variable template}} concept bool; // expected-error {{'concept' can only appear on the definition of a function template or variable template}} + +template concept bool VCEI { true }; +template concept bool VCEI; // expected-error {{'concept' cannot be applied on an explicit instantiation}} +extern template concept bool VCEI; // expected-error {{'concept' cannot be applied on an explicit instantiation}} + +template concept bool VCPS { true }; +template concept bool VCPS { true }; // expected-error {{'concept' cannot be applied on an partial specialization}} + +template concept bool VCES { true }; +template<> concept bool VCES { true }; // expected-error {{'concept' cannot be applied on an explicit specialization}} + +template concept bool FCEI() { return true; } +template concept bool FCEI(); // expected-error {{'concept' cannot be applied on an explicit instantiation}} +extern template concept bool FCEI(); // expected-error {{'concept' cannot be applied on an explicit instantiation}} + +template concept bool FCES() { return true; } +template<> concept bool FCES() { return true; } // expected-error {{'concept' cannot be applied on an explicit specialization}}