[clang-tools-extra] af01f71 - Default implicit function pointer conversions diagnostic to be an error

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 10 10:54:26 PDT 2022


Author: Aaron Ballman
Date: 2022-08-10T13:54:17-04:00
New Revision: af01f717c48f0fd2481600ed6c00441763365b62

URL: https://github.com/llvm/llvm-project/commit/af01f717c48f0fd2481600ed6c00441763365b62
DIFF: https://github.com/llvm/llvm-project/commit/af01f717c48f0fd2481600ed6c00441763365b62.diff

LOG: Default implicit function pointer conversions diagnostic to be an error

Implicitly converting between incompatible function pointers in C is
currently a default-on warning (it is an error in C++). However, this
is very poor security posture. A mismatch in parameters or return
types, or a mismatch in calling conventions, etc can lead to
exploitable security vulnerabilities. Rather than allow this unsafe
practice with a warning, this patch strengthens the warning to be an
error (while still allowing users the ability to disable the error or
the warning entirely to ease migration). Users should either ensure the
signatures are correctly compatible or they should use an explicit cast
if they believe that's more reasonable.

Differential Revision: https://reviews.llvm.org/D131351

Added: 
    

Modified: 
    clang-tools-extra/test/clang-tidy/checkers/bugprone/signal-handler-minimal.c
    clang-tools-extra/test/clang-tidy/checkers/bugprone/signal-handler.c
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/test/CodeGen/attributes.c
    clang/test/CodeGen/overloadable.c
    clang/test/Sema/aarch64-svepcs.c
    clang/test/Sema/aarch64-vpcs.c
    clang/test/Sema/arm-cmse.c
    clang/test/Sema/attr-nocf_check.c
    clang/test/Sema/block-return.c
    clang/test/Sema/c2x-func-prototype.c
    clang/test/Sema/callingconv-ms_abi.c
    clang/test/Sema/callingconv-sysv_abi.c
    clang/test/Sema/callingconv.c
    clang/test/Sema/incompatible-function-pointer-types.c
    clang/test/Sema/initialize-noreturn.c
    clang/test/Sema/noescape.c
    clang/test/Sema/overloadable.c
    clang/test/Sema/pass-object-size.c
    clang/test/Sema/preserve-call-conv.c
    clang/test/SemaObjC/comptypes-legal.m

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/signal-handler-minimal.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone/signal-handler-minimal.c
index 57c58fc6df684..08fb7a694f819 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/signal-handler-minimal.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/signal-handler-minimal.c
@@ -13,7 +13,9 @@ void handler_bad1(int) {
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: standard function '_exit' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
 }
 
-void handler_bad2(void *dst, const void *src) {
+void handler_bad2(int) {
+  void *dst;
+  const void *src;
   memcpy(dst, src, 10);
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: standard function 'memcpy' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
 }

diff  --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/signal-handler.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone/signal-handler.c
index 51f7b07a39109..edd24a9c36cd9 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/signal-handler.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/signal-handler.c
@@ -14,6 +14,7 @@ typedef void (*sighandler_t)(int);
 sighandler_t signal(int signum, sighandler_t handler);
 
 void f_extern(void);
+void f_extern_handler(int);
 
 void handler_printf(int) {
   printf("1234");
@@ -185,8 +186,8 @@ void test_other(void) {
   signal(SIGINT, _Exit);
   signal(SIGINT, other_call);
   // CHECK-NOTES: :[[@LINE-1]]:18: warning: standard function 'other_call' may not be asynchronous-safe; using it as a signal handler may be dangerous [bugprone-signal-handler]
-  signal(SIGINT, f_extern);
-  // CHECK-NOTES: :[[@LINE-1]]:18: warning: cannot verify that external function 'f_extern' is asynchronous-safe; using it as a signal handler may be dangerous [bugprone-signal-handler]
+  signal(SIGINT, f_extern_handler);
+  // CHECK-NOTES: :[[@LINE-1]]:18: warning: cannot verify that external function 'f_extern_handler' is asynchronous-safe; using it as a signal handler may be dangerous [bugprone-signal-handler]
 
   signal(SIGINT, SIG_IGN);
   signal(SIGINT, SIG_DFL);

diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4b01f018005ed..a37120ba2d56c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -85,6 +85,10 @@ Improvements to Clang's diagnostics
 - ``-Wbitfield-constant-conversion`` now diagnoses implicit truncation when 1 is
   assigned to a 1-bit signed integer bitfield. This fixes
   `Issue 53253 <https://github.com/llvm/llvm-project/issues/53253>`_.
+- ``-Wincompatible-function-pointer-types`` now defaults to an error in all C
+  language modes. It may be downgraded to a warning with
+  ``-Wno-error=incompatible-function-pointer-types`` or disabled entirely with
+  ``-Wno-implicit-function-pointer-types``.
 
 Non-comprehensive list of changes in this release
 -------------------------------------------------

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a9eff8a66297e..d794c68397ad5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8157,24 +8157,6 @@ def err_typecheck_convert_incompatible_pointer : Error<
   "; take the address with &|"
   "; remove *|"
   "; remove &}3">;
-def ext_typecheck_convert_incompatible_function_pointer : ExtWarn<
-  "incompatible function pointer types "
-  "%select{%
diff {assigning to $ from $|assigning to 
diff erent types}0,1"
-  "|%
diff {passing $ to parameter of type $|"
-  "passing to parameter of 
diff erent type}0,1"
-  "|%
diff {returning $ from a function with result type $|"
-  "returning from function with 
diff erent return type}0,1"
-  "|%
diff {converting $ to type $|converting between types}0,1"
-  "|%
diff {initializing $ with an expression of type $|"
-  "initializing with expression of 
diff erent type}0,1"
-  "|%
diff {sending $ to parameter of type $|"
-  "sending to parameter of 
diff erent type}0,1"
-  "|%
diff {casting $ to type $|casting between types}0,1}2"
-  "%select{|; dereference with *|"
-  "; take the address with &|"
-  "; remove *|"
-  "; remove &}3">,
-  InGroup<IncompatibleFunctionPointerTypes>;
 def err_typecheck_convert_incompatible_function_pointer : Error<
   "incompatible function pointer types "
   "%select{%
diff {assigning to $ from $|assigning to 
diff erent types}0,1"
@@ -8192,6 +8174,9 @@ def err_typecheck_convert_incompatible_function_pointer : Error<
   "; take the address with &|"
   "; remove *|"
   "; remove &}3">;
+def ext_typecheck_convert_incompatible_function_pointer : ExtWarn<
+  err_typecheck_convert_incompatible_function_pointer.Text>,
+  InGroup<IncompatibleFunctionPointerTypes>, DefaultError;
 def ext_typecheck_convert_discards_qualifiers : ExtWarn<
   "%select{%
diff {assigning to $ from $|assigning to 
diff erent types}0,1"
   "|%
diff {passing $ to parameter of type $|"

diff  --git a/clang/test/CodeGen/attributes.c b/clang/test/CodeGen/attributes.c
index 95c6e67f1fead..530f80975a524 100644
--- a/clang/test/CodeGen/attributes.c
+++ b/clang/test/CodeGen/attributes.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -Wno-strict-prototypes -fcf-protection=branch -triple i386-linux-gnu %s -o - | FileCheck %s
+// RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -Wno-strict-prototypes -Wno-incompatible-function-pointer-types -fcf-protection=branch -triple i386-linux-gnu %s -o - | FileCheck %s
 
 // CHECK: @t5 = weak{{.*}} global i32 2
 int t5 __attribute__((weak)) = 2;

diff  --git a/clang/test/CodeGen/overloadable.c b/clang/test/CodeGen/overloadable.c
index f55b00e9fcb01..9d64888d6873b 100644
--- a/clang/test/CodeGen/overloadable.c
+++ b/clang/test/CodeGen/overloadable.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -no-opaque-pointers -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -no-opaque-pointers -triple %itanium_abi_triple -Wno-incompatible-function-pointer-types -emit-llvm %s -o - | FileCheck %s
 // CHECK: _Z1fPA10_1X
 // CHECK: _Z1fPFvvE
 

diff  --git a/clang/test/Sema/aarch64-svepcs.c b/clang/test/Sema/aarch64-svepcs.c
index 96661c80767fa..8ae84b21896e3 100644
--- a/clang/test/Sema/aarch64-svepcs.c
+++ b/clang/test/Sema/aarch64-svepcs.c
@@ -15,5 +15,5 @@ void __attribute__((aarch64_sve_pcs)) foo3(void) {} // expected-error {{function
 typedef int (*fn_ty)(void);
 typedef int __attribute__((aarch64_sve_pcs)) (*aasvepcs_fn_ty)(void);
 void foo4(fn_ty ptr1, aasvepcs_fn_ty ptr2) {
-  ptr1 = ptr2; // expected-warning {{incompatible function pointer types}}
+  ptr1 = ptr2; // expected-error {{incompatible function pointer types}}
 }

diff  --git a/clang/test/Sema/aarch64-vpcs.c b/clang/test/Sema/aarch64-vpcs.c
index 93ad003241770..64a8f9e65f9fd 100644
--- a/clang/test/Sema/aarch64-vpcs.c
+++ b/clang/test/Sema/aarch64-vpcs.c
@@ -15,5 +15,5 @@ void __attribute__((aarch64_vector_pcs)) foo3(void) {} // expected-error {{funct
 typedef int (*fn_ty)(void);
 typedef int __attribute__((aarch64_vector_pcs)) (*aavpcs_fn_ty)(void);
 void foo4(fn_ty ptr1, aavpcs_fn_ty ptr2) {
-  ptr1 = ptr2; // expected-warning {{incompatible function pointer types}}
+  ptr1 = ptr2; // expected-error {{incompatible function pointer types}}
 }

diff  --git a/clang/test/Sema/arm-cmse.c b/clang/test/Sema/arm-cmse.c
index f27486fc4304d..f3b1c602bcfe0 100644
--- a/clang/test/Sema/arm-cmse.c
+++ b/clang/test/Sema/arm-cmse.c
@@ -8,8 +8,8 @@ typedef void (*callback_2t)(void);
 void foo(callback_ns_1t nsfptr, // expected-error{{functions may not be declared with 'cmse_nonsecure_call' attribute}}
          callback_1t fptr) __attribute__((cmse_nonsecure_call))
 {
-  callback_1t fp1 = nsfptr; // expected-warning{{incompatible function pointer types initializing 'callback_1t'}}
-  callback_ns_1t fp2 = fptr; // expected-warning{{incompatible function pointer types initializing 'callback_ns_1t'}}
+  callback_1t fp1 = nsfptr; // expected-error{{incompatible function pointer types initializing 'callback_1t'}}
+  callback_ns_1t fp2 = fptr; // expected-error{{incompatible function pointer types initializing 'callback_ns_1t'}}
   callback_2t fp3 = fptr;
   callback_ns_2t fp4 = nsfptr;
 }

diff  --git a/clang/test/Sema/attr-nocf_check.c b/clang/test/Sema/attr-nocf_check.c
index 0910a8060a917..59ec85ed2629b 100644
--- a/clang/test/Sema/attr-nocf_check.c
+++ b/clang/test/Sema/attr-nocf_check.c
@@ -15,7 +15,7 @@ void testNoCfCheckImpl(double __attribute__((nocf_check)) i) {} // expected-warn
 // Allow attributed function pointers as well as casting between attributed
 // and non-attributed function pointers.
 void testNoCfCheckMismatch(FuncPointer f) {
-  FuncPointerWithNoCfCheck fNoCfCheck = f; // expected-warning {{incompatible function pointer types}}
+  FuncPointerWithNoCfCheck fNoCfCheck = f; // expected-error {{incompatible function pointer types}}
   (*fNoCfCheck)();                         // no-warning
 }
 

diff  --git a/clang/test/Sema/block-return.c b/clang/test/Sema/block-return.c
index fb8b4bb698798..f66db13b9b9a3 100644
--- a/clang/test/Sema/block-return.c
+++ b/clang/test/Sema/block-return.c
@@ -81,7 +81,7 @@ static int funk(char *s) {
 void next(void);
 void foo4(void) {
   int (^xx)(const char *s) = ^(char *s) { return 1; }; // expected-error {{incompatible block pointer types initializing 'int (^)(const char *)' with an expression of type 'int (^)(char *)'}}
-  int (*yy)(const char *s) = funk; // expected-warning {{incompatible function pointer types initializing 'int (*)(const char *)' with an expression of type 'int (char *)'}}
+  int (*yy)(const char *s) = funk; // expected-error {{incompatible function pointer types initializing 'int (*)(const char *)' with an expression of type 'int (char *)'}}
 
   int (^nested)(char *s) = ^(char *str) { void (^nest)(void) = ^(void) { printf("%s\n", str); }; next(); return 1; };
 }

diff  --git a/clang/test/Sema/c2x-func-prototype.c b/clang/test/Sema/c2x-func-prototype.c
index 07b5d4286c6dc..46bce4643ebc9 100644
--- a/clang/test/Sema/c2x-func-prototype.c
+++ b/clang/test/Sema/c2x-func-prototype.c
@@ -13,7 +13,7 @@ void call(void) {
   fp call_me = func;
   call_me(1, 2, 3); // c2x-error {{too many arguments to function call, expected 0, have 3}}
 
-  fp nope = other_func; // c2x-warning {{incompatible function pointer types initializing 'fp' (aka 'void (*)(void)') with an expression of type 'void (int)'}}
+  fp nope = other_func; // c2x-error {{incompatible function pointer types initializing 'fp' (aka 'void (*)(void)') with an expression of type 'void (int)'}}
 }
 
 // Ensure these function declarations do not merge in C2x.

diff  --git a/clang/test/Sema/callingconv-ms_abi.c b/clang/test/Sema/callingconv-ms_abi.c
index 311df725d81f0..9b766f6868629 100644
--- a/clang/test/Sema/callingconv-ms_abi.c
+++ b/clang/test/Sema/callingconv-ms_abi.c
@@ -4,6 +4,6 @@ void __attribute__((ms_abi)) foo(void);
 void (*pfoo)(void) = foo;
 
 void __attribute__((sysv_abi)) bar(void);
-void (*pbar)(void) = bar; // expected-warning{{incompatible function pointer types}}
+void (*pbar)(void) = bar; // expected-error{{incompatible function pointer types}}
 
-void (__attribute__((sysv_abi)) *pfoo2)(void) = foo; // expected-warning{{incompatible function pointer types}}
+void (__attribute__((sysv_abi)) *pfoo2)(void) = foo; // expected-error{{incompatible function pointer types}}

diff  --git a/clang/test/Sema/callingconv-sysv_abi.c b/clang/test/Sema/callingconv-sysv_abi.c
index 2dcc30c92f4f9..0c4d926233e68 100644
--- a/clang/test/Sema/callingconv-sysv_abi.c
+++ b/clang/test/Sema/callingconv-sysv_abi.c
@@ -1,9 +1,9 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-pc-linux-gnu %s
 
 void __attribute__((ms_abi)) foo(void);
-void (*pfoo)(void) = foo; // expected-warning{{incompatible function pointer types}}
+void (*pfoo)(void) = foo; // expected-error{{incompatible function pointer types}}
 
 void __attribute__((sysv_abi)) bar(void);
 void (*pbar)(void) = bar;
 
-void (__attribute__((ms_abi)) *pbar2)(void) = bar; // expected-warning{{incompatible function pointer types}}
+void (__attribute__((ms_abi)) *pbar2)(void) = bar; // expected-error{{incompatible function pointer types}}

diff  --git a/clang/test/Sema/callingconv.c b/clang/test/Sema/callingconv.c
index 1555a993218f7..fd009b8973bfc 100644
--- a/clang/test/Sema/callingconv.c
+++ b/clang/test/Sema/callingconv.c
@@ -31,7 +31,7 @@ void (__attribute__((fastcall)) *pfoo)(float*) = foo;
 
 void (__attribute__((stdcall)) *pbar)(float*) = bar;
 
-void (__attribute__((cdecl)) *ptest1)(void) = test1; // expected-warning {{incompatible function pointer types}}
+void (__attribute__((cdecl)) *ptest1)(void) = test1; // expected-error {{incompatible function pointer types}}
 
 void (*pctest0)() = ctest0;
 

diff  --git a/clang/test/Sema/incompatible-function-pointer-types.c b/clang/test/Sema/incompatible-function-pointer-types.c
index d0320299ad116..da57e87dc2b1e 100644
--- a/clang/test/Sema/incompatible-function-pointer-types.c
+++ b/clang/test/Sema/incompatible-function-pointer-types.c
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 -fsyntax-only %s -Wincompatible-pointer-types -verify
-// RUN: %clang_cc1 -fsyntax-only %s -Wincompatible-function-pointer-types -verify
+// RUN: %clang_cc1 -fsyntax-only %s -Wincompatible-pointer-types -verify=hard,expected
+// RUN: %clang_cc1 -fsyntax-only %s -Wno-error=incompatible-pointer-types -verify=soft,expected
+// RUN: %clang_cc1 -fsyntax-only %s -Wincompatible-function-pointer-types -verify=hard,expected
+// RUN: %clang_cc1 -fsyntax-only %s -Wno-error=incompatible-function-pointer-types -verify=soft,expected
 
 // This test ensures that the subgroup of -Wincompatible-pointer-types warnings
 // that concern function pointers can be promoted (or not promoted) to an error
@@ -10,5 +12,6 @@ int bar(char *a, int *b) { return 0; }
 int foo(MyFnTyA x) { return 0; } // expected-note {{passing argument to parameter 'x' here}}
 
 void baz(void) {
-  foo(&bar); // expected-warning {{incompatible function pointer types passing 'int (*)(char *, int *)' to parameter of type 'MyFnTyA' (aka 'int (*)(int *, char *)')}}
+  foo(&bar); // soft-warning {{incompatible function pointer types passing 'int (*)(char *, int *)' to parameter of type 'MyFnTyA' (aka 'int (*)(int *, char *)')}} \
+                hard-error {{incompatible function pointer types passing 'int (*)(char *, int *)' to parameter of type 'MyFnTyA' (aka 'int (*)(int *, char *)')}}
 }

diff  --git a/clang/test/Sema/initialize-noreturn.c b/clang/test/Sema/initialize-noreturn.c
index 4e0d845b9b4e5..8ccefeee8455a 100644
--- a/clang/test/Sema/initialize-noreturn.c
+++ b/clang/test/Sema/initialize-noreturn.c
@@ -14,14 +14,14 @@ void foo_noproto();
 void foo_noret_noproto()  __attribute__((noreturn));
 
 void test() {
-  Fn_noret fn2 = &foo; // expected-warning {{incompatible function pointer types initializing 'Fn_noret'}}
-  Fn_noret fn3 = &foo_noret; 
-  Fn_ret fn4 = &foo_noret; 
+  Fn_noret fn2 = &foo; // expected-error {{incompatible function pointer types initializing 'Fn_noret'}}
+  Fn_noret fn3 = &foo_noret;
+  Fn_ret fn4 = &foo_noret;
   Fn_ret fn5 = &foo;
 
-  Fn_noret_noproto fn6 = &foo_noproto; // expected-warning {{incompatible function pointer types initializing 'Fn_noret_noproto'}}
-  Fn_noret_noproto fn7 = &foo_noret_noproto; 
-  Fn_ret_noproto fn8 = &foo_noret_noproto; 
+  Fn_noret_noproto fn6 = &foo_noproto; // expected-error {{incompatible function pointer types initializing 'Fn_noret_noproto'}}
+  Fn_noret_noproto fn7 = &foo_noret_noproto;
+  Fn_ret_noproto fn8 = &foo_noret_noproto;
   Fn_ret_noproto fn9 = &foo_noproto;
 }
 

diff  --git a/clang/test/Sema/noescape.c b/clang/test/Sema/noescape.c
index 39f3f6f542ac7..2e03fd6d25d2e 100644
--- a/clang/test/Sema/noescape.c
+++ b/clang/test/Sema/noescape.c
@@ -14,12 +14,12 @@ void (*funcptr_nn)(__attribute__((noescape)) int *, __attribute__((noescape)) in
 void test0(int c) {
   escapefuncptr = &escapefunc;
   escapefuncptr = &noescapefunc;
-  noescapefuncptr = &escapefunc; // expected-warning {{incompatible function pointer types assigning to 'void (*)(__attribute__((noescape)) int *)' from 'void (*)(int *)'}}
+  noescapefuncptr = &escapefunc; // expected-error {{incompatible function pointer types assigning to 'void (*)(__attribute__((noescape)) int *)' from 'void (*)(int *)'}}
   noescapefuncptr = &noescapefunc;
 
   escapefuncptr = c ? &escapefunc : &noescapefunc;
-  noescapefuncptr = c ? &escapefunc : &noescapefunc; // expected-warning {{incompatible function pointer types assigning to 'void (*)(__attribute__((noescape)) int *)' from 'void (*)(int *)'}}
+  noescapefuncptr = c ? &escapefunc : &noescapefunc; // expected-error {{incompatible function pointer types assigning to 'void (*)(__attribute__((noescape)) int *)' from 'void (*)(int *)'}}
 
   funcptr_ee = c ? &func_ne : &func_en;
-  funcptr_nn = c ? &func_ne : &func_en; // expected-warning {{incompatible function pointer types assigning to 'void (*)(__attribute__((noescape)) int *, __attribute__((noescape)) int *)' from 'void (*)(int *, int *)'}}
+  funcptr_nn = c ? &func_ne : &func_en; // expected-error {{incompatible function pointer types assigning to 'void (*)(__attribute__((noescape)) int *, __attribute__((noescape)) int *)' from 'void (*)(int *, int *)'}}
 }

diff  --git a/clang/test/Sema/overloadable.c b/clang/test/Sema/overloadable.c
index 7e52d67ea29ea..ebd9ad1b6d2aa 100644
--- a/clang/test/Sema/overloadable.c
+++ b/clang/test/Sema/overloadable.c
@@ -112,7 +112,7 @@ void fn_type_conversions() {
   void (*ambiguous)(int *) = &foo; // expected-error{{initializing 'void (*)(int *)' with an expression of incompatible type '<overloaded function type>'}} expected-note at -4{{candidate function}} expected-note at -3{{candidate function}}
   void *vp_ambiguous = &foo; // expected-error{{initializing 'void *' with an expression of incompatible type '<overloaded function type>'}} expected-note at -5{{candidate function}} expected-note at -4{{candidate function}}
 
-  void (*specific1)(int *) = (void (*)(void *))&foo; // expected-warning{{incompatible function pointer types initializing 'void (*)(int *)' with an expression of type 'void (*)(void *)'}}
+  void (*specific1)(int *) = (void (*)(void *))&foo; // expected-error{{incompatible function pointer types initializing 'void (*)(int *)' with an expression of type 'void (*)(void *)'}}
   void *specific2 = (void (*)(void *))&foo;
 
   void disabled(void *c) __attribute__((overloadable, enable_if(0, "")));
@@ -120,8 +120,8 @@ void fn_type_conversions() {
   void disabled(char *c) __attribute__((overloadable, enable_if(1, "The function name lies.")));
   // To be clear, these should all point to the last overload of 'disabled'
   void (*dptr1)(char *c) = &disabled;
-  void (*dptr2)(void *c) = &disabled; // expected-warning{{incompatible function pointer types initializing 'void (*)(void *)' with an expression of type '<overloaded function type>'}} expected-note at -5{{candidate function made ineligible by enable_if}} expected-note at -4{{candidate function made ineligible by enable_if}} expected-note at -3{{candidate function has type mismatch at 1st parameter (expected 'void *' but has 'char *')}}
-  void (*dptr3)(int *c) = &disabled; // expected-warning{{incompatible function pointer types initializing 'void (*)(int *)' with an expression of type '<overloaded function type>'}} expected-note at -6{{candidate function made ineligible by enable_if}} expected-note at -5{{candidate function made ineligible by enable_if}} expected-note at -4{{candidate function has type mismatch at 1st parameter (expected 'int *' but has 'char *')}}
+  void (*dptr2)(void *c) = &disabled; // expected-error{{incompatible function pointer types initializing 'void (*)(void *)' with an expression of type '<overloaded function type>'}} expected-note at -5{{candidate function made ineligible by enable_if}} expected-note at -4{{candidate function made ineligible by enable_if}} expected-note at -3{{candidate function has type mismatch at 1st parameter (expected 'void *' but has 'char *')}}
+  void (*dptr3)(int *c) = &disabled; // expected-error{{incompatible function pointer types initializing 'void (*)(int *)' with an expression of type '<overloaded function type>'}} expected-note at -6{{candidate function made ineligible by enable_if}} expected-note at -5{{candidate function made ineligible by enable_if}} expected-note at -4{{candidate function has type mismatch at 1st parameter (expected 'int *' but has 'char *')}}
 
   void *specific_disabled = &disabled;
 }

diff  --git a/clang/test/Sema/pass-object-size.c b/clang/test/Sema/pass-object-size.c
index c2e9f145efa2b..688290ca9890a 100644
--- a/clang/test/Sema/pass-object-size.c
+++ b/clang/test/Sema/pass-object-size.c
@@ -44,8 +44,8 @@ void FunctionPtrs(void) {
   void (*p)(void *) = NotOverloaded; //expected-error{{cannot take address of function 'NotOverloaded' because parameter 1 has pass_object_size attribute}}
   void (*p2)(void *) = &NotOverloaded; //expected-error{{cannot take address of function 'NotOverloaded' because parameter 1 has pass_object_size attribute}}
 
-  void (*p3)(void *) = IsOverloaded; //expected-warning{{incompatible function pointer types initializing 'void (*)(void *)' with an expression of type '<overloaded function type>'}}
-  void (*p4)(void *) = &IsOverloaded; //expected-warning{{incompatible function pointer types initializing 'void (*)(void *)' with an expression of type '<overloaded function type>'}}
+  void (*p3)(void *) = IsOverloaded; //expected-error{{incompatible function pointer types initializing 'void (*)(void *)' with an expression of type '<overloaded function type>'}}
+  void (*p4)(void *) = &IsOverloaded; //expected-error{{incompatible function pointer types initializing 'void (*)(void *)' with an expression of type '<overloaded function type>'}}
 
   void (*p5)(char *) = IsOverloaded;
   void (*p6)(char *) = &IsOverloaded;

diff  --git a/clang/test/Sema/preserve-call-conv.c b/clang/test/Sema/preserve-call-conv.c
index 6cd8e08cc6dc3..adb851960b2e3 100644
--- a/clang/test/Sema/preserve-call-conv.c
+++ b/clang/test/Sema/preserve-call-conv.c
@@ -14,8 +14,8 @@ void __attribute__((preserve_most(1))) foo1(void *ptr) { // expected-error {{'pr
 
 void (__attribute__((preserve_most)) *pfoo1)(void *) = foo;
 
-void (__attribute__((cdecl)) *pfoo2)(void *) = foo; // expected-warning {{incompatible function pointer types initializing 'void (*)(void *) __attribute__((cdecl))' with an expression of type 'void (void *) __attribute__((preserve_most))'}}
-void (*pfoo3)(void *) = foo; // expected-warning {{incompatible function pointer types initializing 'void (*)(void *)' with an expression of type 'void (void *) __attribute__((preserve_most))'}}
+void (__attribute__((cdecl)) *pfoo2)(void *) = foo; // expected-error {{incompatible function pointer types initializing 'void (*)(void *) __attribute__((cdecl))' with an expression of type 'void (void *) __attribute__((preserve_most))'}}
+void (*pfoo3)(void *) = foo; // expected-error {{incompatible function pointer types initializing 'void (*)(void *)' with an expression of type 'void (void *) __attribute__((preserve_most))'}}
 
 typedef_fun_t typedef_fun_foo; // expected-note {{previous declaration is here}}
 void __attribute__((preserve_most)) typedef_fun_foo(int x) { } // expected-error {{function declared 'preserve_most' here was previously declared without calling convention}}
@@ -30,8 +30,8 @@ void __attribute__((preserve_all(1))) boo1(void *ptr) { // expected-error {{'pre
 
 void (__attribute__((preserve_all)) *pboo1)(void *) = boo;
 
-void (__attribute__((cdecl)) *pboo2)(void *) = boo; // expected-warning {{incompatible function pointer types initializing 'void (*)(void *) __attribute__((cdecl))' with an expression of type 'void (void *) __attribute__((preserve_all))'}}
-void (*pboo3)(void *) = boo; // expected-warning {{incompatible function pointer types initializing 'void (*)(void *)' with an expression of type 'void (void *) __attribute__((preserve_all))'}}
+void (__attribute__((cdecl)) *pboo2)(void *) = boo; // expected-error {{incompatible function pointer types initializing 'void (*)(void *) __attribute__((cdecl))' with an expression of type 'void (void *) __attribute__((preserve_all))'}}
+void (*pboo3)(void *) = boo; // expected-error {{incompatible function pointer types initializing 'void (*)(void *)' with an expression of type 'void (void *) __attribute__((preserve_all))'}}
 
 typedef_fun_t typedef_fun_boo; // expected-note {{previous declaration is here}}
 void __attribute__((preserve_all)) typedef_fun_boo(int x) { } // expected-error {{function declared 'preserve_all' here was previously declared without calling convention}}

diff  --git a/clang/test/SemaObjC/comptypes-legal.m b/clang/test/SemaObjC/comptypes-legal.m
index 58641b1e14aff..f89aba294b86d 100644
--- a/clang/test/SemaObjC/comptypes-legal.m
+++ b/clang/test/SemaObjC/comptypes-legal.m
@@ -31,9 +31,9 @@ + (void)registerFunc:(FuncSignature *)function; // expected-note{{passing argume
 
 void foo(void)
 {
-  // GCC currently allows this (it has some fiarly new support for covariant return types and contravariant argument types).
+  // GCC currently allows this (it has some fairly new support for covariant return types and contravariant argument types).
   // Since registerFunc: expects a Derived object as it's second argument, I don't know why this would be legal.
-  [Derived registerFunc: ExternFunc];  // expected-warning{{incompatible function pointer types sending 'NSObject *(NSObject *, NSObject *)' to parameter of type 'FuncSignature *' (aka 'id (*)(NSObject *, Derived *)')}}
+  [Derived registerFunc: ExternFunc];  // expected-error{{incompatible function pointer types sending 'NSObject *(NSObject *, NSObject *)' to parameter of type 'FuncSignature *' (aka 'id (*)(NSObject *, Derived *)')}}
 }
 
 // rdar://10751015


        


More information about the cfe-commits mailing list