This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] PR c++/80544 strip cv-quals from cast results


This is probably not the best way to do this, but it seems to work.

I also tried to add a warning like EDG's (see the PR) but it gave a
false positive for direct-list-init of scoped enums (P0138R2, r240449)
because that code goes through build_c_cast to perform the conversion,
so looks like a cast to my new warning.

Tested x86_64-linux, OK for trunk?


gcc/cp:

	PR c++/80544
	* typeck.c (build_static_cast_1, build_reinterpret_cast_1)
	(build_const_cast_1): Strip cv-quals from non-class prvalue results.

gcc/testsuite:

	PR c++/80544
	* g++.dg/expr/cast11.C: New test.


commit 47763f3c84de86dd1ebbaac73e341e2de9b5be68
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Apr 27 16:49:25 2017 +0100

    PR c++/80544 strip cv-quals from cast results
    
    gcc/cp:
    
    	PR c++/80544
    	* typeck.c (build_static_cast_1, build_reinterpret_cast_1)
    	(build_const_cast_1): Strip cv-quals from non-class prvalue results.
    
    gcc/testsuite:
    
    	PR c++/80544
    	* g++.dg/expr/cast11.C: New test.

diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 7aee0d6..e41b335 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -6708,6 +6708,10 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
   /* Save casted types in the function's used types hash table.  */
   used_types_insert (type);
 
+  /* A prvalue of non-class type is cv-unqualified.  */
+  if (TREE_CODE (type) != REFERENCE_TYPE && !CLASS_TYPE_P (type))
+    type = cv_unqualified (type);
+
   /* [expr.static.cast]
 
      An lvalue of type "cv1 B", where B is a class type, can be cast
@@ -7070,6 +7074,10 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
   /* Save casted types in the function's used types hash table.  */
   used_types_insert (type);
 
+  /* A prvalue of non-class type is cv-unqualified.  */
+  if (TREE_CODE (type) != REFERENCE_TYPE && !CLASS_TYPE_P (type))
+    type = cv_unqualified (type);
+
   /* [expr.reinterpret.cast]
      An lvalue expression of type T1 can be cast to the type
      "reference to T2" if an expression of type "pointer to T1" can be
@@ -7300,6 +7308,10 @@ build_const_cast_1 (tree dst_type, tree expr, tsubst_flags_t complain,
   /* Save casted types in the function's used types hash table.  */
   used_types_insert (dst_type);
 
+  /* A prvalue of non-class type is cv-unqualified.  */
+  if (TREE_CODE (dst_type) != REFERENCE_TYPE && !CLASS_TYPE_P (dst_type))
+    dst_type = cv_unqualified (dst_type);
+
   src_type = TREE_TYPE (expr);
   /* Expressions do not really have reference types.  */
   if (TREE_CODE (src_type) == REFERENCE_TYPE)
diff --git a/gcc/testsuite/g++.dg/expr/cast11.C b/gcc/testsuite/g++.dg/expr/cast11.C
new file mode 100644
index 0000000..642087e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/expr/cast11.C
@@ -0,0 +1,34 @@
+// { dg-do compile { target c++11 } }
+// c++/80544 cast expressions returned cv-qualified prvalues
+
+template<typename T> void f(T&&) { }
+template<typename T> void f(T const&&) = delete;
+
+template<typename T> void g(T&&) = delete;
+template<typename T> void g(T const&&) { }
+
+struct B { int i; } b;
+
+void f1()
+{
+  int i = 0;
+  f((long const)i);
+  f((int* const)&i);
+  f((int const* const)&i);
+  f((long* const)&i);
+
+  f(static_cast<long const>(i));
+  f(reinterpret_cast<long const>(&i));
+
+  f(static_cast<int* const>(&i));
+  f(const_cast<int* const>(&i));
+  f(reinterpret_cast<long* const>(&i));
+
+  using ptrmem = int B::*;
+  f(static_cast<ptrmem const>(&B::i));
+  f(const_cast<ptrmem const>(&B::i));
+  f(reinterpret_cast<ptrmem const>(&B::i));
+
+  // prvalue of class type can have cv-quals:
+  g(static_cast<const B>(b));
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]