diff mbox series

c++: fix constexpr cast from void* diag issue [PR116741]

Message ID 20240917203037.427316-1-polacek@redhat.com
State New
Headers show
Series c++: fix constexpr cast from void* diag issue [PR116741] | expand

Commit Message

Marek Polacek Sept. 17, 2024, 8:30 p.m. UTC
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/14?

-- >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


base-commit: dfe0d4389a3ce43179563a63046ad3e74d615a08

Comments

Jason Merrill Sept. 17, 2024, 8:59 p.m. UTC | #1
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 mbox series

Patch

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();