mirror of git://gcc.gnu.org/git/gcc.git
Add new option, -Wliteral-suffix.
This option, which is enabled by default, causes the preprocessor to warn when a string or character literal is followed by a ud-suffix which does not begin with an underscore. According to [lex.ext]p10, this is ill-formed. Also modifies the preprocessor to treat such ill-formed suffixes as separate preprocessing tokens. This is consistent with the Clang front end (see http://llvm.org/viewvc/llvm-project?view=rev&revision=152287), and enables backwards compatibility with code that uses formatting macros from <inttypes.h>, as in the following code block: int main() { int64_t i64 = 123; printf("My int64: %"PRId64"\n", i64); } Google ref b/6377711. 2012-04-27 Ollie Wild <aaw@google.com> PR c++/52538 * gcc/c-family/c-common.c: Add CPP_W_LITERAL_SUFFIX mapping. * gcc/c-family/c-opts.c (c_common_handle_option): Handle OPT_Wliteral_suffix. * gcc/c-family/c.opt: Add Wliteral-suffix. * gcc/doc/invoke.texi (Wliteral-suffix): Document new option. * gcc/testsuite/g++.dg/cpp0x/Wliteral-suffix.c: New test. * libcpp/include/cpplib.h (struct cpp_options): Add new field, warn_literal_suffix. (CPP_W_LITERAL_SUFFIX): New enum. * libcpp/init.c (cpp_create_reader): Default initialization of warn_literal_suffix. * libcpp/lex.c (lex_raw_string): Treat user-defined literals which don't begin with '_' as separate tokens and produce a warning. (lex_string): Ditto. From-SVN: r186909
This commit is contained in:
parent
11ec770e46
commit
7f5f5f98c5
|
|
@ -1,3 +1,7 @@
|
||||||
|
2012-04-27 Ollie Wild <aaw@google.com>
|
||||||
|
|
||||||
|
* doc/invoke.texi (Wliteral-suffix): Document new option.
|
||||||
|
|
||||||
2012-04-27 Tom Tromey <tromey@redhat.com>
|
2012-04-27 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
* dwarf2out.c (dwarf_stack_op_name): Use get_DW_OP_name.
|
* dwarf2out.c (dwarf_stack_op_name): Use get_DW_OP_name.
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
2012-04-27 Ollie Wild <aaw@google.com>
|
||||||
|
|
||||||
|
* c-common.c: Add CPP_W_LITERAL_SUFFIX mapping.
|
||||||
|
* c-opts.c (c_common_handle_option): Handle OPT_Wliteral_suffix.
|
||||||
|
* c.opt: Add Wliteral-suffix.
|
||||||
|
|
||||||
2012-04-22 Manuel López-Ibáñez <manu@gcc.gnu.org>
|
2012-04-22 Manuel López-Ibáñez <manu@gcc.gnu.org>
|
||||||
|
|
||||||
PR c/44774
|
PR c/44774
|
||||||
|
|
|
||||||
|
|
@ -8820,6 +8820,7 @@ static const struct reason_option_codes_t option_codes[] = {
|
||||||
{CPP_W_NORMALIZE, OPT_Wnormalized_},
|
{CPP_W_NORMALIZE, OPT_Wnormalized_},
|
||||||
{CPP_W_INVALID_PCH, OPT_Winvalid_pch},
|
{CPP_W_INVALID_PCH, OPT_Winvalid_pch},
|
||||||
{CPP_W_WARNING_DIRECTIVE, OPT_Wcpp},
|
{CPP_W_WARNING_DIRECTIVE, OPT_Wcpp},
|
||||||
|
{CPP_W_LITERAL_SUFFIX, OPT_Wliteral_suffix},
|
||||||
{CPP_W_NONE, 0}
|
{CPP_W_NONE, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -476,6 +476,10 @@ c_common_handle_option (size_t scode, const char *arg, int value,
|
||||||
cpp_opts->warn_invalid_pch = value;
|
cpp_opts->warn_invalid_pch = value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OPT_Wliteral_suffix:
|
||||||
|
cpp_opts->warn_literal_suffix = value;
|
||||||
|
break;
|
||||||
|
|
||||||
case OPT_Wlong_long:
|
case OPT_Wlong_long:
|
||||||
cpp_opts->cpp_warn_long_long = value;
|
cpp_opts->cpp_warn_long_long = value;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -449,6 +449,10 @@ Wjump-misses-init
|
||||||
C ObjC Var(warn_jump_misses_init) Init(-1) Warning
|
C ObjC Var(warn_jump_misses_init) Init(-1) Warning
|
||||||
Warn when a jump misses a variable initialization
|
Warn when a jump misses a variable initialization
|
||||||
|
|
||||||
|
Wliteral-suffix
|
||||||
|
C++ ObjC++ Warning
|
||||||
|
Warn when a string or character literal is followed by a ud-suffix which does not begin with an underscore.
|
||||||
|
|
||||||
Wlogical-op
|
Wlogical-op
|
||||||
C ObjC C++ ObjC++ Var(warn_logical_op) Init(0) Warning
|
C ObjC C++ ObjC++ Var(warn_logical_op) Init(0) Warning
|
||||||
Warn when a logical operator is suspiciously always evaluating to true or false
|
Warn when a logical operator is suspiciously always evaluating to true or false
|
||||||
|
|
|
||||||
|
|
@ -198,8 +198,8 @@ in the following sections.
|
||||||
-fno-default-inline -fvisibility-inlines-hidden @gol
|
-fno-default-inline -fvisibility-inlines-hidden @gol
|
||||||
-fvisibility-ms-compat @gol
|
-fvisibility-ms-compat @gol
|
||||||
-Wabi -Wconversion-null -Wctor-dtor-privacy @gol
|
-Wabi -Wconversion-null -Wctor-dtor-privacy @gol
|
||||||
-Wdelete-non-virtual-dtor -Wnarrowing -Wnoexcept @gol
|
-Wdelete-non-virtual-dtor -Wliteral-suffix -Wnarrowing @gol
|
||||||
-Wnon-virtual-dtor -Wreorder @gol
|
-Wnoexcept -Wnon-virtual-dtor -Wreorder @gol
|
||||||
-Weffc++ -Wstrict-null-sentinel @gol
|
-Weffc++ -Wstrict-null-sentinel @gol
|
||||||
-Wno-non-template-friend -Wold-style-cast @gol
|
-Wno-non-template-friend -Wold-style-cast @gol
|
||||||
-Woverloaded-virtual -Wno-pmf-conversions @gol
|
-Woverloaded-virtual -Wno-pmf-conversions @gol
|
||||||
|
|
@ -2425,6 +2425,30 @@ an instance of a derived class through a pointer to a base class if the
|
||||||
base class does not have a virtual destructor. This warning is enabled
|
base class does not have a virtual destructor. This warning is enabled
|
||||||
by @option{-Wall}.
|
by @option{-Wall}.
|
||||||
|
|
||||||
|
@item -Wliteral-suffix @r{(C++ and Objective-C++ only)}
|
||||||
|
@opindex Wliteral-suffix
|
||||||
|
@opindex Wno-literal-suffix
|
||||||
|
Warn when a string or character literal is followed by a ud-suffix which does
|
||||||
|
not begin with an underscore. As a conforming extension, GCC treats such
|
||||||
|
suffixes as separate preprocessing tokens in order to maintain backwards
|
||||||
|
compatibility with code that uses formatting macros from @code{<inttypes.h>}.
|
||||||
|
For example:
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
#define __STDC_FORMAT_MACROS
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main() @{
|
||||||
|
int64_t i64 = 123;
|
||||||
|
printf("My int64: %"PRId64"\n", i64);
|
||||||
|
@}
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
In this case, @code{PRId64} is treated as a separate preprocessing token.
|
||||||
|
|
||||||
|
This warning is enabled by default.
|
||||||
|
|
||||||
@item -Wnarrowing @r{(C++ and Objective-C++ only)}
|
@item -Wnarrowing @r{(C++ and Objective-C++ only)}
|
||||||
@opindex Wnarrowing
|
@opindex Wnarrowing
|
||||||
@opindex Wno-narrowing
|
@opindex Wno-narrowing
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
2012-04-27 Ollie Wild <aaw@google.com>
|
||||||
|
|
||||||
|
* g++.dg/cpp0x/Wliteral-suffix.c: New test.
|
||||||
|
|
||||||
2012-04-27 Paolo Bonzini <bonzini@gnu.org>
|
2012-04-27 Paolo Bonzini <bonzini@gnu.org>
|
||||||
|
|
||||||
* gcc.c-torture/execute/20120427-2.c: New testcase.
|
* gcc.c-torture/execute/20120427-2.c: New testcase.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
// { dg-do run }
|
||||||
|
// { dg-options "-std=c++0x" }
|
||||||
|
|
||||||
|
// Make sure -Wliteral-suffix is enabled by default and
|
||||||
|
// triggers as expected.
|
||||||
|
|
||||||
|
#define BAR "bar"
|
||||||
|
#define PLUS_ONE + 1
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
test()
|
||||||
|
{
|
||||||
|
char c = '3'PLUS_ONE; // { dg-warning "invalid suffix on literal" }
|
||||||
|
char s[] = "foo"BAR; // { dg-warning "invalid suffix on literal" }
|
||||||
|
|
||||||
|
assert(c == '4');
|
||||||
|
assert(s[3] != '\0');
|
||||||
|
assert(s[3] == 'b');
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
test();
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,14 @@
|
||||||
|
2012-04-27 Ollie Wild <aaw@google.com>
|
||||||
|
|
||||||
|
* include/cpplib.h (struct cpp_options): Add new field,
|
||||||
|
warn_literal_suffix.
|
||||||
|
(CPP_W_LITERAL_SUFFIX): New enum.
|
||||||
|
* init.c (cpp_create_reader): Default initialization of
|
||||||
|
warn_literal_suffix.
|
||||||
|
* lex.c (lex_raw_string): Treat user-defined literals which don't
|
||||||
|
begin with '_' as separate tokens and produce a warning.
|
||||||
|
(lex_string): Ditto.
|
||||||
|
|
||||||
2012-04-26 Manuel López-Ibáñez <manu@gcc.gnu.org>
|
2012-04-26 Manuel López-Ibáñez <manu@gcc.gnu.org>
|
||||||
|
|
||||||
* line-map.c (linemap_resolve_location): Synchronize comments with
|
* line-map.c (linemap_resolve_location): Synchronize comments with
|
||||||
|
|
|
||||||
|
|
@ -427,6 +427,10 @@ struct cpp_options
|
||||||
/* Nonzero for C++ 2011 Standard user-defnied literals. */
|
/* Nonzero for C++ 2011 Standard user-defnied literals. */
|
||||||
unsigned char user_literals;
|
unsigned char user_literals;
|
||||||
|
|
||||||
|
/* Nonzero means warn when a string or character literal is followed by a
|
||||||
|
ud-suffix which does not beging with an underscore. */
|
||||||
|
unsigned char warn_literal_suffix;
|
||||||
|
|
||||||
/* Holds the name of the target (execution) character set. */
|
/* Holds the name of the target (execution) character set. */
|
||||||
const char *narrow_charset;
|
const char *narrow_charset;
|
||||||
|
|
||||||
|
|
@ -906,7 +910,8 @@ enum {
|
||||||
CPP_W_CXX_OPERATOR_NAMES,
|
CPP_W_CXX_OPERATOR_NAMES,
|
||||||
CPP_W_NORMALIZE,
|
CPP_W_NORMALIZE,
|
||||||
CPP_W_INVALID_PCH,
|
CPP_W_INVALID_PCH,
|
||||||
CPP_W_WARNING_DIRECTIVE
|
CPP_W_WARNING_DIRECTIVE,
|
||||||
|
CPP_W_LITERAL_SUFFIX
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Output a diagnostic of some kind. */
|
/* Output a diagnostic of some kind. */
|
||||||
|
|
|
||||||
|
|
@ -175,6 +175,7 @@ cpp_create_reader (enum c_lang lang, hash_table *table,
|
||||||
CPP_OPTION (pfile, warn_variadic_macros) = 1;
|
CPP_OPTION (pfile, warn_variadic_macros) = 1;
|
||||||
CPP_OPTION (pfile, warn_builtin_macro_redefined) = 1;
|
CPP_OPTION (pfile, warn_builtin_macro_redefined) = 1;
|
||||||
CPP_OPTION (pfile, warn_normalize) = normalized_C;
|
CPP_OPTION (pfile, warn_normalize) = normalized_C;
|
||||||
|
CPP_OPTION (pfile, warn_literal_suffix) = 1;
|
||||||
|
|
||||||
/* Default CPP arithmetic to something sensible for the host for the
|
/* Default CPP arithmetic to something sensible for the host for the
|
||||||
benefit of dumb users like fix-header. */
|
benefit of dumb users like fix-header. */
|
||||||
|
|
|
||||||
44
libcpp/lex.c
44
libcpp/lex.c
|
|
@ -1553,14 +1553,30 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base,
|
||||||
|
|
||||||
if (CPP_OPTION (pfile, user_literals))
|
if (CPP_OPTION (pfile, user_literals))
|
||||||
{
|
{
|
||||||
|
/* According to C++11 [lex.ext]p10, a ud-suffix not starting with an
|
||||||
|
underscore is ill-formed. Since this breaks programs using macros
|
||||||
|
from inttypes.h, we generate a warning and treat the ud-suffix as a
|
||||||
|
separate preprocessing token. This approach is under discussion by
|
||||||
|
the standards committee, and has been adopted as a conforming
|
||||||
|
extension by other front ends such as clang. */
|
||||||
|
if (ISALPHA (*cur))
|
||||||
|
{
|
||||||
|
// Raise a warning, but do not consume subsequent tokens.
|
||||||
|
if (CPP_OPTION (pfile, warn_literal_suffix))
|
||||||
|
cpp_warning_with_line (pfile, CPP_W_LITERAL_SUFFIX,
|
||||||
|
token->src_loc, 0,
|
||||||
|
"invalid suffix on literal; C++11 requires "
|
||||||
|
"a space between literal and identifier");
|
||||||
|
}
|
||||||
/* Grab user defined literal suffix. */
|
/* Grab user defined literal suffix. */
|
||||||
if (ISIDST (*cur))
|
else if (*cur == '_')
|
||||||
{
|
{
|
||||||
type = cpp_userdef_string_add_type (type);
|
type = cpp_userdef_string_add_type (type);
|
||||||
++cur;
|
++cur;
|
||||||
|
|
||||||
|
while (ISIDNUM (*cur))
|
||||||
|
++cur;
|
||||||
}
|
}
|
||||||
while (ISIDNUM (*cur))
|
|
||||||
++cur;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pfile->buffer->cur = cur;
|
pfile->buffer->cur = cur;
|
||||||
|
|
@ -1668,15 +1684,31 @@ lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base)
|
||||||
|
|
||||||
if (CPP_OPTION (pfile, user_literals))
|
if (CPP_OPTION (pfile, user_literals))
|
||||||
{
|
{
|
||||||
|
/* According to C++11 [lex.ext]p10, a ud-suffix not starting with an
|
||||||
|
underscore is ill-formed. Since this breaks programs using macros
|
||||||
|
from inttypes.h, we generate a warning and treat the ud-suffix as a
|
||||||
|
separate preprocessing token. This approach is under discussion by
|
||||||
|
the standards committee, and has been adopted as a conforming
|
||||||
|
extension by other front ends such as clang. */
|
||||||
|
if (ISALPHA (*cur))
|
||||||
|
{
|
||||||
|
// Raise a warning, but do not consume subsequent tokens.
|
||||||
|
if (CPP_OPTION (pfile, warn_literal_suffix))
|
||||||
|
cpp_warning_with_line (pfile, CPP_W_LITERAL_SUFFIX,
|
||||||
|
token->src_loc, 0,
|
||||||
|
"invalid suffix on literal; C++11 requires "
|
||||||
|
"a space between literal and identifier");
|
||||||
|
}
|
||||||
/* Grab user defined literal suffix. */
|
/* Grab user defined literal suffix. */
|
||||||
if (ISIDST (*cur))
|
else if (*cur == '_')
|
||||||
{
|
{
|
||||||
type = cpp_userdef_char_add_type (type);
|
type = cpp_userdef_char_add_type (type);
|
||||||
type = cpp_userdef_string_add_type (type);
|
type = cpp_userdef_string_add_type (type);
|
||||||
++cur;
|
++cur;
|
||||||
|
|
||||||
|
while (ISIDNUM (*cur))
|
||||||
|
++cur;
|
||||||
}
|
}
|
||||||
while (ISIDNUM (*cur))
|
|
||||||
++cur;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pfile->buffer->cur = cur;
|
pfile->buffer->cur = cur;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue