aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorAaron Ballman <aaron@aaronballman.com>2022-04-20 13:26:38 -0400
committerAaron Ballman <aaron@aaronballman.com>2022-04-20 13:28:15 -0400
commit9955f14aaf9995f6f0f7bf058ac740463003c470 (patch)
treec596045609299a6625a58bcab9bb108377f7ad22 /clang/lib/Parse/ParseDecl.cpp
parent9c069374cebe0162bc4f0b9d0397cf2b1c5febf6 (diff)
downloadllvm-9955f14aaf9995f6f0f7bf058ac740463003c470.zip
llvm-9955f14aaf9995f6f0f7bf058ac740463003c470.tar.gz
llvm-9955f14aaf9995f6f0f7bf058ac740463003c470.tar.bz2
[C2x] Disallow functions without prototypes/functions with identifier lists
WG14 has elected to remove support for K&R C functions in C2x. The feature was introduced into C89 already deprecated, so after this long of a deprecation period, the committee has made an empty parameter list mean the same thing in C as it means in C++: the function accepts no arguments exactly as if the function were written with (void) as the parameter list. This patch implements WG14 N2841 No function declarators without prototypes (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2841.htm) and WG14 N2432 Remove support for function definitions with identifier lists (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2432.pdf). It also adds The -fno-knr-functions command line option to opt into this behavior in other language modes. Differential Revision: https://reviews.llvm.org/D123955
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp13
1 files changed, 10 insertions, 3 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 233f092..2b386c8 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -6661,8 +6661,11 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
else if (RequiresArg)
Diag(Tok, diag::err_argument_required_after_attribute);
- HasProto = ParamInfo.size() || getLangOpts().CPlusPlus
- || getLangOpts().OpenCL;
+ // OpenCL disallows functions without a prototype, but it doesn't enforce
+ // strict prototypes as in C2x because it allows a function definition to
+ // have an identifier list. See OpenCL 3.0 6.11/g for more details.
+ HasProto = ParamInfo.size() || getLangOpts().requiresStrictPrototypes() ||
+ getLangOpts().OpenCL;
// If we have the closing ')', eat it.
Tracker.consumeClose();
@@ -6799,7 +6802,7 @@ bool Parser::ParseRefQualifier(bool &RefQualifierIsLValueRef,
/// Note that identifier-lists are only allowed for normal declarators, not for
/// abstract-declarators.
bool Parser::isFunctionDeclaratorIdentifierList() {
- return !getLangOpts().CPlusPlus
+ return !getLangOpts().requiresStrictPrototypes()
&& Tok.is(tok::identifier)
&& !TryAltiVecVectorToken()
// K&R identifier lists can't have typedefs as identifiers, per C99
@@ -6833,6 +6836,10 @@ bool Parser::isFunctionDeclaratorIdentifierList() {
void Parser::ParseFunctionDeclaratorIdentifierList(
Declarator &D,
SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo) {
+ // We should never reach this point in C2x or C++.
+ assert(!getLangOpts().requiresStrictPrototypes() &&
+ "Cannot parse an identifier list in C2x or C++");
+
// If there was no identifier specified for the declarator, either we are in
// an abstract-declarator, or we are in a parameter declarator which was found
// to be abstract. In abstract-declarators, identifier lists are not valid: