[Bug c++/86369] constexpr const char* comparison fails

2022-11-04 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86369

--- Comment #11 from Aaron Ballman  ---
(In reply to Jakub Jelinek from comment #10)
> (In reply to Aaron Ballman from comment #9)
> > Doesn't [expr.eq] make it unspecified though?
> 
> Will defer that answer to Jason.
> But please have a look at the comment 6 testcase.  I strongly hope that
> constexpr const char *p = "abc";
> constexpr const char *q = p;
> static_assert (p == q, "");
> doesn't actually mean the string literal is evaluated multiple times, because
> if it would be, then one pretty much can't use string literals for anything
> reliably.

Oh yeah, I agree with you in that case. I was talking about the summary example
with function calls returning a string literal. Sorry for not being more clear!

> I bet the wording in there is for the
> constexpr const char *r = "abc";
> constexpr const char *s = "abc";
> case, where the standard doesn't force implementations to unify same string
> literals within the same TU but allows it (and also allows say tail merging
> of them).  From what I can see in the LLVM constant expression evaluation
> behavior, it doesn't track what comes from which evaluation of a string
> literal (GCC doesn't track that either) and just assumes that it could be
> different evaluation, while GCC assumes it is not.

Yeah, that sounds plausible.

[Bug c++/86369] constexpr const char* comparison fails

2022-11-04 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86369

--- Comment #10 from Jakub Jelinek  ---
(In reply to Aaron Ballman from comment #9)
> Doesn't [expr.eq] make it unspecified though?

Will defer that answer to Jason.
But please have a look at the comment 6 testcase.  I strongly hope that
constexpr const char *p = "abc";
constexpr const char *q = p;
static_assert (p == q, "");
doesn't actually mean the string literal is evaluated multiple times, because
if it would be, then one pretty much can't use string literals for anything
reliably.
I bet the wording in there is for the
constexpr const char *r = "abc";
constexpr const char *s = "abc";
case, where the standard doesn't force implementations to unify same string
literals within the same TU but allows it (and also allows say tail merging of
them).  From what I can see in the LLVM constant expression evaluation
behavior, it doesn't track what comes from which evaluation of a string literal
(GCC doesn't track that either) and just assumes that it could be different
evaluation, while GCC assumes it is not.

[Bug c++/86369] constexpr const char* comparison fails

2022-11-04 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86369

Aaron Ballman  changed:

   What|Removed |Added

 CC||aaron at aaronballman dot com

--- Comment #9 from Aaron Ballman  ---
(In reply to Jason Merrill from comment #8)
> (In reply to Nicolas Lesser from comment #1)
> > For clarity, b1 shouldn't compile.
> > 
> > [lex.string]p16 says: "whether successive evaluations of a string-literal
> > yield the same or a different object is unspecified."
> > 
> > [expr.const]p2 says: "An expression e is a core constant expression unless
> > the evaluation of e, [...], would evaluate one of the following expressions:
> > [...]; a relational or equality operator where the result is unspecified;"
> 
> I think the second quote refers to places in [expr.eq] that say "the result
> is unspecified", not to all instances of unspecified behavior in the
> standard.

Doesn't [expr.eq] make it unspecified though?

[expr.eq]p6 says: "If two operands compare equal, the result is true for the ==
operator and false for the != operator. If two operands compare unequal, the
result is false for the == operator and true for the != operator. Otherwise,
the result of each of the operators is unspecified."

If it is unspecified whether a subsequent string literal evaluation produces
the same object or a different object then it's unspecified whether the two
operands will or won't compare equal, so the result of the operators is also
unspecified.

[Bug c++/86369] constexpr const char* comparison fails

2022-01-18 Thread jason at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86369

Jason Merrill  changed:

   What|Removed |Added

 CC||jason at gcc dot gnu.org

--- Comment #8 from Jason Merrill  ---
(In reply to Nicolas Lesser from comment #1)
> For clarity, b1 shouldn't compile.
> 
> [lex.string]p16 says: "whether successive evaluations of a string-literal
> yield the same or a different object is unspecified."
> 
> [expr.const]p2 says: "An expression e is a core constant expression unless
> the evaluation of e, [...], would evaluate one of the following expressions:
> [...]; a relational or equality operator where the result is unspecified;"

I think the second quote refers to places in [expr.eq] that say "the result is
unspecified", not to all instances of unspecified behavior in the standard.

[Bug c++/86369] constexpr const char* comparison fails

2021-08-06 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86369

--- Comment #7 from Richard Biener  ---
constexpr evaluation shouldn't blindly call fold* if it doesn't expect things
to end up constant that are not or non-constant that are.  fold* is _not_ a
constexpr evaluator in the C++ semantic sense.

So no, match.pd isn't at fault and we shouldn't change it.  Fix the constexpr
code instead.

[Bug c++/86369] constexpr const char* comparison fails

2021-08-05 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86369

--- Comment #6 from Jakub Jelinek  ---
Another possibility would be to detect it in cxx_eval_binary_expression before
calling fold_binary_loc and punt.

But, the constant evaluation actually doesn't track whether it is the same or
different evaluation of the same string literal, so not optimizing it would on
the other side mean we'd reject valid code.  Consider

constexpr auto name3(const char *p) { return p; }

int main() {
constexpr auto p1 = "test3";
constexpr auto p2 = "test4";
constexpr auto b1 = (name3(p1) == name3(p1)); // should be true
constexpr auto b2 = (name3(p1) == name3(p2)); // should be false
}

Note, latest clang++ seems to accept b1 in both #c0 and #c6 testcases and
reject b2 in both.

[Bug c++/86369] constexpr const char* comparison fails

2021-08-05 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86369

Jakub Jelinek  changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org,
   ||rguenth at gcc dot gnu.org

--- Comment #5 from Jakub Jelinek  ---
So, either those match.pd rules should be marked #ifdef GIMPLE only, or perhaps
we should have some flag whether C++ constexpr evaluation is in progress and
allow some foldings if GENERIC only if C++ constexpr evaluation is not in
progress?

[Bug c++/86369] constexpr const char* comparison fails

2021-08-05 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86369

Jonathan Wakely  changed:

   What|Removed |Added

 Ever confirmed|0   |1
   Keywords||accepts-invalid
   Last reconfirmed||2021-08-05
 Status|UNCONFIRMED |NEW
  Known to work|10.1.0  |

--- Comment #4 from Jonathan Wakely  ---
Confirming as accepts-invalid based on comment 1.


GCC started to accept both comparisons with r270845:

re PR tree-optimization/87314 (pointless comparison of malloc result to a
string not eliminated)

2019-05-03  Richard Biener  

PR middle-end/87314
* match.pd (cmp (convert1?@2 addr@0) (convert2? addr@1)):
Handle STRING_CST vs DECL or STRING_CST.

* gcc.dg/pr87314-1.c: New testcase.

[Bug c++/86369] constexpr const char* comparison fails

2021-08-04 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86369

--- Comment #3 from Andrew Pinski  ---
GCC accepts both with GCC 10+.

[Bug c++/86369] constexpr const char* comparison fails

2018-07-02 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86369

--- Comment #2 from Jonathan Wakely  ---
Clang trunk also rejects it for the same reason, icc accepts it.

[Bug c++/86369] constexpr const char* comparison fails

2018-07-02 Thread blitzrakete at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86369

Nicolas Lesser  changed:

   What|Removed |Added

 CC||blitzrakete at gmail dot com

--- Comment #1 from Nicolas Lesser  ---
For clarity, b1 shouldn't compile.

[lex.string]p16 says: "whether successive evaluations of a string-literal yield
the same or a different object is unspecified."

[expr.const]p2 says: "An expression e is a core constant expression unless the
evaluation of e, [...], would evaluate one of the following expressions: [...];
a relational or equality operator where the result is unspecified;"