Bug 37041 - -Wc++-compat refinements
Summary: -Wc++-compat refinements
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.4.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on: 40564
Blocks:
  Show dependency treegraph
 
Reported: 2008-08-06 20:53 UTC by Joseph S. Myers
Modified: 2015-03-06 18:56 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2008-08-07 11:54:54


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Joseph S. Myers 2008-08-06 20:53:40 UTC
-Wc++-compat should allow bool, wchar_t, char16_t and char32_t as typedefs
defined in system headers, while warning if they are used other than as types
or the typedefs are defined other than in system headers.

-Wc++-compat should warn for asm and inline when used in a C mode where they
are identifiers not keywords, but not in a mode when they are keywords and
not for the __ variants in any case.

-Wc++-compat should warn for uses of the alternative representations for
operators and punctuators such as "and", including uses as macro names (except
when defined in system headers, because of iso646.h) and macro parameter names.
Comment 1 Manuel López-Ibáñez 2008-08-07 11:54:53 UTC
Confirmed as enhancement.

To clarify how to implement this, I have some questions:

(In reply to comment #0)
> -Wc++-compat should allow bool, wchar_t, char16_t and char32_t as typedefs
> defined in system headers, while warning if they are used other than as types
> or the typedefs are defined other than in system headers.

This will require:

* a check in CPP when defining new macros. It should probably allow also to be used as macro name if defined in system header (#define bool _Bool).

* various checks in c-parser.c or c-decl.c to check for
   a) typedefs outside system headers.
   b) Names except for types.

> -Wc++-compat should warn for asm and inline when used in a C mode where they
> are identifiers not keywords, but not in a mode when they are keywords and
> not for the __ variants in any case.

I think that not checking the __ variants is given. I don't understand what you mean by "not in a mode when they are keywords". My understanding is that we should warn always that they are used as names (type names, identifiers, macro names, macro parameters) and never when they are keywords (independently of the C mode).

> -Wc++-compat should warn for uses of the alternative representations for
> operators and punctuators such as "and", including uses as macro names (except
> when defined in system headers, because of iso646.h) and macro parameter names.

Hence:

* a check in CPP when defining new macros.

* various checks in c-parser.c or c-decl.c to check for names. Any use here is wrong. (CPP would have already replaced 'and' if it is a macro).


Am I missing something?

Cheers,

Manuel.

Comment 2 joseph@codesourcery.com 2008-08-07 12:04:07 UTC
Subject: Re:  -Wc++-compat refinements

On Thu, 7 Aug 2008, manu at gcc dot gnu dot org wrote:

