aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2019-08-01 16:27:04 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2019-08-01 16:27:04 +0000
commitf339eb66071559a02a0c05b3ee89fc8352969bc9 (patch)
treec1268328a554cc53785e00df31c20caa2dfbf9fb
parent3a66e68ad92f7b4150e35e20e2bb22f777837b63 (diff)
downloadgcc-f339eb66071559a02a0c05b3ee89fc8352969bc9.zip
gcc-f339eb66071559a02a0c05b3ee89fc8352969bc9.tar.gz
gcc-f339eb66071559a02a0c05b3ee89fc8352969bc9.tar.bz2
PR c++/90805 - detect narrowing in case values.
* decl.c (case_conversion): Detect narrowing in case values. * c-c++-common/pr89888.c: Update expected dg-error. * g++.dg/cpp0x/Wnarrowing17.C: New test. * g++.dg/cpp0x/enum28.C: Update expected dg-error. From-SVN: r273976
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/decl.c23
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/c-c++-common/pr89888.c4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/Wnarrowing17.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/enum28.C4
6 files changed, 50 insertions, 12 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f374636..9a6c2e3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2019-08-01 Marek Polacek <polacek@redhat.com>
+
+ PR c++/90805 - detect narrowing in case values.
+ * decl.c (case_conversion): Detect narrowing in case values.
+
2019-07-31 Paolo Carlini <paolo.carlini@oracle.com>
* decl2.c (delete_sanity): Improve diagnostic locations, use
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 9fa090c..c8b9e3b 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -3631,16 +3631,23 @@ case_conversion (tree type, tree value)
value = mark_rvalue_use (value);
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
+ type = type_promotes_to (type);
+
+ tree ovalue = value;
+ /* The constant-expression VALUE shall be a converted constant expression
+ of the adjusted type of the switch condition, which doesn't allow
+ narrowing conversions. */
+ value = build_converted_constant_expr (type, value, tf_warning_or_error);
+
if (cxx_dialect >= cxx11
&& (SCOPED_ENUM_P (type)
- || !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (value))))
- {
- if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
- type = type_promotes_to (type);
- value = (perform_implicit_conversion_flags
- (type, value, tf_warning_or_error,
- LOOKUP_IMPLICIT | LOOKUP_NO_NON_INTEGRAL));
- }
+ || !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (ovalue))))
+ /* Use the converted value. */;
+ else
+ /* The already integral case. */
+ value = ovalue;
+
return cxx_constant_value (value);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8b0365a..d16e123 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2019-08-01 Marek Polacek <polacek@redhat.com>
+
+ PR c++/90805 - detect narrowing in case values.
+ * c-c++-common/pr89888.c: Update expected dg-error.
+ * g++.dg/cpp0x/Wnarrowing17.C: New test.
+ * g++.dg/cpp0x/enum28.C: Update expected dg-error.
+
2019-08-01 Wilco Dijkstra <wdijkstr@arm.com>
* gcc/testsuite/g++.dg/lto/pr89330_0.C: Add effective-target shared.
diff --git a/gcc/testsuite/c-c++-common/pr89888.c b/gcc/testsuite/c-c++-common/pr89888.c
index d9e11d6..f14881c 100644
--- a/gcc/testsuite/c-c++-common/pr89888.c
+++ b/gcc/testsuite/c-c++-common/pr89888.c
@@ -11,8 +11,8 @@ foo (unsigned char x)
{
case -1: y = -1; break; /* { dg-message "previously used here" } */
/* { dg-warning "case label value is less than minimum value for type" "" { target *-*-* } .-1 } */
- case 0xffffffff: y = 0xffffffff; break; /* { dg-error "duplicate case value" } */
- case ~0U: y = ~0U; break; /* { dg-error "duplicate case value" } */
+ case 0xffffffff: y = 0xffffffff; break; /* { dg-error "duplicate case value|narrowing" } */
+ case ~0U: y = ~0U; break; /* { dg-error "duplicate case value|narrowing" } */
}
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/Wnarrowing17.C b/gcc/testsuite/g++.dg/cpp0x/Wnarrowing17.C
new file mode 100644
index 0000000..064de53
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/Wnarrowing17.C
@@ -0,0 +1,19 @@
+// PR c++/90805 - detect narrowing in case values.
+// { dg-do compile { target c++11 } }
+
+void f(int i, char c, unsigned u)
+{
+ switch (i)
+ {
+ case 2149056512u:; // { dg-error "narrowing conversion of .2149056512. from .unsigned int. to .int." }
+ case (long long int) 1e10:; // { dg-error "narrowing conversion of .10000000000. from .long long int. to .int." }
+ // { dg-warning "overflow in conversion" "overflow" { target *-*-* } .-1 }
+ }
+
+ switch (c)
+ // No narrowing, the adjusted type is int.
+ case 300:; // { dg-warning "exceeds maximum value for type" }
+
+ switch (u)
+ case -42:; // { dg-error "narrowing conversion of .-42. from .int. to .unsigned int." }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum28.C b/gcc/testsuite/g++.dg/cpp0x/enum28.C
index 3967699..bfebde5 100644
--- a/gcc/testsuite/g++.dg/cpp0x/enum28.C
+++ b/gcc/testsuite/g++.dg/cpp0x/enum28.C
@@ -7,11 +7,11 @@ void f(int i)
{
switch (i)
{
- case 1.0:; // { dg-error "could not convert" }
+ case 1.0:; // { dg-error "could not convert|conversion from" }
}
switch (i)
{
- case g():; // { dg-error "could not convert" }
+ case g():; // { dg-error "could not convert|conversion from" }
}
}