From ab7351b1640dd4a1965d5c0e403d3b864e1f8c9b Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Sun, 13 Apr 2014 16:08:24 +0000 Subject: [PATCH] Fix diagnostics for C-style cast to function type. If the C-style type cast is applied to the overloaded function and the destination type is function type, then Clang will crash with assertion failure. For example, void foo(int); void foo(int, int); void bar() { typedef void (ft)(int); ft p = (ft)foo; } In this case, the overloaded function foo will be cast to a function type, which should be considered as an error. But, unfortunately, since the function resolution is using canonical type, the matched function will be returned, and result in SEGV. This patch fixes this issue by removing the assertion and add some error diagnostics as the one in static_cast. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@206133 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaCast.cpp | 14 ++++++++++---- .../addr-of-overloaded-function-casting.cpp | 13 +++++++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp index 5d49225ac4..41570962a2 100644 --- a/lib/Sema/SemaCast.cpp +++ b/lib/Sema/SemaCast.cpp @@ -2097,10 +2097,16 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle, DestType, /*Complain*/ true, Found); - - assert(!Fn && "cast failed but able to resolve overload expression!!"); - (void)Fn; - + if (Fn) { + // If DestType is a function type (not to be confused with the function + // pointer type), it will be possible to resolve the function address, + // but the type cast should be considered as failure. + OverloadExpr *OE = OverloadExpr::find(SrcExpr.get()).Expression; + Self.Diag(OpRange.getBegin(), diag::err_bad_cstyle_cast_overload) + << OE->getName() << DestType << OpRange + << OE->getQualifierLoc().getSourceRange(); + Self.NoteAllOverloadCandidates(SrcExpr.get()); + } } else { diagnoseBadCast(Self, msg, (FunctionalStyle ? CT_Functional : CT_CStyle), OpRange, SrcExpr.get(), DestType, ListInitialization); diff --git a/test/SemaCXX/addr-of-overloaded-function-casting.cpp b/test/SemaCXX/addr-of-overloaded-function-casting.cpp index 784c8a0007..edf4c138a8 100644 --- a/test/SemaCXX/addr-of-overloaded-function-casting.cpp +++ b/test/SemaCXX/addr-of-overloaded-function-casting.cpp @@ -1,8 +1,8 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s void g(); -void f(); // expected-note 9{{candidate function}} -void f(int); // expected-note 9{{candidate function}} +void f(); // expected-note 11{{candidate function}} +void f(int); // expected-note 11{{candidate function}} template void t(T); // expected-note 3{{candidate function}} \ @@ -58,4 +58,13 @@ int main() { bool b = static_cast(t); } // expected-error{{does not match required}} { bool b = static_cast(f); } // expected-error{{does not match}} + + { + // The error should be reported when casting overloaded function to the + // compatible function type (not to be confused with function pointer or + // function reference type.) + typedef void (FnType)(int); + FnType a = static_cast(f); // expected-error{{address of overloaded function}} + FnType b = (FnType)(f); // expected-error{{address of overloaded function}} + } } -- 2.40.0