From: Nathan Sidwell Date: Fri, 11 Sep 2020 20:42:59 +0000 (-0700) Subject: c++: Concepts and local externs X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f76b0f231b3785bbf49c97173692371f769e4573;p=gcc.git c++: Concepts and local externs 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. --- diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 8922ef54d74..ad2a30fcf71 100644 --- a/gcc/cp/decl.c +++ b/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 a/gcc/testsuite/g++.dg/concepts/local-extern.C b/gcc/testsuite/g++.dg/concepts/local-extern.C new file mode 100644 index 00000000000..69ecc2361c0 --- /dev/null +++ b/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 + concept input_or_output_iterator + = requires(_Iter __i) { { *__i } ; }; + + + template + 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 concept C = true; + +template +void F () +{ + void bad () requires C; // { dg-error "a non-templated function" } + +}