Hi,

It seems that 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 raise SEGV at lib/Sema/SemaCast.cpp:2101.

This patch fixes this issue by removing the assertion and add some error
diagnostics as the one in static_cast.  Please have a look.  Thanks.

Logan
From d50ceba7940388439bec118ce731c5eef1f84d71 Mon Sep 17 00:00:00 2001
From: Logan Chien <[email protected]>
Date: Mon, 17 Mar 2014 15:20:40 +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.
---
 lib/Sema/SemaCast.cpp                                | 15 +++++++++++----
 test/SemaCXX/addr-of-overloaded-function-casting.cpp | 14 ++++++++++++--
 2 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp
index 5d49225..0f45e4e 100644
--- a/lib/Sema/SemaCast.cpp
+++ b/lib/Sema/SemaCast.cpp
@@ -2097,10 +2097,17 @@ 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 784c8a0..deddcb6 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 <class T>
 void t(T); // expected-note 3{{candidate function}} \
@@ -58,4 +58,14 @@ int main()
   { bool b = static_cast<int (&)(char)>(t); } // expected-error{{does not 
match required}}
   
   { bool b = static_cast<void (&)(char)>(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 (f_type)(int);
+    f_type f_cast = static_cast<f_type>(f); // expected-error{{address of 
overloaded function}}
+    f_type f_cast = (f_type)(f); // expected-error{{address of overloaded 
function}}
+  }
 }
-- 
1.8.3.2

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to