[Bug c++/70248] constexpr initialization with unspecified equality expression accepted

2024-01-03 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70248

--- Comment #13 from Jonathan Wakely  ---
Although this is accepted even though it's in a template, so it's more
complicated than just template vs non-template:

template
consteval void f( char const* p )
{
  char buf[N]{};

  if (p == buf) // unspecified
return;

  for (int i = 0; i < 5; ++i)
buf[i] = p[i];
}

int main()
{
  f("test");
}

[Bug c++/70248] constexpr initialization with unspecified equality expression accepted

2024-01-03 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70248

--- Comment #12 from Jonathan Wakely  ---
If the comparison happens in a template, GCC rejects it (see PR 113200).

[Bug c++/70248] constexpr initialization with unspecified equality expression accepted

2024-01-03 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70248

Jonathan Wakely  changed:

   What|Removed |Added

   Last reconfirmed|2020-10-15 00:00:00 |2024-1-3

--- Comment #11 from Jonathan Wakely  ---
And another:

struct S
{
char data_[ 5 ];

constexpr S( char const* p ) : data_()
{
  if (p == data_)
return;

  for (int i = 0; i < 5; ++i)
data_[i] = p[i];
}
};

constexpr S s( "test" );

[Bug c++/70248] constexpr initialization with unspecified equality expression accepted

2023-08-22 Thread pkeir at outlook dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70248

Paul Keir  changed:

   What|Removed |Added

 CC||pkeir at outlook dot com

--- Comment #10 from Paul Keir  ---
Here is another example which GCC accepts, but Clang correctly rejects:

constexpr bool test()
{
  int arr[2]{};
  void *p1 = [0];
  void *p2 = [1];

  return p1 < p2;
}

constexpr bool b = test();

[Bug c++/70248] constexpr initialization with unspecified equality expression accepted

2020-10-15 Thread mpolacek at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70248

--- Comment #9 from Marek Polacek  ---
*** Bug 85474 has been marked as a duplicate of this bug. ***

[Bug c++/70248] constexpr initialization with unspecified equality expression accepted

2020-10-15 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70248

