Index: include/clang/AST/Decl.h =================================================================== --- include/clang/AST/Decl.h +++ include/clang/AST/Decl.h @@ -815,6 +815,9 @@ /// \brief Whether this variable is (C++0x) constexpr. unsigned IsConstexpr : 1; + /// \brief Whether this variable is (C++ Concepts TS) concept. + unsigned IsConcept : 1; + /// \brief Whether this variable is the implicit variable for a lambda /// init-capture. unsigned IsInitCapture : 1; @@ -1238,6 +1241,15 @@ NonParmVarDeclBits.IsConstexpr = IC; } + /// Whether this variable is (C++ Concepts TS) concept. + bool isConcept() const { + return isa(this) ? false : NonParmVarDeclBits.IsConcept; + } + void setConcept(bool IC) { + assert(!isa(this)); + NonParmVarDeclBits.IsConcept = IC; + } + /// Whether this variable is the implicit variable for a lambda init-capture. bool isInitCapture() const { return isa(this) ? false : NonParmVarDeclBits.IsInitCapture; Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -1970,6 +1970,8 @@ "concept declarations may only appear in namespace scope">; def err_function_concept_not_defined : Error< "function concept declaration must be a definition">; +def err_var_concept_not_initialized : Error< + "variable concept declaration must be initialized">; // 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 @@ -5849,6 +5849,9 @@ if (D.getDeclSpec().isConstexprSpecified()) NewVD->setConstexpr(true); + + if (D.getDeclSpec().isConceptSpecified()) + NewVD->setConcept(true); } // Set the lexical context. If the declarator has a C++ scope specifier, the @@ -9407,6 +9410,15 @@ return; } + // C++ Concepts TS [dcl.spec.concept]p1: [...] A variable template + // definition having the concept specifier is called a variable concept. A + // concept definition refers to [...] a variable concept and its initializer. + if (Var->isConcept()) { + Diag(Var->getLocation(), diag::err_var_concept_not_initialized); + Var->setInvalidDecl(); + return; + } + // OpenCL v1.1 s6.5.3: variables declared in the constant address space must // be initialized. if (!Var->isInvalidDecl() && Index: test/SemaCXX/cxx-concept-declaration.cpp =================================================================== --- test/SemaCXX/cxx-concept-declaration.cpp +++ test/SemaCXX/cxx-concept-declaration.cpp @@ -15,3 +15,6 @@ struct C { template static concept bool D3 = true; // expected-error {{concept declarations may only appear in namespace scope}} }; + +template +concept bool D6; // expected-error {{variable concept declaration must be initialized}}