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.
This commit is contained in:
parent
2fda9e9bad
commit
f76b0f231b
@ -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;
|
||||
|
39
gcc/testsuite/g++.dg/concepts/local-extern.C
Normal file
39
gcc/testsuite/g++.dg/concepts/local-extern.C
Normal file
@ -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" }
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user