aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-04-30 17:21:32 -0400
committerJason Merrill <jason@gcc.gnu.org>2018-04-30 17:21:32 -0400
commitfe43c635035edcd29eca0a8e3b08d8bcf14d9ba8 (patch)
tree68ce143bccd54bdb40859152c8f1686258230203 /gcc
parentf026530a85c3d13aaebec5c4e96cd0a2f6ef4f17 (diff)
downloadgcc-fe43c635035edcd29eca0a8e3b08d8bcf14d9ba8.zip
gcc-fe43c635035edcd29eca0a8e3b08d8bcf14d9ba8.tar.gz
gcc-fe43c635035edcd29eca0a8e3b08d8bcf14d9ba8.tar.bz2
PR c++/84701 - unsigned typeof.
* decl.c (grokdeclarator): Overhaul diagnostics for invalid use of long/short/signed/unsigned. From-SVN: r259780
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/decl.c82
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/decomp3.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/typeof13.C8
4 files changed, 62 insertions, 34 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 95f77f4..65f556e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2018-04-30 Jason Merrill <jason@redhat.com>
+ PR c++/84701 - unsigned typeof.
+ * decl.c (grokdeclarator): Overhaul diagnostics for invalid use
+ of long/short/signed/unsigned.
+
PR c++/85305 - pack in lambda init-capture.
* parser.c (cp_parser_initializer): Add subexpression_p parm; don't
check_for_bare_parameter_packs in a subexpression.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 07f3a61..6f2fe01 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -10608,45 +10608,61 @@ grokdeclarator (const cp_declarator *declarator,
if (unsigned_p || signed_p || long_p || short_p)
{
- int ok = 0;
-
- if ((signed_p || unsigned_p) && TREE_CODE (type) != INTEGER_TYPE)
- error ("%<signed%> or %<unsigned%> invalid for %qs", name);
- else if (signed_p && unsigned_p)
- error ("%<signed%> and %<unsigned%> specified together for %qs", name);
- else if (longlong && TREE_CODE (type) != INTEGER_TYPE)
- error ("%<long long%> invalid for %qs", name);
- else if (long_p && TREE_CODE (type) == REAL_TYPE)
- error ("%<long%> invalid for %qs", name);
- else if (short_p && TREE_CODE (type) == REAL_TYPE)
- error ("%<short%> invalid for %qs", name);
- else if ((long_p || short_p) && TREE_CODE (type) != INTEGER_TYPE)
- error ("%<long%> or %<short%> invalid for %qs", name);
- else if ((long_p || short_p || explicit_char || explicit_int) && explicit_intN)
- error ("%<long%>, %<int%>, %<short%>, or %<char%> invalid for %qs", name);
- else if ((long_p || short_p) && explicit_char)
- error ("%<long%> or %<short%> specified with char for %qs", name);
- else if (long_p && short_p)
- error ("%<long%> and %<short%> specified together for %qs", name);
- else if (type == char16_type_node || type == char32_type_node)
+ location_t loc;
+ const char *key;
+ if (unsigned_p)
{
- if (signed_p || unsigned_p)
- error ("%<signed%> or %<unsigned%> invalid for %qs", name);
- else if (short_p || long_p)
- error ("%<short%> or %<long%> invalid for %qs", name);
+ key = "unsigned";
+ loc = declspecs->locations[ds_unsigned];
}
- else
+ else if (signed_p)
+ {
+ key = "signed";
+ loc = declspecs->locations[ds_signed];
+ }
+ else if (longlong)
+ {
+ key = "long long";
+ loc = declspecs->locations[ds_long_long];
+ }
+ else if (long_p)
{
- ok = 1;
- if (!explicit_int && !defaulted_int && !explicit_char && !explicit_intN && pedantic)
+ key = "long";
+ loc = declspecs->locations[ds_long];
+ }
+ else /* if (short_p) */
+ {
+ key = "short";
+ loc = declspecs->locations[ds_short];
+ }
+
+ int ok = 0;
+
+ if (signed_p && unsigned_p)
+ error_at (loc, "%<signed%> and %<unsigned%> specified together");
+ else if (long_p && short_p)
+ error_at (loc, "%<long%> and %<short%> specified together");
+ else if (TREE_CODE (type) != INTEGER_TYPE
+ || type == char16_type_node || type == char32_type_node
+ || ((long_p || short_p)
+ && (explicit_char || explicit_intN)))
+ error_at (loc, "%qs specified with %qT", key, type);
+ else if (!explicit_int && !defaulted_int
+ && !explicit_char && !explicit_intN)
+ {
+ if (typedef_decl)
{
- pedwarn (input_location, OPT_Wpedantic,
- "long, short, signed or unsigned used invalidly for %qs",
- name);
- if (flag_pedantic_errors)
- ok = 0;
+ pedwarn (loc, OPT_Wpedantic, "%qs specified with %qT",
+ key, type);
+ ok = !flag_pedantic_errors;
}
+ else if (declspecs->decltype_p)
+ error_at (loc, "%qs specified with %<decltype%>", key);
+ else
+ error_at (loc, "%qs specified with %<typeof%>", key);
}
+ else
+ ok = 1;
/* Discard the type modifiers if they are invalid. */
if (! ok)
diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp3.C b/gcc/testsuite/g++.dg/cpp1z/decomp3.C
index 1886cdb..4d75e93 100644
--- a/gcc/testsuite/g++.dg/cpp1z/decomp3.C
+++ b/gcc/testsuite/g++.dg/cpp1z/decomp3.C
@@ -29,7 +29,7 @@ test (A &b, B c)
// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
__restrict auto [ t ] = c; // { dg-error "invalid use of 'restrict'" }
// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
- long long auto [ u ] = c; // { dg-error "'long long' invalid for 'structured binding'" }
+ long long auto [ u ] = c; // { dg-error "'long long' specified with 'auto'" }
// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
virtual auto [ v ] = c; // { dg-error "'virtual' outside class declaration" }
// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
diff --git a/gcc/testsuite/g++.dg/ext/typeof13.C b/gcc/testsuite/g++.dg/ext/typeof13.C
new file mode 100644
index 0000000..820d50d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/typeof13.C
@@ -0,0 +1,8 @@
+// PR c++/84701
+// { dg-options "-pedantic" }
+
+typedef short foo_t;
+foo_t s = -1; /* FFFF */
+
+unsigned u = (unsigned foo_t)s; // { dg-warning foo_t }
+unsigned u2 = (unsigned __typeof(s))s; // { dg-error typeof }