# Copyright © 2020, 2023 Nick Bowler # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . AT_BANNER([Invalid C declarations]) m4_define([CHECK_BADDECL], [AT_CHECK([cdecl99 -e '$1'], [1], [], [stderr])]) m4_define([SIMPLE_BADDECL], [AT_SETUP([$1]) m4_map_sep([CHECK_BADDECL], [m4_newline], m4_cdr(m4_dquote_elt($@))) AT_CLEANUP]) SIMPLE_BADDECL([Reject invalid identifiers], [explain int x$], [declare x$ as int]) SIMPLE_BADDECL([Reject long long long], [explain long long long x], [declare x as long long long]) SIMPLE_BADDECL([Reject long long double], [explain long long double x], [declare x as long long double]) SIMPLE_BADDECL([Reject inline on object declarations], [explain inline int x], [declare x as inline int]) dnl Storage-class specifiers SIMPLE_BADDECL([Reject multiple storage-class specifiers], [explain static auto int x], [declare x as static auto int]) SIMPLE_BADDECL([Reject typedef in type names], [explain typedef int], [type typedef int]) dnl Type specifiers SIMPLE_BADDECL([Reject implicit int], [explain auto x], [declare x as auto]) SIMPLE_BADDECL([Reject void declarations], [explain void x], [declare x as void]) SIMPLE_BADDECL([Reject complex integers], [explain int _Complex x], [declare x as int _Complex], [explain short _Complex x], [declare x as short _Complex], [explain long _Complex x], [declare x as long _Complex], [explain char _Complex x], [declare x as char _Complex]) SIMPLE_BADDECL([Reject imaginary integers], [explain int _Imaginary x], [declare x as int _Imaginary], [explain short _Imaginary x], [declare x as short _Imaginary], [explain long _Imaginary x], [declare x as long _Imaginary], [explain char _Imaginary x], [declare x as char _Imaginary]) SIMPLE_BADDECL([Reject signed floats], [explain signed float x], [declare x as signed float], [explain signed double x], [declare x as signed double]) SIMPLE_BADDECL([Reject unsigned floats], [explain unsigned float x], [declare x as unsigned float], [explain unsigned double x], [declare x as unsigned double]) dnl C99§6.7.3p2: Types other than pointer types derived from object or dnl incomplete types shall not be restrict-qualified. SIMPLE_BADDECL([Reject restrict on object declarations], [explain restrict int x], [declare x as restrict int]) SIMPLE_BADDECL([Reject restrict on function pointers], [explain int (*restrict f)(void)], [declare f as restrict pointer to function (void) returning int]) dnl Functions SIMPLE_BADDECL([Reject ... with no formal parameters], [explain void f(...)], [declare f as function (...) returning void]) SIMPLE_BADDECL([Reject identifier lists with extra parentheses], [explain int f((x))], [explain int f(())]) dnl TODO: Find C&V which actually prohibits these "obviously wrong" dnl declarations. SIMPLE_BADDECL([Reject non-trivial void parameters], [explain void f(void, void)], [declare f as function (void, void) returning void], [explain void f(void, ...)], [declare f as function (void, ...) returning void], [explain void f(register void)], [declare f as function (register void) returning void], [explain void f(const void)], [declare f as function (const void) returning void], [explain void f(void const)], [declare f as function (void const) returning void]) SIMPLE_BADDECL([Reject parameters with no type specifier], [explain void f(const)], [declare f as function (const) returning void]) SIMPLE_BADDECL([Reject typedef in function parameters], [explain void f(typedef int x)], [declare f as function (x as typedef int) returning void]) SIMPLE_BADDECL([Reject static in function parameters], [explain void f(static int x)], [declare f as function (x as static int) returning void]) SIMPLE_BADDECL([Reject inline in function parameters], [explain int f(inline int g())], [declare f as function (g as inline function returning int) returning int]) SIMPLE_BADDECL([Reject inline in type names], [explain inline int (void)], [type inline function (void) returning int]) SIMPLE_BADDECL([Reject functions returning arrays], [explain int f(void)[[1]]], [declare f as function (void) returning array 1 of int]) SIMPLE_BADDECL([Reject functions returning functions], [explain int f(void)(void)], [declare f as function (void) returning function (void) returning int]) SIMPLE_BADDECL([Reject 0-length arrays], [explain int a[[0]]], [declare a as array 0 of int]) SIMPLE_BADDECL([Reject arrays of void], [explain void a[[1]]], [declare a as array 1 of void]) SIMPLE_BADDECL([Reject arrays of functions], [explain int a[[1]](void)], [declare a as array 1 of function (void) returning int]) SIMPLE_BADDECL([Reject arrays with invalid identifiers], [explain int a[[1nan]]], [declare a as array 1nan of int]) SIMPLE_BADDECL([Reject arrays of unusual size], [explain int a[[99999999999999999999999999999999999999999999999999999]]], [declare a as array 99999999999999999999999999999999999999999999999999999 of int]) SIMPLE_BADDECL([Reject bad declarators after good ones], [explain int f(void), g(...)], [explain int f, g((x))]) SIMPLE_BADDECL([Reject multiple declarators in type names], [explain int f, g((x))], [explain int x, (void)], [explain int [[5]], (void)]) SIMPLE_BADDECL([Error recovery on multiple object declaration], [explain int inline x, y]) SIMPLE_BADDECL([Reject hyphens in identifiers], [explain int ac-dc], [explain int variable-length])