> To clarify how to implement this, I have some questions:
> 
> (In reply to comment #0)
> > -Wc++-compat should allow bool, wchar_t, char16_t and char32_t as typedefs
> > defined in system headers, while warning if they are used other than as types
> > or the typedefs are defined other than in system headers.
> 
> This will require:
> 
> * a check in CPP when defining new macros. It should probably allow also to be
> used as macro name if defined in system header (#define bool _Bool).

I see no need for macro checks for these type names; the check should be 
for when they reach the C parser as identifiers, just like the checks for 
other C++ keywords both with the restriction on context.  Because they are 
keywords in C++, C++ programs could also define them as macros.

> > -Wc++-compat should warn for asm and inline when used in a C mode where they
> > are identifiers not keywords, but not in a mode when they are keywords and
> > not for the __ variants in any case.
> 
> I think that not checking the __ variants is given. I don't understand what you
> mean by "not in a mode when they are keywords". My understanding is that we
> should warn always that they are used as names (type names, identifiers, macro
> names, macro parameters) and never when they are keywords (independently of the
> C mode).

With -std=c89 -Wc++-compat, both are identifiers and both should be warned 
for when they reach the C parser as identifiers.  No warnings for 
preprocessor uses are needed.

With -std=gnu89 -Wc++-compat, both are keywords and neither should be 
warned for.

With -std=c99 -Wc++-compat, inline is a keyword and should not be warned 
for, but asm is an identifier and should be warned for.

> > -Wc++-compat should warn for uses of the alternative representations for
> > operators and punctuators such as "and", including uses as macro names (except
> > when defined in system headers, because of iso646.h) and macro parameter names.
> 
> Hence:
> 
> * a check in CPP when defining new macros.
> 
> * various checks in c-parser.c or c-decl.c to check for names. Any use here is
> wrong. (CPP would have already replaced 'and' if it is a macro).

That seems right.  If they reach the parser they can probably be handled 
just like the existing -Wc++-compat warnings (put in the keyword table for 
warning, but never actually handled as keywords), but additional 
preprocessor checks are needed as well.  (The relevant preprocessor cases 
give errors in C++.)

Comment 3 Ian Lance Taylor 2009-06-12 21:07:09 UTC
-Wc++-compat now warns about alternative representations for operators and punctuators such as "and".  The other issues have not yet been addressed.
Comment 4 Manuel López-Ibáñez 2010-07-03 20:10:19 UTC
We should collect individual Wc++-compat issues here.
Comment 5 Eric Gallager 2014-12-22 04:39:56 UTC
A few other refinements to -Wc++-compat that I would like to see:

1. Have it properly handle stuff like the following idiom commonly found in header files:

#ifdef __cplusplus
extern "C" {
#endif

/* code that is C-only */

#ifdef __cplusplus
}
#endif /* __cplusplus */

I would expect -Wc++-compat to treat something like the above similarly to how the following pragmas would work:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc++-compat"

/* code that -Wc++-compat should ignore */

#pragma GCC diagnostic pop

While the version with pragmas is shorter, the `extern "C"` stuff is often needed for separate reasons, and as such, it would be nice to avoid the need to do both...

2. Make -Wc++-compat an "umbrella" warning flag like -Wall or -Wextra. Currently -Wc++-compat warns about many different things, and sometimes I would like to just focus on one of those things. I can think of at least the following sub-flags that could be split off from it:
** "-Wc++-compat-pointer-conversion" for the ones like "warning: request for implicit conversion from 'void *' to 'char *' not permitted in C++"
** "-Wc++-compat-keywords" for the ones like "warning: identifier 'class' conflicts with C++ keyword"
** "-Wc++-compat-visibility" for the ones like "warning: enum constant defined in struct or union is not visible in C++" (or likewise with "struct" or "union" instead of "enum constant")
Comment 6 Manuel López-Ibáñez 2014-12-22 19:39:20 UTC
(In reply to Eric Gallager from comment #5)
> #ifdef __cplusplus
> extern "C" {
> #endif
> 
> /* code that is C-only */

This is not what extern "C" means. The code still needs to be valid C++ and this is why -Wc++-compat would be useful here. For example, this is not valid C++ despite being valid C, and -Wc++-compat rightly warns you about it:

#ifdef __cplusplus
extern "C" {
#endif
/* code that is C-only */
int and(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */


> 2. Make -Wc++-compat an "umbrella" warning flag like -Wall or -Wextra.

My guess is that if/when existing GCC developers have time to work on -Wc++-compat, they will likely focus on fixing the missing warnings and particularly invalid warnings, rather than figuring out how to refine -Wc++-compat. But we always welcome new developers (https://gcc.gnu.org/wiki/GettingStarted#Basics:_Contributing_to_GCC_in_10_easy_steps).
Comment 7 Eric Gallager 2015-03-06 18:56:38 UTC
(In reply to Manuel López-Ibáñez from comment #6)
> (In reply to Eric Gallager from comment #5)
> > #ifdef __cplusplus
> > extern "C" {
> > #endif
> > 
> > /* code that is C-only */
> 
> This is not what extern "C" means. The code still needs to be valid C++ and
> this is why -Wc++-compat would be useful here. For example, this is not
> valid C++ despite being valid C, and -Wc++-compat rightly warns you about it:
> 
> #ifdef __cplusplus
> extern "C" {
> #endif
> /* code that is C-only */
> int and(void);
> #ifdef __cplusplus
> }
> #endif /* __cplusplus */
> 

Oops, I made my example needlessly complicated. I should have just said:

#ifndef __cplusplus
/* code that is C-only */
int and(void);
#endif /* !__cplusplus */