PR c++/84701 - unsigned typeof.
* decl.c (grokdeclarator): Overhaul diagnostics for invalid use of long/short/signed/unsigned. From-SVN: r259780
This commit is contained in:
parent
f026530a85
commit
fe43c63503
4 changed files with 62 additions and 34 deletions
|
@ -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.
|
||||
|
|
|
@ -10608,45 +10608,61 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
|
||||
if (unsigned_p || signed_p || long_p || short_p)
|
||||
{
|
||||
location_t loc;
|
||||
const char *key;
|
||||
if (unsigned_p)
|
||||
{
|
||||
key = "unsigned";
|
||||
loc = declspecs->locations[ds_unsigned];
|
||||
}
|
||||
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)
|
||||
{
|
||||
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) && 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);
|
||||
if (signed_p && unsigned_p)
|
||||
error_at (loc, "%<signed%> and %<unsigned%> specified together");
|
||||
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)
|
||||
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 (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);
|
||||
if (typedef_decl)
|
||||
{
|
||||
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;
|
||||
if (!explicit_int && !defaulted_int && !explicit_char && !explicit_intN && pedantic)
|
||||
{
|
||||
pedwarn (input_location, OPT_Wpedantic,
|
||||
"long, short, signed or unsigned used invalidly for %qs",
|
||||
name);
|
||||
if (flag_pedantic_errors)
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
ok = 1;
|
||||
|
||||
/* Discard the type modifiers if they are invalid. */
|
||||
if (! ok)
|
||||
|
|
|
@ -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 }
|
||||
|
|
8
gcc/testsuite/g++.dg/ext/typeof13.C
Normal file
8
gcc/testsuite/g++.dg/ext/typeof13.C
Normal file
|
@ -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 }
|
Loading…
Add table
Reference in a new issue