aaron.ballman updated this revision to Diff 419844.
aaron.ballman marked 5 inline comments as done.
aaron.ballman added a comment.

Updating based on review feedback.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122895/new/

https://reviews.llvm.org/D122895

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/2009-06-01-addrofknr.c
  clang/test/FixIt/fixit.c
  clang/test/Parser/declarators.c
  clang/test/Parser/knr_parameter_attributes.c
  clang/test/Parser/opencl-kernel.cl
  clang/test/Parser/traditional_arg_scope.c
  clang/test/Sema/arg-duplicate.c
  clang/test/Sema/block-return.c
  clang/test/Sema/implicit-decl.c
  clang/test/Sema/knr-def-call.c
  clang/test/Sema/knr-variadic-def.c
  clang/test/Sema/vfprintf-valid-redecl.c
  clang/test/Sema/warn-deprecated-non-prototype.c
  clang/test/Sema/warn-missing-prototypes.c
  clang/test/Sema/warn-strict-prototypes.c
  clang/test/Sema/warn-strict-prototypes.m
  clang/test/SemaObjC/nonnull.m
  clang/test/SemaOpenCL/address-spaces.cl
  clang/test/SemaOpenCL/cl20-device-side-enqueue.cl
  clang/test/SemaOpenCL/func.cl

Index: clang/test/SemaOpenCL/func.cl
===================================================================
--- clang/test/SemaOpenCL/func.cl
+++ clang/test/SemaOpenCL/func.cl
@@ -43,9 +43,9 @@
 #endif
 
 // Expect no diagnostics for an empty parameter list.
-void bar();
+void bar(); // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
 
-void bar()
+void bar() // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
 {
   // declaring a function pointer is an error
   void (*fptr)(int);
Index: clang/test/SemaOpenCL/cl20-device-side-enqueue.cl
===================================================================
--- clang/test/SemaOpenCL/cl20-device-side-enqueue.cl
+++ clang/test/SemaOpenCL/cl20-device-side-enqueue.cl
@@ -11,7 +11,7 @@
 
 typedef struct {int a;} ndrange_t;
 // Diagnostic tests for different overloads of enqueue_kernel from Table 6.13.17.1 of OpenCL 2.0 Spec.
-kernel void enqueue_kernel_tests() {
+kernel void enqueue_kernel_tests(void) {
   queue_t default_queue;
   unsigned flags = 0;
   QUALS ndrange_t ndrange;
@@ -169,7 +169,7 @@
 }
 
 // Diagnostic tests for get_kernel_work_group_size and allowed block parameter types in dynamic parallelism.
-kernel void work_group_size_tests() {
+kernel void work_group_size_tests(void) {
   void (^const block_A)(void) = ^{
     return;
   };
@@ -223,16 +223,22 @@
 kernel void foo(global unsigned int *buf)
 {
   ndrange_t n;
-  buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, ^(){});
+  // FIXME: this should be diagnosed as a block instead of a function, but
+  // block literals don't track the ^ as part of their declarator.
+  buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, ^(){}); // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
   buf[0] = get_kernel_max_sub_group_size_for_ndrange(0, ^(){}); // expected-error{{illegal call to 'get_kernel_max_sub_group_size_for_ndrange', expected 'ndrange_t' argument type}}
+                                                                // expected-warning@-1 {{a function declaration without a prototype is deprecated in all versions of C}}
   buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, 1); // expected-error{{illegal call to 'get_kernel_max_sub_group_size_for_ndrange', expected block argument type}}
 }
 
 kernel void bar(global unsigned int *buf)
 {
   __private ndrange_t n;
-  buf[0] = get_kernel_sub_group_count_for_ndrange(n, ^(){});
+  // FIXME: this should be diagnosed as a block instead of a function, but
+  // block literals don't track the ^ as part of their declarator.
+  buf[0] = get_kernel_sub_group_count_for_ndrange(n, ^(){}); // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
   buf[0] = get_kernel_sub_group_count_for_ndrange(0, ^(){}); // expected-error{{illegal call to 'get_kernel_sub_group_count_for_ndrange', expected 'ndrange_t' argument type}}
+                                                             // expected-warning@-1 {{a function declaration without a prototype is deprecated in all versions of C}}
   buf[0] = get_kernel_sub_group_count_for_ndrange(n, 1); // expected-error{{illegal call to 'get_kernel_sub_group_count_for_ndrange', expected block argument type}}
 }
 
@@ -241,12 +247,18 @@
 kernel void foo1(global unsigned int *buf)
 {
   ndrange_t n;
+  // FIXME: this should be diagnosed as a block instead of a function, but
+  // block literals don't track the ^ as part of their declarator.
   buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, ^(){}); // expected-error {{use of declaration 'get_kernel_max_sub_group_size_for_ndrange' requires cl_khr_subgroups or __opencl_c_subgroups support}}
+                                                                // expected-warning@-1 {{a function declaration without a prototype is deprecated in all versions of C}}
 }
 
 kernel void bar1(global unsigned int *buf)
 {
   ndrange_t n;
+  // FIXME: this should be diagnosed as a block instead of a function, but
+  // block literals don't track the ^ as part of their declarator.
   buf[0] = get_kernel_sub_group_count_for_ndrange(n, ^(){}); // expected-error {{use of declaration 'get_kernel_sub_group_count_for_ndrange' requires cl_khr_subgroups or __opencl_c_subgroups support}}
+                                                             // expected-warning@-1 {{a function declaration without a prototype is deprecated in all versions of C}}
 }
 #endif // ifdef cl_khr_subgroups
