diff mbox series

c++: Concepts and local externs

Message ID 8ff3d8d9-29b3-7494-f367-7197aa352a16@acm.org
State New
Headers show
Series c++: Concepts and local externs | expand

Commit Message

Nathan Sidwell Sept. 11, 2020, 8:54 p.m. UTC
I discovered that we'd accept constraints on block-scope function
decls inside templates.  This fixes that.

         gcc/cp/
         * decl.c (grokfndecl): Don't attach to local extern.
         gcc/testsuite/
         * concepts/local-extern.C: New.

pushed to trunk

nathan
diff mbox series

Patch

diff --git c/gcc/cp/decl.c w/gcc/cp/decl.c
index 8922ef54d74..ad2a30fcf71 100644
--- c/gcc/cp/decl.c
+++ w/gcc/cp/decl.c
@@ -9457,7 +9457,10 @@  grokfndecl (tree ctype,
     {
       tree tmpl_reqs = NULL_TREE;
       tree ctx = friendp ? current_class_type : ctype;
-      bool memtmpl = (processing_template_decl > template_class_depth (ctx));
+      bool block_local = TREE_CODE (current_scope ()) == FUNCTION_DECL;
+      bool memtmpl = (!block_local
+		      && (processing_template_decl
+			  > template_class_depth (ctx)));
       if (memtmpl)
         tmpl_reqs = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms);
       tree ci = build_constraints (tmpl_reqs, decl_reqs);
@@ -9467,9 +9470,11 @@  grokfndecl (tree ctype,
           ci = NULL_TREE;
         }
       /* C++20 CA378: Remove non-templated constrained functions.  */
-      if (ci && !flag_concepts_ts
-	  && (!processing_template_decl
-	      || (friendp && !memtmpl && !funcdef_flag)))
+      if (ci
+	  && (block_local
+	      || (!flag_concepts_ts
+		  && (!processing_template_decl
+		      || (friendp && !memtmpl && !funcdef_flag)))))
 	{
 	  error_at (location, "constraints on a non-templated function");
 	  ci = NULL_TREE;
diff --git c/gcc/testsuite/g++.dg/concepts/local-extern.C w/gcc/testsuite/g++.dg/concepts/local-extern.C
new file mode 100644
index 00000000000..69ecc2361c0
--- /dev/null
+++ w/gcc/testsuite/g++.dg/concepts/local-extern.C
@@ -0,0 +1,39 @@ 
+// { dg-do compile { target c++17 } }
+// { dg-additional-options -fconcepts }
+
+// Don't attach constraints to block-scope fn-decls and ICE
+
+template<typename _Iter>
+    concept input_or_output_iterator
+      = requires(_Iter __i) { { *__i } ; };
+
+
+  template<input_or_output_iterator _It>
+  class common_iterator
+  {
+
+  public:
+    
+void
+      frob ()
+    {
+      if (__builtin_is_constant_evaluated())
+	{
+	  void __failed_assertion(); // ICEd
+	  if (!bool(_M_index == 0)) __failed_assertion();
+	}
+
+    }
+
+  private:
+    unsigned char _M_index;
+  };
+
+template <typename T> concept C = true;
+
+template<typename T>
+void F ()
+{
+  void bad () requires C<T>; // { dg-error "a non-templated function" }
+  
+}