samitolvanen updated this revision to Diff 473306. samitolvanen added a comment.
Added release notes, grouped together with `-Wcast-function-type-strict`. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D136790/new/ https://reviews.llvm.org/D136790 Files: clang/docs/ReleaseNotes.rst clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaExpr.cpp clang/test/Sema/incompatible-function-pointer-types-strict.c
Index: clang/test/Sema/incompatible-function-pointer-types-strict.c =================================================================== --- /dev/null +++ clang/test/Sema/incompatible-function-pointer-types-strict.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only %s -Wincompatible-function-pointer-types-strict -verify=soft,strict +// RUN: %clang_cc1 -fsyntax-only %s -Werror=incompatible-function-pointer-types-strict -verify=hard,strict +// RUN: %clang_cc1 -fsyntax-only %s -Wincompatible-function-pointer-types -verify=nonstrict +// nonstrict-no-diagnostics + +enum E { A = -1, B }; +typedef enum E (*fn_a_t)(void); +typedef void (*fn_b_t)(void); + +int a(void) { return 0; } +void __attribute__((noreturn)) b(void) { while (1); } + +void fa(fn_a_t x) {} // strict-note {{passing argument to parameter 'x' here}} +void fb(fn_b_t x) {} + +void baz(void) { + fa(&a); // soft-warning {{incompatible function pointer types passing 'int (*)(void)' to parameter of type 'fn_a_t' (aka 'enum E (*)(void)')}} \ + hard-error {{incompatible function pointer types passing 'int (*)(void)' to parameter of type 'fn_a_t' (aka 'enum E (*)(void)')}} + fb(&b); // no-warning +} Index: clang/lib/Sema/SemaExpr.cpp =================================================================== --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -9449,7 +9449,8 @@ // This circumvents the usual type rules specified in 6.2.7p1 & 6.7.5.[1-3]. // FIXME: add a couple examples in this comment. static Sema::AssignConvertType -checkPointerTypesForAssignment(Sema &S, QualType LHSType, QualType RHSType) { +checkPointerTypesForAssignment(Sema &S, QualType LHSType, QualType RHSType, + SourceLocation Loc) { assert(LHSType.isCanonical() && "LHS not canonicalized!"); assert(RHSType.isCanonical() && "RHS not canonicalized!"); @@ -9518,6 +9519,13 @@ return Sema::FunctionVoidPointer; } + if (!S.Diags.isIgnored( + diag::warn_typecheck_convert_incompatible_function_pointer_strict, + Loc) && + RHSType->isFunctionPointerType() && LHSType->isFunctionPointerType() && + !S.IsFunctionConversion(RHSType, LHSType, RHSType)) + return Sema::IncompatibleFunctionPointerStrict; + // C99 6.5.16.1p1 (constraint 3): both operands are pointers to qualified or // unqualified versions of compatible types, ... QualType ltrans = QualType(lhptee, 0), rtrans = QualType(rhptee, 0); @@ -9869,7 +9877,8 @@ Kind = CK_NoOp; else Kind = CK_BitCast; - return checkPointerTypesForAssignment(*this, LHSType, RHSType); + return checkPointerTypesForAssignment(*this, LHSType, RHSType, + RHS.get()->getBeginLoc()); } // int -> T* @@ -17158,6 +17167,12 @@ ConvHints.tryToFixConversion(SrcExpr, SrcType, DstType, *this); MayHaveConvFixit = true; break; + case IncompatibleFunctionPointerStrict: + DiagKind = + diag::warn_typecheck_convert_incompatible_function_pointer_strict; + ConvHints.tryToFixConversion(SrcExpr, SrcType, DstType, *this); + MayHaveConvFixit = true; + break; case IncompatibleFunctionPointer: if (getLangOpts().CPlusPlus) { DiagKind = diag::err_typecheck_convert_incompatible_function_pointer; Index: clang/include/clang/Sema/Sema.h =================================================================== --- clang/include/clang/Sema/Sema.h +++ clang/include/clang/Sema/Sema.h @@ -12307,6 +12307,12 @@ /// extension. IncompatibleFunctionPointer, + /// IncompatibleFunctionPointerStrict - The assignment is between two + /// function pointer types that are not identical, but are compatible, + /// unless compiled with -fsanitize=cfi, in which case the type mismatch + /// may trip an indirect call runtime check. + IncompatibleFunctionPointerStrict, + /// IncompatiblePointerSign - The assignment is between two pointers types /// which point to integers which have a different sign, but are otherwise /// identical. This is a subset of the above, but broken out because it's by Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -8218,6 +8218,9 @@ def ext_typecheck_convert_incompatible_function_pointer : ExtWarn< err_typecheck_convert_incompatible_function_pointer.Text>, InGroup<IncompatibleFunctionPointerTypes>, DefaultError; +def warn_typecheck_convert_incompatible_function_pointer_strict : Warning< + err_typecheck_convert_incompatible_function_pointer.Text>, + InGroup<DiagGroup<"incompatible-function-pointer-types-strict">>, DefaultIgnore; def ext_typecheck_convert_discards_qualifiers : ExtWarn< "%select{%diff{assigning to $ from $|assigning to different types}0,1" "|%diff{passing $ to parameter of type $|" Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -366,11 +366,14 @@ - Clang now correctly points to the problematic parameter for the ``-Wnonnull`` warning. This fixes `Issue 58273 <https://github.com/llvm/llvm-project/issues/58273>`_. -- Introduced ``-Wcast-function-type-strict`` to warn about function type mismatches - in casts that may result in runtime indirect call `Control-Flow Integrity (CFI) - <https://clang.llvm.org/docs/ControlFlowIntegrity.html>`_ failures. This diagnostic - is grouped under ``-Wcast-function-type`` as it identifies a more strict set of - potentially problematic function type casts. +- Introduced ``-Wcast-function-type-strict`` and + ``-Wincompatible-function-pointer-types-strict`` to warn about function type + mismatches in casts and assignments that may result in runtime indirect call + `Control-Flow Integrity (CFI) + <https://clang.llvm.org/docs/ControlFlowIntegrity.html>`_ failures. The + ``-Wcast-function-type-strict`` diagnostic is grouped under + ``-Wcast-function-type`` as it identifies a more strict set of potentially + problematic function type casts. - Clang will now disambiguate NTTP types when printing diagnostic that contain NTTP types. Fixes `Issue 57562 <https://github.com/llvm/llvm-project/issues/57562>`_. - Better error recovery for pack expansion of expressions.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits