Message ID | 20240917203037.427316-1-polacek@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: fix constexpr cast from void* diag issue [PR116741] | expand |
On 9/17/24 10:30 PM, Marek Polacek wrote: > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/14? OK. > -- >8 -- > The result of build_fold_indirect_ref can be a COMPONENT_REF in > which case using DECL_SOURCE_LOCATION will crash. Look at its op1 > instead. > > PR c++/116741 > > gcc/cp/ChangeLog: > > * constexpr.cc (cxx_eval_constant_expression) <case CONVERT_EXPR>: If > the result of build_fold_indirect_ref is a COMPONENT_REF, use its op1. > Check DECL_P before calling inform. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp26/constexpr-voidptr4.C: New test. > --- > gcc/cp/constexpr.cc | 7 +++-- > .../g++.dg/cpp26/constexpr-voidptr4.C | 29 +++++++++++++++++++ > 2 files changed, 34 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp26/constexpr-voidptr4.C > > diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc > index c3668b0d7d3..f6fd059be46 100644 > --- a/gcc/cp/constexpr.cc > +++ b/gcc/cp/constexpr.cc > @@ -8201,8 +8201,11 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, > TREE_TYPE (op), TREE_TYPE (TREE_TYPE (sop)), > TREE_TYPE (type)); > tree obj = build_fold_indirect_ref (sop); > - inform (DECL_SOURCE_LOCATION (obj), > - "pointed-to object declared here"); > + if (TREE_CODE (obj) == COMPONENT_REF) > + obj = TREE_OPERAND (obj, 1); > + if (DECL_P (obj)) > + inform (DECL_SOURCE_LOCATION (obj), > + "pointed-to object declared here"); > } > *non_constant_p = true; > return t; > diff --git a/gcc/testsuite/g++.dg/cpp26/constexpr-voidptr4.C b/gcc/testsuite/g++.dg/cpp26/constexpr-voidptr4.C > new file mode 100644 > index 00000000000..53563c928f2 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp26/constexpr-voidptr4.C > @@ -0,0 +1,29 @@ > +// PR c++/116741 > +// { dg-do compile { target c++26 } } > + > +struct S { > + int foo; // { dg-message "pointed-to object" } > +}; > + > +struct S2 { > + int foo; // { dg-message "pointed-to object" } > +}; > + > +struct X { > + S2 s; > +}; > + > +constexpr float f1() { > + S s; > + void* p = &s.foo; > + return *static_cast<float*>(p); // { dg-error "not allowed in a constant expression" } > +} > + > +constexpr float f2() { > + X x; > + void* p = &x.s.foo; > + return *static_cast<float*>(p); // { dg-error "not allowed in a constant expression" } > +} > + > +constexpr auto x1 = f1(); > +constexpr auto x2 = f2(); > > base-commit: dfe0d4389a3ce43179563a63046ad3e74d615a08
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index c3668b0d7d3..f6fd059be46 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -8201,8 +8201,11 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, TREE_TYPE (op), TREE_TYPE (TREE_TYPE (sop)), TREE_TYPE (type)); tree obj = build_fold_indirect_ref (sop); - inform (DECL_SOURCE_LOCATION (obj), - "pointed-to object declared here"); + if (TREE_CODE (obj) == COMPONENT_REF) + obj = TREE_OPERAND (obj, 1); + if (DECL_P (obj)) + inform (DECL_SOURCE_LOCATION (obj), + "pointed-to object declared here"); } *non_constant_p = true; return t; diff --git a/gcc/testsuite/g++.dg/cpp26/constexpr-voidptr4.C b/gcc/testsuite/g++.dg/cpp26/constexpr-voidptr4.C new file mode 100644 index 00000000000..53563c928f2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/constexpr-voidptr4.C @@ -0,0 +1,29 @@ +// PR c++/116741 +// { dg-do compile { target c++26 } } + +struct S { + int foo; // { dg-message "pointed-to object" } +}; + +struct S2 { + int foo; // { dg-message "pointed-to object" } +}; + +struct X { + S2 s; +}; + +constexpr float f1() { + S s; + void* p = &s.foo; + return *static_cast<float*>(p); // { dg-error "not allowed in a constant expression" } +} + +constexpr float f2() { + X x; + void* p = &x.s.foo; + return *static_cast<float*>(p); // { dg-error "not allowed in a constant expression" } +} + +constexpr auto x1 = f1(); +constexpr auto x2 = f2();