summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2011-04-07 21:47:38 +0000
committerJason Merrill <jason@redhat.com>2011-04-08 11:06:50 -0400
commit69f5d6037cf6ea9cb1e1a947cdc060f03c1dbe04 (patch)
treee7dd0e144dbad79530d4c0abee0793bfa9b3df7b
parent2da31f81b58b884316d384c639d5c0013c21332b (diff)
downloadgcc-69f5d6037cf6ea9cb1e1a947cdc060f03c1dbe04.tar.gz
PR c++/48450
* typeck.c (check_for_casting_away_constness): Take complain. (build_static_cast_1, build_reinterpret_cast_1): Pass it. (build_const_cast_1): Pass it. Take full complain parm. (build_const_cast, cp_build_c_cast): Adjust.
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/typeck.c83
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/c-c++-common/Wcast-qual-1.c (renamed from gcc/testsuite/g++.dg/warn/Wcast-qual2.C)5
-rw-r--r--gcc/testsuite/gcc.dg/cast-qual-3.c167
5 files changed, 63 insertions, 206 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6e425df6688..f244ec1449a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,6 +1,14 @@
2011-04-07 Jason Merrill <jason@redhat.com>
PR c++/48450
+ * typeck.c (check_for_casting_away_constness): Take complain.
+ (build_static_cast_1, build_reinterpret_cast_1): Pass it.
+ (build_const_cast_1): Pass it. Take full complain parm.
+ (build_const_cast, cp_build_c_cast): Adjust.
+
+2011-04-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/48450
* tree.c (build_cplus_new, build_aggr_init_expr): Take complain.
(bot_manip): Adjust.
* cp-tree.h: Adjust.
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index df6b172b1f7..ba83393c911 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -5578,42 +5578,47 @@ cp_build_compound_expr (tree lhs, tree rhs, tsubst_flags_t complain)
}
/* Issue a diagnostic message if casting from SRC_TYPE to DEST_TYPE
- casts away constness. CAST gives the type of cast.
+ casts away constness. CAST gives the type of cast. Returns true
+ if the cast is ill-formed, false if it is well-formed.
??? This function warns for casting away any qualifier not just
const. We would like to specify exactly what qualifiers are casted
away.
*/
-static void
+static bool
check_for_casting_away_constness (tree src_type, tree dest_type,
- enum tree_code cast)
+ enum tree_code cast, tsubst_flags_t complain)
{
/* C-style casts are allowed to cast away constness. With
WARN_CAST_QUAL, we still want to issue a warning. */
if (cast == CAST_EXPR && !warn_cast_qual)
- return;
+ return false;
if (!casts_away_constness (src_type, dest_type))
- return;
+ return false;
switch (cast)
{
case CAST_EXPR:
- warning (OPT_Wcast_qual,
- "cast from type %qT to type %qT casts away qualifiers",
- src_type, dest_type);
- return;
+ if (complain & tf_warning)
+ warning (OPT_Wcast_qual,
+ "cast from type %qT to type %qT casts away qualifiers",
+ src_type, dest_type);
+ return false;
case STATIC_CAST_EXPR:
- error ("static_cast from type %qT to type %qT casts away qualifiers",
- src_type, dest_type);
- return;
+ if (complain & tf_error)
+ error ("static_cast from type %qT to type %qT casts away qualifiers",
+ src_type, dest_type);
+ return true;
case REINTERPRET_CAST_EXPR:
- error ("reinterpret_cast from type %qT to type %qT casts away qualifiers",
- src_type, dest_type);
- return;
+ if (complain & tf_error)
+ error ("reinterpret_cast from type %qT to type %qT casts away qualifiers",
+ src_type, dest_type);
+ return true;
+
default:
gcc_unreachable();
}
@@ -5831,8 +5836,10 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
{
tree base;
- if (!c_cast_p)
- check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR);
+ if (!c_cast_p
+ && check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR,
+ complain))
+ return error_mark_node;
base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
c_cast_p ? ba_unique : ba_check,
NULL);
@@ -5867,10 +5874,13 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
}
if (can_convert (t1, t2) || can_convert (t2, t1))
{
- if (!c_cast_p)
- check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR);
+ if (!c_cast_p
+ && check_for_casting_away_constness (intype, type,
+ STATIC_CAST_EXPR,
+ complain))
+ return error_mark_node;
return convert_ptrmem (type, expr, /*allow_inverse_p=*/1,
- c_cast_p, tf_warning_or_error);
+ c_cast_p, complain);
}
}
@@ -5884,8 +5894,10 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
&& VOID_TYPE_P (TREE_TYPE (intype))
&& TYPE_PTROB_P (type))
{
- if (!c_cast_p)
- check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR);
+ if (!c_cast_p
+ && check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR,
+ complain))
+ return error_mark_node;
return build_nop (type, expr);
}
@@ -6089,8 +6101,11 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
{
tree sexpr = expr;
- if (!c_cast_p)
- check_for_casting_away_constness (intype, type, REINTERPRET_CAST_EXPR);
+ if (!c_cast_p
+ && check_for_casting_away_constness (intype, type,
+ REINTERPRET_CAST_EXPR,
+ complain))
+ return error_mark_node;
/* Warn about possible alignment problems. */
if (STRICT_ALIGNMENT && warn_cast_align
&& (complain & tf_warning)
@@ -6167,7 +6182,7 @@ build_reinterpret_cast (tree type, tree expr, tsubst_flags_t complain)
whether or not the conversion succeeded. */
static tree
-build_const_cast_1 (tree dst_type, tree expr, bool complain,
+build_const_cast_1 (tree dst_type, tree expr, tsubst_flags_t complain,
bool *valid_p)
{
tree src_type;
@@ -6186,7 +6201,7 @@ build_const_cast_1 (tree dst_type, tree expr, bool complain,
if (!POINTER_TYPE_P (dst_type) && !TYPE_PTRMEM_P (dst_type))
{
- if (complain)
+ if (complain & tf_error)
error ("invalid use of const_cast with type %qT, "
"which is not a pointer, "
"reference, nor a pointer-to-data-member type", dst_type);
@@ -6195,7 +6210,7 @@ build_const_cast_1 (tree dst_type, tree expr, bool complain,
if (TREE_CODE (TREE_TYPE (dst_type)) == FUNCTION_TYPE)
{
- if (complain)
+ if (complain & tf_error)
error ("invalid use of const_cast with type %qT, which is a pointer "
"or reference to a function type", dst_type);
return error_mark_node;
@@ -6220,7 +6235,7 @@ build_const_cast_1 (tree dst_type, tree expr, bool complain,
reference_type = dst_type;
if (! real_lvalue_p (expr))
{
- if (complain)
+ if (complain & tf_error)
error ("invalid const_cast of an rvalue of type %qT to type %qT",
src_type, dst_type);
return error_mark_node;
@@ -6247,12 +6262,12 @@ build_const_cast_1 (tree dst_type, tree expr, bool complain,
*valid_p = true;
/* This cast is actually a C-style cast. Issue a warning if
the user is making a potentially unsafe cast. */
- check_for_casting_away_constness (src_type, dst_type, CAST_EXPR);
+ check_for_casting_away_constness (src_type, dst_type, CAST_EXPR,
+ complain);
}
if (reference_type)
{
- expr = cp_build_addr_expr (expr,
- complain ? tf_warning_or_error : tf_none);
+ expr = cp_build_addr_expr (expr, complain);
expr = build_nop (reference_type, expr);
return convert_from_reference (expr);
}
@@ -6269,7 +6284,7 @@ build_const_cast_1 (tree dst_type, tree expr, bool complain,
}
}
- if (complain)
+ if (complain & tf_error)
error ("invalid const_cast from type %qT to type %qT",
src_type, dst_type);
return error_mark_node;
@@ -6292,7 +6307,7 @@ build_const_cast (tree type, tree expr, tsubst_flags_t complain)
return convert_from_reference (t);
}
- return build_const_cast_1 (type, expr, complain & tf_error,
+ return build_const_cast_1 (type, expr, complain,
/*valid_p=*/NULL);
}
@@ -6378,7 +6393,7 @@ cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain)
"cast to pointer from integer of different size");
/* A C-style cast can be a const_cast. */
- result = build_const_cast_1 (type, value, /*complain=*/false,
+ result = build_const_cast_1 (type, value, complain & tf_warning,
&valid_p);
if (valid_p)
return result;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5ddfcbfbe52..98cb396d4ff 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,11 @@
2011-04-07 Jason Merrill <jason@redhat.com>
+ * c-c++-common/Wcast-qual-1.c: Move here from...
+ * gcc.dg/cast-qual-3.c: ...here, and...
+ * g++.dg/warn/Wcast-qual2.C: ...here.
+
+2011-04-07 Jason Merrill <jason@redhat.com>
+
* g++.dg/cpp0x/sfinae8.C: New.
2011-03-28 Jason Merrill <jason@redhat.com>
diff --git a/gcc/testsuite/g++.dg/warn/Wcast-qual2.C b/gcc/testsuite/c-c++-common/Wcast-qual-1.c
index 88fdcfb38f5..640e4f0b683 100644
--- a/gcc/testsuite/g++.dg/warn/Wcast-qual2.C
+++ b/gcc/testsuite/c-c++-common/Wcast-qual-1.c
@@ -1,11 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-Wcast-qual" } */
-/* The files gcc.dg/cast-qual-3.c and g++.dg/warn/Wcast-qual2.c are
- duals. they are intended to show that gcc -Wcast-qual and g++
- -Wcast-qual emit warnings in the same cases. If you change this
- file, please also change the other one. */
-
void
f1 (void *bar)
{
diff --git a/gcc/testsuite/gcc.dg/cast-qual-3.c b/gcc/testsuite/gcc.dg/cast-qual-3.c
deleted file mode 100644
index 88fdcfb38f5..00000000000
--- a/gcc/testsuite/gcc.dg/cast-qual-3.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-Wcast-qual" } */
-
-/* The files gcc.dg/cast-qual-3.c and g++.dg/warn/Wcast-qual2.c are
- duals. they are intended to show that gcc -Wcast-qual and g++
- -Wcast-qual emit warnings in the same cases. If you change this
- file, please also change the other one. */
-
-void
-f1 (void *bar)
-{
- const void *p1 = (const void *) bar;
- const char *p2 = (const char *) bar;
- const void **p3 = (const void **) bar;
- const char **p4 = (const char **) bar;
- const void * const *p5 = (const void * const *) bar;
- const char * const *p6 = (const char * const *) bar;
- void * const *p7 = (void * const *) bar;
- char * const *p8 = (char * const *) bar;
- const void ***p9 = (const void ***) bar;
- const char ***p10 = (const char ***) bar;
- void * const **p11 = (void * const **) bar;
- char * const **p12 = (char * const **) bar;
- void ** const *p13 = (void ** const *) bar;
- char ** const *p14 = (char ** const *) bar;
- const void * const **p15 = (const void * const **) bar;
- const char * const **p16 = (const char * const **) bar;
- const void ** const *p17 = (const void ** const *) bar;
- const char ** const *p18 = (const char ** const *) bar;
- void * const * const * p19 = (void * const * const *) bar;
- char * const * const * p20 = (char * const * const *) bar;
- const void * const * const *p21 = (const void * const * const *) bar;
- const char * const * const *p22 = (const char * const * const *) bar;
-}
-
-void
-f2 (void **bar)
-{
- const void *p1 = (const void *) bar;
- const char *p2 = (const char *) bar;
- const void **p3 = (const void **) bar; /* { dg-warning "cast" } */
- const char **p4 = (const char **) bar;
- const void * const *p5 = (const void * const *) bar;
- const char * const *p6 = (const char * const *) bar;
- void * const *p7 = (void * const *) bar;
- char * const *p8 = (char * const *) bar;
- const void ***p9 = (const void ***) bar;
- const char ***p10 = (const char ***) bar;
- void * const **p11 = (void * const **) bar;
- char * const **p12 = (char * const **) bar;
- void ** const *p13 = (void ** const *) bar;
- char ** const *p14 = (char ** const *) bar;
- const void * const **p15 = (const void * const **) bar;
- const char * const **p16 = (const char * const **) bar;
- const void ** const *p17 = (const void ** const *) bar;
- const char ** const *p18 = (const char ** const *) bar;
- void * const * const * p19 = (void * const * const *) bar;
- char * const * const * p20 = (char * const * const *) bar;
- const void * const * const *p21 = (const void * const * const *) bar;
- const char * const * const *p22 = (const char * const * const *) bar;
-}
-
-void
-f3 (void ***bar)
-{
- const void *p1 = (const void *) bar;
- const char *p2 = (const char *) bar;
- const void **p3 = (const void **) bar;
- const char **p4 = (const char **) bar;
- const void * const *p5 = (const void * const *) bar;
- const char * const *p6 = (const char * const *) bar;
- void * const *p7 = (void * const *) bar;
- char * const *p8 = (char * const *) bar;
- const void ***p9 = (const void ***) bar; /* { dg-warning "cast" } */
- const char ***p10 = (const char ***) bar;
- void * const **p11 = (void * const **) bar; /* { dg-warning "cast" } */
- char * const **p12 = (char * const **) bar;
- void ** const *p13 = (void ** const *) bar;
- char ** const *p14 = (char ** const *) bar;
- const void * const **p15 = (const void * const **) bar; /* { dg-warning "cast" } */
- const char * const **p16 = (const char * const **) bar;
- const void ** const *p17 = (const void ** const *) bar; /* { dg-warning "cast" } */
- const char ** const *p18 = (const char ** const *) bar;
- void * const * const * p19 = (void * const * const *) bar;
- char * const * const * p20 = (char * const * const *) bar;
- const void * const * const *p21 = (const void * const * const *) bar;
- const char * const * const *p22 = (const char * const * const *) bar;
-}
-
-void
-f4 (void * const **bar)
-{
- const void ***p9 = (const void ***) bar; /* { dg-warning "cast" } */
- void * const **p11 = (void * const **) bar;
- void ** const *p13 = (void ** const *) bar; /* { dg-warning "cast" } */
- const void * const **p15 = (const void * const **) bar; /* { dg-warning "cast" } */
- const void ** const *p17 = (const void ** const *) bar; /* { dg-warning "cast" } */
- void * const * const * p19 = (void * const * const *) bar;
- const void * const * const *p21 = (const void * const * const *) bar;
-}
-
-void
-f5 (char ***bar)
-{
- volatile const char ***p9 = (volatile const char ***) bar; /* { dg-warning "cast" } */
- volatile char * const **p11 = (volatile char * const **) bar; /* { dg-warning "cast" } */
- volatile char ** const *p13 = (volatile char ** const *) bar; /* { dg-warning "cast" } */
- volatile const char * const **p15 = (volatile const char * const **) bar; /* { dg-warning "cast" } */
- volatile const char ** const *p17 = (volatile const char ** const *) bar; /* { dg-warning "cast" } */
- volatile char * const * const * p19 = (volatile char * const * const *) bar;
- volatile const char * const * const *p21 = (volatile const char * const * const *) bar;
-}
-
-void
-f6 (char ***bar)
-{
- const char * volatile **p9 = (const char * volatile **) bar; /* { dg-warning "cast" } */
- char * volatile const **p11 = (char * volatile const **) bar; /* { dg-warning "cast" } */
- char * volatile * const *p13 = (char * volatile * const *) bar;
- const char * volatile const **p15 = (const char * volatile const **) bar; /* { dg-warning "cast" } */
- const char * volatile * const *p17 = (const char * volatile * const *) bar; /* { dg-warning "cast" } */
- char * volatile const * const * p19 = (char * volatile const * const *) bar;
- const char * volatile const * const *p21 = (const char * volatile const * const *) bar;
-}
-
-void
-f7 (char ***bar)
-{
- const char ** volatile *p9 = (const char ** volatile *) bar; /* { dg-warning "cast" } */
- char * const * volatile *p11 = (char * const * volatile *) bar; /* { dg-warning "cast" } */
- char ** volatile const *p13 = (char ** volatile const *) bar;
- const char * const * volatile *p15 = (const char * const * volatile *) bar; /* { dg-warning "cast" } */
- const char ** volatile const *p17 = (const char ** volatile const *) bar; /* { dg-warning "cast" } */
- char * const * volatile const * p19 = (char * const * volatile const *) bar;
- const char * const * volatile const *p21 = (const char * const * volatile const *) bar;
-}
-
-typedef int (intfn) (int);
-typedef intfn *pintfn;
-typedef const intfn *constfn;
-
-void
-f8 (constfn ***bar)
-{
- const constfn *p1 = (const constfn *) bar;
- const pintfn *p2 = (const pintfn *) bar;
- const constfn **p3 = (const constfn **) bar;
- const pintfn **p4 = (const pintfn **) bar;
- const constfn * const *p5 = (const constfn * const *) bar;
- const pintfn * const *p6 = (const pintfn * const *) bar;
- constfn * const *p7 = (constfn * const *) bar;
- pintfn * const *p8 = (pintfn * const *) bar;
- const constfn ***p9 = (const constfn ***) bar; /* { dg-warning "cast" } */
- const pintfn ***p10 = (const pintfn ***) bar; /* { dg-warning "cast" } */
- constfn * const **p11 = (constfn * const **) bar; /* { dg-warning "cast" } */
- pintfn * const **p12 = (pintfn * const **) bar; /* { dg-warning "cast" } */
- constfn ** const *p13 = (constfn ** const *) bar;
- pintfn ** const *p14 = (pintfn ** const *) bar;
- const constfn * const **p15 = (const constfn * const **) bar; /* { dg-warning "cast" } */
- const pintfn * const **p16 = (const pintfn * const **) bar; /* { dg-warning "cast" } */
- const constfn ** const *p17 = (const constfn ** const *) bar; /* { dg-warning "cast" } */
- const pintfn ** const *p18 = (const pintfn ** const *) bar; /* { dg-warning "cast" } */
- constfn * const * const * p19 = (constfn * const * const *) bar;
- pintfn * const * const * p20 = (pintfn * const * const *) bar;
- const constfn * const * const *p21 = (const constfn * const * const *) bar;
- const pintfn * const * const *p22 = (const pintfn * const * const *) bar;
-}