Index: clang/test/SemaOpenCL/address-spaces.cl
===================================================================
--- clang/test/SemaOpenCL/address-spaces.cl
+++ clang/test/SemaOpenCL/address-spaces.cl
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
-// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -pedantic -fsyntax-only
-// RUN: %clang_cc1 %s -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -verify -pedantic -fsyntax-only
+// RUN: %clang_cc1 %s -verify=expected,c -pedantic -fsyntax-only
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify=expected,c -pedantic -fsyntax-only
+// RUN: %clang_cc1 %s -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -verify=expected,c -pedantic -fsyntax-only
 // RUN: %clang_cc1 %s -cl-std=clc++1.0 -verify -pedantic -fsyntax-only
 // RUN: %clang_cc1 %s -cl-std=clc++2021 -cl-ext=+__opencl_c_generic_address_space -verify -pedantic -fsyntax-only
 
@@ -251,7 +251,7 @@
 
 void func_with_array_param(const unsigned data[16]);
 
-__kernel void k() {
+__kernel void k() { // c-warning {{a function declaration without a prototype is deprecated in all versions of C}}
   unsigned data[16];
   func_with_array_param(data);
 }
Index: clang/test/SemaObjC/nonnull.m
===================================================================
--- clang/test/SemaObjC/nonnull.m
+++ clang/test/SemaObjC/nonnull.m
@@ -2,7 +2,6 @@
 
 // RUN: %clang_cc1 -fblocks -fsyntax-only -verify -Wno-objc-root-class %s
 // REQUIRES: LP64
-
 @class NSObject;
 
 NONNULL_ATTR
@@ -23,7 +22,7 @@
 extern void func4 (void (^block1)(), void (^block2)()) __attribute__((nonnull(1)))
 __attribute__((nonnull(2)));
 
-void func6();
+void func6(); // expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
 void func7();
 
 void
@@ -63,7 +62,7 @@
 __attribute__((nonnull))
 void _dispatch_queue_push_list(dispatch_object_t _head); // no warning
 
-void func6(dispatch_object_t _head) {
+void func6(dispatch_object_t _head) { // expected-warning {{this function declaration with a prototype changes behavior in C2x because it is preceded by a function without a prototype}}
   _dispatch_queue_push_list(0); // expected-warning {{null passed to a callee that requires a non-null argument}}
   _dispatch_queue_push_list(_head._do);  // no warning
 }
Index: clang/test/Sema/warn-strict-prototypes.m
===================================================================
--- clang/test/Sema/warn-strict-prototypes.m
+++ clang/test/Sema/warn-strict-prototypes.m
@@ -2,25 +2,28 @@
 
 @interface Foo
 
-@property (nonatomic, copy) void (^noProtoBlock)(); // expected-warning {{this block declaration is not a prototype}}
+@property (nonatomic, copy) void (^noProtoBlock)(); // expected-warning {{a block declaration without a prototype is deprecated}}
 @property (nonatomic, copy) void (^block)(void); // no warning
 
-- doStuff:(void (^)()) completionHandler; // expected-warning {{this block declaration is not a prototype}}
+- doStuff:(void (^)()) completionHandler; // expected-warning {{a block declaration without a prototype is deprecated}}
 - doOtherStuff:(void (^)(void)) completionHandler; // no warning
 
 @end
 
-void foo() { // expected-warning {{this old-style function definition is not preceded by a prototype}}
-  void (^block)() = // expected-warning {{this block declaration is not a prototype}}
+void foo() { // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
+  void (^block)() = // expected-warning {{a block declaration without a prototype is deprecated}}
                     ^void(int arg) { // no warning
   };
-  void (^block2)(void) = ^void() { // no warning
+  // FIXME: this should say "a block declaration" instead, but block literal
+  // expressions do not track their full declarator information, so we don't
+  // know it's a block when diagnosing.
+  void (^block2)(void) = ^void() { // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
   };
   void (^block3)(void) = ^ { // no warning
   };
 }
 
-void (*(^(*(^block4)()) // expected-warning {{this block declaration is not a prototype}}
-     ()) // expected-warning {{this function declaration is not a prototype}}
-     ()) // expected-warning {{this block declaration is not a prototype}}
-     (); // expected-warning {{this function declaration is not a prototype}}
+void (*(^(*(^block4)()) // expected-warning {{a block declaration without a prototype is deprecated}}
+     ()) // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
+     ()) // expected-warning {{a block declaration without a prototype is deprecated}}
+     (); // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
Index: clang/test/Sema/warn-strict-prototypes.c
===================================================================
--- clang/test/Sema/warn-strict-prototypes.c
+++ clang/test/Sema/warn-strict-prototypes.c
@@ -2,70 +2,70 @@
 // RUN: %clang_cc1 -triple i386-pc-unknown -fsyntax-only -Wstrict-prototypes -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
 
 // function definition with 0 params, no prototype, no preceding declaration.
-void foo0() {} // expected-warning {{this old-style function definition is not preceded by a prototype}}
+void foo0() {} // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
 
 // function declaration with unspecified params
-void foo1(); // expected-warning {{this function declaration is not a prototype}}
+void foo1(); // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
              // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:11}:"void"
 // function declaration with 0 params
 void foo2(void);
 
 // function definition with 0 params, no prototype.
-void foo1() {} // expected-warning {{this old-style function definition is not preceded by a prototype}}
+void foo1() {} // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
 // function definition with 0 params, prototype.
 void foo2(void) {}
 
 // function type typedef unspecified params
-typedef void foo3(); // expected-warning {{this function declaration is not a prototype}}
+typedef void foo3(); // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
                      // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:19-[[@LINE-1]]:19}:"void"
 
 // global fp unspecified params
-void (*foo4)(); // expected-warning {{this function declaration is not a prototype}}
+void (*foo4)(); // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
                 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:14-[[@LINE-1]]:14}:"void"
 
 // struct member fp unspecified params
-struct { void (*foo5)(); } s; // expected-warning {{this function declaration is not a prototype}}
+struct { void (*foo5)(); } s; // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
                               // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:23-[[@LINE-1]]:23}:"void"
 
 // param fp unspecified params
-void bar2(void (*foo6)()) { // expected-warning {{this function declaration is not a prototype}}
+void bar2(void (*foo6)()) { // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
                             // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:24-[[@LINE-1]]:24}:"void"
   // local fp unspecified params
-  void (*foo7)() = 0; // expected-warning {{this function declaration is not a prototype}}
+  void (*foo7)() = 0; // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
                       // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:16-[[@LINE-1]]:16}:"void"
   // array fp unspecified params
-  void (*foo8[2])() = {0}; // expected-warning {{this function declaration is not a prototype}}
+  void (*foo8[2])() = {0}; // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
                            // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:19-[[@LINE-1]]:19}:"void"
 }
 
 // function type cast using using an anonymous function declaration
 void bar3(void) {
   // casting function w/out prototype to unspecified params function type
-  (void)(void(*)()) foo1; // expected-warning {{this function declaration is not a prototype}}
+  (void)(void(*)()) foo1; // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
                           // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:18-[[@LINE-1]]:18}:"void"
   // .. specified params
   (void)(void(*)(void)) foo1;
 }
 
 // K&R function definition not preceded by full prototype
-int foo9(a, b) // expected-warning {{old-style function definition is not preceded by a prototype}}
+int foo9(a, b) // expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
   int a, b;
 {
   return a + b;
 }
 
 // Function declaration with no types
-void foo10(); // expected-warning {{this function declaration is not a prototype}}
-              // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:12-[[@LINE-1]]:12}:"void"
+void foo10(); // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}} \
+                 expected-note {{a function declaration without a prototype is not supported in C2x}}
+              // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"void"
 // K&R function definition with incomplete param list declared
-void foo10(p, p2) void *p; {} // expected-warning {{old-style function definition is not preceded by a prototype}}
+void foo10(p, p2) void *p; {} // expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
 
-// K&R function definition with previous prototype declared is not diagnosed.
 void foo11(int p, int p2);
-void foo11(p, p2) int p; int p2; {}
+void foo11(p, p2) int p; int p2; {} // expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
 
 // PR31020
-void __attribute__((cdecl)) foo12(d) // expected-warning {{this old-style function definition is not preceded by a prototype}}
+void __attribute__((cdecl)) foo12(d) // expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
   short d;
 {}
 
Index: clang/test/Sema/warn-missing-prototypes.c
===================================================================
--- clang/test/Sema/warn-missing-prototypes.c
+++ clang/test/Sema/warn-missing-prototypes.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -Wmissing-prototypes -verify %s
-// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -Wmissing-prototypes -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -Wmissing-prototypes -Wno-deprecated-non-prototype -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -Wmissing-prototypes -Wno-deprecated-non-prototype -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
 
 int f(); // expected-note{{this declaration is not a prototype; add parameter declarations to make it one}}
 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:{{.*}}-[[@LINE-1]]:{{.*}}}:"{{.*}}"
Index: clang/test/Sema/warn-deprecated-non-prototype.c
===================================================================
--- /dev/null
+++ clang/test/Sema/warn-deprecated-non-prototype.c
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=both,expected %s
+// RUN: %clang_cc1 -fsyntax-only -Wstrict-prototypes -verify=both,strict %s
+
+// Test both with and without -Wstrict-prototypes because there are complicated
+// interactions between it and -Wdeprecated-non-prototype.
+
+// Off by default warnings, enabled by -pedantic or -Wstrict-prototypes
+void other_func();   // strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
+void other_func() {} // strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
+
+void never_defined(); // strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
+
+typedef void (*fp)(); // strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
+
+void blerp(
+  void (*func_ptr)() // strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
+);
+
+void whatever(void) {
+  extern void hoo_boy(); // strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
+}
+
+void again() {} // strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
+
+// On by default warnings
+void func();                 // expected-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}} \
+                                strict-note {{a function declaration without a prototype is not supported in C2x}}
+void func(a, b) int a, b; {} // both-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
+
+void one_more(a, b) int a, b; {} // both-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
+
+void sheesh(int a);
+void sheesh(a) int a; {} // both-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
+
+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
+}
+
+void order1();        // expected-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}} \
+                         strict-note {{a function declaration without a prototype is not supported in C2x}}
+void order1(int i);   // both-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
+
+void order2(int i);
+void order2();        // 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}}
+
+void order3();        // expected-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}} \
+                         strict-note {{a function declaration without a prototype is not supported in C2x}}
+void order3(int i) {} // both-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
+
+// Just because the prototype is variadic doesn't mean we shouldn't warn on the
+// K&R C function definition; this still changes behavior in C2x.
+void test(char*,...);
+void test(fmt)        // both-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
+        char*fmt;
+{
+}
+
+// FIXME: we get two diagnostics here when running in pedantic mode. The first
+// comes when forming the function type for the definition, and the second
+// comes from merging the function declarations together. The second is the
+// point at which we know the behavior has changed (because we can see the
+// previous declaration at that point), but we've already issued the type
+// warning by that point. It's not ideal to be this chatty, but this situation
+// should be pretty rare.
+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}}
Index: clang/test/Sema/vfprintf-valid-redecl.c
===================================================================
--- clang/test/Sema/vfprintf-valid-redecl.c
+++ clang/test/Sema/vfprintf-valid-redecl.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -fsyntax-only -pedantic -verify
-// RUN: %clang_cc1 %s -fsyntax-only -pedantic -verify -DPREDECLARE
+// RUN: %clang_cc1 %s -fsyntax-only -pedantic -verify -std=c99
+// RUN: %clang_cc1 %s -fsyntax-only -pedantic -verify -DPREDECLARE -std=c99
 
 #ifdef PREDECLARE
 // PR16344
