public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Giuliano Belinassi <giulianob@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org
Subject: [gcc/devel/autopar_devel] c++: Reject some further reinterpret casts in constexpr [PR82304, PR95307]
Date: Sat, 22 Aug 2020 21:57:47 +0000 (GMT)	[thread overview]
Message-ID: <20200822215747.31C133950C01@sourceware.org> (raw)

https://gcc.gnu.org/g:cfcc31846f718581e6bbb85da522b3dbb3b4a492

commit cfcc31846f718581e6bbb85da522b3dbb3b4a492
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Thu Jun 4 09:09:01 2020 +0200

    c++: Reject some further reinterpret casts in constexpr [PR82304, PR95307]
    
    cxx_eval_outermost_constant_expr had a check for reinterpret_casts from
    pointers (well, it checked from ADDR_EXPRs) to integral type, but that
    only caught such cases at the toplevel of expressions.
    As the comment said, it should be done even inside of the expressions,
    but at the point of the writing e.g. pointer differences used to be a
    problem.  We now have POINTER_DIFF_EXPR, so this is no longer an issue.
    
    Had to do it just for CONVERT_EXPR, because the FE emits NOP_EXPR casts
    from pointers to integrals in various spots, e.g. for the PMR & 1 tests,
    though on NOP_EXPR we have the REINTERPRET_CAST_P bit that we do check,
    while on CONVERT_EXPR we don't.
    
    2020-06-04  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/82304
            PR c++/95307
            * constexpr.c (cxx_eval_constant_expression): Diagnose CONVERT_EXPR
            conversions from pointer types to arithmetic types here...
            (cxx_eval_outermost_constant_expr): ... instead of here.
    
            * g++.dg/template/pr79650.C: Expect different diagnostics and expect
            it on all lines that do pointer to integer casts.
            * g++.dg/cpp1y/constexpr-shift1.C: Expect different diagnostics.
            * g++.dg/cpp1y/constexpr-82304.C: New test.
            * g++.dg/cpp0x/constexpr-95307.C: New test.

Diff:
---
 gcc/cp/constexpr.c                            | 25 ++++++++++++-------------
 gcc/testsuite/g++.dg/cpp0x/constexpr-95307.C  |  5 +++++
 gcc/testsuite/g++.dg/cpp1y/constexpr-82304.C  | 14 ++++++++++++++
 gcc/testsuite/g++.dg/cpp1y/constexpr-shift1.C |  4 ++--
 gcc/testsuite/g++.dg/template/pr79650.C       | 10 +++++-----
 5 files changed, 38 insertions(+), 20 deletions(-)

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 959f0254d09..c7d17e9b86e 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -6210,6 +6210,18 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	if (VOID_TYPE_P (type))
 	  return void_node;
 
+	if (TREE_CODE (t) == CONVERT_EXPR
+	    && ARITHMETIC_TYPE_P (type)
+	    && INDIRECT_TYPE_P (TREE_TYPE (op)))
+	  {
+	    if (!ctx->quiet)
+	      error_at (loc,
+			"conversion from pointer type %qT to arithmetic type "
+			"%qT in a constant expression", TREE_TYPE (op), type);
+	    *non_constant_p = true;
+	    return t;
+	  }
+
 	if (TREE_CODE (op) == PTRMEM_CST && !TYPE_PTRMEM_P (type))
 	  op = cplus_expand_constant (op);
 
@@ -6811,19 +6823,6 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
       non_constant_p = true;
     }
 