--- Comment #8 from Jonathan Wakely  ---
In gcc/cp/typeck.c:cp_build_binary_op this warning should be an error during
constant evaluation for EQ_EXPR and NE_EXPR:

  if (complain & tf_warning)
{
  tree stripped_orig_op0 = tree_strip_any_location_wrapper (orig_op0);
  tree stripped_orig_op1 = tree_strip_any_location_wrapper (orig_op1);
  if ((TREE_CODE (stripped_orig_op0) == STRING_CST
   && !integer_zerop (cp_fully_fold (op1)))
  || (TREE_CODE (stripped_orig_op1) == STRING_CST
  && !integer_zerop (cp_fully_fold (op0
warning_at (location, OPT_Waddress,
"comparison with string literal results in "
"unspecified behavior");
}

And this one for rel ops and spaceships:

  if (TREE_CODE (orig_op0) == STRING_CST
  || TREE_CODE (orig_op1) == STRING_CST)
{
  if (complain & tf_warning)
warning_at (location, OPT_Waddress,
"comparison with string literal results "
"in unspecified behavior");
}

That only handles the string literals cases though, we also need to reject
pointers to distinct objects at the same places.

[Bug c++/70248] constexpr initialization with unspecified equality expression accepted

2020-10-15 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70248

Jonathan Wakely  changed:

   What|Removed |Added

   Last reconfirmed||2020-10-15
   Severity|minor   |normal
 Ever confirmed|0   |1
 Status|UNCONFIRMED |NEW

--- Comment #7 from Jonathan Wakely  ---
Another example with a relational operator:

constexpr const char* s = "";
constexpr const char* n = nullptr;
constexpr bool b = s > n;

The result of the comparison is unspecified because the pointers are not equal
and don't point to subobjects of the same object.

Clang, EDG and MSVC all reject it as expected.

[Bug c++/70248] constexpr initialization with unspecified equality expression accepted

2018-04-17 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70248

Martin Sebor  changed:

   What|Removed |Added

   See Also||https://gcc.gnu.org/bugzill
   ||a/show_bug.cgi?id=85437

--- Comment #6 from Martin Sebor  ---
I raised bug 85437 for the regression.

[Bug c++/70248] constexpr initialization with unspecified equality expression accepted

2018-04-17 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70248

Jakub Jelinek  changed:

   What|Removed |Added

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

--- Comment #5 from Jakub Jelinek  ---
That started with r249088.

[Bug c++/70248] constexpr initialization with unspecified equality expression accepted

2018-04-17 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70248

--- Comment #4 from Martin Sebor  ---
Rejecting the test case because of the initialization is a regression.  The
cast is not a reinterpret cast.  GCC gives the same error with a static cast
too:

$ gcc -S -Wall pr70248.C 
pr70248.C:4:24: error: a reinterpret_cast is not a constant expression
 constexpr int A::*bx = static_cast(::x);
^
pr70248.C:5:24: error: a reinterpret_cast is not a constant expression
 constexpr int A::*cx = static_cast(::x);
^

[Bug c++/70248] constexpr initialization with unspecified equality expression accepted

2018-04-17 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70248

--- Comment #3 from Jonathan Wakely  ---
GCC trunk (8.0.1 20180410) now rejects comment 0 with:

c0.cc:4:24: error: a reinterpret_cast is not a constant expression
 constexpr int A::*bx = (int(A::*))::x;
^
c0.cc:5:24: error: a reinterpret_cast is not a constant expression
 constexpr int A::*cx = (int(A::*))::x;
^

[Bug c++/70248] constexpr initialization with unspecified equality expression accepted

2016-05-12 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70248

Martin Sebor  changed:

   What|Removed |Added

  Known to fail|6.0 |6.1.0

--- Comment #2 from Martin Sebor  ---
Below is another example, one that even elicits a warning where GCC points out
the unspecified behavior:

$ cat xx.cpp && gcc -S -Wall -Wextra -Wpedantic -o/dev/null xx.cpp
constexpr int b = "" == "";
xx.cpp:1:25: warning: comparison with string literal results in unspecified
behavior [-Waddress]
 constexpr int b = "" == "";
 ^~

[Bug c++/70248] constexpr initialization with unspecified equality expression accepted

2016-03-31 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70248

--- Comment #1 from Martin Sebor  ---
Below is a test case (derived from a test discussed in the context of another
bug: https://gcc.gnu.org/ml/gcc-patches/2016-03/msg01644.html) for another
example of a constexpr function whose use in a constexpr context is invalid due
to its return value relying on unspecified effects, this time the result of the
relational expression involving null pointers.

The test case shows two problems: first, that the invalid initialization of the
constexpr variables a0 and b1 is accepted, and second, an error on the use of
SFINAE to select one of the two overloads of the function template f (see also
bug 70380 for a similar SFINAE example that's not handled correctly, though for
a different reason).

The main point of the example is to demonstrate the first problem, but fixing
it should take into consideration the SFINAE case.

$ cat v.c && /build/gcc-trunk-bootstrap/gcc/xgcc -B
/build/gcc-trunk-bootstrap/gcc -S -Wall -Wextra -Wpedantic -xc++ v.c
constexpr int *p = 0;
constexpr int *q = 0;

struct A {
  constexpr A (bool b) : m (b ? 1 : p < q) { }
  constexpr int foo () const { return m; }
  int m;
};

struct B {
  constexpr B (bool b) : m (b ? p < q : 1) { }
  constexpr int bar () const { return m; }
  int m;
};

constexpr int a0 = A (false).foo ();   // invalid, accepted
constexpr int a1 = A (true).foo ();// valid, accepted
constexpr int b0 = B (false).bar ();   // valid, accepted
constexpr int b1 = B (true).bar ();// invalid, accepted

template 
int f (int (*)[A (X).foo ()] = 0) { return !X; }

template 
int f (int (*)[B (X).bar ()] = 0) { return X; }

constexpr int f0 = f<0>();// valid, rejected
constexpr int f1 = f<1>();// valid, rejected
v.c:27:24: error: call to non-constexpr function ‘int f(int
(*)[(B)(X).B::bar()]) [with bool X = false]’
 constexpr int f0 = f<0>();// valid, rejected
^~
v.c:28:24: error: call to non-constexpr function ‘int f(int
(*)[(A)(X).A::foo()]) [with bool X = true]’
 constexpr int f1 = f<1>();// valid, rejected
^~