@@ -12,7 +12,7 @@
 // PR4290
 // The following declaration is compatible with vfprintf, so we shouldn't
 // reject.
-int vfprintf();
+int vfprintf(); // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
 #ifndef PREDECLARE
 // expected-warning@-2 {{requires inclusion of the header <stdio.h>}}
 #endif
Index: clang/test/Sema/knr-variadic-def.c
===================================================================
--- clang/test/Sema/knr-variadic-def.c
+++ clang/test/Sema/knr-variadic-def.c
@@ -1,12 +1,11 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s -std=c99
 // PR4287
 
 #include <stdarg.h>
 char *foo = "test";
 int test(char*,...);
 
-int test(fmt)
+int test(fmt) // expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
         char*fmt;
 {
         va_list ap;
@@ -20,9 +19,9 @@
         return x;
 }
 
-void exit();
+void exit(); // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
 
-int main(argc,argv)
+int main(argc,argv) // expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
         int argc;char**argv;
 {
         exit(test("",foo));
Index: clang/test/Sema/knr-def-call.c
===================================================================
--- clang/test/Sema/knr-def-call.c
+++ clang/test/Sema/knr-def-call.c
@@ -1,18 +1,19 @@
 // RUN: %clang_cc1 -triple i386-pc-unknown -Wconversion -Wliteral-conversion -fsyntax-only -verify %s
 
 // C DR #316, PR 3626.
-void f0(a, b, c, d) int a,b,c,d; {}
+void f0(a, b, c, d) int a,b,c,d; {} // expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
 void t0(void) {
   f0(1);  // expected-warning{{too few arguments}}
 }
 
-void f1(a, b) int a, b; {}
+void f1(a, b) int a, b; {} // expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
 void t1(void) {
   f1(1, 2, 3); // expected-warning{{too many arguments}}
 }
 
 void f2(float); // expected-note{{previous declaration is here}}
-void f2(x) float x; { } // expected-warning{{promoted type 'double' of K&R function parameter is not compatible with the parameter type 'float' declared in a previous prototype}}
+void f2(x) float x; { } // expected-warning{{promoted type 'double' of K&R function parameter is not compatible with the parameter type 'float' declared in a previous prototype}} \
+                           expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
 
 typedef void (*f3)(void);
 f3 t3(int b) { return b? f0 : f1; } // okay
@@ -22,6 +23,8 @@
     char *rindex();
 }
 