-  /* Technically we should check this for all subexpressions, but that
-     runs into problems with our internal representation of pointer
-     subtraction and the 5.19 rules are still in flux.  */
-  if (CONVERT_EXPR_CODE_P (TREE_CODE (r))
-      && ARITHMETIC_TYPE_P (TREE_TYPE (r))
-      && TREE_CODE (TREE_OPERAND (r, 0)) == ADDR_EXPR)
-    {
-      if (!allow_non_constant)
-	error ("conversion from pointer type %qT "
-	       "to arithmetic type %qT in a constant expression",
-	       TREE_TYPE (TREE_OPERAND (r, 0)), TREE_TYPE (r));
-      non_constant_p = true;
-    }
 
   if (!non_constant_p && overflow_p)
     non_constant_p = true;
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-95307.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-95307.C
new file mode 100644
index 00000000000..bd3c6a8f91f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-95307.C
@@ -0,0 +1,5 @@
+// PR c++/95307
+// { dg-do compile { target c++11 } }
+
+int v;
+constexpr auto p{reinterpret_cast<__UINTPTR_TYPE__>(&v) - 1u};	// { dg-error "conversion from pointer type" }
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-82304.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-82304.C
new file mode 100644
index 00000000000..3b05243df25
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-82304.C
@@ -0,0 +1,14 @@
+// PR c++/82304
+// { dg-do compile { target c++14 } }
+
+typedef __UINTPTR_TYPE__ uintptr_t;
+
+constexpr const char *
+foo (const char *p)
+{
+  auto l = reinterpret_cast<uintptr_t>(p);	// { dg-error "conversion from pointer" }
+  ++l;
+  return reinterpret_cast<const char *>(l);
+}
+
+constexpr auto s = foo ("Hello");
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-shift1.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-shift1.C
index d63c954f42f..e0e56e262f0 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-shift1.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-shift1.C
@@ -3,7 +3,7 @@
 constexpr int p = 1;
 constexpr __PTRDIFF_TYPE__ bar (int a)
 {
-  return ((__PTRDIFF_TYPE__) &p) << a; // { dg-error "is not a constant expression" }
+  return ((__PTRDIFF_TYPE__) &p) << a;	// { dg-error "conversion from pointer" }
 }
 constexpr __PTRDIFF_TYPE__ r = bar (2); // { dg-message "in .constexpr. expansion of" }
-constexpr __PTRDIFF_TYPE__ s = bar (0); // { dg-error "conversion from pointer" }
+constexpr __PTRDIFF_TYPE__ s = bar (0);
diff --git a/gcc/testsuite/g++.dg/template/pr79650.C b/gcc/testsuite/g++.dg/template/pr79650.C
index 72c78140942..11d28c5b207 100644
--- a/gcc/testsuite/g++.dg/template/pr79650.C
+++ b/gcc/testsuite/g++.dg/template/pr79650.C
@@ -11,10 +11,10 @@ foo ()
   static int a, b;
 lab1:
 lab2:
-  A<(intptr_t)&&lab1 - (__INTPTR_TYPE__)&&lab2> c;	// { dg-error "not a constant integer" }
-  A<(intptr_t)&&lab1 - (__INTPTR_TYPE__)&&lab1> d;
-  A<(intptr_t)&a - (intptr_t)&b> e;			// { dg-error "is not a constant expression" }
-  A<(intptr_t)&a - (intptr_t)&a> f;
-  A<(intptr_t)sizeof(a) + (intptr_t)&a> g;		// { dg-error "not a constant integer" }
+  A<(intptr_t)&&lab1 - (__INTPTR_TYPE__)&&lab2> c;	// { dg-error "conversion from pointer type" }
+  A<(intptr_t)&&lab1 - (__INTPTR_TYPE__)&&lab1> d;	// { dg-error "conversion from pointer type" }
+  A<(intptr_t)&a - (intptr_t)&b> e;			// { dg-error "conversion from pointer type" }
+  A<(intptr_t)&a - (intptr_t)&a> f;			// { dg-error "conversion from pointer type" }
+  A<(intptr_t)sizeof(a) + (intptr_t)&a> g;		// { dg-error "conversion from pointer type" }
   A<(intptr_t)&a> h;					// { dg-error "conversion from pointer type" }
 }


                 reply	other threads:[~2020-08-22 21:57 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200822215747.31C133950C01@sourceware.org \
    --to=giulianob@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).