aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2020-09-11 13:42:59 -0700
committerNathan Sidwell <nathan@acm.org>2020-09-11 13:55:45 -0700
commitf76b0f231b3785bbf49c97173692371f769e4573 (patch)
tree20ab01a07101e6130a2ad0680347feea9db02ef4 /gcc
parent2fda9e9badbd78d1033075a44a7d6c1b33de239c (diff)
downloadgcc-f76b0f231b3785bbf49c97173692371f769e4573.zip
gcc-f76b0f231b3785bbf49c97173692371f769e4573.tar.gz
gcc-f76b0f231b3785bbf49c97173692371f769e4573.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/decl.c13
-rw-r--r--gcc/testsuite/g++.dg/concepts/local-extern.C39
2 files changed, 48 insertions, 4 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 8922ef5..ad2a30f 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 0000000..69ecc23
--- /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<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" }
+
+}