diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-10-20 00:01:36 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-10-20 00:01:36 +0000 |
commit | 6f42740707bb08185c9feedb22196d63acb8abb2 (patch) | |
tree | 580a6ea4f15f0220bac1465fce1f247651ea61e6 | |
parent | 990504e625a3bf3f3276576f42e07dfdf9f74c4c (diff) | |
download | bcm5719-llvm-6f42740707bb08185c9feedb22196d63acb8abb2.tar.gz bcm5719-llvm-6f42740707bb08185c9feedb22196d63acb8abb2.zip |
Fix crash on noreturn conversion in unprototyped function type. Thanks to Keith
Walker for spotting the bug.
llvm-svn: 284673
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 4 | ||||
-rw-r--r-- | clang/test/Sema/initialize-noreturn.c | 11 |
2 files changed, 13 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 0c7ef74a248..db97f3d57f5 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1432,7 +1432,7 @@ bool Sema::IsFunctionConversion(QualType FromType, QualType ToType, const auto *FromFn = cast<FunctionType>(CanFrom); FunctionType::ExtInfo FromEInfo = FromFn->getExtInfo(); - const auto *ToFn = dyn_cast<FunctionProtoType>(CanTo); + const auto *ToFn = cast<FunctionType>(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<FunctionProtoType>(FromFn)) { - const auto *ToFPT = dyn_cast<FunctionProtoType>(ToFn); + const auto *ToFPT = cast<FunctionProtoType>(ToFn); if (FromFPT->isNothrow(Context) && !ToFPT->isNothrow(Context)) { FromFn = cast<FunctionType>( Context.getFunctionType(FromFPT->getReturnType(), diff --git a/clang/test/Sema/initialize-noreturn.c b/clang/test/Sema/initialize-noreturn.c index b90d46d6beb..21ff29585ff 100644 --- a/clang/test/Sema/initialize-noreturn.c +++ b/clang/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; } |