[cfe-commits] r83211 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaCXXCast.cpp lib/Sema/SemaOverload.cpp test/CodeGenCXX/cast-conversion.cpp test/SemaCXX/cast-conversion.cpp

Fariborz Jahanian fjahanian at apple.com
Thu Oct 1 13:39:52 PDT 2009


Author: fjahanian
Date: Thu Oct  1 15:39:51 2009
New Revision: 83211

URL: http://llvm.org/viewvc/llvm-project?rev=83211&view=rev
Log:
Patch to implement static casting which requires one 
user-defined type conversion. Fixes PR5040.


Added:
    cfe/trunk/test/CodeGenCXX/cast-conversion.cpp
    cfe/trunk/test/SemaCXX/cast-conversion.cpp
Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaCXXCast.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=83211&r1=83210&r2=83211&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Thu Oct  1 15:39:51 2009
@@ -766,7 +766,8 @@
                         bool SuppressUserConversions,
                         bool AllowExplicit,
                         bool ForceRValue,
-                        bool InOverloadResolution);
+                        bool InOverloadResolution,
+                        bool UserCast = false);
   bool IsStandardConversion(Expr *From, QualType ToType,
                             bool InOverloadResolution,
                             StandardConversionSequence& SCS);
@@ -790,7 +791,8 @@
                                UserDefinedConversionSequence& User,
                                OverloadCandidateSet& Conversions,
                                bool AllowConversionFunctions,
-                               bool AllowExplicit, bool ForceRValue);
+                               bool AllowExplicit, bool ForceRValue,
+                               bool UserCast = false);
   bool DiagnoseAmbiguousUserDefinedConversion(Expr *From, QualType ToType);
                                               
 

Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXCast.cpp?rev=83211&r1=83210&r2=83211&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXCast.cpp Thu Oct  1 15:39:51 2009
@@ -806,7 +806,8 @@
                                /*SuppressUserConversions=*/false,
                                /*AllowExplicit=*/true,
                                /*ForceRValue=*/false,
-                               /*InOverloadResolution=*/false);
+                               /*InOverloadResolution=*/false,
+                               /*one of user provided casts*/true);
 
   if (ICS.ConversionKind == ImplicitConversionSequence::BadConversion)
     return TC_NotApplicable;

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=83211&r1=83210&r2=83211&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Thu Oct  1 15:39:51 2009
@@ -404,11 +404,14 @@
 /// permitted.
 /// If @p ForceRValue, then overloading is performed as if From was an rvalue,
 /// no matter its actual lvalueness.
+/// If @p UserCast, the implicit conversion is being done for a user-specified
+/// cast.
 ImplicitConversionSequence
 Sema::TryImplicitConversion(Expr* From, QualType ToType,
                             bool SuppressUserConversions,
                             bool AllowExplicit, bool ForceRValue,
-                            bool InOverloadResolution) {
+                            bool InOverloadResolution,
+                            bool UserCast) {
   ImplicitConversionSequence ICS;
   OverloadCandidateSet Conversions;
   OverloadingResult UserDefResult = OR_Success;
@@ -419,7 +422,7 @@
                                    ICS.UserDefined,
                                    Conversions,
                                    !SuppressUserConversions, AllowExplicit,
-                                   ForceRValue)) == OR_Success) {
+				   ForceRValue, UserCast)) == OR_Success) {
     ICS.ConversionKind = ImplicitConversionSequence::UserDefinedConversion;
     // C++ [over.ics.user]p4:
     //   A conversion of an expression of class type to the same class
@@ -1372,12 +1375,15 @@
 ///
 /// \param ForceRValue  true if the expression should be treated as an rvalue
 /// for overload resolution.
+/// \param UserCast true if looking for user defined conversion for a static
+/// cast.
 Sema::OverloadingResult Sema::IsUserDefinedConversion(
                                    Expr *From, QualType ToType,
                                    UserDefinedConversionSequence& User,
                                    OverloadCandidateSet& CandidateSet,
                                    bool AllowConversionFunctions,
-                                   bool AllowExplicit, bool ForceRValue) {
+                                   bool AllowExplicit, bool ForceRValue,
+                                   bool UserCast) {
   if (const RecordType *ToRecordType = ToType->getAs<RecordType>()) {
     if (CXXRecordDecl *ToRecordDecl
           = dyn_cast<CXXRecordDecl>(ToRecordType->getDecl())) {
@@ -1411,11 +1417,14 @@
           if (ConstructorTmpl)
             AddTemplateOverloadCandidate(ConstructorTmpl, false, 0, 0, &From,
                                          1, CandidateSet,
-                                         /*SuppressUserConversions=*/true,
+                                         /*SuppressUserConversions=*/!UserCast,
                                          ForceRValue);
           else
+            // Allow one user-defined conversion when user specifies a
+            // From->ToType conversion via an static cast (c-style, etc).
             AddOverloadCandidate(Constructor, &From, 1, CandidateSet,
-                                 /*SuppressUserConversions=*/true, ForceRValue);
+                                 /*SuppressUserConversions=*/!UserCast, 
+                                 ForceRValue);
         }
       }
     }

Added: cfe/trunk/test/CodeGenCXX/cast-conversion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cast-conversion.cpp?rev=83211&view=auto

==============================================================================
--- cfe/trunk/test/CodeGenCXX/cast-conversion.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/cast-conversion.cpp Thu Oct  1 15:39:51 2009
@@ -0,0 +1,33 @@
+// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s &&
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s &&
+// RUN: clang-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s &&
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s &&
+// RUN: true
+
+struct A {
+  A(int);
+};
+
+struct B {
+  B(A);
+};
+
+int main () {
+  (B)10;
+  B(10);
+  static_cast<B>(10);
+}
+
+// CHECK-LP64: call     __ZN1AC1Ei
+// CHECK-LP64: call     __ZN1BC1E1A
+// CHECK-LP64: call     __ZN1AC1Ei
+// CHECK-LP64: call     __ZN1BC1E1A
+// CHECK-LP64: call     __ZN1AC1Ei
+// CHECK-LP64: call     __ZN1BC1E1A
+
+// CHECK-LP32: call     L__ZN1AC1Ei
+// CHECK-LP32: call     L__ZN1BC1E1A
+// CHECK-LP32: call     L__ZN1AC1Ei
+// CHECK-LP32: call     L__ZN1BC1E1A
+// CHECK-LP32: call     L__ZN1AC1Ei
+// CHECK-LP32: call     L__ZN1BC1E1A

Added: cfe/trunk/test/SemaCXX/cast-conversion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cast-conversion.cpp?rev=83211&view=auto

==============================================================================
--- cfe/trunk/test/SemaCXX/cast-conversion.cpp (added)
+++ cfe/trunk/test/SemaCXX/cast-conversion.cpp Thu Oct  1 15:39:51 2009
@@ -0,0 +1,21 @@
+// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x
+
+struct R {
+  R(int);
+};
+
+struct A {
+  A(R);
+};
+
+struct B {
+  B(A);
+};
+
+int main () {
+  B(10);	// expected-error {{functional-style cast from 'int' to 'struct B' is not allowed}}
+  (B)10;	// expected-error {{C-style cast from 'int' to 'struct B' is not allowed}}
+  static_cast<B>(10);	// expected-error {{static_cast from 'int' to 'struct B' is not allowed}} \\
+			// expected-warning {{expression result unused}}
+}
+





More information about the cfe-commits mailing list