From: Richard Smith Date: Thu, 20 Oct 2016 00:01:36 +0000 (+0000) Subject: Fix crash on noreturn conversion in unprototyped function type. Thanks to Keith X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=562d964f19a1e9b054c26bc780e263d03233c2d3;p=clang Fix crash on noreturn conversion in unprototyped function type. Thanks to Keith Walker for spotting the bug. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@284673 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 0c7ef74a24..db97f3d57f 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -1432,7 +1432,7 @@ bool Sema::IsFunctionConversion(QualType FromType, QualType ToType, const auto *FromFn = cast(CanFrom); FunctionType::ExtInfo FromEInfo = FromFn->getExtInfo(); - const auto *ToFn = dyn_cast(CanTo); + const auto *ToFn = cast(CanTo); FunctionType::ExtInfo ToEInfo = ToFn->getExtInfo(); bool Changed = false; @@ -1445,7 +1445,7 @@ bool Sema::IsFunctionConversion(QualType FromType, QualType ToType, // Drop 'noexcept' if not present in target type. if (const auto *FromFPT = dyn_cast(FromFn)) { - const auto *ToFPT = dyn_cast(ToFn); + const auto *ToFPT = cast(ToFn); if (FromFPT->isNothrow(Context) && !ToFPT->isNothrow(Context)) { FromFn = cast( Context.getFunctionType(FromFPT->getReturnType(), diff --git a/test/Sema/initialize-noreturn.c b/test/Sema/initialize-noreturn.c index b90d46d6be..21ff29585f 100644 --- a/test/Sema/initialize-noreturn.c +++ b/test/Sema/initialize-noreturn.c @@ -4,13 +4,24 @@ typedef void (*Fn_noret)(void) __attribute__((noreturn)); typedef void (*Fn_ret)(void); +typedef void (*Fn_noret_noproto)() __attribute__((noreturn)); +typedef void (*Fn_ret_noproto)(); + void foo(void); void foo_noret(void) __attribute__((noreturn)); +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_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_ret_noproto fn9 = &foo_noproto; }