[prev in list] [next in list] [prev in thread] [next in thread] 

List:       cfe-commits
Subject:    [PATCH] D11027: [CONCEPTS] Creating Diagnostics for ill-formed function concept declaration
From:       Nathan Wilson <nwilson20 () gmail ! com>
Date:       2015-07-08 5:17:45
Message-ID: differential-rev-PHID-DREV-ntzh4d6jyb2xwgbfafhj-req () reviews ! llvm ! org
[Download RAW message or body]

nwilson added reviewers: rsmith, hubert.reinterpretcast, faisalv, fraggamuffin.
nwilson added a subscriber: cfe-commits.

Create Diagnostic for function concept which doesn't have a definition
Create Diagnostic for function concept which isn't in namespace scope
Create associated tests

http://reviews.llvm.org/D11027

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaDecl.cpp
  test/SemaCXX/cxx-concept-declaration.cpp

Index: test/SemaCXX/cxx-concept-declaration.cpp
===================================================================
--- /dev/null
+++ test/SemaCXX/cxx-concept-declaration.cpp
@@ -0,0 +1,11 @@
+// RUN:  %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
+
+template<typename T> concept bool C1 = true;
+
+template<typename T> concept decltype(!0) C2 = true;
+
+template<typename T> concept bool D1(); // expected-error {{function concept \
requires definition}} +
+struct A {
+  template<typename T> concept bool D1() { return true; } // expected-error \
{{concept declaration required to be in namespace scope}} +};
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -7223,6 +7223,7 @@
     bool isVirtual = D.getDeclSpec().isVirtualSpecified();
     bool isExplicit = D.getDeclSpec().isExplicitSpecified();
     bool isConstexpr = D.getDeclSpec().isConstexprSpecified();
+    bool isConcept = D.getDeclSpec().isConceptSpecified();
     isFriend = D.getDeclSpec().isFriendSpecified();
     if (isFriend && !isInline && D.isFunctionDefinition()) {
       // C++ [class.friend]p5
@@ -7439,6 +7440,28 @@
         Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_constexpr_dtor);
     }
 
+    if (isConcept) {
+      // 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
+      if (!NewFD->getParent()->getRedeclContext()->isFileContext()) {
+        Diag(D.getIdentifierLoc(), diag::err_invalid_concept_scope);
+        NewFD->setInvalidDecl();
+      }
+
+      // C++ Concepts TS [dcl.spec.concept]p1: A concept definition refers to a
+      // function concept and its definition
+      if (!D.isFunctionDefinition()) {
+        Diag(D.getDeclSpec().getConceptSpecLoc(),
+             diag::err_function_concept_not_defined);
+        NewFD->setInvalidDecl();
+      }
+
+      // C++ Concepts TS [dcl.spec.concept]p2: Every concepts definition is
+      // implicity defined to be a constexpr declaration (implicitly inline)
+      NewFD->setImplicitlyInline();
+    }
+
     // If __module_private__ was specified, mark the function accordingly.
     if (D.getDeclSpec().isModulePrivateSpecified()) {
       if (isFunctionTemplateSpecialization) {
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -1959,6 +1959,12 @@
 def note_private_extern : Note<
   "use __attribute__((visibility(\"hidden\"))) attribute instead">;
 
+// C++ Concepts TS
+def err_invalid_concept_scope : Error<
+  "concept declaration required to be in namespace scope">;
+def err_function_concept_not_defined : Error<
+  "function concept requires definition">;
+
 // C++11 char16_t/char32_t
 def warn_cxx98_compat_unicode_type : Warning<
   "'%0' type specifier is incompatible with C++98">,


["D11027.29241.patch" (text/x-patch)]

Index: test/SemaCXX/cxx-concept-declaration.cpp
===================================================================
--- /dev/null
+++ test/SemaCXX/cxx-concept-declaration.cpp
@@ -0,0 +1,11 @@
+// RUN:  %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
+
+template<typename T> concept bool C1 = true;
+
+template<typename T> concept decltype(!0) C2 = true;
+
+template<typename T> concept bool D1(); // expected-error {{function concept \
requires definition}} +
+struct A {
+  template<typename T> concept bool D1() { return true; } // expected-error \
{{concept declaration required to be in namespace scope}} +};
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -7223,6 +7223,7 @@
     bool isVirtual = D.getDeclSpec().isVirtualSpecified();
     bool isExplicit = D.getDeclSpec().isExplicitSpecified();
     bool isConstexpr = D.getDeclSpec().isConstexprSpecified();
+    bool isConcept = D.getDeclSpec().isConceptSpecified();
     isFriend = D.getDeclSpec().isFriendSpecified();
     if (isFriend && !isInline && D.isFunctionDefinition()) {
       // C++ [class.friend]p5
@@ -7439,6 +7440,28 @@
         Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_constexpr_dtor);
     }
 
+    if (isConcept) {
+      // 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
+      if (!NewFD->getParent()->getRedeclContext()->isFileContext()) {
+        Diag(D.getIdentifierLoc(), diag::err_invalid_concept_scope);
+        NewFD->setInvalidDecl();
+      }
+
+      // C++ Concepts TS [dcl.spec.concept]p1: A concept definition refers to a
+      // function concept and its definition
+      if (!D.isFunctionDefinition()) {
+        Diag(D.getDeclSpec().getConceptSpecLoc(),
+             diag::err_function_concept_not_defined);
+        NewFD->setInvalidDecl();
+      }
+
+      // C++ Concepts TS [dcl.spec.concept]p2: Every concepts definition is
+      // implicity defined to be a constexpr declaration (implicitly inline)
+      NewFD->setImplicitlyInline();
+    }
+
     // If __module_private__ was specified, mark the function accordingly.
     if (D.getDeclSpec().isModulePrivateSpecified()) {
       if (isFunctionTemplateSpecialization) {
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -1959,6 +1959,12 @@
 def note_private_extern : Note<
   "use __attribute__((visibility(\"hidden\"))) attribute instead">;
 
+// C++ Concepts TS
+def err_invalid_concept_scope : Error<
+  "concept declaration required to be in namespace scope">;
+def err_function_concept_not_defined : Error<
+  "function concept requires definition">;
+
 // C++11 char16_t/char32_t
 def warn_cxx98_compat_unicode_type : Warning<
   "'%0' type specifier is incompatible with C++98">,



_______________________________________________
cfe-commits mailing list
cfe-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic