aaron.ballman updated this revision to Diff 421738. aaron.ballman marked 2 inline comments as done. aaron.ballman added a comment.
Updated based on review comments. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D123456/new/ https://reviews.llvm.org/D123456 Files: clang/docs/ReleaseNotes.rst clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaExpr.cpp clang/test/Analysis/nullability.c clang/test/Analysis/svalbuilder-float-cast.c clang/test/Sema/warn-deprecated-non-prototype.c
Index: clang/test/Sema/warn-deprecated-non-prototype.c =================================================================== --- clang/test/Sema/warn-deprecated-non-prototype.c +++ clang/test/Sema/warn-deprecated-non-prototype.c @@ -36,7 +36,7 @@ void another(); // strict-warning {{a function declaration without a prototype is deprecated in all versions of C}} int main(void) { - another(1, 2); // OK for now + another(1, 2); // both-warning {{calling 'another' with arguments when the function has no prototype}} } void order1(); // expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}} \ @@ -71,3 +71,47 @@ void blapp(int); void blapp() { } // both-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}} \ // strict-warning {{a function declaration without a prototype is deprecated in all versions of C}} + +// Disable -Wdeprecated-non-prototype +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-non-prototype" +void depr_non_prot(); // strict-warning {{a function declaration without a prototype is deprecated in all versions of C}} +#pragma GCC diagnostic pop +// Reenable it. + +// Disable -Wstrict-prototypes +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +void strict_prot(); // OK +#pragma GCC diagnostic pop +// Reenable it. + +void calls(void) { + // Ensure that we diagnose calls to functions without a prototype, but only + // if they pass arguments. + never_defined(); // OK + never_defined(1); // both-warning {{calling 'never_defined' with arguments when the function has no prototype}} + + // Ensure that calls to builtins without a traditional prototype are not + // diagnosed. + (void)__builtin_isless(1.0, 1.0); // OK + + // Calling a function whose prototype was provided by a function with an + // identifier list is still fine. + func(1, 2); // OK + + // Ensure that a call through a function pointer is still diagnosed properly. + fp f; + f(); // OK + f(1, 2); // both-warning {{calling a function with arguments when the function has no prototype}} + + // Ensure that we don't diagnose when the diagnostic group is disabled. + depr_non_prot(1); // OK + strict_prot(1); // OK + + // Ensure we don't issue diagnostics if the function without a prototype was + // later given a prototype by a definintion. Also ensure we don't duplicate + // diagnostics if such a call is incorrect. + func(1, 2); // OK + func(1, 2, 3); // both-warning {{too many arguments in call to 'func'}} +} Index: clang/test/Analysis/svalbuilder-float-cast.c =================================================================== --- clang/test/Analysis/svalbuilder-float-cast.c +++ clang/test/Analysis/svalbuilder-float-cast.c @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker debug.ExprInspection -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker debug.ExprInspection -Wno-deprecated-non-prototype -verify %s void clang_analyzer_denote(int, const char *); void clang_analyzer_express(int); Index: clang/test/Analysis/nullability.c =================================================================== --- clang/test/Analysis/nullability.c +++ clang/test/Analysis/nullability.c @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability -verify %s +// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability -Wno-deprecated-non-prototype -verify %s void it_takes_two(int a, int b); void function_pointer_arity_mismatch() { Index: clang/lib/Sema/SemaExpr.cpp =================================================================== --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -7047,6 +7047,23 @@ Proto = FDecl->getType()->getAs<FunctionProtoType>(); } + // If we still haven't found a prototype to use but there are arguments to + // the call, diagnose this as calling a function without a prototype. + // However, if we found a function declaration, check to see if + // -Wdeprecated-non-prototype was disabled where the function was declared. + // If so, we will silence the diagnostic here on the assumption that this + // interface is intentional and the user knows what they're doing. We will + // also silence the diagnostic if there is a function declaration but it + // was implicitly defined (the user already gets diagnostics about the + // creation of the implicit function declaration, so the additional warning + // is not helpful). + if (!Proto && !Args.empty() && + (!FDecl || (!FDecl->isImplicit() && + !Diags.isIgnored(diag::warn_strict_uses_without_prototype, + FDecl->getLocation())))) + Diag(LParenLoc, diag::warn_strict_uses_without_prototype) + << (FDecl != nullptr) << FDecl; + // Promote the arguments (C99 6.5.2.2p6). for (unsigned i = 0, e = Args.size(); i != e; i++) { Expr *Arg = Args[i]; Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5554,6 +5554,9 @@ InGroup<Sentinel>; def note_sentinel_here : Note< "%select{function|method|block}0 has been explicitly marked sentinel here">; +def warn_strict_uses_without_prototype : Warning< + "calling %select{a function|%1}0 with arguments when the function has no " + "prototype">, InGroup<DeprecatedNonPrototype>; def warn_missing_prototype : Warning< "no previous prototype for function %0">, InGroup<DiagGroup<"missing-prototypes">>, DefaultIgnore; Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -122,8 +122,13 @@ diagnostic remains off by default but is now enabled via ``-pedantic`` due to it being a deprecation warning. ``-Wdeprecated-non-prototype`` will diagnose cases where the deprecated declarations or definitions of a function without - a prototype will change behavior in C2x. This diagnostic is grouped under the - ``-Wstrict-prototypes`` warning group, but is enabled by default. + a prototype will change behavior in C2x. Additionally, it will diagnose calls + to a function without a prototype but arguments are provided, only so long as + the ``-Wdeprecated-non-prototype`` option is enabled at the function + declaration. (This allows a developer to locally disable the diagnostic for a + declaration without a prototype to silence the call-site diagnostics as + well.) This diagnostic is grouped under the ``-Wstrict-prototypes`` warning + group, but is enabled by default. Non-comprehensive list of changes in this release -------------------------------------------------
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits