Skip to content
Snippets Groups Projects
  • Dodji Seketeli's avatar
    0b2c4be5
    PR preprocessor/7263 - Avoid pedantic warnings on system headers macro tokens · 0b2c4be5
    Dodji Seketeli authored
    Now that we track token locations accross macro expansions, it would
    be cool to be able to fix PR preprocessor/7263 for real.  That is,
    consider this example where we have a system header named header.h
    like this:
    
    	#define _Complex __complex__ #define _Complex_I 1.0iF
    
    and then a normal C file like this:
    
        #include "header.h"
    
        static _Complex float c = _Complex_I;
    
    If we compile the file with -pedantic, the usages of _Complex or
    _Complex_I should not trigger any warning, even though __complex__ and
    the complex literal are extensions to the standard C.
    
    They shouldn't trigger any warning because _Complex and _Complex_I are
    defined in a system header (and expanded in normal user code).
    
    To be able to handle this, we must address two separate concerns.
    
    First, warnings about non-standard usage of numerical literals are emitted
    directly from within libcpp.  So we must teach libcpp's parser for numerical
    literals to use virtual locations, instead of the spelling
    location it uses today.  Once we have that, as the diagnostics machinery
    already knows how to avoid emitting errors happening on tokens that come from
    system headers, we win.
    
    Second, there is the issue of tracking locations for declaration
    specifiers, like the "_Complex" in the declaration:
    
    	static _Complex float c;
    
    For that, we need to arrange for each possible declaration specifier
    to have its own location, because otherwise, we'd warn on e.g, on:
    
        _Complex float c;
    
    but not on:
    
        static _Complex float c;
    
    So this patch addresses the two concerns above.  It's actually a
    follow-up on an earlier patch[1] I wrote as part of my initial work on
    virtual locations.  We then agreed[2] that the second concern was
    important to address before the patch could get a chance to go in.
    
    [1]: http://gcc.gnu.org/ml/gcc-patches/2011-09/msg00957.html
    [2]: http://gcc.gnu.org/ml/gcc-patches/2011-10/msg00264.html
    
    Bootstrapped and tested on x86_64-unknown-linux-gnu against trunk.
    
    libcpp/
    
    	PR preprocessor/7263
    	* include/cpplib.h (cpp_classify_number): Take a location
    	parameter.
    	* expr.c (SYNTAX_ERROR_AT, SYNTAX_ERROR2_AT): New diagnostic
    	macros that take a location parameter.
    	(cpp_classify_number): Take a (virtual) location parameter.  Use
    	it for diagnostics.  Adjust comments.
    	(eval_token): Take a location parameter.  Pass it to
    	cpp_classify_number and to diagnostic routines.
    	(_cpp_parse_expr): Use virtual locations of tokens when parsing
    	expressions.  Pass a virtual location to eval_token and to
    	diagnostic routines.
    
    gcc/c-family/
    
    	PR preprocessor/7263
    	* c-lex.c (c_lex_with_flags):  Pass a virtual location to the call
    	to cpp_classify_number.  For diagnostics, use the precise location
    	instead of the global input_location.
    
    gcc/
    	PR preprocessor/7263
    	* c-tree.h (enum c_declspec_word): Declare new enum.
    	(struct c_declspecs::locations): New member.
    	(declspecs_add_qual, declspecs_add_scspec)
    	(declspecs_add_addrspace, declspecs_add_alignas): Take a new
    	location parameter.
    	* c-decl.c (build_null_declspecs): Initialize the new struct
    	c_declspecs::locations member.
    	(declspecs_add_addrspace): Take a location parameter for the
    	address space.  Store it onto declaration specifiers.
    	(declspecs_add_qual): Likewise, take a location parameter for the
    	qualifier.
    	(declspecs_add_type): Likewise, take a location parameter for the
    	type specifier.
    	(declspecs_add_scspec): Likewise, take a location parameter for
    	the storage class specifier.
    	(declspecs_add_attrs): Likewise, take a location parameter for the
    	first attribute.
    	(declspecs_add_alignas): Likewise, take a location parameter for
    	the alignas token.
    	(finish_declspecs): For diagnostics, use the location of the
    	relevant declspec, instead of the global input_location.
    	* c-parser.c (c_parser_parameter_declaration): Pass the precise
    	virtual location of the declspec to the declspecs-setters.
    	(c_parser_declspecs): Likewise.  Avoid calling c_parser_peek_token
    	repeatedly.
    
    gcc/cp/
    
    	PR preprocessor/7263
    	* cp-tree.h (enum cp_decl_spec): Add new enumerators to cover all
    	the possible declarator specifiers so far.
    	(struct cp_decl_specifier_seq::locations): Declare new member.
    	(cp_decl_specifier_seq::{specs, type_location}): Remove.
    	(decl_spec_seq_has_spec_p): Declare new function.
    	* parser.c (cp_parser_check_decl_spec): Remove.
    	(set_and_check_decl_spec_loc): Define new static function.
    	(decl_spec_seq_has_spec_p): Define new public function.
    	(cp_parser_decl_specifier_seq, cp_parser_function_specifier_opt)
    	(cp_parser_type_specifier, cp_parser_simple_type_specifier)
    	(cp_parser_set_storage_class, cp_parser_set_decl_spec_type)
    	(cp_parser_alias_declaration): Set the locations for each
    	declspec, using set_and_check_decl_spec_loc.
    	(cp_parser_explicit_instantiation, cp_parser_init_declarator)
    	(cp_parser_member_declaration, cp_parser_init_declarator): Use the
    	new declspec location for specifiers.  Use the new
    	decl_spec_seq_has_spec_p.
    	(cp_parser_type_specifier_seq): Use the new
    	set_and_check_decl_spec_loc.  Stop using
    	cp_parser_check_decl_spec.  Use the new decl_spec_seq_has_spec_p.
    	(, cp_parser_init_declarator): Use the new
    	set_and_check_decl_spec_loc.
    	(cp_parser_single_declaration, cp_parser_friend_p)
    	(cp_parser_objc_class_ivars, cp_parser_objc_struct_declaration):
    	Use the new decl_spec_seq_has_spec_p.
    	* decl.c (check_tag_decl): Use new decl_spec_seq_has_spec_p.  Use
    	the more precise ds_redefined_builtin_type_spec location for
    	diagnostics about re-declaring C++ built-in types.
    	(start_decl, grokvardecl, grokdeclarator): Use the new
    	decl_spec_seq_has_spec_p.
    
    gcc/testsuite/
    
    	PR preprocessor/7263
    	* gcc.dg/binary-constants-2.c: Run without tracking locations
    	accross macro expansion.
    	* gcc.dg/binary-constants-3.c: Likewise.
    	* gcc.dg/cpp/sysmac2.c: Likewise.
    	* testsuite/gcc.dg/nofixed-point-2.c: Adjust for more precise
    	location.
    	* gcc.dg/cpp/syshdr3.c: New test.
    	* gcc.dg/cpp/syshdr3.h: New header for the new test above.
    	* gcc.dg/system-binary-constants-1.c: New test.
    	* gcc.dg/system-binary-constants-1.h: New header for the new test
    	above.
    	* g++.dg/cpp/syshdr3.C: New test.
    	* g++.dg/cpp/syshdr3.h: New header the new test above.
    	* g++.dg/system-binary-constants-1.C: New test.
    	* g++.dg/system-binary-constants-1.h: New header the new test
    	above.
    
    From-SVN: r187587
    0b2c4be5
    History
    PR preprocessor/7263 - Avoid pedantic warnings on system headers macro tokens
    Dodji Seketeli authored
    Now that we track token locations accross macro expansions, it would
    be cool to be able to fix PR preprocessor/7263 for real.  That is,
    consider this example where we have a system header named header.h
    like this:
    
    	#define _Complex __complex__ #define _Complex_I 1.0iF
    
    and then a normal C file like this:
    
        #include "header.h"
    
        static _Complex float c = _Complex_I;
    
    If we compile the file with -pedantic, the usages of _Complex or
    _Complex_I should not trigger any warning, even though __complex__ and
    the complex literal are extensions to the standard C.
    
    They shouldn't trigger any warning because _Complex and _Complex_I are
    defined in a system header (and expanded in normal user code).
    
    To be able to handle this, we must address two separate concerns.
    
    First, warnings about non-standard usage of numerical literals are emitted
    directly from within libcpp.  So we must teach libcpp's parser for numerical
    literals to use virtual locations, instead of the spelling
    location it uses today.  Once we have that, as the diagnostics machinery
    already knows how to avoid emitting errors happening on tokens that come from
    system headers, we win.
    
    Second, there is the issue of tracking locations for declaration
    specifiers, like the "_Complex" in the declaration:
    
    	static _Complex float c;
    
    For that, we need to arrange for each possible declaration specifier
    to have its own location, because otherwise, we'd warn on e.g, on:
    
        _Complex float c;
    
    but not on:
    
        static _Complex float c;
    
    So this patch addresses the two concerns above.  It's actually a
    follow-up on an earlier patch[1] I wrote as part of my initial work on
    virtual locations.  We then agreed[2] that the second concern was
    important to address before the patch could get a chance to go in.
    
    [1]: http://gcc.gnu.org/ml/gcc-patches/2011-09/msg00957.html
    [2]: http://gcc.gnu.org/ml/gcc-patches/2011-10/msg00264.html
    
    Bootstrapped and tested on x86_64-unknown-linux-gnu against trunk.
    
    libcpp/
    
    	PR preprocessor/7263
    	* include/cpplib.h (cpp_classify_number): Take a location
    	parameter.
    	* expr.c (SYNTAX_ERROR_AT, SYNTAX_ERROR2_AT): New diagnostic
    	macros that take a location parameter.
    	(cpp_classify_number): Take a (virtual) location parameter.  Use
    	it for diagnostics.  Adjust comments.
    	(eval_token): Take a location parameter.  Pass it to
    	cpp_classify_number and to diagnostic routines.
    	(_cpp_parse_expr): Use virtual locations of tokens when parsing
    	expressions.  Pass a virtual location to eval_token and to
    	diagnostic routines.
    
    gcc/c-family/
    
    	PR preprocessor/7263
    	* c-lex.c (c_lex_with_flags):  Pass a virtual location to the call
    	to cpp_classify_number.  For diagnostics, use the precise location
    	instead of the global input_location.
    
    gcc/
    	PR preprocessor/7263
    	* c-tree.h (enum c_declspec_word): Declare new enum.
    	(struct c_declspecs::locations): New member.
    	(declspecs_add_qual, declspecs_add_scspec)
    	(declspecs_add_addrspace, declspecs_add_alignas): Take a new
    	location parameter.
    	* c-decl.c (build_null_declspecs): Initialize the new struct
    	c_declspecs::locations member.
    	(declspecs_add_addrspace): Take a location parameter for the
    	address space.  Store it onto declaration specifiers.
    	(declspecs_add_qual): Likewise, take a location parameter for the
    	qualifier.
    	(declspecs_add_type): Likewise, take a location parameter for the
    	type specifier.
    	(declspecs_add_scspec): Likewise, take a location parameter for
    	the storage class specifier.
    	(declspecs_add_attrs): Likewise, take a location parameter for the
    	first attribute.
    	(declspecs_add_alignas): Likewise, take a location parameter for
    	the alignas token.
    	(finish_declspecs): For diagnostics, use the location of the
    	relevant declspec, instead of the global input_location.
    	* c-parser.c (c_parser_parameter_declaration): Pass the precise
    	virtual location of the declspec to the declspecs-setters.
    	(c_parser_declspecs): Likewise.  Avoid calling c_parser_peek_token
    	repeatedly.
    
    gcc/cp/
    
    	PR preprocessor/7263
    	* cp-tree.h (enum cp_decl_spec): Add new enumerators to cover all
    	the possible declarator specifiers so far.
    	(struct cp_decl_specifier_seq::locations): Declare new member.
    	(cp_decl_specifier_seq::{specs, type_location}): Remove.
    	(decl_spec_seq_has_spec_p): Declare new function.
    	* parser.c (cp_parser_check_decl_spec): Remove.
    	(set_and_check_decl_spec_loc): Define new static function.
    	(decl_spec_seq_has_spec_p): Define new public function.
    	(cp_parser_decl_specifier_seq, cp_parser_function_specifier_opt)
    	(cp_parser_type_specifier, cp_parser_simple_type_specifier)
    	(cp_parser_set_storage_class, cp_parser_set_decl_spec_type)
    	(cp_parser_alias_declaration): Set the locations for each
    	declspec, using set_and_check_decl_spec_loc.
    	(cp_parser_explicit_instantiation, cp_parser_init_declarator)
    	(cp_parser_member_declaration, cp_parser_init_declarator): Use the
    	new declspec location for specifiers.  Use the new
    	decl_spec_seq_has_spec_p.
    	(cp_parser_type_specifier_seq): Use the new
    	set_and_check_decl_spec_loc.  Stop using
    	cp_parser_check_decl_spec.  Use the new decl_spec_seq_has_spec_p.
    	(, cp_parser_init_declarator): Use the new
    	set_and_check_decl_spec_loc.
    	(cp_parser_single_declaration, cp_parser_friend_p)
    	(cp_parser_objc_class_ivars, cp_parser_objc_struct_declaration):
    	Use the new decl_spec_seq_has_spec_p.
    	* decl.c (check_tag_decl): Use new decl_spec_seq_has_spec_p.  Use
    	the more precise ds_redefined_builtin_type_spec location for
    	diagnostics about re-declaring C++ built-in types.
    	(start_decl, grokvardecl, grokdeclarator): Use the new
    	decl_spec_seq_has_spec_p.
    
    gcc/testsuite/
    
    	PR preprocessor/7263
    	* gcc.dg/binary-constants-2.c: Run without tracking locations
    	accross macro expansion.
    	* gcc.dg/binary-constants-3.c: Likewise.
    	* gcc.dg/cpp/sysmac2.c: Likewise.
    	* testsuite/gcc.dg/nofixed-point-2.c: Adjust for more precise
    	location.
    	* gcc.dg/cpp/syshdr3.c: New test.
    	* gcc.dg/cpp/syshdr3.h: New header for the new test above.
    	* gcc.dg/system-binary-constants-1.c: New test.
    	* gcc.dg/system-binary-constants-1.h: New header for the new test
    	above.
    	* g++.dg/cpp/syshdr3.C: New test.
    	* g++.dg/cpp/syshdr3.h: New header the new test above.
    	* g++.dg/system-binary-constants-1.C: New test.
    	* g++.dg/system-binary-constants-1.h: New header the new test
    	above.
    
    From-SVN: r187587