* [C++ PATCH RFC] PR c++/80265 - constexpr __builtin_mem*.
@ 2020-01-11 5:13 Jason Merrill
2020-01-13 11:37 ` Jonathan Wakely
0 siblings, 1 reply; 5+ messages in thread
From: Jason Merrill @ 2020-01-11 5:13 UTC (permalink / raw)
To: gcc-patches; +Cc: jwakely
The library has already worked around this issue, but I was curious about
why it wasn't working. The answer: because we were passing &var to fold,
which doesn't know about the constexpr values hash table. Fixed by passing
&"str" instead.
Tested x86_64-pc-linux-gnu. Does this seem useful even though it isn't
necessary anymore?
* constexpr.c (cxx_eval_builtin_function_call): Expose STRING_CST
to str/mem builtins.
---
gcc/cp/constexpr.c | 70 +++++++++++++++++--
gcc/testsuite/g++.dg/ext/constexpr-builtin1.C | 37 ++++++++++
2 files changed, 102 insertions(+), 5 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/ext/constexpr-builtin1.C
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 3ca3b9ecd65..3a9fb566a52 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1260,28 +1260,76 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
if (fndecl_built_in_p (fun, CP_BUILT_IN_SOURCE_LOCATION, BUILT_IN_FRONTEND))
return fold_builtin_source_location (EXPR_LOCATION (t));
+ int strops = 0;
+ int strret = 0;
+ if (fndecl_built_in_p (fun, BUILT_IN_NORMAL))
+ switch (DECL_FUNCTION_CODE (fun))
+ {
+ case BUILT_IN_STRLEN:
+ case BUILT_IN_STRNLEN:
+ strops = 1;
+ break;
+ case BUILT_IN_MEMCHR:
+ case BUILT_IN_STRCHR:
+ case BUILT_IN_STRRCHR:
+ strops = 1;
+ strret = 1;
+ break;
+ case BUILT_IN_MEMCMP:
+ case BUILT_IN_STRCMP:
+ strops = 2;
+ break;
+ case BUILT_IN_STRSTR:
+ strops = 2;
+ strret = 1;
+ default:
+ break;
+ }
+
/* Be permissive for arguments to built-ins; __builtin_constant_p should
return constant false for a non-constant argument. */
constexpr_ctx new_ctx = *ctx;
new_ctx.quiet = true;
for (i = 0; i < nargs; ++i)
{
- args[i] = CALL_EXPR_ARG (t, i);
+ tree arg = CALL_EXPR_ARG (t, i);
+
+ /* To handle string built-ins we need to pass ADDR_EXPR<STRING_CST> since
+ expand_builtin doesn't know how to look in the values table. */
+ bool strop = i < strops;
+ if (strop)
+ {
+ STRIP_NOPS (arg);
+ if (TREE_CODE (arg) == ADDR_EXPR)
+ arg = TREE_OPERAND (arg, 0);
+ else
+ strop = false;
+ }
+
/* If builtin_valid_in_constant_expr_p is true,
potential_constant_expression_1 has not recursed into the arguments
of the builtin, verify it here. */
if (!builtin_valid_in_constant_expr_p (fun)
- || potential_constant_expression (args[i]))
+ || potential_constant_expression (arg))
{
bool dummy1 = false, dummy2 = false;
- args[i] = cxx_eval_constant_expression (&new_ctx, args[i], false,
- &dummy1, &dummy2);
+ arg = cxx_eval_constant_expression (&new_ctx, arg, false,
+ &dummy1, &dummy2);
}
if (bi_const_p)
/* For __builtin_constant_p, fold all expressions with constant values
even if they aren't C++ constant-expressions. */
- args[i] = cp_fold_rvalue (args[i]);
+ arg = cp_fold_rvalue (arg);
+ else if (strop)
+ {
+ if (TREE_CODE (arg) == CONSTRUCTOR)
+ arg = braced_lists_to_strings (TREE_TYPE (arg), arg);
+ if (TREE_CODE (arg) == STRING_CST)
+ arg = build_address (arg);
+ }
+
+ args[i] = arg;
}
bool save_ffbcp = force_folding_builtin_constant_p;
@@ -1325,6 +1373,18 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
return t;
}
+ if (strret)
+ {
+ /* memchr returns a pointer into the first argument, but we replaced the
+ argument above with a STRING_CST; put it back it now. */
+ tree op = CALL_EXPR_ARG (t, strret-1);
+ STRIP_NOPS (new_call);
+ if (TREE_CODE (new_call) == POINTER_PLUS_EXPR)
+ TREE_OPERAND (new_call, 0) = op;
+ else if (TREE_CODE (new_call) == ADDR_EXPR)
+ new_call = op;
+ }
+
return cxx_eval_constant_expression (&new_ctx, new_call, lval,
non_constant_p, overflow_p);
}
diff --git a/gcc/testsuite/g++.dg/ext/constexpr-builtin1.C b/gcc/testsuite/g++.dg/ext/constexpr-builtin1.C
new file mode 100644
index 00000000000..2d0904b6e08
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/constexpr-builtin1.C
@@ -0,0 +1,37 @@
+// PR c++/80265
+// { dg-do compile { target c++14 } }
+
+constexpr bool compare() {
+ char s1[] = "foo";
+ char s2[] = "fxo";
+ if (!__builtin_memcmp(s1, s2, 3))
+ return false;
+ s2[1] = 'o';
+ if (__builtin_memcmp(s1, s2, 3))
+ return false;
+ if (__builtin_strcmp(s1, s2))
+ return false;
+ return true;
+}
+
+constexpr bool length() {
+ char s[] = "foo";
+ if (__builtin_strlen(s) != 3)
+ return false;
+ return true;
+}
+
+constexpr bool find() {
+ char s[] = "foo";
+ if (__builtin_memchr(s, 'f', 3) != s)
+ return false;
+ if (__builtin_strchr(s, 'o') != s+1)
+ return false;
+ if (__builtin_strstr(s, "oo") != s+1)
+ return false;
+ return true;
+}
+
+static_assert( compare(), "" );
+static_assert( length(), "" );
+static_assert( find(), "" );
base-commit: d3cf980217ce13b1eda01d4c42a7e3afd2bf3217
--
2.18.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [C++ PATCH RFC] PR c++/80265 - constexpr __builtin_mem*.
2020-01-11 5:13 [C++ PATCH RFC] PR c++/80265 - constexpr __builtin_mem* Jason Merrill
@ 2020-01-13 11:37 ` Jonathan Wakely
2020-01-13 18:12 ` Jason Merrill
0 siblings, 1 reply; 5+ messages in thread
From: Jonathan Wakely @ 2020-01-13 11:37 UTC (permalink / raw)
To: Jason Merrill; +Cc: gcc-patches
On 11/01/20 00:03 -0500, Jason Merrill wrote:
>The library has already worked around this issue, but I was curious about
>why it wasn't working. The answer: because we were passing &var to fold,
>which doesn't know about the constexpr values hash table. Fixed by passing
>&"str" instead.
>
>Tested x86_64-pc-linux-gnu. Does this seem useful even though it isn't
>necessary anymore?
I'd still like to be able to use memcpy and memmove in constexpr
evaluation. We've added our own "std::__memmove" for use at compile
time, but it doesn't really have the same semantics. We could fix
that, but it would be better to just use the real thing.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [C++ PATCH RFC] PR c++/80265 - constexpr __builtin_mem*.
2020-01-13 11:37 ` Jonathan Wakely
@ 2020-01-13 18:12 ` Jason Merrill
2020-01-13 20:25 ` Jonathan Wakely
0 siblings, 1 reply; 5+ messages in thread
From: Jason Merrill @ 2020-01-13 18:12 UTC (permalink / raw)
To: Jonathan Wakely; +Cc: gcc-patches List
On Mon, Jan 13, 2020 at 6:11 AM Jonathan Wakely <jwakely@redhat.com> wrote:
> On 11/01/20 00:03 -0500, Jason Merrill wrote:
> >The library has already worked around this issue, but I was curious about
> >why it wasn't working. The answer: because we were passing &var to fold,
> >which doesn't know about the constexpr values hash table. Fixed by
> passing
> >&"str" instead.
> >
> >Tested x86_64-pc-linux-gnu. Does this seem useful even though it isn't
> >necessary anymore?
>
> I'd still like to be able to use memcpy and memmove in constexpr
> evaluation. We've added our own "std::__memmove" for use at compile
> time, but it doesn't really have the same semantics. We could fix
> that, but it would be better to just use the real thing.
>
Ah, supporting memcpy/memmove would be more work than the cmp/chr
functions, I'd have to reimplement them entirely in constexpr.c.
Jason
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [C++ PATCH RFC] PR c++/80265 - constexpr __builtin_mem*.
2020-01-13 18:12 ` Jason Merrill
@ 2020-01-13 20:25 ` Jonathan Wakely
2020-01-13 20:27 ` Jakub Jelinek
0 siblings, 1 reply; 5+ messages in thread
From: Jonathan Wakely @ 2020-01-13 20:25 UTC (permalink / raw)
To: Jason Merrill; +Cc: gcc-patches List
On 13/01/20 12:53 -0500, Jason Merrill wrote:
>On Mon, Jan 13, 2020 at 6:11 AM Jonathan Wakely <jwakely@redhat.com> wrote:
>
>> On 11/01/20 00:03 -0500, Jason Merrill wrote:
>> >The library has already worked around this issue, but I was curious about
>> >why it wasn't working. The answer: because we were passing &var to fold,
>> >which doesn't know about the constexpr values hash table. Fixed by
>> passing
>> >&"str" instead.
>> >
>> >Tested x86_64-pc-linux-gnu. Does this seem useful even though it isn't
>> >necessary anymore?
>>
>> I'd still like to be able to use memcpy and memmove in constexpr
>> evaluation. We've added our own "std::__memmove" for use at compile
>> time, but it doesn't really have the same semantics. We could fix
>> that, but it would be better to just use the real thing.
>>
>
>Ah, supporting memcpy/memmove would be more work than the cmp/chr
>functions, I'd have to reimplement them entirely in constexpr.c.
Ah, OK, nevermind then. We'll reimplement just what we need in the
library.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [C++ PATCH RFC] PR c++/80265 - constexpr __builtin_mem*.
2020-01-13 20:25 ` Jonathan Wakely
@ 2020-01-13 20:27 ` Jakub Jelinek
0 siblings, 0 replies; 5+ messages in thread
From: Jakub Jelinek @ 2020-01-13 20:27 UTC (permalink / raw)
To: Jonathan Wakely; +Cc: Jason Merrill, gcc-patches List
On Mon, Jan 13, 2020 at 06:38:23PM +0000, Jonathan Wakely wrote:
> > > On 11/01/20 00:03 -0500, Jason Merrill wrote:
> > > >The library has already worked around this issue, but I was curious about
> > > >why it wasn't working. The answer: because we were passing &var to fold,
> > > >which doesn't know about the constexpr values hash table. Fixed by
> > > passing
> > > >&"str" instead.
> > > >
> > > >Tested x86_64-pc-linux-gnu. Does this seem useful even though it isn't
> > > >necessary anymore?
> > >
> > > I'd still like to be able to use memcpy and memmove in constexpr
> > > evaluation. We've added our own "std::__memmove" for use at compile
> > > time, but it doesn't really have the same semantics. We could fix
> > > that, but it would be better to just use the real thing.
> > >
> >
> > Ah, supporting memcpy/memmove would be more work than the cmp/chr
> > functions, I'd have to reimplement them entirely in constexpr.c.
>
> Ah, OK, nevermind then. We'll reimplement just what we need in the
> library.
Guess the hardest part is write helper functions that reads or stores a
single byte at specific address, the builtins then could be easily
implemented by just calling those in a way simplest C implementation of
those functions would do. But if we have those, we could handle easily many
of the str/mem* functions that way.
Jakub
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2020-01-13 18:43 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-11 5:13 [C++ PATCH RFC] PR c++/80265 - constexpr __builtin_mem* Jason Merrill
2020-01-13 11:37 ` Jonathan Wakely
2020-01-13 18:12 ` Jason Merrill
2020-01-13 20:25 ` Jonathan Wakely
2020-01-13 20:27 ` Jakub Jelinek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).