+// FIXME: we should diagnose this case, but when merging function declarations,
+// we don't diagnose it because the function is a builtin.
 char *rindex(s, c)
      register char *s, c; // expected-warning{{promoted type 'char *' of K&R function parameter is not compatible with the parameter type 'const char *' declared in a previous prototype}}
 {
@@ -30,7 +33,7 @@
 
 // PR8314
 void proto(int);
-void proto(x)
+void proto(x) // expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
      int x;
 {
 }
@@ -42,6 +45,6 @@
 
 // PR31020
 void func(short d) __attribute__((cdecl)); // expected-note{{previous declaration is here}}
-void __attribute__((cdecl)) func(d)
+void __attribute__((cdecl)) func(d) // expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
   short d; // expected-warning{{promoted type 'int' of K&R function parameter is not compatible with the parameter type 'short' declared in a previous prototype}}
 {}
Index: clang/test/Sema/implicit-decl.c
===================================================================
--- clang/test/Sema/implicit-decl.c
+++ clang/test/Sema/implicit-decl.c
@@ -20,6 +20,7 @@
 
   __builtin_is_les(1, 3); // expected-error{{use of unknown builtin '__builtin_is_les'}}
 }
+// The implicit declaration for this has no prototype.
 Boolean _CFCalendarDecomposeAbsoluteTimeV(const char *componentDesc, int32_t **vector, int32_t count) { // expected-error {{conflicting types}}
  return 0;
 }
Index: clang/test/Sema/block-return.c
===================================================================
--- clang/test/Sema/block-return.c
+++ clang/test/Sema/block-return.c
@@ -99,6 +99,7 @@
 int (*funcptr3[5])(long);
 int sz8 = sizeof(^int (*[5])(long) {return funcptr3;}); // expected-error {{block cannot return array type}} expected-warning {{incompatible pointer to integer conversion}}
 int sz9 = sizeof(^int(*())()[3]{ }); // expected-error {{function cannot return array type}}
