aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2024-09-17 14:34:30 -0400
committerMarek Polacek <polacek@redhat.com>2024-09-17 17:04:20 -0400
commitd6d8445c85509b66a59aa6247ad7b2cfeab17725 (patch)
tree23072283ba1e3363c7a5ac78e3cc6f7c498eb49c
parent7ca486889b1b1c7e7bcbbca3b6caa103294ec07d (diff)
downloadgcc-d6d8445c85509b66a59aa6247ad7b2cfeab17725.zip
gcc-d6d8445c85509b66a59aa6247ad7b2cfeab17725.tar.gz
gcc-d6d8445c85509b66a59aa6247ad7b2cfeab17725.tar.bz2
c++: fix constexpr cast from void* diag issue [PR116741]
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. Reviewed-by: Jason Merrill <jason@redhat.com>
-rw-r--r--gcc/cp/constexpr.cc7
-rw-r--r--gcc/testsuite/g++.dg/cpp26/constexpr-voidptr4.C29
2 files changed, 34 insertions, 2 deletions
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index c3668b0..f6fd059 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 0000000..53563c9
--- /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();