Skip to content

Commit

Permalink
compilers: c: add Modern C -Werrors for GCC, Clang
Browse files Browse the repository at this point in the history
Add the following flags to error out by default via a new default-on 'Dc_legal_code'
option for GCC and Clang:
* -Werror=implicit (-> -Werror=implicit-int,implicit-function-declaration)
* -Werror=int-conversion
* -Werror=incompatible-pointer-types

Implicit function declarations were removed in C99 with no deprecation
period because of how dangerous they are.

Implicit conversions between integers and pointers were also never
allowed in >= C89.

These were allowed by GCC and Clang until recently for compatibility
reasons:
* GCC plans to make these errors by default in GCC 14
* Clang made -Werror=int-conversion a default error in Clang 15 and made
the others an error in Clang 16

The reason for Meson to do this even for older compilers is straightforward:
* It'll take time for these newer versions to propagate into distributions.
* The code emitting these is broken *now*.
* Projects like PipeWire and various GNOME components are adding these flags
manually to catch them already.

Signed-off-by: Sam James <[email protected]>
  • Loading branch information
thesamesam committed Jan 2, 2024
1 parent e110fae commit 51eb5ac
Showing 1 changed file with 27 additions and 2 deletions.
29 changes: 27 additions & 2 deletions mesonbuild/compilers/c.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,14 @@ def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_

def get_options(self) -> 'MutableKeyedOptionDictType':
opts = super().get_options()

opts.update({
OptionKey('legal_code', machine=self.for_machine, lang=self.language): coredata.UserBooleanOption(
'Ban use of dangerous constructs',
True
)
})

if self.info.is_windows() or self.info.is_cygwin():
opts.update({
OptionKey('winlibs', machine=self.for_machine, lang=self.language): coredata.UserArrayOption(
Expand All @@ -160,9 +168,15 @@ def get_options(self) -> 'MutableKeyedOptionDictType':

def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
std = options[OptionKey('std', machine=self.for_machine, lang=self.language)]
key = OptionKey('std', machine=self.for_machine, lang=self.language)
std = options[key]
if std.value != 'none':
args.append('-std=' + std.value)

if options[key.evolve('legal_code')].value:
if version_compare(self.version, '>=3.3.0') and std.value not in ('c89', 'c90', 'gnu89', 'gnu90'):
args.extend(('-Werror=implicit', '-Werror=int-conversion', '-Werror=incompatible-pointer-types', '-Wno-error=incompatible-pointer-types-discards-qualifiers'))

return args

def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
Expand Down Expand Up @@ -284,6 +298,11 @@ def get_options(self) -> 'MutableKeyedOptionDictType':
std_opt = opts[key]
assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
std_opt.set_versions(stds, gnu=True)

opts.update({
key.evolve('legal_code'): coredata.UserBooleanOption('Ban use of dangerous constructs', True),
})

if self.info.is_windows() or self.info.is_cygwin():
opts.update({
key.evolve('winlibs'): coredata.UserArrayOption(
Expand All @@ -295,9 +314,15 @@ def get_options(self) -> 'MutableKeyedOptionDictType':

def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
std = options[OptionKey('std', lang=self.language, machine=self.for_machine)]
key = OptionKey('std', lang=self.language, machine=self.for_machine)
std = options[key]
if std.value != 'none':
args.append('-std=' + std.value)

if options[key.evolve('legal_code')].value:
if version_compare(self.version, '>=5.1.0') and version_compare(self.version, '<14.0.0') and std.value not in ('c89', 'c90', 'gnu89', 'gnu90'):
args.extend(('-Werror=implicit', '-Werror=int-conversion', '-Werror=incompatible-pointer-types'))

return args

def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
Expand Down

0 comments on commit 51eb5ac

Please sign in to comment.