+                                     // expected-warning@-1 2 {{a function declaration without a prototype is deprecated in all versions of C}}
 
 void foo6(void) {
   int (^b)(int) __attribute__((noreturn));
Index: clang/test/Sema/arg-duplicate.c
===================================================================
--- clang/test/Sema/arg-duplicate.c
+++ clang/test/Sema/arg-duplicate.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c99
 
-int f3(y, x, 
+int f3(y, x,       // expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
        x)          // expected-error {{redefinition of parameter}}
   int y, 
       x,           // expected-note {{previous declaration is here}}
Index: clang/test/Parser/traditional_arg_scope.c
===================================================================
--- clang/test/Parser/traditional_arg_scope.c
+++ clang/test/Parser/traditional_arg_scope.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only %s -verify
+// RUN: %clang_cc1 -fsyntax-only %s -verify -Wno-deprecated-non-prototype -std=c99
 
 int x(a) int a; {return a;}
 int y(b) int b; {return a;} // expected-error {{use of undeclared identifier}}
Index: clang/test/Parser/opencl-kernel.cl
===================================================================
--- clang/test/Parser/opencl-kernel.cl
+++ clang/test/Parser/opencl-kernel.cl
@@ -1,10 +1,9 @@
 // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
-// expected-no-diagnostics
 
-__kernel void test()
+__kernel void test() // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
 {
 }
 
-kernel void test1()
+kernel void test1() // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
 {
 }
Index: clang/test/Parser/knr_parameter_attributes.c
===================================================================
--- clang/test/Parser/knr_parameter_attributes.c
+++ clang/test/Parser/knr_parameter_attributes.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -W -Wall -Werror -verify %s
+// RUN: %clang_cc1 -fsyntax-only -W -Wall -Wno-deprecated-non-prototype -Werror -verify %s -std=c99
 // expected-no-diagnostics
 
 int f(int i __attribute__((__unused__)))
Index: clang/test/Parser/declarators.c
===================================================================
--- clang/test/Parser/declarators.c
+++ clang/test/Parser/declarators.c
@@ -1,8 +1,8 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic
+// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic -std=c99
 
 extern int a1[];
 
-void f0();
+void f0(); /* expected-warning {{a function declaration without a prototype is deprecated in all versions of C}} */
 void f1(int [*]);
 void f2(int [const *]);
 void f3(int [volatile const*]);
@@ -27,11 +27,12 @@
 }
 
 typedef int atype;
-void test3(x, 
+void test3(x,            /* expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}} */
            atype         /* expected-error {{unexpected type name 'atype': expected identifier}} */
           ) int x, atype; {}
 
-void test4(x, x) int x; {} /* expected-error {{redefinition of parameter 'x'}} */
+void test4(x, x) int x; {} // expected-error {{redefinition of parameter 'x'}} \
+                           // expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
 
 
 // PR3031
@@ -43,7 +44,9 @@
 
 foo_t *d;      // expected-error {{unknown type name 'foo_t'}}
 foo_t a;   // expected-error {{unknown type name 'foo_t'}}
-int test6() { return a; }  // a should be declared.
+int test6() { /* expected-warning {{a function declaration without a prototype is deprecated in all versions of C}} */
+  return a; // a should be declared.
+}
 
 // Use of tagged type without tag. rdar://6783347
 struct xyz { int y; };
@@ -51,13 +54,13 @@
 xyz b;         // expected-error {{must use 'struct' tag to refer to type 'xyz'}}
 myenum c;      // expected-error {{must use 'enum' tag to refer to type 'myenum'}}
 
-float *test7() {
+float *test7(void) {
   // We should recover 'b' by parsing it with a valid type of "struct xyz", which
   // allows us to diagnose other bad things done with y, such as this.
   return &b.y;   // expected-warning {{incompatible pointer types returning 'int *' from a function with result type 'float *'}}
 }
 
-struct xyz test8() { return a; }  // a should be be marked invalid, no diag.
+struct xyz test8(void) { return a; }  // a should be be marked invalid, no diag.
 
 
 // Verify that implicit int still works.
@@ -78,7 +81,7 @@
 struct test11 { int a; } const test11x;
 
 // PR6216
-void test12() {
+void test12(void) {
   (void)__builtin_offsetof(struct { char c; int i; }, i);
 }
 
@@ -91,21 +94,23 @@
 
 // PR7617 - error recovery on missing ;.
 
-void test14()  // expected-error {{expected ';' after top level declarator}}
+void test14(void)  // expected-error {{expected ';' after top level declarator}}
 
-void test14a();
+void test14a(void);
 void *test14b = (void*)test14a; // Make sure test14a didn't get skipped.
 
 // rdar://problem/8358508
-long struct X { int x; } test15(); // expected-error {{'long struct' is invalid}}
-
-void test16(i) int i j; { } // expected-error {{expected ';' at end of declaration}}
-void test17(i, j) int i, j k; { } // expected-error {{expected ';' at end of declaration}}
-void knrNoSemi(i) int i { } // expected-error {{expected ';' at end of declaration}}
+long struct X { int x; } test15(void); // expected-error {{'long struct' is invalid}}
 
+void test16(i) int i j; { } // expected-error {{expected ';' at end of declaration}} \
+                            // expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
+void test17(i, j) int i, j k; { } // expected-error {{expected ';' at end of declaration}} \
+                                  // expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
+void knrNoSemi(i) int i { } // expected-error {{expected ';' at end of declaration}} \
+                            // expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
 
 // PR12595
-void test18() {
+void test18(void) {
   int x = 4+(5-12));  // expected-error {{extraneous ')' before ';'}}
 }
 
Index: clang/test/FixIt/fixit.c
===================================================================
--- clang/test/FixIt/fixit.c
+++ clang/test/FixIt/fixit.c
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -pedantic -Wunused-label -verify -x c %s
+// RUN: %clang_cc1 -pedantic -Wunused-label -Wno-deprecated-non-prototype -verify -x c %s
 // RUN: cp %s %t
 // RUN: not %clang_cc1 -pedantic -Wunused-label -fixit -x c %t
-// RUN: %clang_cc1 -pedantic -Wunused-label -Werror -x c %t
+// RUN: %clang_cc1 -pedantic -Wunused-label -Wno-deprecated-non-prototype -Werror -x c %t
 // RUN: grep -v CHECK %t | FileCheck %t
 
 /* This is a test of the various code modification hints that are
Index: clang/test/CodeGen/2009-06-01-addrofknr.c
===================================================================
--- clang/test/CodeGen/2009-06-01-addrofknr.c
+++ clang/test/CodeGen/2009-06-01-addrofknr.c
@@ -1,12 +1,11 @@
-// RUN: %clang_cc1 %s -o %t -emit-llvm -verify
-// expected-no-diagnostics
+// RUN: %clang_cc1 %s -o %t -emit-llvm -verify -std=c89
 // PR4289
 
 struct funcptr {
   int (*func)();
 };
 
-static int func(f)
+static int func(f) // expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}}
   void *f;
 {
   return 0;
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -5548,15 +5548,16 @@
            diag::warn_noderef_on_non_pointer_or_array);
 
   // GNU warning -Wstrict-prototypes
-  //   Warn if a function declaration is without a prototype.
+  //   Warn if a function declaration or definition is without a prototype.
   //   This warning is issued for all kinds of unprototyped function
   //   declarations (i.e. function type typedef, function pointer etc.)
   //   C99 6.7.5.3p14:
   //   The empty list in a function declarator that is not part of a definition
   //   of that function specifies that no information about the number or types
   //   of the parameters is supplied.
-  if (!LangOpts.CPlusPlus &&
-      D.getFunctionDefinitionKind() == FunctionDefinitionKind::Declaration) {
+  // See ActOnFinishFunctionBody() and MergeFunctionDecl() for handling of
+  // function declarations whose behavior changes in C2x.
+  if (!LangOpts.CPlusPlus) {
     bool IsBlock = false;
     for (const DeclaratorChunk &DeclType : D.type_objects()) {
       switch (DeclType.Kind) {
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -3856,39 +3856,118 @@
 
   // C: Function types need to be compatible, not identical. This handles
   // duplicate function decls like "void f(int); void f(enum X);" properly.
-  if (!getLangOpts().CPlusPlus &&
-      Context.typesAreCompatible(OldQType, NewQType)) {
-    const FunctionType *OldFuncType = OldQType->getAs<FunctionType>();
-    const FunctionType *NewFuncType = NewQType->getAs<FunctionType>();
-    const FunctionProtoType *OldProto = nullptr;
-    if (MergeTypeWithOld && isa<FunctionNoProtoType>(NewFuncType) &&
-        (OldProto = dyn_cast<FunctionProtoType>(OldFuncType))) {
-      // The old declaration provided a function prototype, but the
-      // new declaration does not. Merge in the prototype.
-      assert(!OldProto->hasExceptionSpec() && "Exception spec in C");
-      SmallVector<QualType, 16> ParamTypes(OldProto->param_types());
-      NewQType =
-          Context.getFunctionType(NewFuncType->getReturnType(), ParamTypes,
-                                  OldProto->getExtProtoInfo());
-      New->setType(NewQType);
-      New->setHasInheritedPrototype();
-
-      // Synthesize parameters with the same types.
-      SmallVector<ParmVarDecl*, 16> Params;
-      for (const auto &ParamType : OldProto->param_types()) {
-        ParmVarDecl *Param = ParmVarDecl::Create(Context, New, SourceLocation(),
-                                                 SourceLocation(), nullptr,
-                                                 ParamType, /*TInfo=*/nullptr,
-                                                 SC_None, nullptr);
-        Param->setScopeInfo(0, Params.size());
-        Param->setImplicit();
-        Params.push_back(Param);
+  if (!getLangOpts().CPlusPlus) {
+    // If we are merging two functions where only one of them has a prototype,
+    // we may have enough information to decide to issue a diagnostic that the
+    // function without a protoype will change behavior in C2x. This handles
+    // cases like:
+    //   void i(); void i(int j);
+    //   void i(int j); void i();
+    //   void i(); void i(int j) {}
+    // See ActOnFinishFunctionBody() for other cases of the behavior change
+    // diagnostic. See GetFullTypeForDeclarator() for handling of a function
+    // type without a prototype.
+    if (New->hasWrittenPrototype() != Old->hasWrittenPrototype() &&
+        !New->isImplicit() && !Old->isImplicit()) {
+      const FunctionDecl *WithProto, *WithoutProto;
+      if (New->hasWrittenPrototype()) {
+        WithProto = New;
+        WithoutProto = Old;
+      } else {
+        WithProto = Old;
+        WithoutProto = New;
       }
 
-      New->setParams(Params);
+      if (WithProto->getNumParams() != 0) {
+        // The function definition has parameters, so this will change
+        // behavior in C2x.
+        //
+        // If we already warned about about the function without a prototype
+        // being deprecated, add a note that it also changes behavior. If we
+        // didn't warn about it being deprecated (because the diagnostic is
+        // not enabled), warn now that it is deprecated and changes behavior.
+        bool AddNote = false;
+        if (Diags.isIgnored(diag::warn_strict_prototypes,
+                            WithoutProto->getLocation())) {
+          if (WithoutProto->getBuiltinID() == 0 &&
+              !WithoutProto->isImplicit() &&
+              SourceMgr.isBeforeInTranslationUnit(WithoutProto->getLocation(),
+                                                  WithProto->getLocation())) {
+            PartialDiagnostic PD =
+                PDiag(diag::warn_non_prototype_changes_behavior);
+            if (TypeSourceInfo *TSI = WithoutProto->getTypeSourceInfo()) {
+              if (auto FTL = TSI->getTypeLoc().getAs<FunctionNoProtoTypeLoc>())
+                PD << FixItHint::CreateInsertion(FTL.getRParenLoc(), "void");
+            }
+            Diag(WithoutProto->getLocation(), PD);
+          }
+        } else {
+          AddNote = true;
+        }
+
+        // Because the function with a prototype has parameters but a previous
+        // declaration had none, the function with the prototype will also
+        // change behavior in C2x.
+        if (WithProto->getBuiltinID() == 0 && !WithProto->isImplicit()) {
+          if (SourceMgr.isBeforeInTranslationUnit(
+                  WithProto->getLocation(), WithoutProto->getLocation())) {
+            // If the function with the prototype comes before the function
+            // without the prototype, we only want to diagnose the one without
+            // the prototype.
+            Diag(WithoutProto->getLocation(),
+                 diag::warn_non_prototype_changes_behavior);
+          } else {
+            // Otherwise, diagnose the one with the prototype, and potentially
+            // attach a note to the one without a prototype if needed.
+            Diag(WithProto->getLocation(),
+                 diag::warn_non_prototype_changes_behavior);
+            if (AddNote && WithoutProto->getBuiltinID() == 0)
+              Diag(WithoutProto->getLocation(),
+                   diag::note_func_decl_changes_behavior);
+          }
+        } else if (AddNote && WithoutProto->getBuiltinID() == 0 &&
+                   !WithoutProto->isImplicit()) {
+          // If we were supposed to add a note but the function with a
+          // prototype is a builtin or was implicitly declared, which means we
+          // have nothing to attach the note to, so we issue a warning instead.
+          Diag(WithoutProto->getLocation(),
+               diag::warn_non_prototype_changes_behavior);
+        }
+      }
     }
 
-    return MergeCompatibleFunctionDecls(New, Old, S, MergeTypeWithOld);
+    if (Context.typesAreCompatible(OldQType, NewQType)) {
+      const FunctionType *OldFuncType = OldQType->getAs<FunctionType>();
+      const FunctionType *NewFuncType = NewQType->getAs<FunctionType>();
+      const FunctionProtoType *OldProto = nullptr;
+      if (MergeTypeWithOld && isa<FunctionNoProtoType>(NewFuncType) &&
+          (OldProto = dyn_cast<FunctionProtoType>(OldFuncType))) {
+        // The old declaration provided a function prototype, but the
+        // new declaration does not. Merge in the prototype.
+        assert(!OldProto->hasExceptionSpec() && "Exception spec in C");
+        SmallVector<QualType, 16> ParamTypes(OldProto->param_types());
+        NewQType =
+            Context.getFunctionType(NewFuncType->getReturnType(), ParamTypes,
+                                    OldProto->getExtProtoInfo());
+        New->setType(NewQType);
+        New->setHasInheritedPrototype();
+
+        // Synthesize parameters with the same types.
+        SmallVector<ParmVarDecl *, 16> Params;
+        for (const auto &ParamType : OldProto->param_types()) {
+          ParmVarDecl *Param = ParmVarDecl::Create(
+              Context, New, SourceLocation(), SourceLocation(), nullptr,
+              ParamType, /*TInfo=*/nullptr, SC_None, nullptr);
+          Param->setScopeInfo(0, Params.size());
+          Param->setImplicit();
+          Params.push_back(Param);
+        }
+
+        New->setParams(Params);
+      }
+
+      return MergeCompatibleFunctionDecls(New, Old, S, MergeTypeWithOld);
+    }
   }
 
   // Check if the function types are compatible when pointer size address
@@ -14815,18 +14894,63 @@
                       ? FixItHint::CreateInsertion(findBeginLoc(), "static ")
                       : FixItHint{});
         }
+      }
 
-        // GNU warning -Wstrict-prototypes
-        //   Warn if K&R function is defined without a previous declaration.
-        //   This warning is issued only if the definition itself does not
-        //   provide a prototype. Only K&R definitions do not provide a
-        //   prototype.
-        if (!FD->hasWrittenPrototype()) {
-          TypeSourceInfo *TI = FD->getTypeSourceInfo();
-          TypeLoc TL = TI->getTypeLoc();
-          FunctionTypeLoc FTL = TL.getAsAdjusted<FunctionTypeLoc>();
-          Diag(FTL.getLParenLoc(), diag::warn_strict_prototypes) << 2;
+      // If the function being defined does not have a prototype, then we may
+      // need to diagnose it as changing behavior in C2x because we now know
+      // whether the function accepts arguments or not. This only handles the
+      // case where the definition has no prototype but does have parameters
+      // and either there is no previous potential prototype, or the previous
+      // potential prototype also has no actual prototype. This handles cases
+      // like:
+      //   void f(); void f(a) int a; {}
+      //   void g(a) int a; {}
+      // See MergeFunctionDecl() for other cases of the behavior change
+      // diagnostic. See GetFullTypeForDeclarator() for handling of a function
+      // type without a prototype.
+      if (!FD->hasWrittenPrototype() && FD->getNumParams() != 0 &&
+          (!PossiblePrototype || (!PossiblePrototype->hasWrittenPrototype() &&
+                                  !PossiblePrototype->isImplicit()))) {
+        // The function definition has parameters, so this will change behavior
+        // in C2x. If there is a possible prototype, it comes before the
+        // function definition.
+        // FIXME: The declaration may have already been diagnosed as being
+        // deprecated in GetFullTypeForDeclarator() if it had no arguments, but
+        // there's no way to test for the "changes behavior" condition in
+        // SemaType.cpp when forming the declaration's function type. So, we do
+        // this awkward dance instead.
+        //
+        // If we have a possible prototype and it declares a function with a
+        // prototype, we don't want to diagnose it; if we have a possible
+        // prototype and it has no prototype, it may have already been
+        // diagnosed in SemaType.cpp as deprecated depending on whether
+        // -Wstrict-prototypes is enabled. If we already warned about it being
+        // deprecated, add a note that it also changes behavior. If we didn't
+        // warn about it being deprecated (because the diagnostic is not
+        // enabled), warn now that it is deprecated and changes behavior.
+        bool AddNote = false;
+        if (PossiblePrototype) {
+          if (Diags.isIgnored(diag::warn_strict_prototypes,
+                              PossiblePrototype->getLocation())) {
+
+            PartialDiagnostic PD =
+                PDiag(diag::warn_non_prototype_changes_behavior);
+            if (TypeSourceInfo *TSI = PossiblePrototype->getTypeSourceInfo()) {
+              if (auto FTL = TSI->getTypeLoc().getAs<FunctionNoProtoTypeLoc>())
+                PD << FixItHint::CreateInsertion(FTL.getRParenLoc(), "void");
+            }
+            Diag(PossiblePrototype->getLocation(), PD);
+          } else {
+            AddNote = true;
+          }
         }
+
+        // Because this function definition has no prototype and it has
+        // parameters, it will definitely change behavior in C2x.
+        Diag(FD->getLocation(), diag::warn_non_prototype_changes_behavior);
+        if (AddNote)
+          Diag(PossiblePrototype->getLocation(),
+               diag::note_func_decl_changes_behavior);
       }
 
       // Warn on CPUDispatch with an actual body.
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5557,10 +5557,16 @@
 def note_declaration_not_a_prototype : Note<
   "this declaration is not a prototype; add %select{'void'|parameter declarations}0 "
   "to make it %select{a prototype for a zero-parameter function|one}0">;
-def warn_strict_prototypes : Warning<
-  "this %select{function declaration is not|block declaration is not|"
-  "old-style function definition is not preceded by}0 a prototype">,
-  InGroup<DiagGroup<"strict-prototypes">>, DefaultIgnore;
+// This is not actually an extension, but we only want it to be enabled in
+// -pedantic mode and this is the most direct way of accomplishing that.
+def warn_strict_prototypes : Extension<
+  "a %select{function|block}0 declaration without a prototype is deprecated "
+  "%select{in all versions of C|}0">, InGroup<StrictPrototypes>;
+def warn_non_prototype_changes_behavior : Warning<
+  "a function declaration without a prototype is deprecated in all versions of "
+  "C and is not supported in C2x">, InGroup<DeprecatedNonPrototype>;
+def note_func_decl_changes_behavior : Note<
+  "a function declaration without a prototype is not supported in C2x">;
 def warn_missing_variable_declarations : Warning<
   "no previous extern declaration for non-static variable %0">,
   InGroup<DiagGroup<"missing-variable-declarations">>, DefaultIgnore;
Index: clang/include/clang/Basic/DiagnosticGroups.td
===================================================================
--- clang/include/clang/Basic/DiagnosticGroups.td
+++ clang/include/clang/Basic/DiagnosticGroups.td
@@ -444,6 +444,8 @@
 def InvalidNoreturn : DiagGroup<"invalid-noreturn">;
 def InvalidSourceEncoding : DiagGroup<"invalid-source-encoding">;
 def KNRPromotedParameter : DiagGroup<"knr-promoted-parameter">;
+def DeprecatedNonPrototype : DiagGroup<"deprecated-non-prototype">;
+def StrictPrototypes : DiagGroup<"strict-prototypes", [DeprecatedNonPrototype]>;
 def : DiagGroup<"init-self">;
 def : DiagGroup<"inline">;
 def : DiagGroup<"invalid-pch">;
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -110,6 +110,17 @@
   <https://github.com/llvm/llvm-project/issues/50794>`_.
 - ``-Wunused-but-set-variable`` now also warns if the variable is only used
   by unary operators.
+- Modified the behavior of ``-Wstrict-prototypes`` and added a new, related
+  diagnostic ``-Wdeprecated-non-prototype``. The strict prototypes warning will
+  now only diagnose deprecated declarations and definitions of functions
+  without a prototype where the behavior in C2x will remain correct. This
+  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.
+- ``-Wmisexpect`` warns when the branch weights collected during profiling
+  conflict with those added by ``llvm.expect``.
 
 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

Reply via email to